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
74static inline int DPRINTK(void *nothing, ...) {return 0;}
75#endif
76
77static struct parport *this_port[MAX_MFC] = {NULL, };
78static volatile int dummy; /* for trigger readds */
79
80#define pia(dev) ((struct pia *)(dev->base))
81static struct parport_operations pp_mfc3_ops;
82
83static void mfc3_write_data(struct parport *p, unsigned char data)
84{
85DPRINTK(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
92static unsigned char mfc3_read_data(struct parport *p)
93{
94	/* clears interrupt bit. Triggers also /STROBE. */
95	return pia(p)->pprb;
96}
97
98static unsigned char control_pc_to_mfc3(unsigned char control)
99{
100	unsigned char ret = 32|64;
101
102	if (control & PARPORT_CONTROL_SELECT)
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
113static 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
127static void mfc3_write_control(struct parport *p, unsigned char control)
128{
129DPRINTK(KERN_DEBUG "write_control %02x\n",control);
130	pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control);
131}
132
133static unsigned char mfc3_read_control( struct parport *p)
134{
135DPRINTK(KERN_DEBUG "read_control \n");
136	return control_mfc3_to_pc(pia(p)->ppra & 0xe0);
137}
138
139static unsigned char mfc3_frob_control( struct parport *p, unsigned char mask, unsigned char val)
140{
141	unsigned char old;
142
143DPRINTK(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
150static unsigned char status_mfc3_to_pc(unsigned char status)
151{
152	unsigned char ret = PARPORT_STATUS_BUSY;
153
154	if (status & 1) /* Busy */
155		ret &= ~PARPORT_STATUS_BUSY;
156	if (status & 2) /* PaperOut */
157		ret |= PARPORT_STATUS_PAPEROUT;
158	if (status & 4) /* Selected */
159		ret |= PARPORT_STATUS_SELECT;
160	if (status & 8) /* Ack */
161		ret |= PARPORT_STATUS_ACK;
162	if (status & 16) /* /ERROR */
163		ret |= PARPORT_STATUS_ERROR;
164
165	return ret;
166}
167
168
169static unsigned char mfc3_read_status(struct parport *p)
170{
171	unsigned char status;
172
173	status = status_mfc3_to_pc(pia(p)->ppra & 0x1f);
174DPRINTK(KERN_DEBUG "read_status %02x\n", status);
175	return status;
176}
177
178
179static int use_cnt = 0;
180
181static void mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
182{
183	int i;
184
185	for( i = 0; i < MAX_MFC; i++)
186		if (this_port[i] != NULL)
187			if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */
188				dummy = pia(this_port[i])->pprb; /* clear irq bit */
189				parport_generic_irq(irq, this_port[i], regs);
190			}
191}
192
193static void mfc3_enable_irq(struct parport *p)
194{
195	pia(p)->crb |= PIA_C1_ENABLE_IRQ;
196}
197
198static void mfc3_disable_irq(struct parport *p)
199{
200	pia(p)->crb &= ~PIA_C1_ENABLE_IRQ;
201}
202
203static void mfc3_data_forward(struct parport *p)
204{
205	DPRINTK(KERN_DEBUG "forward\n");
206	pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
207	pia(p)->pddrb = 255; /* all pins output */
208	pia(p)->crb |= PIA_DDR; /* make data register visible - default */
209}
210
211static void mfc3_data_reverse(struct parport *p)
212{
213	DPRINTK(KERN_DEBUG "reverse\n");
214	pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
215	pia(p)->pddrb = 0; /* all pins input */
216	pia(p)->crb |= PIA_DDR; /* make data register visible - default */
217}
218
219static void mfc3_init_state(struct pardevice *dev, struct parport_state *s)
220{
221	s->u.amiga.data = 0;
222	s->u.amiga.datadir = 255;
223	s->u.amiga.status = 0;
224	s->u.amiga.statusdir = 0xe0;
225}
226
227static void mfc3_save_state(struct parport *p, struct parport_state *s)
228{
229	s->u.amiga.data = pia(p)->pprb;
230	pia(p)->crb &= ~PIA_DDR;
231	s->u.amiga.datadir = pia(p)->pddrb;
232	pia(p)->crb |= PIA_DDR;
233	s->u.amiga.status = pia(p)->ppra;
234	pia(p)->cra &= ~PIA_DDR;
235	s->u.amiga.statusdir = pia(p)->pddrb;
236	pia(p)->cra |= PIA_DDR;
237}
238
239static void mfc3_restore_state(struct parport *p, struct parport_state *s)
240{
241	pia(p)->pprb = s->u.amiga.data;
242	pia(p)->crb &= ~PIA_DDR;
243	pia(p)->pddrb = s->u.amiga.datadir;
244	pia(p)->crb |= PIA_DDR;
245	pia(p)->ppra = s->u.amiga.status;
246	pia(p)->cra &= ~PIA_DDR;
247	pia(p)->pddrb = s->u.amiga.statusdir;
248	pia(p)->cra |= PIA_DDR;
249}
250
251static void mfc3_inc_use_count(void)
252{
253	MOD_INC_USE_COUNT;
254}
255
256static void mfc3_dec_use_count(void)
257{
258	MOD_DEC_USE_COUNT;
259}
260
261static struct parport_operations pp_mfc3_ops = {
262	mfc3_write_data,
263	mfc3_read_data,
264
265	mfc3_write_control,
266	mfc3_read_control,
267	mfc3_frob_control,
268
269	mfc3_read_status,
270
271	mfc3_enable_irq,
272	mfc3_disable_irq,
273
274	mfc3_data_forward,
275	mfc3_data_reverse,
276
277	mfc3_init_state,
278	mfc3_save_state,
279	mfc3_restore_state,
280
281	mfc3_inc_use_count,
282	mfc3_dec_use_count,
283
284	parport_ieee1284_epp_write_data,
285	parport_ieee1284_epp_read_data,
286	parport_ieee1284_epp_write_addr,
287	parport_ieee1284_epp_read_addr,
288
289	parport_ieee1284_ecp_write_data,
290	parport_ieee1284_ecp_read_data,
291	parport_ieee1284_ecp_write_addr,
292
293	parport_ieee1284_write_compat,
294	parport_ieee1284_read_nibble,
295	parport_ieee1284_read_byte,
296};
297
298/* ----------- Initialisation code --------------------------------- */
299
300int __init parport_mfc3_init(void)
301{
302	struct parport *p;
303	int pias = 0;
304	struct pia *pp;
305	struct zorro_dev *z = NULL;
306
307	if (!MACH_IS_AMIGA)
308		return -ENODEV;
309
310	while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) {
311		unsigned long piabase = z->resource.start+PIABASE;
312		if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
313			continue;
314
315		pp = (struct pia *)ZTWO_VADDR(piabase);
316		pp->crb = 0;
317		pp->pddrb = 255; /* all data pins output */
318		pp->crb = PIA_DDR|32|8;
319		dummy = pp->pddrb; /* reading clears interrupt */
320		pp->cra = 0;
321		pp->pddra = 0xe0; /* /RESET,  /DIR ,/AUTO-FEED output */
322		pp->cra = PIA_DDR;
323		pp->ppra = 0; /* reset printer */
324		udelay(10);
325		pp->ppra = 128;
326		p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS,
327					  PARPORT_DMA_NONE, &pp_mfc3_ops);
328		if (!p)
329			goto out_port;
330
331		if (p->irq != PARPORT_IRQ_NONE) {
332			if (use_cnt++ == 0)
333				if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops))
334					goto out_irq;
335		}
336
337		this_port[pias++] = p;
338		printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
339		parport_proc_register(p);
340
341		p->private_data = (void *)piabase;
342		parport_announce_port (p);
343
344		if (pias >= MAX_MFC)
345			break;
346		continue;
347
348	out_irq:
349		parport_unregister_port(p);
350	out_port:
351		release_mem_region(piabase, sizeof(struct pia));
352	}
353
354	return pias ? 0 : -ENODEV;
355}
356
357void __exit parport_mfc3_exit(void)
358{
359	int i;
360
361	for (i = 0; i < MAX_MFC; i++) {
362		if (!this_port[i])
363			continue;
364		if (!this_port[i]->irq != PARPORT_IRQ_NONE) {
365			if (--use_cnt == 0)
366				free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
367		}
368		parport_proc_unregister(this_port[i]);
369		parport_unregister_port(this_port[i]);
370		release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia));
371	}
372}
373
374
375MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
376MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralllel Port");
377MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port");
378MODULE_LICENSE("GPL");
379
380module_init(parport_mfc3_init)
381module_exit(parport_mfc3_exit)
382
383