1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __LINUX_PARPORT_PC_H |
3 | #define __LINUX_PARPORT_PC_H |
4 | |
5 | #include <asm/io.h> |
6 | |
7 | /* --- register definitions ------------------------------- */ |
8 | |
9 | #define ECONTROL(p) ((p)->base_hi + 0x2) |
10 | #define CONFIGB(p) ((p)->base_hi + 0x1) |
11 | #define CONFIGA(p) ((p)->base_hi + 0x0) |
12 | #define FIFO(p) ((p)->base_hi + 0x0) |
13 | #define EPPDATA(p) ((p)->base + 0x4) |
14 | #define EPPADDR(p) ((p)->base + 0x3) |
15 | #define CONTROL(p) ((p)->base + 0x2) |
16 | #define STATUS(p) ((p)->base + 0x1) |
17 | #define DATA(p) ((p)->base + 0x0) |
18 | |
19 | struct parport_pc_private { |
20 | /* Contents of CTR. */ |
21 | unsigned char ctr; |
22 | |
23 | /* Bitmask of writable CTR bits. */ |
24 | unsigned char ctr_writable; |
25 | |
26 | /* Whether or not there's an ECR. */ |
27 | int ecr; |
28 | |
29 | /* Bitmask of writable ECR bits. */ |
30 | unsigned char ecr_writable; |
31 | |
32 | /* Number of PWords that FIFO will hold. */ |
33 | int fifo_depth; |
34 | |
35 | /* Number of bytes per portword. */ |
36 | int pword; |
37 | |
38 | /* Not used yet. */ |
39 | int readIntrThreshold; |
40 | int writeIntrThreshold; |
41 | |
42 | /* buffer suitable for DMA, if DMA enabled */ |
43 | char *dma_buf; |
44 | dma_addr_t dma_handle; |
45 | struct list_head list; |
46 | struct parport *port; |
47 | }; |
48 | |
49 | struct parport_pc_via_data |
50 | { |
51 | /* ISA PnP IRQ routing register 1 */ |
52 | u8 via_pci_parport_irq_reg; |
53 | /* ISA PnP DMA request routing register */ |
54 | u8 via_pci_parport_dma_reg; |
55 | /* Register and value to enable SuperIO configuration access */ |
56 | u8 via_pci_superio_config_reg; |
57 | u8 via_pci_superio_config_data; |
58 | /* SuperIO function register number */ |
59 | u8 viacfg_function; |
60 | /* parallel port control register number */ |
61 | u8 viacfg_parport_control; |
62 | /* Parallel port base address register */ |
63 | u8 viacfg_parport_base; |
64 | }; |
65 | |
66 | static __inline__ void parport_pc_write_data(struct parport *p, unsigned char d) |
67 | { |
68 | #ifdef DEBUG_PARPORT |
69 | printk (KERN_DEBUG "parport_pc_write_data(%p,0x%02x)\n" , p, d); |
70 | #endif |
71 | outb(value: d, DATA(p)); |
72 | } |
73 | |
74 | static __inline__ unsigned char parport_pc_read_data(struct parport *p) |
75 | { |
76 | unsigned char val = inb (DATA (p)); |
77 | #ifdef DEBUG_PARPORT |
78 | printk (KERN_DEBUG "parport_pc_read_data(%p) = 0x%02x\n" , |
79 | p, val); |
80 | #endif |
81 | return val; |
82 | } |
83 | |
84 | #ifdef DEBUG_PARPORT |
85 | static inline void dump_parport_state (char *str, struct parport *p) |
86 | { |
87 | /* here's hoping that reading these ports won't side-effect anything underneath */ |
88 | unsigned char ecr = inb (ECONTROL (p)); |
89 | unsigned char dcr = inb (CONTROL (p)); |
90 | unsigned char dsr = inb (STATUS (p)); |
91 | static const char *const ecr_modes[] = {"SPP" , "PS2" , "PPFIFO" , "ECP" , "xXx" , "yYy" , "TST" , "CFG" }; |
92 | const struct parport_pc_private *priv = p->physport->private_data; |
93 | int i; |
94 | |
95 | printk (KERN_DEBUG "*** parport state (%s): ecr=[%s" , str, ecr_modes[(ecr & 0xe0) >> 5]); |
96 | if (ecr & 0x10) printk (",nErrIntrEn" ); |
97 | if (ecr & 0x08) printk (",dmaEn" ); |
98 | if (ecr & 0x04) printk (",serviceIntr" ); |
99 | if (ecr & 0x02) printk (",f_full" ); |
100 | if (ecr & 0x01) printk (",f_empty" ); |
101 | for (i=0; i<2; i++) { |
102 | printk ("] dcr(%s)=[" , i ? "soft" : "hard" ); |
103 | dcr = i ? priv->ctr : inb (CONTROL (p)); |
104 | |
105 | if (dcr & 0x20) { |
106 | printk ("rev" ); |
107 | } else { |
108 | printk ("fwd" ); |
109 | } |
110 | if (dcr & 0x10) printk (",ackIntEn" ); |
111 | if (!(dcr & 0x08)) printk (",N-SELECT-IN" ); |
112 | if (dcr & 0x04) printk (",N-INIT" ); |
113 | if (!(dcr & 0x02)) printk (",N-AUTOFD" ); |
114 | if (!(dcr & 0x01)) printk (",N-STROBE" ); |
115 | } |
116 | printk ("] dsr=[" ); |
117 | if (!(dsr & 0x80)) printk ("BUSY" ); |
118 | if (dsr & 0x40) printk (",N-ACK" ); |
119 | if (dsr & 0x20) printk (",PERROR" ); |
120 | if (dsr & 0x10) printk (",SELECT" ); |
121 | if (dsr & 0x08) printk (",N-FAULT" ); |
122 | printk ("]\n" ); |
123 | return; |
124 | } |
125 | #else /* !DEBUG_PARPORT */ |
126 | #define dump_parport_state(args...) |
127 | #endif /* !DEBUG_PARPORT */ |
128 | |
129 | /* __parport_pc_frob_control differs from parport_pc_frob_control in that |
130 | * it doesn't do any extra masking. */ |
131 | static __inline__ unsigned char __parport_pc_frob_control (struct parport *p, |
132 | unsigned char mask, |
133 | unsigned char val) |
134 | { |
135 | struct parport_pc_private *priv = p->physport->private_data; |
136 | unsigned char ctr = priv->ctr; |
137 | #ifdef DEBUG_PARPORT |
138 | printk (KERN_DEBUG |
139 | "__parport_pc_frob_control(%02x,%02x): %02x -> %02x\n" , |
140 | mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); |
141 | #endif |
142 | ctr = (ctr & ~mask) ^ val; |
143 | ctr &= priv->ctr_writable; /* only write writable bits. */ |
144 | outb (value: ctr, CONTROL (p)); |
145 | priv->ctr = ctr; /* Update soft copy */ |
146 | return ctr; |
147 | } |
148 | |
149 | static __inline__ void parport_pc_data_reverse (struct parport *p) |
150 | { |
151 | __parport_pc_frob_control (p, mask: 0x20, val: 0x20); |
152 | } |
153 | |
154 | static __inline__ void parport_pc_data_forward (struct parport *p) |
155 | { |
156 | __parport_pc_frob_control (p, mask: 0x20, val: 0x00); |
157 | } |
158 | |
159 | static __inline__ void parport_pc_write_control (struct parport *p, |
160 | unsigned char d) |
161 | { |
162 | const unsigned char wm = (PARPORT_CONTROL_STROBE | |
163 | PARPORT_CONTROL_AUTOFD | |
164 | PARPORT_CONTROL_INIT | |
165 | PARPORT_CONTROL_SELECT); |
166 | |
167 | /* Take this out when drivers have adapted to newer interface. */ |
168 | if (d & 0x20) { |
169 | printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n" , |
170 | p->name, p->cad->name); |
171 | parport_pc_data_reverse (p); |
172 | } |
173 | |
174 | __parport_pc_frob_control (p, mask: wm, val: d & wm); |
175 | } |
176 | |
177 | static __inline__ unsigned char parport_pc_read_control(struct parport *p) |
178 | { |
179 | const unsigned char rm = (PARPORT_CONTROL_STROBE | |
180 | PARPORT_CONTROL_AUTOFD | |
181 | PARPORT_CONTROL_INIT | |
182 | PARPORT_CONTROL_SELECT); |
183 | const struct parport_pc_private *priv = p->physport->private_data; |
184 | return priv->ctr & rm; /* Use soft copy */ |
185 | } |
186 | |
187 | static __inline__ unsigned char parport_pc_frob_control (struct parport *p, |
188 | unsigned char mask, |
189 | unsigned char val) |
190 | { |
191 | const unsigned char wm = (PARPORT_CONTROL_STROBE | |
192 | PARPORT_CONTROL_AUTOFD | |
193 | PARPORT_CONTROL_INIT | |
194 | PARPORT_CONTROL_SELECT); |
195 | |
196 | /* Take this out when drivers have adapted to newer interface. */ |
197 | if (mask & 0x20) { |
198 | printk (KERN_DEBUG "%s (%s): use data_%s for this!\n" , |
199 | p->name, p->cad->name, |
200 | (val & 0x20) ? "reverse" : "forward" ); |
201 | if (val & 0x20) |
202 | parport_pc_data_reverse (p); |
203 | else |
204 | parport_pc_data_forward (p); |
205 | } |
206 | |
207 | /* Restrict mask and val to control lines. */ |
208 | mask &= wm; |
209 | val &= wm; |
210 | |
211 | return __parport_pc_frob_control (p, mask, val); |
212 | } |
213 | |
214 | static __inline__ unsigned char parport_pc_read_status(struct parport *p) |
215 | { |
216 | return inb(STATUS(p)); |
217 | } |
218 | |
219 | |
220 | static __inline__ void parport_pc_disable_irq(struct parport *p) |
221 | { |
222 | __parport_pc_frob_control (p, mask: 0x10, val: 0x00); |
223 | } |
224 | |
225 | static __inline__ void parport_pc_enable_irq(struct parport *p) |
226 | { |
227 | __parport_pc_frob_control (p, mask: 0x10, val: 0x10); |
228 | } |
229 | |
230 | extern void parport_pc_release_resources(struct parport *p); |
231 | |
232 | extern int parport_pc_claim_resources(struct parport *p); |
233 | |
234 | /* PCMCIA code will want to get us to look at a port. Provide a mechanism. */ |
235 | extern struct parport *parport_pc_probe_port(unsigned long base, |
236 | unsigned long base_hi, |
237 | int irq, int dma, |
238 | struct device *dev, |
239 | int irqflags); |
240 | extern void parport_pc_unregister_port(struct parport *p); |
241 | |
242 | #endif |
243 | |