File: /usr/src/linux/drivers/parport/parport_mfc3.c

1     /* Low-level parallel port routines for the Multiface 3 card
2      *
3      * Author: Joerg Dorchain <joerg@dorchain.net>
4      *
5      * (C) The elitist m68k Users(TM)
6      *
7      * based on the existing parport_amiga and lp_mfc
8      *
9      *
10      * From the MFC3 documentation:
11      * 
12      * Miscellaneous PIA Details
13      * -------------------------
14      * 
15      * 	The two open-drain interrupt outputs /IRQA and /IRQB are routed to
16      * /INT2 of the Z2 bus.
17      * 
18      * 	The CPU data bus of the PIA (D0-D7) is connected to D8-D15 on the Z2
19      * bus. This means that any PIA registers are accessed at even addresses.
20      * 
21      * Centronics Pin Connections for the PIA
22      * --------------------------------------
23      * 
24      * 	The following table shows the connections between the PIA and the
25      * Centronics interface connector. These connections implement a single, but
26      * very complete, Centronics type interface. The Pin column gives the pin
27      * numbers of the PIA. The Centronics pin numbers can be found in the section
28      * "Parallel Connectors".
29      * 
30      * 
31      *    Pin | PIA | Dir | Centronics Names
32      * -------+-----+-----+---------------------------------------------------------
33      *     19 | CB2 | --> | /STROBE (aka /DRDY)
34      *  10-17 | PBx | <-> | DATA0 - DATA7
35      *     18 | CB1 | <-- | /ACK
36      *     40 | CA1 | <-- | BUSY
37      *      3 | PA1 | <-- | PAPER-OUT (aka POUT)
38      *      4 | PA2 | <-- | SELECTED (aka SEL)
39      *      9 | PA7 | --> | /INIT (aka /RESET or /INPUT-PRIME)
40      *      6 | PA4 | <-- | /ERROR (aka /FAULT)
41      *      7 | PA5 | --> | DIR (aka /SELECT-IN)
42      *      8 | PA6 | --> | /AUTO-FEED-XT
43      *     39 | CA2 | --> | open
44      *      5 | PA3 | <-- | /ACK (same as CB1!)
45      *      2 | PA0 | <-- | BUSY (same as CA1!)
46      * -------+-----+-----+---------------------------------------------------------
47      * 
48      * Should be enough to understand some of the driver.
49      *
50      * Per convention for normal use the port registers are visible.
51      * If you need the data direction registers, restore the value in the
52      * control register.
53      */
54     
55     #include "multiface.h"
56     #include <linux/module.h>
57     #include <linux/init.h>
58     #include <linux/parport.h>
59     #include <linux/delay.h>
60     #include <linux/mc6821.h>
61     #include <linux/zorro.h>
62     #include <asm/setup.h>
63     #include <asm/amigahw.h>
64     #include <asm/irq.h>
65     #include <asm/amigaints.h>
66     
67     /* Maximum Number of Cards supported */
68     #define MAX_MFC 5
69     
70     #undef DEBUG
71     #ifdef DEBUG
72     #define DPRINTK printk
73     #else
74     static inline int DPRINTK(void *nothing, ...) {return 0;}
75     #endif
76     
77     static struct parport *this_port[MAX_MFC] = {NULL, };
78     static volatile int dummy; /* for trigger readds */
79     
80     #define pia(dev) ((struct pia *)(dev->base))
81     static struct parport_operations pp_mfc3_ops;
82     
83     static void mfc3_write_data(struct parport *p, unsigned char data)
84     {
85     DPRINTK(KERN_DEBUG "write_data %c\n",data);
86     
87     	dummy = pia(p)->pprb; /* clears irq bit */
88     	/* Triggers also /STROBE.*/
89     	pia(p)->pprb = data;
90     }
91     
92     static unsigned char mfc3_read_data(struct parport *p)
93     {
94     	/* clears interrupt bit. Triggers also /STROBE. */
95     	return pia(p)->pprb;
96     }
97     
98     static unsigned char control_pc_to_mfc3(unsigned char control)
99     {
100     	unsigned char ret = 32|64;
101     
102     	if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
103     		ret &= ~32; /* /SELECT_IN */
104     	if (control & PARPORT_CONTROL_INIT) /* INITP */
105     		ret |= 128;
106     	if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
107     		ret &= ~64;
108     	if (control & PARPORT_CONTROL_STROBE) /* Strobe */
109     		/* Handled directly by hardware */;
110     	return ret;
111     }
112     
113     static unsigned char control_mfc3_to_pc(unsigned char control)
114     {
115     	unsigned char ret = PARPORT_CONTROL_STROBE 
116     			  | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT;
117     
118     	if (control & 128) /* /INITP */
119     		ret |= PARPORT_CONTROL_INIT;
120     	if (control & 64) /* /AUTOLF */
121     		ret &= ~PARPORT_CONTROL_AUTOFD;
122     	if (control & 32) /* /SELECT_IN */
123     		ret &= ~PARPORT_CONTROL_SELECT;
124     	return ret;
125     }
126     
127     static void mfc3_write_control(struct parport *p, unsigned char control)
128     {
129     DPRINTK(KERN_DEBUG "write_control %02x\n",control);
130     	pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control);
131     }
132     	
133     static unsigned char mfc3_read_control( struct parport *p)
134     {
135     DPRINTK(KERN_DEBUG "read_control \n");
136     	return control_mfc3_to_pc(pia(p)->ppra & 0xe0);
137     }
138     
139     static unsigned char mfc3_frob_control( struct parport *p, unsigned char mask, unsigned char val)
140     {
141     	unsigned char old;
142     
143     DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
144     	old = mfc3_read_control(p);
145     	mfc3_write_control(p, (old & ~mask) ^ val);
146     	return old;
147     }
148     
149     #if 0 /* currently unused */
150     static unsigned char status_pc_to_mfc3(unsigned char status)
151     {
152     	unsigned char ret = 1;
153     
154     	if (status & PARPORT_STATUS_BUSY) /* Busy */
155     		ret &= ~1;
156     	if (status & PARPORT_STATUS_ACK) /* Ack */
157     		ret |= 8;
158     	if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
159     		ret |= 2;
160     	if (status & PARPORT_STATUS_SELECT) /* select */
161     		ret |= 4;
162     	if (status & PARPORT_STATUS_ERROR) /* error */
163     		ret |= 16;
164     	return ret;
165     }
166     #endif
167     
168     static unsigned char status_mfc3_to_pc(unsigned char status)
169     {
170     	unsigned char ret = PARPORT_STATUS_BUSY;
171     
172     	if (status & 1) /* Busy */
173     		ret &= ~PARPORT_STATUS_BUSY;
174     	if (status & 2) /* PaperOut */
175     		ret |= PARPORT_STATUS_PAPEROUT;
176     	if (status & 4) /* Selected */
177     		ret |= PARPORT_STATUS_SELECT;
178     	if (status & 8) /* Ack */
179     		ret |= PARPORT_STATUS_ACK;
180     	if (status & 16) /* /ERROR */
181     		ret |= PARPORT_STATUS_ERROR;
182     
183     	return ret;
184     }
185     
186     #if 0 /* currently unused */
187     static void mfc3_write_status( struct parport *p, unsigned char status)
188     {
189     DPRINTK(KERN_DEBUG "write_status %02x\n",status);
190     	pia(p)->ppra = (pia(p)->ppra & 0xe0) | status_pc_to_mfc3(status);
191     }
192     #endif
193     
194     static unsigned char mfc3_read_status(struct parport *p)
195     {
196     	unsigned char status;
197     
198     	status = status_mfc3_to_pc(pia(p)->ppra & 0x1f);
199     DPRINTK(KERN_DEBUG "read_status %02x\n", status);
200     	return status;
201     }
202     
203     #if 0 /* currently unused */
204     static void mfc3_change_mode( struct parport *p, int m)
205     {
206     	/* XXX: This port only has one mode, and I am
207     	not sure about the corresponding PC-style mode*/
208     }
209     #endif
210     
211     static int use_cnt = 0;
212     
213     static void mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
214     {
215     	int i;
216     
217     	for( i = 0; i < MAX_MFC; i++)
218     		if (this_port[i] != NULL)
219     			if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */
220     				dummy = pia(this_port[i])->pprb; /* clear irq bit */
221     				parport_generic_irq(irq, this_port[i], regs);
222     			}
223     }
224     
225     static void mfc3_enable_irq(struct parport *p)
226     {
227     	pia(p)->crb |= PIA_C1_ENABLE_IRQ;
228     }
229     
230     static void mfc3_disable_irq(struct parport *p)
231     {
232     	pia(p)->crb &= ~PIA_C1_ENABLE_IRQ;
233     }
234     
235     static void mfc3_data_forward(struct parport *p)
236     {
237     	DPRINTK(KERN_DEBUG "forward\n");
238     	pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
239     	pia(p)->pddrb = 255; /* all pins output */
240     	pia(p)->crb |= PIA_DDR; /* make data register visible - default */
241     }
242     
243     static void mfc3_data_reverse(struct parport *p)
244     {
245     	DPRINTK(KERN_DEBUG "reverse\n");
246     	pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
247     	pia(p)->pddrb = 0; /* all pins input */
248     	pia(p)->crb |= PIA_DDR; /* make data register visible - default */
249     }
250     
251     static void mfc3_init_state(struct pardevice *dev, struct parport_state *s)
252     {
253     	s->u.amiga.data = 0;
254     	s->u.amiga.datadir = 255;
255     	s->u.amiga.status = 0;
256     	s->u.amiga.statusdir = 0xe0;
257     }
258     
259     static void mfc3_save_state(struct parport *p, struct parport_state *s)
260     {
261     	s->u.amiga.data = pia(p)->pprb;
262     	pia(p)->crb &= ~PIA_DDR;
263     	s->u.amiga.datadir = pia(p)->pddrb;
264     	pia(p)->crb |= PIA_DDR;
265     	s->u.amiga.status = pia(p)->ppra;
266     	pia(p)->cra &= ~PIA_DDR;
267     	s->u.amiga.statusdir = pia(p)->pddrb;
268     	pia(p)->cra |= PIA_DDR;
269     }
270     
271     static void mfc3_restore_state(struct parport *p, struct parport_state *s)
272     {
273     	pia(p)->pprb = s->u.amiga.data;
274     	pia(p)->crb &= ~PIA_DDR;
275     	pia(p)->pddrb = s->u.amiga.datadir;
276     	pia(p)->crb |= PIA_DDR;
277     	pia(p)->ppra = s->u.amiga.status;
278     	pia(p)->cra &= ~PIA_DDR;
279     	pia(p)->pddrb = s->u.amiga.statusdir;
280     	pia(p)->cra |= PIA_DDR;
281     }
282     
283     static void mfc3_inc_use_count(void)
284     {
285     	MOD_INC_USE_COUNT;
286     }
287     
288     static void mfc3_dec_use_count(void)
289     {
290     	MOD_DEC_USE_COUNT;
291     }
292     
293     static struct parport_operations pp_mfc3_ops = {
294     	mfc3_write_data,
295     	mfc3_read_data,
296     
297     	mfc3_write_control,
298     	mfc3_read_control,
299     	mfc3_frob_control,
300     
301     	mfc3_read_status,
302     
303     	mfc3_enable_irq,
304     	mfc3_disable_irq,
305     
306     	mfc3_data_forward, 
307     	mfc3_data_reverse, 
308     
309     	mfc3_init_state,
310     	mfc3_save_state,
311     	mfc3_restore_state,
312     
313     	mfc3_inc_use_count,
314     	mfc3_dec_use_count,
315     
316     	parport_ieee1284_epp_write_data,
317     	parport_ieee1284_epp_read_data,
318     	parport_ieee1284_epp_write_addr,
319     	parport_ieee1284_epp_read_addr,
320     
321     	parport_ieee1284_ecp_write_data,
322     	parport_ieee1284_ecp_read_data,
323     	parport_ieee1284_ecp_write_addr,
324     
325     	parport_ieee1284_write_compat,
326     	parport_ieee1284_read_nibble,
327     	parport_ieee1284_read_byte,
328     };
329     
330     /* ----------- Initialisation code --------------------------------- */
331     
332     int __init parport_mfc3_init(void)
333     {
334     	struct parport *p;
335     	int pias;
336     	struct pia *pp;
337     	struct zorro_dev *z = NULL;
338     
339     	if (!MACH_IS_AMIGA)
340     		return -ENODEV;
341     
342     	while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) {
343     		unsigned long piabase = z->resource.start+PIABASE;
344     		if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
345     			continue;
346     
347     		pp = (struct pia *)ZTWO_VADDR(piabase);
348     		pp->crb = 0;
349     		pp->pddrb = 255; /* all data pins output */
350     		pp->crb = PIA_DDR|32|8;
351     		dummy = pp->pddrb; /* reading clears interrupt */
352     		pp->cra = 0;
353     		pp->pddra = 0xe0; /* /RESET,  /DIR ,/AUTO-FEED output */
354     		pp->cra = PIA_DDR;
355     		pp->ppra = 0; /* reset printer */
356     		udelay(10);
357     		pp->ppra = 128;
358     		p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS,
359     					  PARPORT_DMA_NONE, &pp_mfc3_ops);
360     		if (!p)
361     			goto out_port;
362     
363     		if (p->irq != PARPORT_IRQ_NONE) {
364     			if (use_cnt++ == 0)
365     				if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops))
366     					goto out_irq;
367     		}
368     
369     		this_port[pias++] = p;
370     		printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
371     		/* XXX: set operating mode */
372     		parport_proc_register(p);
373     
374     		p->private_data = (void *)piabase;
375     		parport_announce_port (p);
376     
377     		if (pias >= MAX_MFC)
378     			break;
379     		continue;
380     
381     	out_irq:
382     		parport_unregister_port(p);
383     	out_port:
384     		release_mem_region(piabase, sizeof(struct pia));
385     	}
386     
387     	return pias ? 0 : -ENODEV;
388     }
389     
390     void __exit parport_mfc3_exit(void)
391     {
392     	int i;
393     
394     	for (i = 0; i < MAX_MFC; i++) {
395     		if (!this_port[i])
396     			continue;
397     		if (!this_port[i]->irq != PARPORT_IRQ_NONE) {
398     			if (--use_cnt == 0) 
399     				free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
400     		}
401     		parport_proc_unregister(this_port[i]);
402     		parport_unregister_port(this_port[i]);
403     		release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia));
404     	}
405     }
406     
407     
408     MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
409     MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralllel Port");
410     MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port");
411     
412     module_init(parport_mfc3_init)
413     module_exit(parport_mfc3_exit)
414     
415