Linux 2.3.7pre1
[davej-history.git] / drivers / char / lp_intern.c
blob45f2a289b45e70aa738dfccb6be38e1fb803ebfc
2 /*
3 * split into mid and low-level for better support of different hardware
4 * by Joerg Dorchain (dorchain@mpi-sb.mpg.de)
6 * Amiga printer device by Michael Rausch (linux@uni-koblenz.de);
7 * Atari support added by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de);
8 * based upon work from
10 * Copyright (C) 1992 by Jim Weigand and Linus Torvalds
11 * Copyright (C) 1992,1993 by Michael K. Johnson
12 * - Thanks much to Gunter Windau for pointing out to me where the error
13 * checking ought to be.
14 * Copyright (C) 1993 by Nigel Gamble (added interrupt code)
17 #include <linux/module.h>
18 #include <linux/config.h>
19 #include <linux/kernel.h>
20 #include <linux/types.h>
21 #include <linux/sched.h>
22 #include <linux/init.h>
23 #include <asm/irq.h>
24 #include <asm/setup.h>
25 #ifdef CONFIG_AMIGA
26 #include <asm/amigahw.h>
27 #include <asm/amigaints.h>
28 #endif
29 #ifdef CONFIG_ATARI
30 #include <linux/delay.h>
31 #include <linux/sched.h>
32 #include <asm/atarihw.h>
33 #include <asm/atariints.h>
34 #endif
35 #ifdef CONFIG_MVME16x
36 #include <asm/mvme16xhw.h>
37 #endif
38 #ifdef CONFIG_BVME6000
39 #include<asm/bvme6000hw.h>
40 #endif
41 #include <linux/lp_intern.h>
43 static int minor = -1;
44 MODULE_PARM(minor,"i");
46 static void lp_int_out(int, int);
47 static int lp_int_busy(int);
48 static int lp_int_pout(int);
49 static int lp_int_online(int);
52 static void
53 lp_int_out (int c, int dev)
55 switch (m68k_machtype)
57 #ifdef CONFIG_AMIGA
58 case MACH_AMIGA:
60 int wait = 0;
61 while (wait != lp_table[dev]->wait) wait++;
62 ciaa.prb = c;
64 break;
65 #endif
66 #ifdef CONFIG_ATARI
67 case MACH_ATARI:
69 int wait = 0;
70 sound_ym.rd_data_reg_sel = 15;
71 sound_ym.wd_data = c;
72 sound_ym.rd_data_reg_sel = 14;
73 while (wait != lp_table[dev]->wait) wait++;
74 sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~(1 << 5);
75 while (wait) wait--;
76 sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
77 break;
79 #endif
80 #ifdef CONFIG_MVME16x
81 case MACH_MVME16x:
83 int wait = 0;
84 while (wait != lp_table[dev]->wait) wait++;
85 mvmelp.data = c;
86 break;
88 #endif
89 #ifdef CONFIG_BVME6000
90 case MACH_BVME6000:
92 int wait = 0;
93 while (wait != lp_table[dev]->wait) wait++;
94 bvmepit.padr = c;
95 bvmepit.pacr |= 0x02;
96 break;
98 #endif
102 static int
103 lp_int_busy (int dev)
105 switch (m68k_machtype)
107 #ifdef CONFIG_AMIGA
108 case MACH_AMIGA:
109 return ciab.pra & 1;
110 #endif
111 #ifdef CONFIG_ATARI
112 case MACH_ATARI:
113 return mfp.par_dt_reg & 1;
114 #endif
115 #ifdef CONFIG_MVME16x
116 case MACH_MVME16x:
117 return mvmelp.isr & 1;
118 #endif
119 #ifdef CONFIG_BVME6000
120 case MACH_BVME6000:
121 return 0 /* !(bvmepit.psr & 0x40) */ ;
122 #endif
123 default:
124 return 0;
128 static int
129 lp_int_pout (int dev)
131 switch (m68k_machtype)
133 #ifdef CONFIG_AMIGA
134 case MACH_AMIGA:
135 return ciab.pra & 2;
136 #endif
137 #ifdef CONFIG_ATARI
138 case MACH_ATARI:
139 return 0;
140 #endif
141 #ifdef CONFIG_MVME16x
142 case MACH_MVME16x:
143 return mvmelp.isr & 2;
144 #endif
145 #ifdef CONFIG_BVME6000
146 case MACH_BVME6000:
147 return 0;
148 #endif
149 default:
150 return 0;
154 static int
155 lp_int_online (int dev)
157 switch (m68k_machtype)
159 #ifdef CONFIG_AMIGA
160 case MACH_AMIGA:
161 return ciab.pra & 4;
162 #endif
163 #ifdef CONFIG_ATARI
164 case MACH_ATARI:
165 return !(mfp.par_dt_reg & 1);
166 #endif
167 #ifdef CONFIG_MVME16x
168 case MACH_MVME16x:
169 return mvmelp.isr & 4;
170 #endif
171 #ifdef CONFIG_BVME6000
172 case MACH_BVME6000:
173 return 1;
174 #endif
175 default:
176 return 0;
180 static void lp_int_interrupt(int irq, void *data, struct pt_regs *fp)
182 #ifdef CONFIG_MVME16x
183 if (MACH_IS_MVME16x)
184 mvmelp.ack_icr |= 0x08;
185 #endif
186 #ifdef CONFIG_BVME6000
187 if (MACH_IS_BVME6000)
188 bvmepit.pacr &= ~0x02;
189 #endif
190 lp_interrupt(minor);
193 static int lp_int_open(int dev)
195 MOD_INC_USE_COUNT;
196 return 0;
199 static void lp_int_release(int dev)
201 MOD_DEC_USE_COUNT;
204 static struct lp_struct tab = {
205 "Builtin parallel port", /* name */
206 0, /* irq */
207 lp_int_out,
208 lp_int_busy,
209 lp_int_pout,
210 lp_int_online,
212 NULL, /* ioctl */
213 lp_int_open,
214 lp_int_release,
215 LP_EXIST,
216 LP_INIT_CHAR,
217 LP_INIT_TIME,
218 LP_INIT_WAIT,
219 NULL,
220 NULL,
223 __initfunc(int lp_internal_init(void))
225 #ifdef CONFIG_AMIGA
226 if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_PARALLEL))
228 ciaa.ddrb = 0xff;
229 ciab.ddra &= 0xf8;
230 if (lp_irq)
231 tab.irq = request_irq(IRQ_AMIGA_CIAA_FLG, lp_int_interrupt,
232 0, "builtin printer port", lp_int_interrupt);
233 tab.base = (void *) &ciaa.prb; /* dummy, not used */
234 tab.type = LP_AMIGA;
236 #endif
237 #ifdef CONFIG_ATARI
238 if (MACH_IS_ATARI)
240 unsigned long flags;
242 save_flags(flags);
243 cli();
244 sound_ym.rd_data_reg_sel = 7;
245 sound_ym.wd_data = (sound_ym.rd_data_reg_sel & 0x3f) | 0xc0;
246 restore_flags(flags);
247 if (lp_irq)
248 tab.irq = request_irq(IRQ_MFP_BUSY, lp_int_interrupt,
249 IRQ_TYPE_SLOW, "builtin printer port", lp_int_interrupt);
250 tab.base = (void *) &sound_ym.wd_data; /* dummy, not used */
251 tab.type = LP_ATARI;
253 #endif
254 #ifdef CONFIG_MAC
255 if (MACH_IS_MAC)
256 return -ENODEV;
257 #endif
258 #ifdef CONFIG_MVME16x
259 if (MACH_IS_MVME16x)
261 unsigned long flags;
263 if (!(mvme16x_config & MVME16x_CONFIG_GOT_LP))
264 return -ENODEV;
266 save_flags(flags);
267 cli();
268 mvmelp.ack_icr = 0x08;
269 mvmelp.flt_icr = 0x08;
270 mvmelp.sel_icr = 0x08;
271 mvmelp.pe_icr = 0x08;
272 mvmelp.bsy_icr = 0x08;
273 mvmelp.cr = 0x10;
274 mvmelp.ack_icr = 0xd9; /* Int on trailing edge of ACK */
275 restore_flags(flags);
277 if (lp_irq)
278 tab.irq = request_irq(MVME167_IRQ_PRN, lp_int_interrupt,
279 0, "builtin printer port", lp_int_interrupt);
280 tab.base = (void *)&mvmelp; /* dummy, not used */
281 tab.type = LP_MVME167;
283 #endif
284 #ifdef CONFIG_BVME6000
285 if (MACH_IS_BVME6000)
287 unsigned long flags;
289 save_flags(flags);
290 cli();
291 bvmepit.pgcr = 0x0f;
292 bvmepit.psrr = 0x18;
293 bvmepit.paddr = 0xff;
294 bvmepit.pcdr = (bvmepit.pcdr & 0xfc) | 0x02;
295 bvmepit.pcddr |= 0x03;
296 bvmepit.pacr = 0x78;
297 bvmepit.pbcr = 0x00;
298 bvmepit.pivr = BVME_IRQ_PRN;
299 bvmepit.pgcr = 0x1f;
300 restore_flags(flags);
302 if (lp_irq)
303 tab.irq = request_irq(BVME_IRQ_PRN, lp_int_interrupt,
304 0, "builtin printer port", lp_int_interrupt);
305 tab.base = (void *)&bvmepit; /* dummy, not used */
306 tab.type = LP_BVME6000;
308 #endif
311 if ((minor = register_parallel(&tab, minor)) < 0) {
312 printk("builtin lp init: cant get a minor\n");
313 if (lp_irq) {
314 #ifdef CONFIG_AMIGA
315 if (MACH_IS_AMIGA)
316 free_irq(IRQ_AMIGA_CIAA_FLG, lp_int_interrupt);
317 #endif
318 #ifdef CONFIG_ATARI
319 if (MACH_IS_ATARI)
320 free_irq(IRQ_MFP_BUSY, lp_int_interrupt);
321 #endif
322 #ifdef CONFIG_MVME16x
323 if (MACH_IS_MVME16x)
324 free_irq(MVME167_IRQ_PRN, lp_int_interrupt);
325 #endif
326 #ifdef CONFIG_BVME6000
327 if (MACH_IS_BVME6000)
328 free_irq(BVME_IRQ_PRN, lp_int_interrupt);
329 #endif
331 return -ENODEV;
334 return 0;
337 #ifdef MODULE
338 int init_module(void)
340 return lp_internal_init();
343 void cleanup_module(void)
345 if (lp_irq) {
346 #ifdef CONFIG_AMIGA
347 if (MACH_IS_AMIGA)
348 free_irq(IRQ_AMIGA_CIAA_FLG, lp_int_interrupt);
349 #endif
350 #ifdef CONFIG_ATARI
351 if (MACH_IS_ATARI)
352 free_irq(IRQ_MFP_BUSY, lp_int_interrupt);
353 #endif
354 #ifdef CONFIG_MVME16x
355 if (MACH_IS_MVME16x)
356 free_irq(MVME167_IRQ_PRN, lp_int_interrupt);
357 #endif
358 #ifdef CONFIG_BVME6000
359 if (MACH_IS_BVME6000)
360 free_irq(BVME_IRQ_PRN, lp_int_interrupt);
361 #endif
363 unregister_parallel(minor);
365 #endif