1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
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 | * |
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> |
13 | * David Campbell |
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 | struct pci_dev *dev; |
67 | }; |
68 | |
69 | static inline void parport_gsc_write_data(struct parport *p, unsigned char d) |
70 | { |
71 | #ifdef DEBUG_PARPORT |
72 | printk(KERN_DEBUG "%s(%p,0x%02x)\n" , __func__, p, d); |
73 | #endif |
74 | parport_writeb(d, DATA(p)); |
75 | } |
76 | |
77 | static inline unsigned char parport_gsc_read_data(struct parport *p) |
78 | { |
79 | unsigned char val = parport_readb (DATA (p)); |
80 | #ifdef DEBUG_PARPORT |
81 | printk(KERN_DEBUG "%s(%p) = 0x%02x\n" , __func__, p, val); |
82 | #endif |
83 | return val; |
84 | } |
85 | |
86 | /* __parport_gsc_frob_control differs from parport_gsc_frob_control in that |
87 | * it doesn't do any extra masking. */ |
88 | static inline unsigned char __parport_gsc_frob_control(struct parport *p, |
89 | unsigned char mask, |
90 | unsigned char val) |
91 | { |
92 | struct parport_gsc_private *priv = p->physport->private_data; |
93 | unsigned char ctr = priv->ctr; |
94 | #ifdef DEBUG_PARPORT |
95 | printk(KERN_DEBUG "%s(%02x,%02x): %02x -> %02x\n" , |
96 | __func__, mask, val, |
97 | ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); |
98 | #endif |
99 | ctr = (ctr & ~mask) ^ val; |
100 | ctr &= priv->ctr_writable; /* only write writable bits. */ |
101 | parport_writeb (ctr, CONTROL (p)); |
102 | priv->ctr = ctr; /* Update soft copy */ |
103 | return ctr; |
104 | } |
105 | |
106 | static inline void parport_gsc_data_reverse(struct parport *p) |
107 | { |
108 | __parport_gsc_frob_control (p, mask: 0x20, val: 0x20); |
109 | } |
110 | |
111 | static inline void parport_gsc_data_forward(struct parport *p) |
112 | { |
113 | __parport_gsc_frob_control (p, mask: 0x20, val: 0x00); |
114 | } |
115 | |
116 | static inline void parport_gsc_write_control(struct parport *p, |
117 | unsigned char d) |
118 | { |
119 | const unsigned char wm = (PARPORT_CONTROL_STROBE | |
120 | PARPORT_CONTROL_AUTOFD | |
121 | PARPORT_CONTROL_INIT | |
122 | PARPORT_CONTROL_SELECT); |
123 | |
124 | /* Take this out when drivers have adapted to newer interface. */ |
125 | if (d & 0x20) { |
126 | printk(KERN_DEBUG "%s (%s): use data_reverse for this!\n" , |
127 | p->name, p->cad->name); |
128 | parport_gsc_data_reverse (p); |
129 | } |
130 | |
131 | __parport_gsc_frob_control (p, mask: wm, val: d & wm); |
132 | } |
133 | |
134 | static inline unsigned char parport_gsc_read_control(struct parport *p) |
135 | { |
136 | const unsigned char rm = (PARPORT_CONTROL_STROBE | |
137 | PARPORT_CONTROL_AUTOFD | |
138 | PARPORT_CONTROL_INIT | |
139 | PARPORT_CONTROL_SELECT); |
140 | const struct parport_gsc_private *priv = p->physport->private_data; |
141 | return priv->ctr & rm; /* Use soft copy */ |
142 | } |
143 | |
144 | static inline unsigned char parport_gsc_frob_control(struct parport *p, |
145 | unsigned char mask, |
146 | unsigned char val) |
147 | { |
148 | const unsigned char wm = (PARPORT_CONTROL_STROBE | |
149 | PARPORT_CONTROL_AUTOFD | |
150 | PARPORT_CONTROL_INIT | |
151 | PARPORT_CONTROL_SELECT); |
152 | |
153 | /* Take this out when drivers have adapted to newer interface. */ |
154 | if (mask & 0x20) { |
155 | printk(KERN_DEBUG "%s (%s): use data_%s for this!\n" , |
156 | p->name, p->cad->name, |
157 | (val & 0x20) ? "reverse" : "forward" ); |
158 | if (val & 0x20) |
159 | parport_gsc_data_reverse (p); |
160 | else |
161 | parport_gsc_data_forward (p); |
162 | } |
163 | |
164 | /* Restrict mask and val to control lines. */ |
165 | mask &= wm; |
166 | val &= wm; |
167 | |
168 | return __parport_gsc_frob_control (p, mask, val); |
169 | } |
170 | |
171 | static inline unsigned char parport_gsc_read_status(struct parport *p) |
172 | { |
173 | return parport_readb (STATUS(p)); |
174 | } |
175 | |
176 | static inline void parport_gsc_disable_irq(struct parport *p) |
177 | { |
178 | __parport_gsc_frob_control (p, mask: 0x10, val: 0x00); |
179 | } |
180 | |
181 | static inline void parport_gsc_enable_irq(struct parport *p) |
182 | { |
183 | __parport_gsc_frob_control (p, mask: 0x10, val: 0x10); |
184 | } |
185 | |
186 | extern void parport_gsc_release_resources(struct parport *p); |
187 | |
188 | extern int parport_gsc_claim_resources(struct parport *p); |
189 | |
190 | extern void parport_gsc_init_state(struct pardevice *, struct parport_state *s); |
191 | |
192 | extern void parport_gsc_save_state(struct parport *p, struct parport_state *s); |
193 | |
194 | extern void parport_gsc_restore_state(struct parport *p, struct parport_state *s); |
195 | |
196 | extern void parport_gsc_inc_use_count(void); |
197 | |
198 | extern void parport_gsc_dec_use_count(void); |
199 | |
200 | #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ |
201 | |