• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /****************************************************************************
3  *
4  *  Filename: cpia2_v4l.c
5  *
6  *  Copyright 2001, STMicrolectronics, Inc.
7  *      Contact:  steve.miller@st.com
8  *  Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com>
9  *
10  *  Description:
11  *     This is a USB driver for CPia2 based video cameras.
12  *     The infrastructure of this driver is based on the cpia usb driver by
13  *     Jochen Scharrlach and Johannes Erdfeldt.
14  *
15  *  Stripped of 2.4 stuff ready for main kernel submit by
16  *		Alan Cox <alan@lxorguk.ukuu.org.uk>
17  ****************************************************************************/
18 
19 #define CPIA_VERSION "3.0.1"
20 
21 #include <linux/module.h>
22 #include <linux/time.h>
23 #include <linux/sched.h>
24 #include <linux/slab.h>
25 #include <linux/init.h>
26 #include <linux/videodev2.h>
27 #include <linux/stringify.h>
28 #include <media/v4l2-ioctl.h>
29 #include <media/v4l2-event.h>
30 
31 #include "cpia2.h"
32 
33 static int video_nr = -1;
34 module_param(video_nr, int, 0);
35 MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
36 
37 static int buffer_size = 68 * 1024;
38 module_param(buffer_size, int, 0);
39 MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
40 
41 static int num_buffers = 3;
42 module_param(num_buffers, int, 0);
43 MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
44 		 __stringify(VIDEO_MAX_FRAME) ", default 3)");
45 
46 static int alternate = DEFAULT_ALT;
47 module_param(alternate, int, 0);
48 MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
49 		 __stringify(USBIF_ISO_6) ", default "
50 		 __stringify(DEFAULT_ALT) ")");
51 
52 static int flicker_mode;
53 module_param(flicker_mode, int, 0);
54 MODULE_PARM_DESC(flicker_mode, "Flicker frequency (0 (disabled), " __stringify(50) " or "
55 		 __stringify(60) ", default 0)");
56 
57 MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
58 MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
59 MODULE_SUPPORTED_DEVICE("video");
60 MODULE_LICENSE("GPL");
61 MODULE_VERSION(CPIA_VERSION);
62 
63 #define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
64 #define CPIA2_CID_USB_ALT (V4L2_CID_USER_BASE | 0xf000)
65 
66 /******************************************************************************
67  *
68  *  cpia2_open
69  *
70  *****************************************************************************/
cpia2_open(struct file * file)71 static int cpia2_open(struct file *file)
72 {
73 	struct camera_data *cam = video_drvdata(file);
74 	int retval;
75 
76 	if (mutex_lock_interruptible(&cam->v4l2_lock))
77 		return -ERESTARTSYS;
78 	retval = v4l2_fh_open(file);
79 	if (retval)
80 		goto open_unlock;
81 
82 	if (v4l2_fh_is_singular_file(file)) {
83 		if (cpia2_allocate_buffers(cam)) {
84 			v4l2_fh_release(file);
85 			retval = -ENOMEM;
86 			goto open_unlock;
87 		}
88 
89 		/* reset the camera */
90 		if (cpia2_reset_camera(cam) < 0) {
91 			v4l2_fh_release(file);
92 			retval = -EIO;
93 			goto open_unlock;
94 		}
95 
96 		cam->APP_len = 0;
97 		cam->COM_len = 0;
98 	}
99 
100 	cpia2_dbg_dump_registers(cam);
101 open_unlock:
102 	mutex_unlock(&cam->v4l2_lock);
103 	return retval;
104 }
105 
106 /******************************************************************************
107  *
108  *  cpia2_close
109  *
110  *****************************************************************************/
cpia2_close(struct file * file)111 static int cpia2_close(struct file *file)
112 {
113 	struct video_device *dev = video_devdata(file);
114 	struct camera_data *cam = video_get_drvdata(dev);
115 
116 	mutex_lock(&cam->v4l2_lock);
117 	if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) {
118 		cpia2_usb_stream_stop(cam);
119 
120 		/* save camera state for later open */
121 		cpia2_save_camera_state(cam);
122 
123 		cpia2_set_low_power(cam);
124 		cpia2_free_buffers(cam);
125 	}
126 
127 	if (cam->stream_fh == file->private_data) {
128 		cam->stream_fh = NULL;
129 		cam->mmapped = 0;
130 	}
131 	mutex_unlock(&cam->v4l2_lock);
132 	return v4l2_fh_release(file);
133 }
134 
135 /******************************************************************************
136  *
137  *  cpia2_v4l_read
138  *
139  *****************************************************************************/
cpia2_v4l_read(struct file * file,char __user * buf,size_t count,loff_t * off)140 static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
141 			      loff_t *off)
142 {
143 	struct camera_data *cam = video_drvdata(file);
144 	int noblock = file->f_flags&O_NONBLOCK;
145 	ssize_t ret;
146 
147 	if(!cam)
148 		return -EINVAL;
149 
150 	if (mutex_lock_interruptible(&cam->v4l2_lock))
151 		return -ERESTARTSYS;
152 	ret = cpia2_read(cam, buf, count, noblock);
153 	mutex_unlock(&cam->v4l2_lock);
154 	return ret;
155 }
156 
157 
158 /******************************************************************************
159  *
160  *  cpia2_v4l_poll
161  *
162  *****************************************************************************/
cpia2_v4l_poll(struct file * filp,struct poll_table_struct * wait)163 static __poll_t cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
164 {
165 	struct camera_data *cam = video_drvdata(filp);
166 	__poll_t res;
167 
168 	mutex_lock(&cam->v4l2_lock);
169 	res = cpia2_poll(cam, filp, wait);
170 	mutex_unlock(&cam->v4l2_lock);
171 	return res;
172 }
173 
174 
sync(struct camera_data * cam,int frame_nr)175 static int sync(struct camera_data *cam, int frame_nr)
176 {
177 	struct framebuf *frame = &cam->buffers[frame_nr];
178 
179 	while (1) {
180 		if (frame->status == FRAME_READY)
181 			return 0;
182 
183 		if (!cam->streaming) {
184 			frame->status = FRAME_READY;
185 			frame->length = 0;
186 			return 0;
187 		}
188 
189 		mutex_unlock(&cam->v4l2_lock);
190 		wait_event_interruptible(cam->wq_stream,
191 					 !cam->streaming ||
192 					 frame->status == FRAME_READY);
193 		mutex_lock(&cam->v4l2_lock);
194 		if (signal_pending(current))
195 			return -ERESTARTSYS;
196 		if (!video_is_registered(&cam->vdev))
197 			return -ENOTTY;
198 	}
199 }
200 
201 /******************************************************************************
202  *
203  *  ioctl_querycap
204  *
205  *  V4L2 device capabilities
206  *
207  *****************************************************************************/
208 
cpia2_querycap(struct file * file,void * fh,struct v4l2_capability * vc)209 static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc)
210 {
211 	struct camera_data *cam = video_drvdata(file);
212 
213 	strscpy(vc->driver, "cpia2", sizeof(vc->driver));
214 
215 	if (cam->params.pnp_id.product == 0x151)
216 		strscpy(vc->card, "QX5 Microscope", sizeof(vc->card));
217 	else
218 		strscpy(vc->card, "CPiA2 Camera", sizeof(vc->card));
219 	switch (cam->params.pnp_id.device_type) {
220 	case DEVICE_STV_672:
221 		strcat(vc->card, " (672/");
222 		break;
223 	case DEVICE_STV_676:
224 		strcat(vc->card, " (676/");
225 		break;
226 	default:
227 		strcat(vc->card, " (XXX/");
228 		break;
229 	}
230 	switch (cam->params.version.sensor_flags) {
231 	case CPIA2_VP_SENSOR_FLAGS_404:
232 		strcat(vc->card, "404)");
233 		break;
234 	case CPIA2_VP_SENSOR_FLAGS_407:
235 		strcat(vc->card, "407)");
236 		break;
237 	case CPIA2_VP_SENSOR_FLAGS_409:
238 		strcat(vc->card, "409)");
239 		break;
240 	case CPIA2_VP_SENSOR_FLAGS_410:
241 		strcat(vc->card, "410)");
242 		break;
243 	case CPIA2_VP_SENSOR_FLAGS_500:
244 		strcat(vc->card, "500)");
245 		break;
246 	default:
247 		strcat(vc->card, "XXX)");
248 		break;
249 	}
250 
251 	if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
252 		memset(vc->bus_info,0, sizeof(vc->bus_info));
253 	return 0;
254 }
255 
256 /******************************************************************************
257  *
258  *  ioctl_input
259  *
260  *  V4L2 input get/set/enumerate
261  *
262  *****************************************************************************/
263 
cpia2_enum_input(struct file * file,void * fh,struct v4l2_input * i)264 static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i)
265 {
266 	if (i->index)
267 		return -EINVAL;
268 	strscpy(i->name, "Camera", sizeof(i->name));
269 	i->type = V4L2_INPUT_TYPE_CAMERA;
270 	return 0;
271 }
272 
cpia2_g_input(struct file * file,void * fh,unsigned int * i)273 static int cpia2_g_input(struct file *file, void *fh, unsigned int *i)
274 {
275 	*i = 0;
276 	return 0;
277 }
278 
cpia2_s_input(struct file * file,void * fh,unsigned int i)279 static int cpia2_s_input(struct file *file, void *fh, unsigned int i)
280 {
281 	return i ? -EINVAL : 0;
282 }
283 
284 /******************************************************************************
285  *
286  *  ioctl_enum_fmt
287  *
288  *  V4L2 format enumerate
289  *
290  *****************************************************************************/
291 
cpia2_enum_fmt_vid_cap(struct file * file,void * fh,struct v4l2_fmtdesc * f)292 static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
293 					    struct v4l2_fmtdesc *f)
294 {
295 	if (f->index > 1)
296 		return -EINVAL;
297 
298 	if (f->index == 0)
299 		f->pixelformat = V4L2_PIX_FMT_MJPEG;
300 	else
301 		f->pixelformat = V4L2_PIX_FMT_JPEG;
302 	return 0;
303 }
304 
305 /******************************************************************************
306  *
307  *  ioctl_try_fmt
308  *
309  *  V4L2 format try
310  *
311  *****************************************************************************/
312 
cpia2_try_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * f)313 static int cpia2_try_fmt_vid_cap(struct file *file, void *fh,
314 					  struct v4l2_format *f)
315 {
316 	struct camera_data *cam = video_drvdata(file);
317 
318 	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
319 	    f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
320 	       return -EINVAL;
321 
322 	f->fmt.pix.field = V4L2_FIELD_NONE;
323 	f->fmt.pix.bytesperline = 0;
324 	f->fmt.pix.sizeimage = cam->frame_size;
325 	f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
326 
327 	switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
328 	case VIDEOSIZE_VGA:
329 		f->fmt.pix.width = 640;
330 		f->fmt.pix.height = 480;
331 		break;
332 	case VIDEOSIZE_CIF:
333 		f->fmt.pix.width = 352;
334 		f->fmt.pix.height = 288;
335 		break;
336 	case VIDEOSIZE_QVGA:
337 		f->fmt.pix.width = 320;
338 		f->fmt.pix.height = 240;
339 		break;
340 	case VIDEOSIZE_288_216:
341 		f->fmt.pix.width = 288;
342 		f->fmt.pix.height = 216;
343 		break;
344 	case VIDEOSIZE_256_192:
345 		f->fmt.pix.width = 256;
346 		f->fmt.pix.height = 192;
347 		break;
348 	case VIDEOSIZE_224_168:
349 		f->fmt.pix.width = 224;
350 		f->fmt.pix.height = 168;
351 		break;
352 	case VIDEOSIZE_192_144:
353 		f->fmt.pix.width = 192;
354 		f->fmt.pix.height = 144;
355 		break;
356 	case VIDEOSIZE_QCIF:
357 	default:
358 		f->fmt.pix.width = 176;
359 		f->fmt.pix.height = 144;
360 		break;
361 	}
362 
363 	return 0;
364 }
365 
366 /******************************************************************************
367  *
368  *  ioctl_set_fmt
369  *
370  *  V4L2 format set
371  *
372  *****************************************************************************/
373 
cpia2_s_fmt_vid_cap(struct file * file,void * _fh,struct v4l2_format * f)374 static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh,
375 					struct v4l2_format *f)
376 {
377 	struct camera_data *cam = video_drvdata(file);
378 	int err, frame;
379 
380 	err = cpia2_try_fmt_vid_cap(file, _fh, f);
381 	if(err != 0)
382 		return err;
383 
384 	cam->pixelformat = f->fmt.pix.pixelformat;
385 
386 	/* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
387 	 * the missing Huffman table properly. */
388 	cam->params.compression.inhibit_htables = 0;
389 		/*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/
390 
391 	/* we set the video window to something smaller or equal to what
392 	 * is requested by the user???
393 	 */
394 	DBG("Requested width = %d, height = %d\n",
395 	    f->fmt.pix.width, f->fmt.pix.height);
396 	if (f->fmt.pix.width != cam->width ||
397 	    f->fmt.pix.height != cam->height) {
398 		cam->width = f->fmt.pix.width;
399 		cam->height = f->fmt.pix.height;
400 		cam->params.roi.width = f->fmt.pix.width;
401 		cam->params.roi.height = f->fmt.pix.height;
402 		cpia2_set_format(cam);
403 	}
404 
405 	for (frame = 0; frame < cam->num_frames; ++frame) {
406 		if (cam->buffers[frame].status == FRAME_READING)
407 			if ((err = sync(cam, frame)) < 0)
408 				return err;
409 
410 		cam->buffers[frame].status = FRAME_EMPTY;
411 	}
412 
413 	return 0;
414 }
415 
416 /******************************************************************************
417  *
418  *  ioctl_get_fmt
419  *
420  *  V4L2 format get
421  *
422  *****************************************************************************/
423 
cpia2_g_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * f)424 static int cpia2_g_fmt_vid_cap(struct file *file, void *fh,
425 					struct v4l2_format *f)
426 {
427 	struct camera_data *cam = video_drvdata(file);
428 
429 	f->fmt.pix.width = cam->width;
430 	f->fmt.pix.height = cam->height;
431 	f->fmt.pix.pixelformat = cam->pixelformat;
432 	f->fmt.pix.field = V4L2_FIELD_NONE;
433 	f->fmt.pix.bytesperline = 0;
434 	f->fmt.pix.sizeimage = cam->frame_size;
435 	f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
436 
437 	return 0;
438 }
439 
440 /******************************************************************************
441  *
442  *  ioctl_cropcap
443  *
444  *  V4L2 query cropping capabilities
445  *  NOTE: cropping is currently disabled
446  *
447  *****************************************************************************/
448 
cpia2_g_selection(struct file * file,void * fh,struct v4l2_selection * s)449 static int cpia2_g_selection(struct file *file, void *fh,
450 			     struct v4l2_selection *s)
451 {
452 	struct camera_data *cam = video_drvdata(file);
453 
454 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
455 		return -EINVAL;
456 
457 	switch (s->target) {
458 	case V4L2_SEL_TGT_CROP_BOUNDS:
459 	case V4L2_SEL_TGT_CROP_DEFAULT:
460 		s->r.left = 0;
461 		s->r.top = 0;
462 		s->r.width = cam->width;
463 		s->r.height = cam->height;
464 		break;
465 	default:
466 		return -EINVAL;
467 	}
468 	return 0;
469 }
470 
471 struct framerate_info {
472 	int value;
473 	struct v4l2_fract period;
474 };
475 
476 static const struct framerate_info framerate_controls[] = {
477 	{ CPIA2_VP_FRAMERATE_6_25, { 4, 25 } },
478 	{ CPIA2_VP_FRAMERATE_7_5,  { 2, 15 } },
479 	{ CPIA2_VP_FRAMERATE_12_5, { 2, 25 } },
480 	{ CPIA2_VP_FRAMERATE_15,   { 1, 15 } },
481 	{ CPIA2_VP_FRAMERATE_25,   { 1, 25 } },
482 	{ CPIA2_VP_FRAMERATE_30,   { 1, 30 } },
483 };
484 
cpia2_g_parm(struct file * file,void * fh,struct v4l2_streamparm * p)485 static int cpia2_g_parm(struct file *file, void *fh, struct v4l2_streamparm *p)
486 {
487 	struct camera_data *cam = video_drvdata(file);
488 	struct v4l2_captureparm *cap = &p->parm.capture;
489 	int i;
490 
491 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
492 		return -EINVAL;
493 
494 	cap->capability = V4L2_CAP_TIMEPERFRAME;
495 	cap->readbuffers = cam->num_frames;
496 	for (i = 0; i < ARRAY_SIZE(framerate_controls); i++)
497 		if (cam->params.vp_params.frame_rate == framerate_controls[i].value) {
498 			cap->timeperframe = framerate_controls[i].period;
499 			break;
500 		}
501 	return 0;
502 }
503 
cpia2_s_parm(struct file * file,void * fh,struct v4l2_streamparm * p)504 static int cpia2_s_parm(struct file *file, void *fh, struct v4l2_streamparm *p)
505 {
506 	struct camera_data *cam = video_drvdata(file);
507 	struct v4l2_captureparm *cap = &p->parm.capture;
508 	struct v4l2_fract tpf = cap->timeperframe;
509 	int max = ARRAY_SIZE(framerate_controls) - 1;
510 	int ret;
511 	int i;
512 
513 	ret = cpia2_g_parm(file, fh, p);
514 	if (ret || !tpf.denominator || !tpf.numerator)
515 		return ret;
516 
517 	/* Maximum 15 fps for this model */
518 	if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
519 	    cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
520 		max -= 2;
521 	for (i = 0; i <= max; i++) {
522 		struct v4l2_fract f1 = tpf;
523 		struct v4l2_fract f2 = framerate_controls[i].period;
524 
525 		f1.numerator *= f2.denominator;
526 		f2.numerator *= f1.denominator;
527 		if (f1.numerator >= f2.numerator)
528 			break;
529 	}
530 	if (i > max)
531 		i = max;
532 	cap->timeperframe = framerate_controls[i].period;
533 	return cpia2_set_fps(cam, framerate_controls[i].value);
534 }
535 
536 static const struct {
537 	u32 width;
538 	u32 height;
539 } cpia2_framesizes[] = {
540 	{ 640, 480 },
541 	{ 352, 288 },
542 	{ 320, 240 },
543 	{ 288, 216 },
544 	{ 256, 192 },
545 	{ 224, 168 },
546 	{ 192, 144 },
547 	{ 176, 144 },
548 };
549 
cpia2_enum_framesizes(struct file * file,void * fh,struct v4l2_frmsizeenum * fsize)550 static int cpia2_enum_framesizes(struct file *file, void *fh,
551 					 struct v4l2_frmsizeenum *fsize)
552 {
553 
554 	if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG &&
555 	    fsize->pixel_format != V4L2_PIX_FMT_JPEG)
556 		return -EINVAL;
557 	if (fsize->index >= ARRAY_SIZE(cpia2_framesizes))
558 		return -EINVAL;
559 	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
560 	fsize->discrete.width = cpia2_framesizes[fsize->index].width;
561 	fsize->discrete.height = cpia2_framesizes[fsize->index].height;
562 
563 	return 0;
564 }
565 
cpia2_enum_frameintervals(struct file * file,void * fh,struct v4l2_frmivalenum * fival)566 static int cpia2_enum_frameintervals(struct file *file, void *fh,
567 					   struct v4l2_frmivalenum *fival)
568 {
569 	struct camera_data *cam = video_drvdata(file);
570 	int max = ARRAY_SIZE(framerate_controls) - 1;
571 	int i;
572 
573 	if (fival->pixel_format != V4L2_PIX_FMT_MJPEG &&
574 	    fival->pixel_format != V4L2_PIX_FMT_JPEG)
575 		return -EINVAL;
576 
577 	/* Maximum 15 fps for this model */
578 	if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
579 	    cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
580 		max -= 2;
581 	if (fival->index > max)
582 		return -EINVAL;
583 	for (i = 0; i < ARRAY_SIZE(cpia2_framesizes); i++)
584 		if (fival->width == cpia2_framesizes[i].width &&
585 		    fival->height == cpia2_framesizes[i].height)
586 			break;
587 	if (i == ARRAY_SIZE(cpia2_framesizes))
588 		return -EINVAL;
589 	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
590 	fival->discrete = framerate_controls[fival->index].period;
591 	return 0;
592 }
593 
594 /******************************************************************************
595  *
596  *  ioctl_s_ctrl
597  *
598  *  V4L2 set the value of a control variable
599  *
600  *****************************************************************************/
601 
cpia2_s_ctrl(struct v4l2_ctrl * ctrl)602 static int cpia2_s_ctrl(struct v4l2_ctrl *ctrl)
603 {
604 	struct camera_data *cam =
605 		container_of(ctrl->handler, struct camera_data, hdl);
606 	static const int flicker_table[] = {
607 		NEVER_FLICKER,
608 		FLICKER_50,
609 		FLICKER_60,
610 	};
611 
612 	DBG("Set control id:%d, value:%d\n", ctrl->id, ctrl->val);
613 
614 	switch (ctrl->id) {
615 	case V4L2_CID_BRIGHTNESS:
616 		cpia2_set_brightness(cam, ctrl->val);
617 		break;
618 	case V4L2_CID_CONTRAST:
619 		cpia2_set_contrast(cam, ctrl->val);
620 		break;
621 	case V4L2_CID_SATURATION:
622 		cpia2_set_saturation(cam, ctrl->val);
623 		break;
624 	case V4L2_CID_HFLIP:
625 		cpia2_set_property_mirror(cam, ctrl->val);
626 		break;
627 	case V4L2_CID_VFLIP:
628 		cpia2_set_property_flip(cam, ctrl->val);
629 		break;
630 	case V4L2_CID_POWER_LINE_FREQUENCY:
631 		return cpia2_set_flicker_mode(cam, flicker_table[ctrl->val]);
632 	case V4L2_CID_ILLUMINATORS_1:
633 		return cpia2_set_gpio(cam, (cam->top_light->val << 6) |
634 					   (cam->bottom_light->val << 7));
635 	case V4L2_CID_JPEG_ACTIVE_MARKER:
636 		cam->params.compression.inhibit_htables =
637 			!(ctrl->val & V4L2_JPEG_ACTIVE_MARKER_DHT);
638 		break;
639 	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
640 		cam->params.vc_params.quality = ctrl->val;
641 		break;
642 	case CPIA2_CID_USB_ALT:
643 		cam->params.camera_state.stream_mode = ctrl->val;
644 		break;
645 	default:
646 		return -EINVAL;
647 	}
648 
649 	return 0;
650 }
651 
652 /******************************************************************************
653  *
654  *  ioctl_g_jpegcomp
655  *
656  *  V4L2 get the JPEG compression parameters
657  *
658  *****************************************************************************/
659 
cpia2_g_jpegcomp(struct file * file,void * fh,struct v4l2_jpegcompression * parms)660 static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
661 {
662 	struct camera_data *cam = video_drvdata(file);
663 
664 	memset(parms, 0, sizeof(*parms));
665 
666 	parms->quality = 80; // TODO: Can this be made meaningful?
667 
668 	parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI;
669 	if(!cam->params.compression.inhibit_htables) {
670 		parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT;
671 	}
672 
673 	parms->APPn = cam->APPn;
674 	parms->APP_len = cam->APP_len;
675 	if(cam->APP_len > 0) {
676 		memcpy(parms->APP_data, cam->APP_data, cam->APP_len);
677 		parms->jpeg_markers |= V4L2_JPEG_MARKER_APP;
678 	}
679 
680 	parms->COM_len = cam->COM_len;
681 	if(cam->COM_len > 0) {
682 		memcpy(parms->COM_data, cam->COM_data, cam->COM_len);
683 		parms->jpeg_markers |= JPEG_MARKER_COM;
684 	}
685 
686 	DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n",
687 	    parms->APP_len, parms->COM_len);
688 
689 	return 0;
690 }
691 
692 /******************************************************************************
693  *
694  *  ioctl_s_jpegcomp
695  *
696  *  V4L2 set the JPEG compression parameters
697  *  NOTE: quality and some jpeg_markers are ignored.
698  *
699  *****************************************************************************/
700 
cpia2_s_jpegcomp(struct file * file,void * fh,const struct v4l2_jpegcompression * parms)701 static int cpia2_s_jpegcomp(struct file *file, void *fh,
702 		const struct v4l2_jpegcompression *parms)
703 {
704 	struct camera_data *cam = video_drvdata(file);
705 
706 	DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
707 	    parms->APP_len, parms->COM_len);
708 
709 	cam->params.compression.inhibit_htables =
710 		!(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
711 
712 	if(parms->APP_len != 0) {
713 		if(parms->APP_len > 0 &&
714 		   parms->APP_len <= sizeof(cam->APP_data) &&
715 		   parms->APPn >= 0 && parms->APPn <= 15) {
716 			cam->APPn = parms->APPn;
717 			cam->APP_len = parms->APP_len;
718 			memcpy(cam->APP_data, parms->APP_data, parms->APP_len);
719 		} else {
720 			LOG("Bad APPn Params n=%d len=%d\n",
721 			    parms->APPn, parms->APP_len);
722 			return -EINVAL;
723 		}
724 	} else {
725 		cam->APP_len = 0;
726 	}
727 
728 	if(parms->COM_len != 0) {
729 		if(parms->COM_len > 0 &&
730 		   parms->COM_len <= sizeof(cam->COM_data)) {
731 			cam->COM_len = parms->COM_len;
732 			memcpy(cam->COM_data, parms->COM_data, parms->COM_len);
733 		} else {
734 			LOG("Bad COM_len=%d\n", parms->COM_len);
735 			return -EINVAL;
736 		}
737 	}
738 
739 	return 0;
740 }
741 
742 /******************************************************************************
743  *
744  *  ioctl_reqbufs
745  *
746  *  V4L2 Initiate memory mapping.
747  *  NOTE: The user's request is ignored. For now the buffers are fixed.
748  *
749  *****************************************************************************/
750 
cpia2_reqbufs(struct file * file,void * fh,struct v4l2_requestbuffers * req)751 static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req)
752 {
753 	struct camera_data *cam = video_drvdata(file);
754 
755 	if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
756 	   req->memory != V4L2_MEMORY_MMAP)
757 		return -EINVAL;
758 
759 	DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames);
760 	req->count = cam->num_frames;
761 	memset(&req->reserved, 0, sizeof(req->reserved));
762 
763 	return 0;
764 }
765 
766 /******************************************************************************
767  *
768  *  ioctl_querybuf
769  *
770  *  V4L2 Query memory buffer status.
771  *
772  *****************************************************************************/
773 
cpia2_querybuf(struct file * file,void * fh,struct v4l2_buffer * buf)774 static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
775 {
776 	struct camera_data *cam = video_drvdata(file);
777 
778 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
779 	   buf->index >= cam->num_frames)
780 		return -EINVAL;
781 
782 	buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
783 	buf->length = cam->frame_size;
784 
785 	buf->memory = V4L2_MEMORY_MMAP;
786 
787 	if(cam->mmapped)
788 		buf->flags = V4L2_BUF_FLAG_MAPPED;
789 	else
790 		buf->flags = 0;
791 
792 	buf->flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
793 
794 	switch (cam->buffers[buf->index].status) {
795 	case FRAME_EMPTY:
796 	case FRAME_ERROR:
797 	case FRAME_READING:
798 		buf->bytesused = 0;
799 		buf->flags = V4L2_BUF_FLAG_QUEUED;
800 		break;
801 	case FRAME_READY:
802 		buf->bytesused = cam->buffers[buf->index].length;
803 		v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
804 		buf->sequence = cam->buffers[buf->index].seq;
805 		buf->flags = V4L2_BUF_FLAG_DONE;
806 		break;
807 	}
808 
809 	DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n",
810 	     buf->index, buf->m.offset, buf->flags, buf->sequence,
811 	     buf->bytesused);
812 
813 	return 0;
814 }
815 
816 /******************************************************************************
817  *
818  *  ioctl_qbuf
819  *
820  *  V4L2 User is freeing buffer
821  *
822  *****************************************************************************/
823 
cpia2_qbuf(struct file * file,void * fh,struct v4l2_buffer * buf)824 static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
825 {
826 	struct camera_data *cam = video_drvdata(file);
827 
828 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
829 	   buf->memory != V4L2_MEMORY_MMAP ||
830 	   buf->index >= cam->num_frames)
831 		return -EINVAL;
832 
833 	DBG("QBUF #%d\n", buf->index);
834 
835 	if(cam->buffers[buf->index].status == FRAME_READY)
836 		cam->buffers[buf->index].status = FRAME_EMPTY;
837 
838 	return 0;
839 }
840 
841 /******************************************************************************
842  *
843  *  find_earliest_filled_buffer
844  *
845  *  Helper for ioctl_dqbuf. Find the next ready buffer.
846  *
847  *****************************************************************************/
848 
find_earliest_filled_buffer(struct camera_data * cam)849 static int find_earliest_filled_buffer(struct camera_data *cam)
850 {
851 	int i;
852 	int found = -1;
853 	for (i=0; i<cam->num_frames; i++) {
854 		if(cam->buffers[i].status == FRAME_READY) {
855 			if(found < 0) {
856 				found = i;
857 			} else {
858 				/* find which buffer is earlier */
859 				if (cam->buffers[i].ts < cam->buffers[found].ts)
860 					found = i;
861 			}
862 		}
863 	}
864 	return found;
865 }
866 
867 /******************************************************************************
868  *
869  *  ioctl_dqbuf
870  *
871  *  V4L2 User is asking for a filled buffer.
872  *
873  *****************************************************************************/
874 
cpia2_dqbuf(struct file * file,void * fh,struct v4l2_buffer * buf)875 static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
876 {
877 	struct camera_data *cam = video_drvdata(file);
878 	int frame;
879 
880 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
881 	   buf->memory != V4L2_MEMORY_MMAP)
882 		return -EINVAL;
883 
884 	frame = find_earliest_filled_buffer(cam);
885 
886 	if(frame < 0 && file->f_flags&O_NONBLOCK)
887 		return -EAGAIN;
888 
889 	if(frame < 0) {
890 		/* Wait for a frame to become available */
891 		struct framebuf *cb=cam->curbuff;
892 		mutex_unlock(&cam->v4l2_lock);
893 		wait_event_interruptible(cam->wq_stream,
894 					 !video_is_registered(&cam->vdev) ||
895 					 (cb=cam->curbuff)->status == FRAME_READY);
896 		mutex_lock(&cam->v4l2_lock);
897 		if (signal_pending(current))
898 			return -ERESTARTSYS;
899 		if (!video_is_registered(&cam->vdev))
900 			return -ENOTTY;
901 		frame = cb->num;
902 	}
903 
904 
905 	buf->index = frame;
906 	buf->bytesused = cam->buffers[buf->index].length;
907 	buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE
908 		| V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
909 	buf->field = V4L2_FIELD_NONE;
910 	v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
911 	buf->sequence = cam->buffers[buf->index].seq;
912 	buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
913 	buf->length = cam->frame_size;
914 	buf->reserved2 = 0;
915 	buf->request_fd = 0;
916 	memset(&buf->timecode, 0, sizeof(buf->timecode));
917 
918 	DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
919 	    cam->buffers[buf->index].status, buf->sequence, buf->bytesused);
920 
921 	return 0;
922 }
923 
cpia2_streamon(struct file * file,void * fh,enum v4l2_buf_type type)924 static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
925 {
926 	struct camera_data *cam = video_drvdata(file);
927 	int ret = -EINVAL;
928 
929 	DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
930 	if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
931 		return -EINVAL;
932 
933 	if (!cam->streaming) {
934 		ret = cpia2_usb_stream_start(cam,
935 				cam->params.camera_state.stream_mode);
936 		if (!ret)
937 			v4l2_ctrl_grab(cam->usb_alt, true);
938 	}
939 	return ret;
940 }
941 
cpia2_streamoff(struct file * file,void * fh,enum v4l2_buf_type type)942 static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
943 {
944 	struct camera_data *cam = video_drvdata(file);
945 	int ret = -EINVAL;
946 
947 	DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
948 	if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
949 		return -EINVAL;
950 
951 	if (cam->streaming) {
952 		ret = cpia2_usb_stream_stop(cam);
953 		if (!ret)
954 			v4l2_ctrl_grab(cam->usb_alt, false);
955 	}
956 	return ret;
957 }
958 
959 /******************************************************************************
960  *
961  *  cpia2_mmap
962  *
963  *****************************************************************************/
cpia2_mmap(struct file * file,struct vm_area_struct * area)964 static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
965 {
966 	struct camera_data *cam = video_drvdata(file);
967 	int retval;
968 
969 	if (mutex_lock_interruptible(&cam->v4l2_lock))
970 		return -ERESTARTSYS;
971 	retval = cpia2_remap_buffer(cam, area);
972 
973 	if(!retval)
974 		cam->stream_fh = file->private_data;
975 	mutex_unlock(&cam->v4l2_lock);
976 	return retval;
977 }
978 
979 /******************************************************************************
980  *
981  *  reset_camera_struct_v4l
982  *
983  *  Sets all values to the defaults
984  *****************************************************************************/
reset_camera_struct_v4l(struct camera_data * cam)985 static void reset_camera_struct_v4l(struct camera_data *cam)
986 {
987 	cam->width = cam->params.roi.width;
988 	cam->height = cam->params.roi.height;
989 
990 	cam->frame_size = buffer_size;
991 	cam->num_frames = num_buffers;
992 
993 	/* Flicker modes */
994 	cam->params.flicker_control.flicker_mode_req = flicker_mode;
995 
996 	/* stream modes */
997 	cam->params.camera_state.stream_mode = alternate;
998 
999 	cam->pixelformat = V4L2_PIX_FMT_JPEG;
1000 }
1001 
1002 static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
1003 	.vidioc_querycap		    = cpia2_querycap,
1004 	.vidioc_enum_input		    = cpia2_enum_input,
1005 	.vidioc_g_input			    = cpia2_g_input,
1006 	.vidioc_s_input			    = cpia2_s_input,
1007 	.vidioc_enum_fmt_vid_cap	    = cpia2_enum_fmt_vid_cap,
1008 	.vidioc_g_fmt_vid_cap		    = cpia2_g_fmt_vid_cap,
1009 	.vidioc_s_fmt_vid_cap		    = cpia2_s_fmt_vid_cap,
1010 	.vidioc_try_fmt_vid_cap		    = cpia2_try_fmt_vid_cap,
1011 	.vidioc_g_jpegcomp		    = cpia2_g_jpegcomp,
1012 	.vidioc_s_jpegcomp		    = cpia2_s_jpegcomp,
1013 	.vidioc_g_selection		    = cpia2_g_selection,
1014 	.vidioc_reqbufs			    = cpia2_reqbufs,
1015 	.vidioc_querybuf		    = cpia2_querybuf,
1016 	.vidioc_qbuf			    = cpia2_qbuf,
1017 	.vidioc_dqbuf			    = cpia2_dqbuf,
1018 	.vidioc_streamon		    = cpia2_streamon,
1019 	.vidioc_streamoff		    = cpia2_streamoff,
1020 	.vidioc_s_parm			    = cpia2_s_parm,
1021 	.vidioc_g_parm			    = cpia2_g_parm,
1022 	.vidioc_enum_framesizes		    = cpia2_enum_framesizes,
1023 	.vidioc_enum_frameintervals	    = cpia2_enum_frameintervals,
1024 	.vidioc_subscribe_event		    = v4l2_ctrl_subscribe_event,
1025 	.vidioc_unsubscribe_event	    = v4l2_event_unsubscribe,
1026 };
1027 
1028 /***
1029  * The v4l video device structure initialized for this device
1030  ***/
1031 static const struct v4l2_file_operations cpia2_fops = {
1032 	.owner		= THIS_MODULE,
1033 	.open		= cpia2_open,
1034 	.release	= cpia2_close,
1035 	.read		= cpia2_v4l_read,
1036 	.poll		= cpia2_v4l_poll,
1037 	.unlocked_ioctl	= video_ioctl2,
1038 	.mmap		= cpia2_mmap,
1039 };
1040 
1041 static const struct video_device cpia2_template = {
1042 	/* I could not find any place for the old .initialize initializer?? */
1043 	.name =		"CPiA2 Camera",
1044 	.fops =		&cpia2_fops,
1045 	.ioctl_ops =	&cpia2_ioctl_ops,
1046 	.release =	video_device_release_empty,
1047 };
1048 
cpia2_camera_release(struct v4l2_device * v4l2_dev)1049 void cpia2_camera_release(struct v4l2_device *v4l2_dev)
1050 {
1051 	struct camera_data *cam =
1052 		container_of(v4l2_dev, struct camera_data, v4l2_dev);
1053 
1054 	v4l2_ctrl_handler_free(&cam->hdl);
1055 	v4l2_device_unregister(&cam->v4l2_dev);
1056 	kfree(cam);
1057 }
1058 
1059 static const struct v4l2_ctrl_ops cpia2_ctrl_ops = {
1060 	.s_ctrl = cpia2_s_ctrl,
1061 };
1062 
1063 /******************************************************************************
1064  *
1065  *  cpia2_register_camera
1066  *
1067  *****************************************************************************/
cpia2_register_camera(struct camera_data * cam)1068 int cpia2_register_camera(struct camera_data *cam)
1069 {
1070 	struct v4l2_ctrl_handler *hdl = &cam->hdl;
1071 	struct v4l2_ctrl_config cpia2_usb_alt = {
1072 		.ops = &cpia2_ctrl_ops,
1073 		.id = CPIA2_CID_USB_ALT,
1074 		.name = "USB Alternate",
1075 		.type = V4L2_CTRL_TYPE_INTEGER,
1076 		.min = USBIF_ISO_1,
1077 		.max = USBIF_ISO_6,
1078 		.step = 1,
1079 	};
1080 	int ret;
1081 
1082 	v4l2_ctrl_handler_init(hdl, 12);
1083 	v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1084 			V4L2_CID_BRIGHTNESS,
1085 			cam->params.pnp_id.device_type == DEVICE_STV_672 ? 1 : 0,
1086 			255, 1, DEFAULT_BRIGHTNESS);
1087 	v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1088 			V4L2_CID_CONTRAST, 0, 255, 1, DEFAULT_CONTRAST);
1089 	v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1090 			V4L2_CID_SATURATION, 0, 255, 1, DEFAULT_SATURATION);
1091 	v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1092 			V4L2_CID_HFLIP, 0, 1, 1, 0);
1093 	v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1094 			V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1095 			V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1096 			V4L2_JPEG_ACTIVE_MARKER_DHT);
1097 	v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1098 			V4L2_CID_JPEG_COMPRESSION_QUALITY, 1,
1099 			100, 1, 100);
1100 	cpia2_usb_alt.def = alternate;
1101 	cam->usb_alt = v4l2_ctrl_new_custom(hdl, &cpia2_usb_alt, NULL);
1102 	/* VP5 Only */
1103 	if (cam->params.pnp_id.device_type != DEVICE_STV_672)
1104 		v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1105 			V4L2_CID_VFLIP, 0, 1, 1, 0);
1106 	/* Flicker control only valid for 672 */
1107 	if (cam->params.pnp_id.device_type == DEVICE_STV_672)
1108 		v4l2_ctrl_new_std_menu(hdl, &cpia2_ctrl_ops,
1109 			V4L2_CID_POWER_LINE_FREQUENCY,
1110 			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
1111 	/* Light control only valid for the QX5 Microscope */
1112 	if (cam->params.pnp_id.product == 0x151) {
1113 		cam->top_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1114 				V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
1115 		cam->bottom_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1116 				V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
1117 		v4l2_ctrl_cluster(2, &cam->top_light);
1118 	}
1119 
1120 	if (hdl->error) {
1121 		ret = hdl->error;
1122 		v4l2_ctrl_handler_free(hdl);
1123 		return ret;
1124 	}
1125 
1126 	cam->vdev = cpia2_template;
1127 	video_set_drvdata(&cam->vdev, cam);
1128 	cam->vdev.lock = &cam->v4l2_lock;
1129 	cam->vdev.ctrl_handler = hdl;
1130 	cam->vdev.v4l2_dev = &cam->v4l2_dev;
1131 	cam->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1132 				V4L2_CAP_STREAMING;
1133 
1134 	reset_camera_struct_v4l(cam);
1135 
1136 	/* register v4l device */
1137 	if (video_register_device(&cam->vdev, VFL_TYPE_VIDEO, video_nr) < 0) {
1138 		ERR("video_register_device failed\n");
1139 		return -ENODEV;
1140 	}
1141 
1142 	return 0;
1143 }
1144 
1145 /******************************************************************************
1146  *
1147  *  cpia2_unregister_camera
1148  *
1149  *****************************************************************************/
cpia2_unregister_camera(struct camera_data * cam)1150 void cpia2_unregister_camera(struct camera_data *cam)
1151 {
1152 	video_unregister_device(&cam->vdev);
1153 }
1154 
1155 /******************************************************************************
1156  *
1157  *  check_parameters
1158  *
1159  *  Make sure that all user-supplied parameters are sensible
1160  *****************************************************************************/
check_parameters(void)1161 static void __init check_parameters(void)
1162 {
1163 	if(buffer_size < PAGE_SIZE) {
1164 		buffer_size = PAGE_SIZE;
1165 		LOG("buffer_size too small, setting to %d\n", buffer_size);
1166 	} else if(buffer_size > 1024*1024) {
1167 		/* arbitrary upper limiit */
1168 		buffer_size = 1024*1024;
1169 		LOG("buffer_size ridiculously large, setting to %d\n",
1170 		    buffer_size);
1171 	} else {
1172 		buffer_size += PAGE_SIZE-1;
1173 		buffer_size &= ~(PAGE_SIZE-1);
1174 	}
1175 
1176 	if(num_buffers < 1) {
1177 		num_buffers = 1;
1178 		LOG("num_buffers too small, setting to %d\n", num_buffers);
1179 	} else if(num_buffers > VIDEO_MAX_FRAME) {
1180 		num_buffers = VIDEO_MAX_FRAME;
1181 		LOG("num_buffers too large, setting to %d\n", num_buffers);
1182 	}
1183 
1184 	if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) {
1185 		alternate = DEFAULT_ALT;
1186 		LOG("alternate specified is invalid, using %d\n", alternate);
1187 	}
1188 
1189 	if (flicker_mode != 0 && flicker_mode != FLICKER_50 && flicker_mode != FLICKER_60) {
1190 		flicker_mode = 0;
1191 		LOG("Flicker mode specified is invalid, using %d\n",
1192 		    flicker_mode);
1193 	}
1194 
1195 	DBG("Using %d buffers, each %d bytes, alternate=%d\n",
1196 	    num_buffers, buffer_size, alternate);
1197 }
1198 
1199 /************   Module Stuff ***************/
1200 
1201 
1202 /******************************************************************************
1203  *
1204  * cpia2_init/module_init
1205  *
1206  *****************************************************************************/
cpia2_init(void)1207 static int __init cpia2_init(void)
1208 {
1209 	LOG("%s v%s\n",
1210 	    ABOUT, CPIA_VERSION);
1211 	check_parameters();
1212 	return cpia2_usb_init();
1213 }
1214 
1215 
1216 /******************************************************************************
1217  *
1218  * cpia2_exit/module_exit
1219  *
1220  *****************************************************************************/
cpia2_exit(void)1221 static void __exit cpia2_exit(void)
1222 {
1223 	cpia2_usb_cleanup();
1224 	schedule_timeout(2 * HZ);
1225 }
1226 
1227 module_init(cpia2_init);
1228 module_exit(cpia2_exit);
1229