File: /usr/src/linux/drivers/media/video/cpia_pp.c

1     /*
2      * cpia_pp CPiA Parallel Port driver
3      *
4      * Supports CPiA based parallel port Video Camera's.
5      *
6      * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
7      * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@mindspring.com>,
8      * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com>
9      *
10      * This program is free software; you can redistribute it and/or modify
11      * it under the terms of the GNU General Public License as published by
12      * the Free Software Foundation; either version 2 of the License, or
13      * (at your option) any later version.
14      *
15      * This program is distributed in the hope that it will be useful,
16      * but WITHOUT ANY WARRANTY; without even the implied warranty of
17      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18      * GNU General Public License for more details.
19      *
20      * You should have received a copy of the GNU General Public License
21      * along with this program; if not, write to the Free Software
22      * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23      */
24     
25     #include <linux/config.h>
26     #include <linux/version.h>
27     
28     #include <linux/module.h>
29     #include <linux/init.h>
30     
31     #include <linux/kernel.h>
32     #include <linux/parport.h>
33     #include <linux/interrupt.h>
34     #include <linux/delay.h>
35     #include <linux/smp_lock.h>
36     
37     #include <linux/kmod.h>
38     
39     /* #define _CPIA_DEBUG_		define for verbose debug output */
40     #include "cpia.h"
41     
42     static int cpia_pp_open(void *privdata);
43     static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
44                                         void *cbdata);
45     static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
46     static int cpia_pp_streamStart(void *privdata);
47     static int cpia_pp_streamStop(void *privdata);
48     static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
49     static int cpia_pp_close(void *privdata);
50     
51     #define ABOUT "Parallel port driver for Vision CPiA based cameras"
52     
53     /* IEEE 1284 Compatiblity Mode signal names 	*/
54     #define nStrobe		PARPORT_CONTROL_STROBE	  /* inverted */
55     #define nAutoFd		PARPORT_CONTROL_AUTOFD	  /* inverted */
56     #define nInit		PARPORT_CONTROL_INIT
57     #define nSelectIn	PARPORT_CONTROL_SELECT
58     #define IntrEnable	PARPORT_CONTROL_INTEN	  /* normally zero for no IRQ */
59     #define DirBit		PARPORT_CONTROL_DIRECTION /* 0 = Forward, 1 = Reverse	*/
60     
61     #define nFault		PARPORT_STATUS_ERROR
62     #define Select		PARPORT_STATUS_SELECT
63     #define PError		PARPORT_STATUS_PAPEROUT
64     #define nAck		PARPORT_STATUS_ACK
65     #define Busy		PARPORT_STATUS_BUSY	  /* inverted */	
66     
67     /* some more */
68     #define HostClk		nStrobe
69     #define HostAck		nAutoFd
70     #define nReverseRequest	nInit
71     #define Active_1284	nSelectIn
72     #define nPeriphRequest	nFault
73     #define XFlag		Select
74     #define nAckReverse	PError
75     #define PeriphClk	nAck
76     #define PeriphAck	Busy
77     
78     /* these can be used to correct for the inversion on some bits */
79     #define STATUS_INVERSION_MASK	(Busy)
80     #define CONTROL_INVERSION_MASK	(nStrobe|nAutoFd|nSelectIn)
81     
82     #define ECR_empty	0x01
83     #define ECR_full	0x02
84     #define ECR_serviceIntr 0x04
85     #define ECR_dmaEn	0x08
86     #define ECR_nErrIntrEn	0x10
87     
88     #define ECR_mode_mask	0xE0
89     #define ECR_SPP_mode	0x00
90     #define ECR_PS2_mode	0x20
91     #define ECR_FIFO_mode	0x40
92     #define ECR_ECP_mode	0x60
93     
94     #define ECP_FIFO_SIZE	16
95     #define DMA_BUFFER_SIZE               PAGE_SIZE
96     	/* for 16bit DMA make sure DMA_BUFFER_SIZE is 16 bit aligned */
97     #define PARPORT_CHUNK_SIZE	PAGE_SIZE/* >=2.3.x */
98     				/* we read this many bytes at once */
99     
100     #define GetECRMasked(port,mask)	(parport_read_econtrol(port) & (mask))
101     #define GetStatus(port)		((parport_read_status(port)^STATUS_INVERSION_MASK)&(0xf8))
102     #define SetStatus(port,val)	parport_write_status(port,(val)^STATUS_INVERSION_MASK)
103     #define GetControl(port)	((parport_read_control(port)^CONTROL_INVERSION_MASK)&(0x3f))
104     #define SetControl(port,val)	parport_write_control(port,(val)^CONTROL_INVERSION_MASK)
105     
106     #define GetStatusMasked(port,mask)	(GetStatus(port) & (mask))
107     #define GetControlMasked(port,mask)	(GetControl(port) & (mask))
108     #define SetControlMasked(port,mask)	SetControl(port,GetControl(port) | (mask));
109     #define ClearControlMasked(port,mask)	SetControl(port,GetControl(port)&~(mask));
110     #define FrobControlBit(port,mask,value)	SetControl(port,(GetControl(port)&~(mask))|((value)&(mask)));
111     
112     #define PACKET_LENGTH 	8
113     
114     /* Magic numbers for defining port-device mappings */
115     #define PPCPIA_PARPORT_UNSPEC -4
116     #define PPCPIA_PARPORT_AUTO -3
117     #define PPCPIA_PARPORT_OFF -2
118     #define PPCPIA_PARPORT_NONE -1
119     
120     #ifdef MODULE
121     static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
122     static char *parport[PARPORT_MAX] = {NULL,};
123     
124     MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
125     MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
126     MODULE_PARM(parport, "1-" __MODULE_STRING(PARPORT_MAX) "s");
127     MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
128     #else
129     static int parport_nr[PARPORT_MAX] __initdata =
130     	{[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
131     static int parport_ptr = 0;
132     #endif
133     
134     struct pp_cam_entry {
135     	struct pardevice *pdev;
136     	struct parport *port;
137     	struct tq_struct cb_task;
138     	int open_count;
139     	wait_queue_head_t wq_stream;
140     	/* image state flags */
141     	int image_ready;	/* we got an interrupt */
142     	int image_complete;	/* we have seen 4 EOI */
143     
144     	int streaming; /* we are in streaming mode */
145     	int stream_irq;
146     };
147     
148     static struct cpia_camera_ops cpia_pp_ops = 
149     {
150     	cpia_pp_open,
151     	cpia_pp_registerCallback,
152     	cpia_pp_transferCmd,
153     	cpia_pp_streamStart,
154     	cpia_pp_streamStop,
155     	cpia_pp_streamRead,
156     	cpia_pp_close,
157     	1
158     };
159     
160     static struct cam_data *cam_list;
161     
162     #ifdef _CPIA_DEBUG_
163     #define DEB_PORT(port) { \
164     u8 controll = GetControl(port); \
165     u8 statusss = GetStatus(port); \
166     DBG("nsel %c per %c naut %c nstrob %c nak %c busy %c nfaul %c sel %c init %c dir %c\n",\
167     ((controll & nSelectIn)	? 'U' : 'D'), \
168     ((statusss & PError)	? 'U' : 'D'), \
169     ((controll & nAutoFd)	? 'U' : 'D'), \
170     ((controll & nStrobe)	? 'U' : 'D'), \
171     ((statusss & nAck)	? 'U' : 'D'), \
172     ((statusss & Busy)	? 'U' : 'D'), \
173     ((statusss & nFault)	? 'U' : 'D'), \
174     ((statusss & Select)	? 'U' : 'D'), \
175     ((controll & nInit)	? 'U' : 'D'), \
176     ((controll & DirBit)	? 'R' : 'F')  \
177     ); }
178     #else
179     #define DEB_PORT(port) {}
180     #endif
181     
182     #define WHILE_OUT_TIMEOUT (HZ/10)
183     #define DMA_TIMEOUT 10*HZ
184     
185     /* FIXME */
186     static void cpia_parport_enable_irq( struct parport *port ) {
187     	parport_enable_irq(port);
188     	mdelay(10);
189     	return;
190     }
191     
192     static void cpia_parport_disable_irq( struct parport *port ) {
193     	parport_disable_irq(port);
194     	mdelay(10);
195     	return;
196     }
197     
198     /****************************************************************************
199      *
200      *  EndTransferMode
201      *
202      ***************************************************************************/
203     static void EndTransferMode(struct pp_cam_entry *cam)
204     {
205     	parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
206     }
207     
208     /****************************************************************************
209      *
210      *  ForwardSetup
211      *
212      ***************************************************************************/
213     static int ForwardSetup(struct pp_cam_entry *cam)
214     {
215     	int retry;
216     	
217     	/* After some commands the camera needs extra time before
218     	 * it will respond again, so we try up to 3 times */
219     	for(retry=0; retry<3; ++retry) {
220     		if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
221     			break;
222     		}
223     	}
224     	if(retry == 3) {
225     		DBG("Unable to negotiate ECP mode\n");
226     		return -1;
227     	}
228     	return 0;
229     }
230     
231     /****************************************************************************
232      *
233      *  ReverseSetup
234      *
235      ***************************************************************************/
236     static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
237     {
238     	int retry;
239     	int mode = IEEE1284_MODE_ECP;
240     	if(extensibility) mode = 8|3|IEEE1284_EXT_LINK;
241     
242     	/* After some commands the camera needs extra time before
243     	 * it will respond again, so we try up to 3 times */
244     	for(retry=0; retry<3; ++retry) {
245     		if(!parport_negotiate(cam->port, mode)) {
246     			break;
247     		}
248     	}
249     	if(retry == 3) {
250     		if(extensibility)
251     			DBG("Unable to negotiate extensibility mode\n");
252     		else
253     			DBG("Unable to negotiate ECP mode\n");
254     		return -1;
255     	}
256     	if(extensibility) cam->port->ieee1284.mode = IEEE1284_MODE_ECP;
257     	return 0;
258     }
259     
260     /****************************************************************************
261      *
262      *  WritePacket
263      *
264      ***************************************************************************/
265     static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
266     {
267     	int retval=0;
268     	int size_written;
269     
270     	if (packet == NULL) {
271     		return -EINVAL;
272     	}
273     	if (ForwardSetup(cam)) {
274     		DBG("Write failed in setup\n");
275     		return -EIO;
276     	}
277     	size_written = parport_write(cam->port, packet, size);
278     	if(size_written != size) {
279     		DBG("Write failed, wrote %d/%d\n", size_written, size);
280     		retval = -EIO;
281     	}
282     	EndTransferMode(cam);
283     	return retval;
284     }
285     
286     /****************************************************************************
287      *
288      *  ReadPacket
289      *
290      ***************************************************************************/
291     static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
292     {
293     	int retval=0;
294     	if (packet == NULL) {
295     		return -EINVAL;
296     	}
297     	if (ReverseSetup(cam, 0)) {
298     		return -EIO;
299     	}
300     	if(parport_read(cam->port, packet, size) != size) {
301     		retval = -EIO;
302     	}
303     	EndTransferMode(cam);
304     	return retval;
305     }
306     
307     /****************************************************************************
308      *
309      *  cpia_pp_streamStart
310      *
311      ***************************************************************************/
312     static int cpia_pp_streamStart(void *privdata)
313     {
314     	struct pp_cam_entry *cam = privdata;
315     	DBG("\n");
316     	cam->streaming=1;
317     	cam->image_ready=0;
318     	//if (ReverseSetup(cam,1)) return -EIO;
319     	if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
320     	return 0;
321     }
322     
323     /****************************************************************************
324      *
325      *  cpia_pp_streamStop
326      *
327      ***************************************************************************/
328     static int cpia_pp_streamStop(void *privdata)
329     {
330     	struct pp_cam_entry *cam = privdata;
331     
332     	DBG("\n");
333     	cam->streaming=0;
334     	cpia_parport_disable_irq(cam->port);
335     	//EndTransferMode(cam);
336     
337     	return 0;
338     }
339     
340     static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
341     {
342     	int bytes_read, new_bytes;
343     	for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
344     		new_bytes = parport_read(port, buffer+bytes_read,
345     			                 len-bytes_read);
346     		if(new_bytes < 0) break;
347     	}
348     	return bytes_read;
349     }
350     
351     /****************************************************************************
352      *
353      *  cpia_pp_streamRead
354      *
355      ***************************************************************************/
356     static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
357     {
358     	struct pp_cam_entry *cam = privdata;
359     	int read_bytes = 0;
360     	int i, endseen, block_size, new_bytes;
361     
362     	if(cam == NULL) {
363     		DBG("Internal driver error: cam is NULL\n");
364     		return -EINVAL;
365     	}
366     	if(buffer == NULL) {
367     		DBG("Internal driver error: buffer is NULL\n");
368     		return -EINVAL;
369     	}
370     	//if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
371     	if( cam->stream_irq ) {
372     		DBG("%d\n", cam->image_ready);
373     		cam->image_ready--;
374     	}
375     	cam->image_complete=0;
376     	if (0/*cam->streaming*/) {
377     		if(!cam->image_ready) {
378     			if(noblock) return -EWOULDBLOCK;
379     			interruptible_sleep_on(&cam->wq_stream);
380     			if( signal_pending(current) ) return -EINTR;
381     			DBG("%d\n", cam->image_ready);
382     		}
383     	} else {
384     		if (ReverseSetup(cam, 1)) {
385     			DBG("unable to ReverseSetup\n");
386     			return -EIO;
387     		}
388     	}
389     	endseen = 0;
390     	block_size = PARPORT_CHUNK_SIZE;
391     	while( !cam->image_complete ) {
392     		if(current->need_resched)  schedule();
393     		
394     		new_bytes = cpia_pp_read(cam->port, buffer, block_size );
395     		if( new_bytes <= 0 ) {
396     			break;
397     		}
398     		i=-1;
399     		while(++i<new_bytes && endseen<4) {
400     	        	if(*buffer==EOI) {
401     	                	endseen++;
402     	                } else {
403     	                	endseen=0;
404     	                }
405     			buffer++;
406     		}
407     		read_bytes += i;
408     		if( endseen==4 ) {
409     			cam->image_complete=1;
410     			break;
411     		}
412     		if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
413     			block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
414     		}
415     	}
416     	EndTransferMode(cam);
417     	return cam->image_complete ? read_bytes : -EIO;
418     }
419     
420     /****************************************************************************
421      *
422      *  cpia_pp_transferCmd
423      *
424      ***************************************************************************/
425     static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
426     {
427     	int err;
428     	int retval=0;
429     	int databytes;
430     	struct pp_cam_entry *cam = privdata;
431     
432     	if(cam == NULL) {
433     		DBG("Internal driver error: cam is NULL\n");
434     		return -EINVAL;
435     	}
436     	if(command == NULL) {
437     		DBG("Internal driver error: command is NULL\n");
438     		return -EINVAL;
439     	}
440     	databytes = (((int)command[7])<<8) | command[6];
441     	if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
442     		DBG("Error writing command\n");
443     		return err;
444     	}
445     	if(command[0] == DATA_IN) {
446     		u8 buffer[8];
447     		if(data == NULL) {
448     			DBG("Internal driver error: data is NULL\n");
449     			return -EINVAL;
450     		}
451     		if((err = ReadPacket(cam, buffer, 8)) < 0) {
452     			return err;
453     			DBG("Error reading command result\n");
454     		}
455     		memcpy(data, buffer, databytes);
456     	} else if(command[0] == DATA_OUT) {
457     		if(databytes > 0) {
458     			if(data == NULL) {
459     				DBG("Internal driver error: data is NULL\n");
460     				retval = -EINVAL;
461     			} else {
462     				if((err=WritePacket(cam, data, databytes)) < 0){
463     					DBG("Error writing command data\n");
464     					return err;
465     				}
466     			}
467     		}
468     	} else {
469     		DBG("Unexpected first byte of command: %x\n", command[0]);
470     		retval = -EINVAL;
471     	}
472     	return retval;
473     }
474     
475     /****************************************************************************
476      *
477      *  cpia_pp_open
478      *
479      ***************************************************************************/
480     static int cpia_pp_open(void *privdata)
481     {
482     	struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
483     	
484     	if (cam == NULL)
485     		return -EINVAL;
486     	
487     	if(cam->open_count == 0) {
488     		if (parport_claim(cam->pdev)) {
489     			DBG("failed to claim the port\n");
490     			return -EBUSY;
491     		}
492     		parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
493     		parport_data_forward(cam->port);
494     		parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
495     		udelay(50);
496     		parport_write_control(cam->port,
497     		                      PARPORT_CONTROL_SELECT
498     		                      | PARPORT_CONTROL_INIT);
499     	}
500     	
501     	++cam->open_count;
502     	
503     	return 0;
504     }
505     
506     /****************************************************************************
507      *
508      *  cpia_pp_registerCallback
509      *
510      ***************************************************************************/
511     static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
512     {
513     	struct pp_cam_entry *cam = privdata;
514     	int retval = 0;
515     	
516     	if(cam->port->irq != PARPORT_IRQ_NONE) {
517     		cam->cb_task.routine = cb;
518     		cam->cb_task.data = cbdata;
519     	} else {
520     		retval = -1;
521     	}
522     	return retval;
523     }
524     
525     /****************************************************************************
526      *
527      *  cpia_pp_close
528      *
529      ***************************************************************************/
530     static int cpia_pp_close(void *privdata)
531     {
532     	struct pp_cam_entry *cam = privdata;
533     	if (--cam->open_count == 0) {
534     		parport_release(cam->pdev);
535     	}
536     	return 0;
537     }
538     
539     /****************************************************************************
540      *
541      *  cpia_pp_register
542      *
543      ***************************************************************************/
544     static int cpia_pp_register(struct parport *port)
545     {
546     	struct pardevice *pdev = NULL;
547     	struct pp_cam_entry *cam;
548     	struct cam_data *cpia;
549     
550     	if (!(port->modes & PARPORT_MODE_ECP) &&
551     	    !(port->modes & PARPORT_MODE_TRISTATE)) {
552     		LOG("port is not ECP capable\n");
553     		return -ENXIO;
554     	}
555     
556     	cam = kmalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
557     	if (cam == NULL) {
558     		LOG("failed to allocate camera structure\n");
559     		return -ENOMEM;
560     	}
561     	memset(cam,0,sizeof(struct pp_cam_entry));
562     	
563     	pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
564     	                               NULL, 0, cam);
565     
566     	if (!pdev) {
567     		LOG("failed to parport_register_device\n");
568     		kfree(cam);
569     		return -ENXIO;
570     	}
571     
572     	cam->pdev = pdev;
573     	cam->port = port;
574     	init_waitqueue_head(&cam->wq_stream);
575     
576     	cam->streaming = 0;
577     	cam->stream_irq = 0;
578     
579     	if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
580     		LOG("failed to cpia_register_camera\n");
581     		parport_unregister_device(pdev);
582     		kfree(cam);
583     		return -ENXIO;
584     	}
585     	ADD_TO_LIST(cam_list, cpia);
586     
587     	return 0;
588     }
589     
590     static void cpia_pp_detach (struct parport *port)
591     {
592     	struct cam_data *cpia;
593     
594     	for(cpia = cam_list; cpia != NULL; cpia = cpia->next) {
595     		struct pp_cam_entry *cam = cpia->lowlevel_data;
596     		if (cam && cam->port->number == port->number) {
597     			REMOVE_FROM_LIST(cpia);
598     			
599     			cpia_unregister_camera(cpia);
600     			
601     			if(cam->open_count > 0) {
602     				cpia_pp_close(cam);
603     			}
604     
605     			parport_unregister_device(cam->pdev);
606     		
607     			kfree(cam);
608     			cpia->lowlevel_data = NULL;
609     			break;
610     		}
611     	}
612     }
613     
614     static void cpia_pp_attach (struct parport *port)
615     {
616     	unsigned int i;
617     
618     	switch (parport_nr[0])
619     	{
620     	case PPCPIA_PARPORT_UNSPEC:
621     	case PPCPIA_PARPORT_AUTO:
622     		if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
623     		    port->probe_info[0].cmdset == NULL ||
624     		    strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
625     			return;
626     
627     		cpia_pp_register(port);
628     
629     		break;
630     
631     	default:
632     		for (i = 0; i < PARPORT_MAX; ++i) {
633     			if (port->number == parport_nr[i]) {
634     				cpia_pp_register(port);
635     				break;
636     			}
637     		}
638     		break;
639     	}
640     }
641     
642     static struct parport_driver cpia_pp_driver = {
643     	"cpia_pp",
644     	cpia_pp_attach,
645     	cpia_pp_detach,
646     	NULL
647     };
648     
649     int cpia_pp_init(void)
650     {
651     	printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, 
652     	       CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
653     
654     	if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
655     		printk("  disabled\n");
656     		return 0;
657     	}
658     	
659     	if (parport_register_driver (&cpia_pp_driver)) {
660     		LOG ("unable to register with parport\n");
661     		return -EIO;
662     	}
663     
664     	return 0;
665     }
666     
667     #ifdef MODULE
668     int init_module(void)
669     {
670     	if (parport[0]) {
671     		/* The user gave some parameters.  Let's see what they were. */
672     		if (!strncmp(parport[0], "auto", 4)) {
673     			parport_nr[0] = PPCPIA_PARPORT_AUTO;
674     		} else {
675     			int n;
676     			for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
677     				if (!strncmp(parport[n], "none", 4)) {
678     					parport_nr[n] = PPCPIA_PARPORT_NONE;
679     				} else {
680     					char *ep;
681     					unsigned long r = simple_strtoul(parport[n], &ep, 0);
682     					if (ep != parport[n]) {
683     						parport_nr[n] = r;
684     					} else {
685     						LOG("bad port specifier `%s'\n", parport[n]);
686     						return -ENODEV;
687     					}
688     				}
689     			}
690     		}
691     	}
692     #if defined(CONFIG_KMOD) && defined(CONFIG_PNP_PARPORT_MODULE)
693     	if(parport_enumerate() && !parport_enumerate()->probe_info.model) {
694     		request_module("parport_probe");
695     	}
696     #endif
697     	return cpia_pp_init();
698     }
699     
700     void cleanup_module(void)
701     {
702     	parport_unregister_driver (&cpia_pp_driver);
703     	return;
704     }
705     
706     #else /* !MODULE */
707     
708     static int __init cpia_pp_setup(char *str)
709     {
710     #if 0
711     	/* Is this only a 2.2ism? -jerdfelt */
712     	if (!str) {
713     		if (ints[0] == 0 || ints[1] == 0) {
714     			/* disable driver on "cpia_pp=" or "cpia_pp=0" */
715     			parport_nr[0] = PPCPIA_PARPORT_OFF;
716     		}
717     	} else
718     #endif
719     	if (!strncmp(str, "parport", 7)) {
720     		int n = simple_strtoul(str + 7, NULL, 10);
721     		if (parport_ptr < PARPORT_MAX) {
722     			parport_nr[parport_ptr++] = n;
723     		} else {
724     			LOG("too many ports, %s ignored.\n", str);
725     		}
726     	} else if (!strcmp(str, "auto")) {
727     		parport_nr[0] = PPCPIA_PARPORT_AUTO;
728     	} else if (!strcmp(str, "none")) {
729     		parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
730     	}
731     
732     	return 0;
733     }
734     
735     __setup("cpia_pp=", cpia_pp_setup);
736     
737     #endif /* !MODULE */
738