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