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