57 #include <linux/module.h>
60 #include <linux/videodev2.h>
61 #include <linux/slab.h>
68 #include <linux/parport.h>
73 #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a)
82 #define W9966_DRIVERNAME "W9966CF Webcam"
83 #define W9966_MAXCAMS 4
84 #define W9966_RBUFFER 2048
85 #define W9966_SRAMSIZE 131072
86 #define W9966_SRAMID 0x02
89 #define W9966_WND_MIN_X 16
90 #define W9966_WND_MIN_Y 14
91 #define W9966_WND_MAX_X 705
92 #define W9966_WND_MAX_Y 253
93 #define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
94 #define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
97 #define W9966_STATE_PDEV 0x01
98 #define W9966_STATE_CLAIMED 0x02
99 #define W9966_STATE_VDEV 0x04
101 #define W9966_I2C_W_ID 0x48
102 #define W9966_I2C_R_ID 0x49
103 #define W9966_I2C_R_DATA 0x08
104 #define W9966_I2C_R_CLOCK 0x04
105 #define W9966_I2C_W_DATA 0x02
106 #define W9966_I2C_W_CLOCK 0x01
138 static char *pardev[] = {[0 ...
W9966_MAXCAMS] =
"aggressive"};
142 "\teach camera. 'aggressive' means brute-force search.\n"
143 "\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n"
144 "\tcam 1 to parport3 and search every parport for cam 2 etc...");
150 static int video_nr = -1;
161 static inline void w9966_set_state(
struct w9966 *
cam,
int mask,
int val)
167 static inline int w9966_get_state(
struct w9966 *
cam,
int mask,
int val)
173 static void w9966_pdev_claim(
struct w9966 *cam)
182 static void w9966_pdev_release(
struct w9966 *cam)
193 static int w9966_read_reg(
struct w9966 *cam,
int reg)
196 const unsigned char addr = 0x80 | (reg & 0x1f);
214 static int w9966_write_reg(
struct w9966 *cam,
int reg,
int data)
217 const unsigned char addr = 0xc0 | (reg & 0x1f);
218 const unsigned char val =
data;
238 static void w9966_i2c_setsda(
struct w9966 *cam,
int state)
245 w9966_write_reg(cam, 0x18, cam->
i2c_state);
251 static int w9966_i2c_getscl(
struct w9966 *cam)
253 const unsigned char state = w9966_read_reg(cam, 0x18);
259 static int w9966_i2c_setscl(
struct w9966 *cam,
int state)
268 w9966_write_reg(cam, 0x18, cam->
i2c_state);
274 while (!w9966_i2c_getscl(cam)) {
285 static int w9966_i2c_getsda(
struct w9966 *cam)
287 const unsigned char state = w9966_read_reg(cam, 0x18);
294 static int w9966_i2c_wbyte(
struct w9966 *cam,
int data)
298 for (i = 7; i >= 0; i--) {
299 w9966_i2c_setsda(cam, (data >> i) & 0x01);
301 if (w9966_i2c_setscl(cam, 1) == -1)
303 w9966_i2c_setscl(cam, 0);
306 w9966_i2c_setsda(cam, 1);
308 if (w9966_i2c_setscl(cam, 1) == -1)
310 w9966_i2c_setscl(cam, 0);
318 static int w9966_i2c_rbyte(
struct w9966 *cam)
320 unsigned char data = 0x00;
323 w9966_i2c_setsda(cam, 1);
325 for (i = 0; i < 8; i++) {
326 if (w9966_i2c_setscl(cam, 1) == -1)
329 if (w9966_i2c_getsda(cam))
332 w9966_i2c_setscl(cam, 0);
341 static int w9966_read_reg_i2c(
struct w9966 *cam,
int reg)
345 w9966_i2c_setsda(cam, 0);
346 w9966_i2c_setscl(cam, 0);
349 w9966_i2c_wbyte(cam, reg) == -1)
352 w9966_i2c_setsda(cam, 1);
353 if (w9966_i2c_setscl(cam, 1) == -1)
355 w9966_i2c_setsda(cam, 0);
356 w9966_i2c_setscl(cam, 0);
360 data = w9966_i2c_rbyte(cam);
364 w9966_i2c_setsda(cam, 0);
366 if (w9966_i2c_setscl(cam, 1) == -1)
368 w9966_i2c_setsda(cam, 1);
376 static int w9966_write_reg_i2c(
struct w9966 *cam,
int reg,
int data)
378 w9966_i2c_setsda(cam, 0);
379 w9966_i2c_setscl(cam, 0);
382 w9966_i2c_wbyte(cam, reg) == -1 ||
383 w9966_i2c_wbyte(cam, data) == -1)
386 w9966_i2c_setsda(cam, 0);
387 if (w9966_i2c_setscl(cam, 1) == -1)
390 w9966_i2c_setsda(cam, 1);
398 static int w9966_findlen(
int near,
int size,
int maxlen)
401 int besterr =
abs(near - bestlen);
404 for (len = size + 1; len < maxlen; len++) {
406 if (((64 * size) % len) != 0)
409 err =
abs(near - len);
425 static int w9966_calcscale(
int size,
int min,
int max,
int *beg,
int *
end,
unsigned char *factor)
427 int maxlen = max -
min;
428 int len = *end - *beg + 1;
429 int newlen = w9966_findlen(len, size, maxlen);
430 int err = newlen - len;
433 if (newlen > maxlen || newlen < size)
437 *factor = (64 *
size) / newlen;
445 *end += err - (err / 2);
463 static int w9966_setup(
struct w9966 *cam,
int x1,
int y1,
int x2,
int y2,
int w,
int h)
466 unsigned int enh_s, enh_e;
467 unsigned char scale_x, scale_y;
468 unsigned char regs[0x1c];
469 unsigned char saa7111_regs[] = {
470 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
471 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
472 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
478 DPRINTF(
"capture window exceeds SRAM size!.\n");
503 DPRINTF(
"%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
504 w, h, x1, x2, y1, y2, scale_x & ~0x80, scale_y & ~0x80);
509 regs[0x02] = scale_y;
510 regs[0x03] = scale_x;
513 regs[0x04] = (x1 & 0x0ff);
514 regs[0x05] = (x1 & 0x300)>>8;
515 regs[0x06] = (y1 & 0x0ff);
516 regs[0x07] = (y1 & 0x300)>>8;
517 regs[0x08] = (x2 & 0x0ff);
518 regs[0x09] = (x2 & 0x300)>>8;
519 regs[0x0a] = (y2 & 0x0ff);
524 regs[0x0d] = (enh_s & 0x000ff);
525 regs[0x0e] = (enh_s & 0x0ff00) >> 8;
526 regs[0x0f] = (enh_s & 0x70000) >> 16;
527 regs[0x10] = (enh_e & 0x000ff);
528 regs[0x11] = (enh_e & 0x0ff00) >> 8;
529 regs[0x12] = (enh_e & 0x70000) >> 16;
542 saa7111_regs[0x0c] = cam->
color;
543 saa7111_regs[0x0d] = cam->
hue;
546 if (w9966_write_reg(cam, 0x00, 0x03) == -1)
550 for (i = 0; i < 0x1c; i++)
551 if (w9966_write_reg(cam, i, regs[i]) == -1)
555 for (i = 0; i < 0x20; i++)
556 if (w9966_write_reg_i2c(cam, i, saa7111_regs[i]) == -1)
569 struct w9966 *cam = video_drvdata(file);
592 static int cam_g_input(
struct file *file,
void *fh,
unsigned int *
inp)
598 static int cam_s_input(
struct file *file,
void *fh,
unsigned int inp)
600 return (inp > 0) ? -
EINVAL : 0;
629 w9966_pdev_claim(cam);
631 if (w9966_write_reg_i2c(cam, 0x0a, cam->
brightness) == -1 ||
632 w9966_write_reg_i2c(cam, 0x0b, cam->
contrast) == -1 ||
633 w9966_write_reg_i2c(cam, 0x0c, cam->
color) == -1 ||
634 w9966_write_reg_i2c(cam, 0x0d, cam->
hue) == -1) {
638 w9966_pdev_release(cam);
644 static int cam_g_fmt_vid_cap(
struct file *file,
void *fh,
struct v4l2_format *
fmt)
646 struct w9966 *cam = video_drvdata(file);
660 static int cam_try_fmt_vid_cap(
struct file *file,
void *fh,
struct v4l2_format *
fmt)
681 static int cam_s_fmt_vid_cap(
struct file *file,
void *fh,
struct v4l2_format *fmt)
683 struct w9966 *cam = video_drvdata(file);
685 int ret = cam_try_fmt_vid_cap(file, fh, fmt);
692 w9966_pdev_claim(cam);
693 ret = w9966_setup(cam, 0, 0, 1023, 1023, pix->
width, pix->
height);
694 w9966_pdev_release(cam);
699 static int cam_enum_fmt_vid_cap(
struct file *file,
void *fh,
struct v4l2_fmtdesc *fmt)
712 *fmt = formats[fmt->
index];
718 static ssize_t w9966_v4l_read(
struct file *file,
char __user *
buf,
719 size_t count, loff_t *ppos)
721 struct w9966 *cam = video_drvdata(file);
722 unsigned char addr = 0xa0;
724 unsigned long dleft =
count;
732 w9966_pdev_claim(cam);
733 w9966_write_reg(cam, 0x00, 0x02);
734 w9966_write_reg(cam, 0x00, 0x00);
735 w9966_write_reg(cam, 0x01, 0x98);
741 w9966_pdev_release(cam);
767 w9966_write_reg(cam, 0x01, 0x18);
771 w9966_pdev_release(cam);
783 .read = w9966_v4l_read,
787 .vidioc_querycap = cam_querycap,
788 .vidioc_g_input = cam_g_input,
789 .vidioc_s_input = cam_s_input,
790 .vidioc_enum_input = cam_enum_input,
791 .vidioc_enum_fmt_vid_cap = cam_enum_fmt_vid_cap,
792 .vidioc_g_fmt_vid_cap = cam_g_fmt_vid_cap,
793 .vidioc_s_fmt_vid_cap = cam_s_fmt_vid_cap,
794 .vidioc_try_fmt_vid_cap = cam_try_fmt_vid_cap,
801 .s_ctrl = cam_s_ctrl,
819 v4l2_err(v4l2_dev,
"Could not register v4l2_device\n");
832 if (cam->
hdl.error) {
833 v4l2_err(v4l2_dev,
"couldn't register controls\n");
864 DPRINTF(
"parport_register_device() failed\n");
869 w9966_pdev_claim(cam);
872 if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
873 DPRINTF(
"w9966_setup() failed.\n");
877 w9966_pdev_release(cam);
881 cam->
vdev.v4l2_dev = v4l2_dev;
882 cam->
vdev.fops = &w9966_fops;
883 cam->
vdev.ioctl_ops = &w9966_ioctl_ops;
885 cam->
vdev.ctrl_handler = &cam->
hdl;
887 video_set_drvdata(&cam->
vdev, cam);
897 v4l2_info(v4l2_dev,
"Found and initialized a webcam on %s.\n",
904 static void w9966_term(
struct w9966 *cam)
916 w9966_pdev_claim(cam);
918 w9966_pdev_release(cam);
926 memset(cam, 0,
sizeof(*cam));
931 static void w9966_attach(
struct parport *port)
938 if (
strcmp(pardev[i],
"aggressive") == 0 ||
strcmp(pardev[i], port->
name) == 0) {
939 if (w9966_init(&w9966_cams[i], port) != 0)
940 w9966_term(&w9966_cams[i]);
947 static void w9966_detach(
struct parport *port)
953 w9966_term(&w9966_cams[i]);
959 .attach = w9966_attach,
960 .detach = w9966_detach,
964 static int __init w9966_mod_init(
void)
975 static void __exit w9966_mod_term(
void)