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@securenym.net>,
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 /* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
26 /* #define _CPIA_DEBUG_  1 */
27 
28 #include <linux/config.h>
29 #include <linux/version.h>
30 
31 #include <linux/module.h>
32 #include <linux/init.h>
33 
34 #include <linux/kernel.h>
35 #include <linux/parport.h>
36 #include <linux/interrupt.h>
37 #include <linux/delay.h>
38 #include <linux/smp_lock.h>
39 #include <linux/sched.h>
40 
41 #include <linux/kmod.h>
42 
43 /* #define _CPIA_DEBUG_		define for verbose debug output */
44 #include "cpia.h"
45 
46 static int cpia_pp_open(void *privdata);
47 static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
48                                     void *cbdata);
49 static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
50 static int cpia_pp_streamStart(void *privdata);
51 static int cpia_pp_streamStop(void *privdata);
52 static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
53 static int cpia_pp_close(void *privdata);
54 
55 #define ABOUT "Parallel port driver for Vision CPiA based cameras"
56 
57 #define PACKET_LENGTH 	8
58 
59 /* Magic numbers for defining port-device mappings */
60 #define PPCPIA_PARPORT_UNSPEC -4
61 #define PPCPIA_PARPORT_AUTO -3
62 #define PPCPIA_PARPORT_OFF -2
63 #define PPCPIA_PARPORT_NONE -1
64 
65 #ifdef MODULE
66 static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
67 static char *parport[PARPORT_MAX] = {NULL,};
68 
69 MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
70 MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
71 MODULE_LICENSE("GPL");
72 
73 MODULE_PARM(parport, "1-" __MODULE_STRING(PARPORT_MAX) "s");
74 MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
75 #else
76 static int parport_nr[PARPORT_MAX] __initdata =
77 	{[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
78 static int parport_ptr = 0;
79 #endif
80 
81 struct pp_cam_entry {
82 	struct pardevice *pdev;
83 	struct parport *port;
84 	struct tq_struct cb_task;
85 	int open_count;
86 	wait_queue_head_t wq_stream;
87 	/* image state flags */
88 	int image_ready;	/* we got an interrupt */
89 	int image_complete;	/* we have seen 4 EOI */
90 
91 	int streaming; /* we are in streaming mode */
92 	int stream_irq;
93 };
94 
95 static struct cpia_camera_ops cpia_pp_ops =
96 {
97 	cpia_pp_open,
98 	cpia_pp_registerCallback,
99 	cpia_pp_transferCmd,
100 	cpia_pp_streamStart,
101 	cpia_pp_streamStop,
102 	cpia_pp_streamRead,
103 	cpia_pp_close,
104 	1,
105 	THIS_MODULE
106 };
107 
108 static LIST_HEAD(cam_list);
109 static spinlock_t cam_list_lock_pp;
110 
111 /* FIXME */
cpia_parport_enable_irq(struct parport * port)112 static void cpia_parport_enable_irq( struct parport *port ) {
113 	parport_enable_irq(port);
114 	mdelay(10);
115 	return;
116 }
117 
cpia_parport_disable_irq(struct parport * port)118 static void cpia_parport_disable_irq( struct parport *port ) {
119 	parport_disable_irq(port);
120 	mdelay(10);
121 	return;
122 }
123 
124 /* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
125  * Link Flag during negotiation */
126 #define UPLOAD_FLAG  0x08
127 #define ECP_TRANSFER 0x03
128 
129 #define PARPORT_CHUNK_SIZE	PAGE_SIZE
130 
131 
132 /****************************************************************************
133  *
134  *  EndTransferMode
135  *
136  ***************************************************************************/
EndTransferMode(struct pp_cam_entry * cam)137 static void EndTransferMode(struct pp_cam_entry *cam)
138 {
139 	parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
140 }
141 
142 /****************************************************************************
143  *
144  *  ForwardSetup
145  *
146  ***************************************************************************/
ForwardSetup(struct pp_cam_entry * cam)147 static int ForwardSetup(struct pp_cam_entry *cam)
148 {
149 	int retry;
150 
151 	/* After some commands the camera needs extra time before
152 	 * it will respond again, so we try up to 3 times */
153 	for(retry=0; retry<3; ++retry) {
154 		if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
155 			break;
156 		}
157 	}
158 	if(retry == 3) {
159 		DBG("Unable to negotiate ECP mode\n");
160 		return -1;
161 	}
162 	return 0;
163 }
164 
165 /****************************************************************************
166  *
167  *  ReverseSetup
168  *
169  ***************************************************************************/
ReverseSetup(struct pp_cam_entry * cam,int extensibility)170 static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
171 {
172 	int retry;
173 	int mode = IEEE1284_MODE_ECP;
174 	if(extensibility) mode = UPLOAD_FLAG|ECP_TRANSFER|IEEE1284_EXT_LINK;
175 
176 	/* After some commands the camera needs extra time before
177 	 * it will respond again, so we try up to 3 times */
178 	for(retry=0; retry<3; ++retry) {
179 		if(!parport_negotiate(cam->port, mode)) {
180 			break;
181 		}
182 	}
183 	if(retry == 3) {
184 		if(extensibility)
185 			DBG("Unable to negotiate extensibility mode\n");
186 		else
187 			DBG("Unable to negotiate ECP mode\n");
188 		return -1;
189 	}
190 	if(extensibility) cam->port->ieee1284.mode = IEEE1284_MODE_ECP;
191 	return 0;
192 }
193 
194 /****************************************************************************
195  *
196  *  WritePacket
197  *
198  ***************************************************************************/
WritePacket(struct pp_cam_entry * cam,const u8 * packet,size_t size)199 static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
200 {
201 	int retval=0;
202 	int size_written;
203 
204 	if (packet == NULL) {
205 		return -EINVAL;
206 	}
207 	if (ForwardSetup(cam)) {
208 		DBG("Write failed in setup\n");
209 		return -EIO;
210 	}
211 	size_written = parport_write(cam->port, packet, size);
212 	if(size_written != size) {
213 		DBG("Write failed, wrote %d/%d\n", size_written, size);
214 		retval = -EIO;
215 	}
216 	EndTransferMode(cam);
217 	return retval;
218 }
219 
220 /****************************************************************************
221  *
222  *  ReadPacket
223  *
224  ***************************************************************************/
ReadPacket(struct pp_cam_entry * cam,u8 * packet,size_t size)225 static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
226 {
227 	int retval=0;
228 	if (packet == NULL) {
229 		return -EINVAL;
230 	}
231 	if (ReverseSetup(cam, 0)) {
232 		return -EIO;
233 	}
234 	if(parport_read(cam->port, packet, size) != size) {
235 		retval = -EIO;
236 	}
237 	EndTransferMode(cam);
238 	return retval;
239 }
240 
241 /****************************************************************************
242  *
243  *  cpia_pp_streamStart
244  *
245  ***************************************************************************/
cpia_pp_streamStart(void * privdata)246 static int cpia_pp_streamStart(void *privdata)
247 {
248 	struct pp_cam_entry *cam = privdata;
249 	DBG("\n");
250 	cam->streaming=1;
251 	cam->image_ready=0;
252 	//if (ReverseSetup(cam,1)) return -EIO;
253 	if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
254 	return 0;
255 }
256 
257 /****************************************************************************
258  *
259  *  cpia_pp_streamStop
260  *
261  ***************************************************************************/
cpia_pp_streamStop(void * privdata)262 static int cpia_pp_streamStop(void *privdata)
263 {
264 	struct pp_cam_entry *cam = privdata;
265 
266 	DBG("\n");
267 	cam->streaming=0;
268 	cpia_parport_disable_irq(cam->port);
269 	//EndTransferMode(cam);
270 
271 	return 0;
272 }
273 
274 /****************************************************************************
275  *
276  *  cpia_pp_streamRead
277  *
278  ***************************************************************************/
cpia_pp_read(struct parport * port,u8 * buffer,int len)279 static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
280 {
281 	int bytes_read, new_bytes;
282 	for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
283 		new_bytes = parport_read(port, buffer+bytes_read,
284 			                 len-bytes_read);
285 		if(new_bytes < 0) break;
286 	}
287 	return bytes_read;
288 }
289 
cpia_pp_streamRead(void * privdata,u8 * buffer,int noblock)290 static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
291 {
292 	struct pp_cam_entry *cam = privdata;
293 	int read_bytes = 0;
294 	int i, endseen, block_size, new_bytes;
295 
296 	if(cam == NULL) {
297 		DBG("Internal driver error: cam is NULL\n");
298 		return -EINVAL;
299 	}
300 	if(buffer == NULL) {
301 		DBG("Internal driver error: buffer is NULL\n");
302 		return -EINVAL;
303 	}
304 	//if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
305 	if( cam->stream_irq ) {
306 		DBG("%d\n", cam->image_ready);
307 		cam->image_ready--;
308 	}
309 	cam->image_complete=0;
310 	if (0/*cam->streaming*/) {
311 		if(!cam->image_ready) {
312 			if(noblock) return -EWOULDBLOCK;
313 			interruptible_sleep_on(&cam->wq_stream);
314 			if( signal_pending(current) ) return -EINTR;
315 			DBG("%d\n", cam->image_ready);
316 		}
317 	} else {
318 		if (ReverseSetup(cam, 1)) {
319 			DBG("unable to ReverseSetup\n");
320 			return -EIO;
321 		}
322 	}
323 	endseen = 0;
324 	block_size = PARPORT_CHUNK_SIZE;
325 	while( !cam->image_complete ) {
326 		if(current->need_resched)  schedule();
327 
328 		new_bytes = cpia_pp_read(cam->port, buffer, block_size );
329 		if( new_bytes <= 0 ) {
330 			break;
331 		}
332 		i=-1;
333 		while(++i<new_bytes && endseen<4) {
334 	        	if(*buffer==EOI) {
335 	                	endseen++;
336 	                } else {
337 	                	endseen=0;
338 	                }
339 			buffer++;
340 		}
341 		read_bytes += i;
342 		if( endseen==4 ) {
343 			cam->image_complete=1;
344 			break;
345 		}
346 		if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
347 			block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
348 		}
349 	}
350 	EndTransferMode(cam);
351 	return cam->image_complete ? read_bytes : -EIO;
352 }
353 
354 /****************************************************************************
355  *
356  *  cpia_pp_transferCmd
357  *
358  ***************************************************************************/
cpia_pp_transferCmd(void * privdata,u8 * command,u8 * data)359 static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
360 {
361 	int err;
362 	int retval=0;
363 	int databytes;
364 	struct pp_cam_entry *cam = privdata;
365 
366 	if(cam == NULL) {
367 		DBG("Internal driver error: cam is NULL\n");
368 		return -EINVAL;
369 	}
370 	if(command == NULL) {
371 		DBG("Internal driver error: command is NULL\n");
372 		return -EINVAL;
373 	}
374 	databytes = (((int)command[7])<<8) | command[6];
375 	if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
376 		DBG("Error writing command\n");
377 		return err;
378 	}
379 	if(command[0] == DATA_IN) {
380 		u8 buffer[8];
381 		if(data == NULL) {
382 			DBG("Internal driver error: data is NULL\n");
383 			return -EINVAL;
384 		}
385 		if((err = ReadPacket(cam, buffer, 8)) < 0) {
386 			DBG("Error reading command result\n");
387                        return err;
388 		}
389 		memcpy(data, buffer, databytes);
390 	} else if(command[0] == DATA_OUT) {
391 		if(databytes > 0) {
392 			if(data == NULL) {
393 				DBG("Internal driver error: data is NULL\n");
394 				retval = -EINVAL;
395 			} else {
396 				if((err=WritePacket(cam, data, databytes)) < 0){
397 					DBG("Error writing command data\n");
398 					return err;
399 				}
400 			}
401 		}
402 	} else {
403 		DBG("Unexpected first byte of command: %x\n", command[0]);
404 		retval = -EINVAL;
405 	}
406 	return retval;
407 }
408 
409 /****************************************************************************
410  *
411  *  cpia_pp_open
412  *
413  ***************************************************************************/
cpia_pp_open(void * privdata)414 static int cpia_pp_open(void *privdata)
415 {
416 	struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
417 
418 	if (cam == NULL)
419 		return -EINVAL;
420 
421 	if(cam->open_count == 0) {
422 		if (parport_claim(cam->pdev)) {
423 			DBG("failed to claim the port\n");
424 			return -EBUSY;
425 		}
426 		parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
427 		parport_data_forward(cam->port);
428 		parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
429 		udelay(50);
430 		parport_write_control(cam->port,
431 		                      PARPORT_CONTROL_SELECT
432 		                      | PARPORT_CONTROL_INIT);
433 	}
434 
435 	++cam->open_count;
436 
437 	return 0;
438 }
439 
440 /****************************************************************************
441  *
442  *  cpia_pp_registerCallback
443  *
444  ***************************************************************************/
cpia_pp_registerCallback(void * privdata,void (* cb)(void * cbdata),void * cbdata)445 static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
446 {
447 	struct pp_cam_entry *cam = privdata;
448 	int retval = 0;
449 
450 	if(cam->port->irq != PARPORT_IRQ_NONE) {
451 		cam->cb_task.routine = cb;
452 		cam->cb_task.data = cbdata;
453 	} else {
454 		retval = -1;
455 	}
456 	return retval;
457 }
458 
459 /****************************************************************************
460  *
461  *  cpia_pp_close
462  *
463  ***************************************************************************/
cpia_pp_close(void * privdata)464 static int cpia_pp_close(void *privdata)
465 {
466 	struct pp_cam_entry *cam = privdata;
467 	if (--cam->open_count == 0) {
468 		parport_release(cam->pdev);
469 	}
470 	return 0;
471 }
472 
473 /****************************************************************************
474  *
475  *  cpia_pp_register
476  *
477  ***************************************************************************/
cpia_pp_register(struct parport * port)478 static int cpia_pp_register(struct parport *port)
479 {
480 	struct pardevice *pdev = NULL;
481 	struct pp_cam_entry *cam;
482 	struct cam_data *cpia;
483 
484 	if (!(port->modes & PARPORT_MODE_ECP) &&
485 	    !(port->modes & PARPORT_MODE_TRISTATE)) {
486 		LOG("port is not ECP capable\n");
487 		return -ENXIO;
488 	}
489 
490 	cam = kmalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
491 	if (cam == NULL) {
492 		LOG("failed to allocate camera structure\n");
493 		return -ENOMEM;
494 	}
495 	memset(cam,0,sizeof(struct pp_cam_entry));
496 
497 	pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
498 	                               NULL, 0, cam);
499 
500 	if (!pdev) {
501 		LOG("failed to parport_register_device\n");
502 		kfree(cam);
503 		return -ENXIO;
504 	}
505 
506 	cam->pdev = pdev;
507 	cam->port = port;
508 	init_waitqueue_head(&cam->wq_stream);
509 
510 	cam->streaming = 0;
511 	cam->stream_irq = 0;
512 
513 	if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
514 		LOG("failed to cpia_register_camera\n");
515 		parport_unregister_device(pdev);
516 		kfree(cam);
517 		return -ENXIO;
518 	}
519 	spin_lock( &cam_list_lock_pp );
520 	list_add( &cpia->cam_data_list, &cam_list );
521 	spin_unlock( &cam_list_lock_pp );
522 
523 	return 0;
524 }
525 
cpia_pp_detach(struct parport * port)526 static void cpia_pp_detach (struct parport *port)
527 {
528 	struct list_head *tmp;
529 	struct cam_data *cpia = NULL;
530 	struct pp_cam_entry *cam;
531 
532 	spin_lock( &cam_list_lock_pp );
533 	list_for_each (tmp, &cam_list) {
534 		cpia = list_entry(tmp, struct cam_data, cam_data_list);
535 		cam = (struct pp_cam_entry *) cpia->lowlevel_data;
536 		if (cam && cam->port->number == port->number) {
537 			list_del(&cpia->cam_data_list);
538 			break;
539 		}
540 		cpia = NULL;
541 	}
542 	spin_unlock( &cam_list_lock_pp );
543 
544 	if (!cpia) {
545 		DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
546 		return;
547 	}
548 
549 	cam = (struct pp_cam_entry *) cpia->lowlevel_data;
550 	cpia_unregister_camera(cpia);
551 	if(cam->open_count > 0)
552 		cpia_pp_close(cam);
553 	parport_unregister_device(cam->pdev);
554 	cpia->lowlevel_data = NULL;
555 	kfree(cam);
556 }
557 
cpia_pp_attach(struct parport * port)558 static void cpia_pp_attach (struct parport *port)
559 {
560 	unsigned int i;
561 
562 	switch (parport_nr[0])
563 	{
564 	case PPCPIA_PARPORT_UNSPEC:
565 	case PPCPIA_PARPORT_AUTO:
566 		if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
567 		    port->probe_info[0].cmdset == NULL ||
568 		    strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
569 			return;
570 
571 		cpia_pp_register(port);
572 
573 		break;
574 
575 	default:
576 		for (i = 0; i < PARPORT_MAX; ++i) {
577 			if (port->number == parport_nr[i]) {
578 				cpia_pp_register(port);
579 				break;
580 			}
581 		}
582 		break;
583 	}
584 }
585 
586 static struct parport_driver cpia_pp_driver = {
587 	"cpia_pp",
588 	cpia_pp_attach,
589 	cpia_pp_detach,
590 	NULL
591 };
592 
cpia_pp_init(void)593 int cpia_pp_init(void)
594 {
595 	printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
596 	       CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
597 
598 	if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
599 		printk("  disabled\n");
600 		return 0;
601 	}
602 
603 	spin_lock_init( &cam_list_lock_pp );
604 
605 	if (parport_register_driver (&cpia_pp_driver)) {
606 		LOG ("unable to register with parport\n");
607 		return -EIO;
608 	}
609 	return 0;
610 }
611 
612 #ifdef MODULE
init_module(void)613 int init_module(void)
614 {
615 	if (parport[0]) {
616 		/* The user gave some parameters.  Let's see what they were. */
617 		if (!strncmp(parport[0], "auto", 4)) {
618 			parport_nr[0] = PPCPIA_PARPORT_AUTO;
619 		} else {
620 			int n;
621 			for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
622 				if (!strncmp(parport[n], "none", 4)) {
623 					parport_nr[n] = PPCPIA_PARPORT_NONE;
624 				} else {
625 					char *ep;
626 					unsigned long r = simple_strtoul(parport[n], &ep, 0);
627 					if (ep != parport[n]) {
628 						parport_nr[n] = r;
629 					} else {
630 						LOG("bad port specifier `%s'\n", parport[n]);
631 						return -ENODEV;
632 					}
633 				}
634 			}
635 		}
636 	}
637 #if defined(CONFIG_KMOD) && defined(CONFIG_PNP_PARPORT_MODULE)
638 	if(parport_enumerate() && !parport_enumerate()->probe_info.model) {
639 		request_module("parport_probe");
640 	}
641 #endif
642 	return cpia_pp_init();
643 }
644 
cleanup_module(void)645 void cleanup_module(void)
646 {
647 	parport_unregister_driver (&cpia_pp_driver);
648 	return;
649 }
650 
651 #else /* !MODULE */
652 
cpia_pp_setup(char * str)653 static int __init cpia_pp_setup(char *str)
654 {
655 	if (!strncmp(str, "parport", 7)) {
656 		int n = simple_strtoul(str + 7, NULL, 10);
657 		if (parport_ptr < PARPORT_MAX) {
658 			parport_nr[parport_ptr++] = n;
659 		} else {
660 			LOG("too many ports, %s ignored.\n", str);
661 		}
662 	} else if (!strcmp(str, "auto")) {
663 		parport_nr[0] = PPCPIA_PARPORT_AUTO;
664 	} else if (!strcmp(str, "none")) {
665 		parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
666 	}
667 
668 	return 0;
669 }
670 
671 __setup("cpia_pp=", cpia_pp_setup);
672 
673 #endif /* !MODULE */
674