1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Low-level parallel-support for PC-style hardware integrated in the
4*4882a593Smuzhiyun * LASI-Controller (on GSC-Bus) for HP-PARISC Workstations
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * (C) 1999-2001 by Helge Deller <deller@gmx.de>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * based on parport_pc.c by
9*4882a593Smuzhiyun * Grant Guenther <grant@torque.net>
10*4882a593Smuzhiyun * Phil Blundell <Philip.Blundell@pobox.com>
11*4882a593Smuzhiyun * Tim Waugh <tim@cyberelk.demon.co.uk>
12*4882a593Smuzhiyun * Jose Renau <renau@acm.org>
13*4882a593Smuzhiyun * David Campbell
14*4882a593Smuzhiyun * Andrea Arcangeli
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #ifndef __DRIVERS_PARPORT_PARPORT_GSC_H
18*4882a593Smuzhiyun #define __DRIVERS_PARPORT_PARPORT_GSC_H
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <asm/io.h>
21*4882a593Smuzhiyun #include <linux/delay.h>
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #undef DEBUG_PARPORT /* undefine for production */
24*4882a593Smuzhiyun #define DELAY_TIME 0
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #if DELAY_TIME == 0
27*4882a593Smuzhiyun #define parport_readb gsc_readb
28*4882a593Smuzhiyun #define parport_writeb gsc_writeb
29*4882a593Smuzhiyun #else
parport_readb(unsigned long port)30*4882a593Smuzhiyun static __inline__ unsigned char parport_readb( unsigned long port )
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun udelay(DELAY_TIME);
33*4882a593Smuzhiyun return gsc_readb(port);
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun
parport_writeb(unsigned char value,unsigned long port)36*4882a593Smuzhiyun static __inline__ void parport_writeb( unsigned char value, unsigned long port )
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun gsc_writeb(value,port);
39*4882a593Smuzhiyun udelay(DELAY_TIME);
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun #endif
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /* --- register definitions ------------------------------- */
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #define EPPDATA(p) ((p)->base + 0x4)
46*4882a593Smuzhiyun #define EPPADDR(p) ((p)->base + 0x3)
47*4882a593Smuzhiyun #define CONTROL(p) ((p)->base + 0x2)
48*4882a593Smuzhiyun #define STATUS(p) ((p)->base + 0x1)
49*4882a593Smuzhiyun #define DATA(p) ((p)->base + 0x0)
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun struct parport_gsc_private {
52*4882a593Smuzhiyun /* Contents of CTR. */
53*4882a593Smuzhiyun unsigned char ctr;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* Bitmask of writable CTR bits. */
56*4882a593Smuzhiyun unsigned char ctr_writable;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /* Number of bytes per portword. */
59*4882a593Smuzhiyun int pword;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* Not used yet. */
62*4882a593Smuzhiyun int readIntrThreshold;
63*4882a593Smuzhiyun int writeIntrThreshold;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /* buffer suitable for DMA, if DMA enabled */
66*4882a593Smuzhiyun char *dma_buf;
67*4882a593Smuzhiyun dma_addr_t dma_handle;
68*4882a593Smuzhiyun struct pci_dev *dev;
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun
parport_gsc_write_data(struct parport * p,unsigned char d)71*4882a593Smuzhiyun static inline void parport_gsc_write_data(struct parport *p, unsigned char d)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun #ifdef DEBUG_PARPORT
74*4882a593Smuzhiyun printk(KERN_DEBUG "%s(%p,0x%02x)\n", __func__, p, d);
75*4882a593Smuzhiyun #endif
76*4882a593Smuzhiyun parport_writeb(d, DATA(p));
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
parport_gsc_read_data(struct parport * p)79*4882a593Smuzhiyun static inline unsigned char parport_gsc_read_data(struct parport *p)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun unsigned char val = parport_readb (DATA (p));
82*4882a593Smuzhiyun #ifdef DEBUG_PARPORT
83*4882a593Smuzhiyun printk(KERN_DEBUG "%s(%p) = 0x%02x\n", __func__, p, val);
84*4882a593Smuzhiyun #endif
85*4882a593Smuzhiyun return val;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /* __parport_gsc_frob_control differs from parport_gsc_frob_control in that
89*4882a593Smuzhiyun * it doesn't do any extra masking. */
__parport_gsc_frob_control(struct parport * p,unsigned char mask,unsigned char val)90*4882a593Smuzhiyun static inline unsigned char __parport_gsc_frob_control(struct parport *p,
91*4882a593Smuzhiyun unsigned char mask,
92*4882a593Smuzhiyun unsigned char val)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun struct parport_gsc_private *priv = p->physport->private_data;
95*4882a593Smuzhiyun unsigned char ctr = priv->ctr;
96*4882a593Smuzhiyun #ifdef DEBUG_PARPORT
97*4882a593Smuzhiyun printk(KERN_DEBUG "%s(%02x,%02x): %02x -> %02x\n",
98*4882a593Smuzhiyun __func__, mask, val,
99*4882a593Smuzhiyun ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun ctr = (ctr & ~mask) ^ val;
102*4882a593Smuzhiyun ctr &= priv->ctr_writable; /* only write writable bits. */
103*4882a593Smuzhiyun parport_writeb (ctr, CONTROL (p));
104*4882a593Smuzhiyun priv->ctr = ctr; /* Update soft copy */
105*4882a593Smuzhiyun return ctr;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
parport_gsc_data_reverse(struct parport * p)108*4882a593Smuzhiyun static inline void parport_gsc_data_reverse(struct parport *p)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun __parport_gsc_frob_control (p, 0x20, 0x20);
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
parport_gsc_data_forward(struct parport * p)113*4882a593Smuzhiyun static inline void parport_gsc_data_forward(struct parport *p)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun __parport_gsc_frob_control (p, 0x20, 0x00);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
parport_gsc_write_control(struct parport * p,unsigned char d)118*4882a593Smuzhiyun static inline void parport_gsc_write_control(struct parport *p,
119*4882a593Smuzhiyun unsigned char d)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun const unsigned char wm = (PARPORT_CONTROL_STROBE |
122*4882a593Smuzhiyun PARPORT_CONTROL_AUTOFD |
123*4882a593Smuzhiyun PARPORT_CONTROL_INIT |
124*4882a593Smuzhiyun PARPORT_CONTROL_SELECT);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /* Take this out when drivers have adapted to newer interface. */
127*4882a593Smuzhiyun if (d & 0x20) {
128*4882a593Smuzhiyun printk(KERN_DEBUG "%s (%s): use data_reverse for this!\n",
129*4882a593Smuzhiyun p->name, p->cad->name);
130*4882a593Smuzhiyun parport_gsc_data_reverse (p);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun __parport_gsc_frob_control (p, wm, d & wm);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
parport_gsc_read_control(struct parport * p)136*4882a593Smuzhiyun static inline unsigned char parport_gsc_read_control(struct parport *p)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun const unsigned char rm = (PARPORT_CONTROL_STROBE |
139*4882a593Smuzhiyun PARPORT_CONTROL_AUTOFD |
140*4882a593Smuzhiyun PARPORT_CONTROL_INIT |
141*4882a593Smuzhiyun PARPORT_CONTROL_SELECT);
142*4882a593Smuzhiyun const struct parport_gsc_private *priv = p->physport->private_data;
143*4882a593Smuzhiyun return priv->ctr & rm; /* Use soft copy */
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
parport_gsc_frob_control(struct parport * p,unsigned char mask,unsigned char val)146*4882a593Smuzhiyun static inline unsigned char parport_gsc_frob_control(struct parport *p,
147*4882a593Smuzhiyun unsigned char mask,
148*4882a593Smuzhiyun unsigned char val)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun const unsigned char wm = (PARPORT_CONTROL_STROBE |
151*4882a593Smuzhiyun PARPORT_CONTROL_AUTOFD |
152*4882a593Smuzhiyun PARPORT_CONTROL_INIT |
153*4882a593Smuzhiyun PARPORT_CONTROL_SELECT);
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun /* Take this out when drivers have adapted to newer interface. */
156*4882a593Smuzhiyun if (mask & 0x20) {
157*4882a593Smuzhiyun printk(KERN_DEBUG "%s (%s): use data_%s for this!\n",
158*4882a593Smuzhiyun p->name, p->cad->name,
159*4882a593Smuzhiyun (val & 0x20) ? "reverse" : "forward");
160*4882a593Smuzhiyun if (val & 0x20)
161*4882a593Smuzhiyun parport_gsc_data_reverse (p);
162*4882a593Smuzhiyun else
163*4882a593Smuzhiyun parport_gsc_data_forward (p);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /* Restrict mask and val to control lines. */
167*4882a593Smuzhiyun mask &= wm;
168*4882a593Smuzhiyun val &= wm;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun return __parport_gsc_frob_control (p, mask, val);
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
parport_gsc_read_status(struct parport * p)173*4882a593Smuzhiyun static inline unsigned char parport_gsc_read_status(struct parport *p)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun return parport_readb (STATUS(p));
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
parport_gsc_disable_irq(struct parport * p)178*4882a593Smuzhiyun static inline void parport_gsc_disable_irq(struct parport *p)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun __parport_gsc_frob_control (p, 0x10, 0x00);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
parport_gsc_enable_irq(struct parport * p)183*4882a593Smuzhiyun static inline void parport_gsc_enable_irq(struct parport *p)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun __parport_gsc_frob_control (p, 0x10, 0x10);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun extern void parport_gsc_release_resources(struct parport *p);
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun extern int parport_gsc_claim_resources(struct parport *p);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun extern void parport_gsc_init_state(struct pardevice *, struct parport_state *s);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun extern void parport_gsc_save_state(struct parport *p, struct parport_state *s);
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun extern void parport_gsc_restore_state(struct parport *p, struct parport_state *s);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun extern void parport_gsc_inc_use_count(void);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun extern void parport_gsc_dec_use_count(void);
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun extern struct parport *parport_gsc_probe_port(unsigned long base,
203*4882a593Smuzhiyun unsigned long base_hi,
204*4882a593Smuzhiyun int irq, int dma,
205*4882a593Smuzhiyun struct parisc_device *padev);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */
208