aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-17 21:16:55 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-17 21:16:55 -0400
commit4b337c5f245b6587ba844ac7bb13c313a2912f7b (patch)
tree999c6a6580b76a083c8efb9dabff709d1c49fcd0 /drivers/media/video/gspca
parent492b057c426e4aa747484958e18e9da29003985d (diff)
parent3fe0344faf7fdcb158bd5c1a9aec960a8d70c8e8 (diff)
Merge commit 'origin/master' into next
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/finepix.c1
-rw-r--r--drivers/media/video/gspca/gspca.c199
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/m5602/Makefile3
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h26
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c44
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c400
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h805
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c227
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h279
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c222
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h57
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c494
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h439
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c391
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h93
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c473
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h280
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h9
-rw-r--r--drivers/media/video/gspca/mr97310a.c8
-rw-r--r--drivers/media/video/gspca/ov519.c520
-rw-r--r--drivers/media/video/gspca/ov534.c277
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c66
-rw-r--r--drivers/media/video/gspca/spca500.c33
-rw-r--r--drivers/media/video/gspca/spca505.c14
-rw-r--r--drivers/media/video/gspca/spca508.c1934
-rw-r--r--drivers/media/video/gspca/spca561.c105
-rw-r--r--drivers/media/video/gspca/sq905.c1
-rw-r--r--drivers/media/video/gspca/sq905c.c1
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h10
-rw-r--r--drivers/media/video/gspca/sunplus.c33
-rw-r--r--drivers/media/video/gspca/t613.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c22
-rw-r--r--drivers/media/video/gspca/zc3xx.c22
37 files changed, 4281 insertions, 3295 deletions
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 00e6863ed666..480ec5c87d0e 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
168 168
169 cam->cam_mode = fpix_mode; 169 cam->cam_mode = fpix_mode;
170 cam->nmodes = 1; 170 cam->nmodes = 1;
171 cam->bulk = 1;
171 cam->bulk_size = FPIX_MAX_TRANSFER; 172 cam->bulk_size = FPIX_MAX_TRANSFER;
172 173
173 INIT_WORK(&dev->work_struct, dostream); 174 INIT_WORK(&dev->work_struct, dostream);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index a2741d7dccfe..f7e0355ad644 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Main USB camera driver 2 * Main USB camera driver
3 * 3 *
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) 50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0)
51 51
52#ifdef GSPCA_DEBUG 52#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 53int gspca_debug = D_ERR | D_PROBE;
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
441 * look for an input transfer endpoint in an alternate setting 441 * look for an input transfer endpoint in an alternate setting
442 */ 442 */
443static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, 443static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
444 __u8 xfer) 444 int xfer)
445{ 445{
446 struct usb_host_endpoint *ep; 446 struct usb_host_endpoint *ep;
447 int i, attr; 447 int i, attr;
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
449 for (i = 0; i < alt->desc.bNumEndpoints; i++) { 449 for (i = 0; i < alt->desc.bNumEndpoints; i++) {
450 ep = &alt->endpoint[i]; 450 ep = &alt->endpoint[i];
451 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 451 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
452 if (attr == xfer) 452 if (attr == xfer
453 && ep->desc.wMaxPacketSize != 0)
453 return ep; 454 return ep;
454 } 455 }
455 return NULL; 456 return NULL;
@@ -467,37 +468,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
467{ 468{
468 struct usb_interface *intf; 469 struct usb_interface *intf;
469 struct usb_host_endpoint *ep; 470 struct usb_host_endpoint *ep;
470 int i, ret; 471 int xfer, i, ret;
471 472
472 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 473 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
473 ep = NULL; 474 ep = NULL;
475 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
476 : USB_ENDPOINT_XFER_ISOC;
474 i = gspca_dev->alt; /* previous alt setting */ 477 i = gspca_dev->alt; /* previous alt setting */
475
476 /* try isoc */
477 while (--i >= 0) { 478 while (--i >= 0) {
478 ep = alt_xfer(&intf->altsetting[i], 479 ep = alt_xfer(&intf->altsetting[i], xfer);
479 USB_ENDPOINT_XFER_ISOC);
480 if (ep) 480 if (ep)
481 break; 481 break;
482 } 482 }
483
484 /* if no isoc, try bulk (alt 0 only) */
485 if (ep == NULL) { 483 if (ep == NULL) {
486 ep = alt_xfer(&intf->altsetting[0], 484 err("no transfer endpoint found");
487 USB_ENDPOINT_XFER_BULK); 485 return NULL;
488 if (ep == NULL) {
489 err("no transfer endpoint found");
490 return NULL;
491 }
492 i = 0;
493 gspca_dev->bulk = 1;
494 } 486 }
495 PDEBUG(D_STREAM, "use alt %d ep 0x%02x", 487 PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
496 i, ep->desc.bEndpointAddress); 488 i, ep->desc.bEndpointAddress);
497 if (i > 0) { 489 if (gspca_dev->nbalt > 1) {
498 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 490 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
499 if (ret < 0) { 491 if (ret < 0) {
500 err("set interface err %d", ret); 492 err("set alt %d err %d", i, ret);
501 return NULL; 493 return NULL;
502 } 494 }
503 } 495 }
@@ -517,13 +509,13 @@ static int create_urbs(struct gspca_dev *gspca_dev,
517 /* calculate the packet size and the number of packets */ 509 /* calculate the packet size and the number of packets */
518 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 510 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
519 511
520 if (!gspca_dev->bulk) { /* isoc */ 512 if (!gspca_dev->cam.bulk) { /* isoc */
521 513
522 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ 514 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
523 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 515 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
524 npkt = ISO_MAX_SIZE / psize; 516 npkt = gspca_dev->cam.npkt;
525 if (npkt > ISO_MAX_PKT) 517 if (npkt == 0)
526 npkt = ISO_MAX_PKT; 518 npkt = 32; /* default value */
527 bsize = psize * npkt; 519 bsize = psize * npkt;
528 PDEBUG(D_STREAM, 520 PDEBUG(D_STREAM,
529 "isoc %d pkts size %d = bsize:%d", 521 "isoc %d pkts size %d = bsize:%d",
@@ -617,7 +609,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
617 goto out; 609 goto out;
618 610
619 /* clear the bulk endpoint */ 611 /* clear the bulk endpoint */
620 if (gspca_dev->bulk) 612 if (gspca_dev->cam.bulk)
621 usb_clear_halt(gspca_dev->dev, 613 usb_clear_halt(gspca_dev->dev,
622 gspca_dev->urb[0]->pipe); 614 gspca_dev->urb[0]->pipe);
623 615
@@ -630,7 +622,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
630 gspca_dev->streaming = 1; 622 gspca_dev->streaming = 1;
631 623
632 /* some bulk transfers are started by the subdriver */ 624 /* some bulk transfers are started by the subdriver */
633 if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) 625 if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
634 break; 626 break;
635 627
636 /* submit the URBs */ 628 /* submit the URBs */
@@ -661,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
661{ 653{
662 int ret; 654 int ret;
663 655
656 if (gspca_dev->alt == 0)
657 return 0;
664 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); 658 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
665 if (ret < 0) 659 if (ret < 0)
666 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); 660 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
@@ -869,6 +863,32 @@ out:
869 return ret; 863 return ret;
870} 864}
871 865
866static int vidioc_enum_framesizes(struct file *file, void *priv,
867 struct v4l2_frmsizeenum *fsize)
868{
869 struct gspca_dev *gspca_dev = priv;
870 int i;
871 __u32 index = 0;
872
873 for (i = 0; i < gspca_dev->cam.nmodes; i++) {
874 if (fsize->pixel_format !=
875 gspca_dev->cam.cam_mode[i].pixelformat)
876 continue;
877
878 if (fsize->index == index) {
879 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
880 fsize->discrete.width =
881 gspca_dev->cam.cam_mode[i].width;
882 fsize->discrete.height =
883 gspca_dev->cam.cam_mode[i].height;
884 return 0;
885 }
886 index++;
887 }
888
889 return -EINVAL;
890}
891
872static void gspca_release(struct video_device *vfd) 892static void gspca_release(struct video_device *vfd)
873{ 893{
874 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); 894 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
@@ -989,43 +1009,54 @@ out:
989 return ret; 1009 return ret;
990} 1010}
991 1011
1012static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev,
1013 int id)
1014{
1015 const struct ctrl *ctrls;
1016 int i;
1017
1018 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
1019 i < gspca_dev->sd_desc->nctrls;
1020 i++, ctrls++) {
1021 if (gspca_dev->ctrl_dis & (1 << i))
1022 continue;
1023 if (id == ctrls->qctrl.id)
1024 return ctrls;
1025 }
1026 return NULL;
1027}
1028
992static int vidioc_queryctrl(struct file *file, void *priv, 1029static int vidioc_queryctrl(struct file *file, void *priv,
993 struct v4l2_queryctrl *q_ctrl) 1030 struct v4l2_queryctrl *q_ctrl)
994{ 1031{
995 struct gspca_dev *gspca_dev = priv; 1032 struct gspca_dev *gspca_dev = priv;
996 int i, ix; 1033 const struct ctrl *ctrls;
1034 int i;
997 u32 id; 1035 u32 id;
998 1036
999 ix = -1; 1037 ctrls = NULL;
1000 id = q_ctrl->id; 1038 id = q_ctrl->id;
1001 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { 1039 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
1002 id &= V4L2_CTRL_ID_MASK; 1040 id &= V4L2_CTRL_ID_MASK;
1003 id++; 1041 id++;
1004 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 1042 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
1005 if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) 1043 if (gspca_dev->ctrl_dis & (1 << i))
1006 continue; 1044 continue;
1007 if (ix < 0) { 1045 if (ctrls->qctrl.id < id)
1008 ix = i;
1009 continue; 1046 continue;
1047 if (ctrls != NULL) {
1048 if (gspca_dev->sd_desc->ctrls[i].qctrl.id
1049 > ctrls->qctrl.id)
1050 continue;
1010 } 1051 }
1011 if (gspca_dev->sd_desc->ctrls[i].qctrl.id 1052 ctrls = &gspca_dev->sd_desc->ctrls[i];
1012 > gspca_dev->sd_desc->ctrls[ix].qctrl.id)
1013 continue;
1014 ix = i;
1015 }
1016 }
1017 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
1018 if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
1019 ix = i;
1020 break;
1021 } 1053 }
1054 } else {
1055 ctrls = get_ctrl(gspca_dev, id);
1022 } 1056 }
1023 if (ix < 0) 1057 if (ctrls == NULL)
1024 return -EINVAL; 1058 return -EINVAL;
1025 memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl, 1059 memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
1026 sizeof *q_ctrl);
1027 if (gspca_dev->ctrl_dis & (1 << ix))
1028 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
1029 return 0; 1060 return 0;
1030} 1061}
1031 1062
@@ -1034,56 +1065,45 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1034{ 1065{
1035 struct gspca_dev *gspca_dev = priv; 1066 struct gspca_dev *gspca_dev = priv;
1036 const struct ctrl *ctrls; 1067 const struct ctrl *ctrls;
1037 int i, ret; 1068 int ret;
1038 1069
1039 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; 1070 ctrls = get_ctrl(gspca_dev, ctrl->id);
1040 i < gspca_dev->sd_desc->nctrls; 1071 if (ctrls == NULL)
1041 i++, ctrls++) { 1072 return -EINVAL;
1042 if (ctrl->id != ctrls->qctrl.id) 1073
1043 continue; 1074 if (ctrl->value < ctrls->qctrl.minimum
1044 if (gspca_dev->ctrl_dis & (1 << i)) 1075 || ctrl->value > ctrls->qctrl.maximum)
1045 return -EINVAL; 1076 return -ERANGE;
1046 if (ctrl->value < ctrls->qctrl.minimum 1077 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
1047 || ctrl->value > ctrls->qctrl.maximum) 1078 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1048 return -ERANGE; 1079 return -ERESTARTSYS;
1049 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); 1080 if (gspca_dev->present)
1050 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 1081 ret = ctrls->set(gspca_dev, ctrl->value);
1051 return -ERESTARTSYS; 1082 else
1052 if (gspca_dev->present) 1083 ret = -ENODEV;
1053 ret = ctrls->set(gspca_dev, ctrl->value); 1084 mutex_unlock(&gspca_dev->usb_lock);
1054 else 1085 return ret;
1055 ret = -ENODEV;
1056 mutex_unlock(&gspca_dev->usb_lock);
1057 return ret;
1058 }
1059 return -EINVAL;
1060} 1086}
1061 1087
1062static int vidioc_g_ctrl(struct file *file, void *priv, 1088static int vidioc_g_ctrl(struct file *file, void *priv,
1063 struct v4l2_control *ctrl) 1089 struct v4l2_control *ctrl)
1064{ 1090{
1065 struct gspca_dev *gspca_dev = priv; 1091 struct gspca_dev *gspca_dev = priv;
1066
1067 const struct ctrl *ctrls; 1092 const struct ctrl *ctrls;
1068 int i, ret; 1093 int ret;
1069 1094
1070 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; 1095 ctrls = get_ctrl(gspca_dev, ctrl->id);
1071 i < gspca_dev->sd_desc->nctrls; 1096 if (ctrls == NULL)
1072 i++, ctrls++) { 1097 return -EINVAL;
1073 if (ctrl->id != ctrls->qctrl.id) 1098
1074 continue; 1099 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1075 if (gspca_dev->ctrl_dis & (1 << i)) 1100 return -ERESTARTSYS;
1076 return -EINVAL; 1101 if (gspca_dev->present)
1077 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 1102 ret = ctrls->get(gspca_dev, &ctrl->value);
1078 return -ERESTARTSYS; 1103 else
1079 if (gspca_dev->present) 1104 ret = -ENODEV;
1080 ret = ctrls->get(gspca_dev, &ctrl->value); 1105 mutex_unlock(&gspca_dev->usb_lock);
1081 else 1106 return ret;
1082 ret = -ENODEV;
1083 mutex_unlock(&gspca_dev->usb_lock);
1084 return ret;
1085 }
1086 return -EINVAL;
1087} 1107}
1088 1108
1089/*fixme: have an audio flag in gspca_dev?*/ 1109/*fixme: have an audio flag in gspca_dev?*/
@@ -1864,6 +1884,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
1864 .vidioc_g_parm = vidioc_g_parm, 1884 .vidioc_g_parm = vidioc_g_parm,
1865 .vidioc_s_parm = vidioc_s_parm, 1885 .vidioc_s_parm = vidioc_s_parm,
1866 .vidioc_s_std = vidioc_s_std, 1886 .vidioc_s_std = vidioc_s_std,
1887 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1867#ifdef CONFIG_VIDEO_V4L1_COMPAT 1888#ifdef CONFIG_VIDEO_V4L1_COMPAT
1868 .vidiocgmbuf = vidiocgmbuf, 1889 .vidiocgmbuf = vidiocgmbuf,
1869#endif 1890#endif
@@ -1943,7 +1964,7 @@ int gspca_dev_probe(struct usb_interface *intf,
1943 1964
1944 /* init video stuff */ 1965 /* init video stuff */
1945 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); 1966 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1946 gspca_dev->vdev.parent = &dev->dev; 1967 gspca_dev->vdev.parent = &intf->dev;
1947 gspca_dev->module = module; 1968 gspca_dev->module = module;
1948 gspca_dev->present = 1; 1969 gspca_dev->present = 1;
1949 ret = video_register_device(&gspca_dev->vdev, 1970 ret = video_register_device(&gspca_dev->vdev,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 58e8ff02136a..bd1faff88644 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -44,8 +44,6 @@ extern int gspca_debug;
44#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ 44#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
45/* image transfers */ 45/* image transfers */
46#define MAX_NURBS 4 /* max number of URBs */ 46#define MAX_NURBS 4 /* max number of URBs */
47#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */
48#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */
49 47
50/* device information - set at probe time */ 48/* device information - set at probe time */
51struct cam { 49struct cam {
@@ -56,6 +54,9 @@ struct cam {
56 * - cannot be > MAX_NURBS 54 * - cannot be > MAX_NURBS
57 * - when 0 and bulk_size != 0 means 55 * - when 0 and bulk_size != 0 means
58 * 1 URB and submit done by subdriver */ 56 * 1 URB and submit done by subdriver */
57 u8 bulk; /* image transfer by 0:isoc / 1:bulk */
58 u8 npkt; /* number of packets in an ISOC message
59 * 0 is the default value: 32 packets */
59 u32 input_flags; /* value for ENUM_INPUT status flags */ 60 u32 input_flags; /* value for ENUM_INPUT status flags */
60}; 61};
61 62
@@ -168,7 +169,6 @@ struct gspca_dev {
168 __u8 iface; /* USB interface number */ 169 __u8 iface; /* USB interface number */
169 __u8 alt; /* USB alternate setting */ 170 __u8 alt; /* USB alternate setting */
170 __u8 nbalt; /* number of USB alternate settings */ 171 __u8 nbalt; /* number of USB alternate settings */
171 u8 bulk; /* image transfer by 0:isoc / 1:bulk */
172}; 172};
173 173
174int gspca_dev_probe(struct usb_interface *intf, 174int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index 9fa3644f4869..bf7a19a1e6d1 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -2,9 +2,10 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o
2 2
3gspca_m5602-objs := m5602_core.o \ 3gspca_m5602-objs := m5602_core.o \
4 m5602_ov9650.o \ 4 m5602_ov9650.o \
5 m5602_ov7660.o \
5 m5602_mt9m111.o \ 6 m5602_mt9m111.o \
6 m5602_po1030.o \ 7 m5602_po1030.o \
7 m5602_s5k83a.o \ 8 m5602_s5k83a.o \
8 m5602_s5k4aa.o 9 m5602_s5k4aa.o
9 10
10EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file 11EXTRA_CFLAGS += -Idrivers/media/video/gspca
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 8f1cea6fd3bf..1127a405c9b2 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -45,6 +45,15 @@
45#define M5602_XB_SEN_CLK_DIV 0x15 45#define M5602_XB_SEN_CLK_DIV 0x15
46#define M5602_XB_AUD_CLK_CTRL 0x16 46#define M5602_XB_AUD_CLK_CTRL 0x16
47#define M5602_XB_AUD_CLK_DIV 0x17 47#define M5602_XB_AUD_CLK_DIV 0x17
48#define M5602_OB_AC_LINK_STATE 0x22
49#define M5602_OB_PCM_SLOT_INDEX 0x24
50#define M5602_OB_GPIO_SLOT_INDEX 0x25
51#define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28
52#define M5602_OB_ACRX_STATUS_DATA_L 0x29
53#define M5602_OB_ACRX_STATUS_DATA_H 0x2a
54#define M5602_OB_ACTX_COMMAND_ADDRESS 0x31
55#define M5602_OB_ACRX_COMMAND_DATA_L 0x32
56#define M5602_OB_ACTX_COMMAND_DATA_H 0X33
48#define M5602_XB_DEVCTR1 0x41 57#define M5602_XB_DEVCTR1 0x41
49#define M5602_XB_EPSETR0 0x42 58#define M5602_XB_EPSETR0 0x42
50#define M5602_XB_EPAFCTR 0x47 59#define M5602_XB_EPAFCTR 0x47
@@ -77,7 +86,18 @@
77#define M5602_XB_GPIO_EN_L 0x75 86#define M5602_XB_GPIO_EN_L 0x75
78#define M5602_XB_GPIO_DAT 0x76 87#define M5602_XB_GPIO_DAT 0x76
79#define M5602_XB_GPIO_DIR 0x77 88#define M5602_XB_GPIO_DIR 0x77
80#define M5602_XB_MISC_CTL 0x70 89#define M5602_XB_SEN_CLK_CONTROL 0x80
90#define M5602_XB_SEN_CLK_DIVISION 0x81
91#define M5602_XB_CPR_CLK_CONTROL 0x82
92#define M5602_XB_CPR_CLK_DIVISION 0x83
93#define M5602_XB_MCU_CLK_CONTROL 0x84
94#define M5602_XB_MCU_CLK_DIVISION 0x85
95#define M5602_XB_DCT_CLK_CONTROL 0x86
96#define M5602_XB_DCT_CLK_DIVISION 0x87
97#define M5602_XB_EC_CLK_CONTROL 0x88
98#define M5602_XB_EC_CLK_DIVISION 0x89
99#define M5602_XB_LBUF_CLK_CONTROL 0x8a
100#define M5602_XB_LBUF_CLK_DIVISION 0x8b
81 101
82#define I2C_BUSY 0x80 102#define I2C_BUSY 0x80
83 103
@@ -128,10 +148,10 @@ struct sd {
128}; 148};
129 149
130int m5602_read_bridge( 150int m5602_read_bridge(
131 struct sd *sd, u8 address, u8 *i2c_data); 151 struct sd *sd, const u8 address, u8 *i2c_data);
132 152
133int m5602_write_bridge( 153int m5602_write_bridge(
134 struct sd *sd, u8 address, u8 i2c_data); 154 struct sd *sd, const u8 address, const u8 i2c_data);
135 155
136int m5602_write_sensor(struct sd *sd, const u8 address, 156int m5602_write_sensor(struct sd *sd, const u8 address,
137 u8 *i2c_data, const u8 len); 157 u8 *i2c_data, const u8 len);
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 1aac2985fee6..8a5bba16ff32 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20#include "m5602_ov7660.h"
20#include "m5602_mt9m111.h" 21#include "m5602_mt9m111.h"
21#include "m5602_po1030.h" 22#include "m5602_po1030.h"
22#include "m5602_s5k83a.h" 23#include "m5602_s5k83a.h"
@@ -35,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = {
35MODULE_DEVICE_TABLE(usb, m5602_table); 36MODULE_DEVICE_TABLE(usb, m5602_table);
36 37
37/* Reads a byte from the m5602 */ 38/* Reads a byte from the m5602 */
38int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) 39int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
39{ 40{
40 int err; 41 int err;
41 struct usb_device *udev = sd->gspca_dev.dev; 42 struct usb_device *udev = sd->gspca_dev.dev;
@@ -56,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
56} 57}
57 58
58/* Writes a byte to to the m5602 */ 59/* Writes a byte to to the m5602 */
59int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) 60int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
60{ 61{
61 int err; 62 int err;
62 struct usb_device *udev = sd->gspca_dev.dev; 63 struct usb_device *udev = sd->gspca_dev.dev;
@@ -80,6 +81,17 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
80 return (err < 0) ? err : 0; 81 return (err < 0) ? err : 0;
81} 82}
82 83
84int m5602_wait_for_i2c(struct sd *sd)
85{
86 int err;
87 u8 data;
88
89 do {
90 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data);
91 } while ((data & I2C_BUSY) && !err);
92 return err;
93}
94
83int m5602_read_sensor(struct sd *sd, const u8 address, 95int m5602_read_sensor(struct sd *sd, const u8 address,
84 u8 *i2c_data, const u8 len) 96 u8 *i2c_data, const u8 len)
85{ 97{
@@ -88,9 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
88 if (!len || len > sd->sensor->i2c_regW) 100 if (!len || len > sd->sensor->i2c_regW)
89 return -EINVAL; 101 return -EINVAL;
90 102
91 do { 103 err = m5602_wait_for_i2c(sd);
92 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
93 } while ((*i2c_data & I2C_BUSY) && !err);
94 if (err < 0) 104 if (err < 0)
95 return err; 105 return err;
96 106
@@ -103,21 +113,25 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
103 if (err < 0) 113 if (err < 0)
104 return err; 114 return err;
105 115
116 /* Sensors with registers that are of only
117 one byte width are differently read */
118
119 /* FIXME: This works with the ov9650, but has issues with the po1030 */
106 if (sd->sensor->i2c_regW == 1) { 120 if (sd->sensor->i2c_regW == 1) {
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len); 121 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1);
108 if (err < 0) 122 if (err < 0)
109 return err; 123 return err;
110 124
111 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); 125 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
112 if (err < 0)
113 return err;
114 } else { 126 } else {
115 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); 127 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
116 if (err < 0)
117 return err;
118 } 128 }
119 129
120 for (i = 0; (i < len) && !err; i++) { 130 for (i = 0; (i < len) && !err; i++) {
131 err = m5602_wait_for_i2c(sd);
132 if (err < 0)
133 return err;
134
121 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); 135 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
122 136
123 PDEBUG(D_CONF, "Reading sensor register " 137 PDEBUG(D_CONF, "Reading sensor register "
@@ -206,6 +220,11 @@ static int m5602_probe_sensor(struct sd *sd)
206 if (!sd->sensor->probe(sd)) 220 if (!sd->sensor->probe(sd))
207 return 0; 221 return 0;
208 222
223 /* Try the ov7660 */
224 sd->sensor = &ov7660;
225 if (!sd->sensor->probe(sd))
226 return 0;
227
209 /* Try the s5k83a */ 228 /* Try the s5k83a */
210 sd->sensor = &s5k83a; 229 sd->sensor = &s5k83a;
211 if (!sd->sensor->probe(sd)) 230 if (!sd->sensor->probe(sd))
@@ -409,8 +428,9 @@ MODULE_DESCRIPTION(DRIVER_DESC);
409MODULE_LICENSE("GPL"); 428MODULE_LICENSE("GPL");
410module_param(force_sensor, int, S_IRUGO | S_IWUSR); 429module_param(force_sensor, int, S_IRUGO | S_IWUSR);
411MODULE_PARM_DESC(force_sensor, 430MODULE_PARM_DESC(force_sensor,
412 "force detection of sensor, " 431 "forces detection of a sensor, "
413 "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030"); 432 "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, "
433 "4 = MT9M111, 5 = PO1030, 6 = OV7660");
414 434
415module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); 435module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
416MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); 436MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 7d3f9e348ef4..8d071dff6944 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,23 @@
18 18
19#include "m5602_mt9m111.h" 19#include "m5602_mt9m111.h"
20 20
21static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
22static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
23static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
24static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
25static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
26static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
27static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
28 __s32 val);
29static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
30 __s32 *val);
31static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
32static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
33static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
34static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
35static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
36static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
37
21static struct v4l2_pix_format mt9m111_modes[] = { 38static struct v4l2_pix_format mt9m111_modes[] = {
22 { 39 {
23 640, 40 640,
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
32}; 49};
33 50
34const static struct ctrl mt9m111_ctrls[] = { 51const static struct ctrl mt9m111_ctrls[] = {
52#define VFLIP_IDX 0
35 { 53 {
36 { 54 {
37 .id = V4L2_CID_VFLIP, 55 .id = V4L2_CID_VFLIP,
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = {
44 }, 62 },
45 .set = mt9m111_set_vflip, 63 .set = mt9m111_set_vflip,
46 .get = mt9m111_get_vflip 64 .get = mt9m111_get_vflip
47 }, { 65 },
66#define HFLIP_IDX 1
67 {
48 { 68 {
49 .id = V4L2_CID_HFLIP, 69 .id = V4L2_CID_HFLIP,
50 .type = V4L2_CTRL_TYPE_BOOLEAN, 70 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = {
56 }, 76 },
57 .set = mt9m111_set_hflip, 77 .set = mt9m111_set_hflip,
58 .get = mt9m111_get_hflip 78 .get = mt9m111_get_hflip
59 }, { 79 },
80#define GAIN_IDX 2
81 {
60 { 82 {
61 .id = V4L2_CID_GAIN, 83 .id = V4L2_CID_GAIN,
62 .type = V4L2_CTRL_TYPE_INTEGER, 84 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = {
64 .minimum = 0, 86 .minimum = 0,
65 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, 87 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
66 .step = 1, 88 .step = 1,
67 .default_value = DEFAULT_GAIN, 89 .default_value = MT9M111_DEFAULT_GAIN,
68 .flags = V4L2_CTRL_FLAG_SLIDER 90 .flags = V4L2_CTRL_FLAG_SLIDER
69 }, 91 },
70 .set = mt9m111_set_gain, 92 .set = mt9m111_set_gain,
71 .get = mt9m111_get_gain 93 .get = mt9m111_get_gain
72 } 94 },
95#define AUTO_WHITE_BALANCE_IDX 3
96 {
97 {
98 .id = V4L2_CID_AUTO_WHITE_BALANCE,
99 .type = V4L2_CTRL_TYPE_BOOLEAN,
100 .name = "auto white balance",
101 .minimum = 0,
102 .maximum = 1,
103 .step = 1,
104 .default_value = 0,
105 },
106 .set = mt9m111_set_auto_white_balance,
107 .get = mt9m111_get_auto_white_balance
108 },
109#define GREEN_BALANCE_IDX 4
110 {
111 {
112 .id = M5602_V4L2_CID_GREEN_BALANCE,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "green balance",
115 .minimum = 0x00,
116 .maximum = 0x7ff,
117 .step = 0x1,
118 .default_value = MT9M111_GREEN_GAIN_DEFAULT,
119 .flags = V4L2_CTRL_FLAG_SLIDER
120 },
121 .set = mt9m111_set_green_balance,
122 .get = mt9m111_get_green_balance
123 },
124#define BLUE_BALANCE_IDX 5
125 {
126 {
127 .id = V4L2_CID_BLUE_BALANCE,
128 .type = V4L2_CTRL_TYPE_INTEGER,
129 .name = "blue balance",
130 .minimum = 0x00,
131 .maximum = 0x7ff,
132 .step = 0x1,
133 .default_value = MT9M111_BLUE_GAIN_DEFAULT,
134 .flags = V4L2_CTRL_FLAG_SLIDER
135 },
136 .set = mt9m111_set_blue_balance,
137 .get = mt9m111_get_blue_balance
138 },
139#define RED_BALANCE_IDX 5
140 {
141 {
142 .id = V4L2_CID_RED_BALANCE,
143 .type = V4L2_CTRL_TYPE_INTEGER,
144 .name = "red balance",
145 .minimum = 0x00,
146 .maximum = 0x7ff,
147 .step = 0x1,
148 .default_value = MT9M111_RED_GAIN_DEFAULT,
149 .flags = V4L2_CTRL_FLAG_SLIDER
150 },
151 .set = mt9m111_set_red_balance,
152 .get = mt9m111_get_red_balance
153 },
73}; 154};
74 155
75
76static void mt9m111_dump_registers(struct sd *sd); 156static void mt9m111_dump_registers(struct sd *sd);
77 157
78int mt9m111_probe(struct sd *sd) 158int mt9m111_probe(struct sd *sd)
79{ 159{
80 u8 data[2] = {0x00, 0x00}; 160 u8 data[2] = {0x00, 0x00};
81 int i; 161 int i;
162 s32 *sensor_settings;
82 163
83 if (force_sensor) { 164 if (force_sensor) {
84 if (force_sensor == MT9M111_SENSOR) { 165 if (force_sensor == MT9M111_SENSOR) {
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd)
117 return -ENODEV; 198 return -ENODEV;
118 199
119sensor_found: 200sensor_found:
201 sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
202 GFP_KERNEL);
203 if (!sensor_settings)
204 return -ENOMEM;
205
120 sd->gspca_dev.cam.cam_mode = mt9m111_modes; 206 sd->gspca_dev.cam.cam_mode = mt9m111_modes;
121 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); 207 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
122 sd->desc->ctrls = mt9m111_ctrls; 208 sd->desc->ctrls = mt9m111_ctrls;
123 sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); 209 sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
210
211 for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
212 sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
213 sd->sensor_priv = sensor_settings;
214
124 return 0; 215 return 0;
125} 216}
126 217
127int mt9m111_init(struct sd *sd) 218int mt9m111_init(struct sd *sd)
128{ 219{
129 int i, err = 0; 220 int i, err = 0;
221 s32 *sensor_settings = sd->sensor_priv;
130 222
131 /* Init the sensor */ 223 /* Init the sensor */
132 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { 224 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd)
147 if (dump_sensor) 239 if (dump_sensor)
148 mt9m111_dump_registers(sd); 240 mt9m111_dump_registers(sd);
149 241
150 return (err < 0) ? err : 0; 242 err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
243 if (err < 0)
244 return err;
245
246 err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
247 if (err < 0)
248 return err;
249
250 err = mt9m111_set_green_balance(&sd->gspca_dev,
251 sensor_settings[GREEN_BALANCE_IDX]);
252 if (err < 0)
253 return err;
254
255 err = mt9m111_set_blue_balance(&sd->gspca_dev,
256 sensor_settings[BLUE_BALANCE_IDX]);
257 if (err < 0)
258 return err;
259
260 err = mt9m111_set_red_balance(&sd->gspca_dev,
261 sensor_settings[RED_BALANCE_IDX]);
262 if (err < 0)
263 return err;
264
265 return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
151} 266}
152 267
153int mt9m111_power_down(struct sd *sd) 268int mt9m111_start(struct sd *sd)
154{ 269{
155 return 0; 270 int i, err = 0;
271 u8 data[2];
272 struct cam *cam = &sd->gspca_dev.cam;
273 s32 *sensor_settings = sd->sensor_priv;
274
275 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
276 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
277
278 for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
279 if (start_mt9m111[i][0] == BRIDGE) {
280 err = m5602_write_bridge(sd,
281 start_mt9m111[i][1],
282 start_mt9m111[i][2]);
283 } else {
284 data[0] = start_mt9m111[i][2];
285 data[1] = start_mt9m111[i][3];
286 err = m5602_write_sensor(sd,
287 start_mt9m111[i][1], data, 2);
288 }
289 }
290 if (err < 0)
291 return err;
292
293 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
294 if (err < 0)
295 return err;
296
297 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
298 if (err < 0)
299 return err;
300
301 for (i = 0; i < 2 && !err; i++)
302 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
303 if (err < 0)
304 return err;
305
306 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
307 if (err < 0)
308 return err;
309
310 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
311 if (err < 0)
312 return err;
313
314 for (i = 0; i < 2 && !err; i++)
315 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
316 if (err < 0)
317 return err;
318
319 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
320 (width >> 8) & 0xff);
321 if (err < 0)
322 return err;
323
324 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
325 if (err < 0)
326 return err;
327
328 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
329 if (err < 0)
330 return err;
331
332 switch (width) {
333 case 640:
334 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
335 data[0] = MT9M111_RMB_OVER_SIZED;
336 data[1] = MT9M111_RMB_ROW_SKIP_2X |
337 MT9M111_RMB_COLUMN_SKIP_2X |
338 (sensor_settings[VFLIP_IDX] << 0) |
339 (sensor_settings[HFLIP_IDX] << 1);
340
341 err = m5602_write_sensor(sd,
342 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
343 break;
344
345 case 320:
346 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
347 data[0] = MT9M111_RMB_OVER_SIZED;
348 data[1] = MT9M111_RMB_ROW_SKIP_4X |
349 MT9M111_RMB_COLUMN_SKIP_4X |
350 (sensor_settings[VFLIP_IDX] << 0) |
351 (sensor_settings[HFLIP_IDX] << 1);
352 err = m5602_write_sensor(sd,
353 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
354 break;
355 }
356 return err;
156} 357}
157 358
158int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 359void mt9m111_disconnect(struct sd *sd)
360{
361 sd->sensor = NULL;
362 kfree(sd->sensor_priv);
363}
364
365static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
159{ 366{
160 int err;
161 u8 data[2] = {0x00, 0x00};
162 struct sd *sd = (struct sd *) gspca_dev; 367 struct sd *sd = (struct sd *) gspca_dev;
368 s32 *sensor_settings = sd->sensor_priv;
163 369
164 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 370 *val = sensor_settings[VFLIP_IDX];
165 data, 2);
166 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
167 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 371 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
168 372
169 return err; 373 return 0;
170} 374}
171 375
172int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 376static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
173{ 377{
174 int err; 378 int err;
175 u8 data[2] = {0x00, 0x00}; 379 u8 data[2] = {0x00, 0x00};
176 struct sd *sd = (struct sd *) gspca_dev; 380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
177 382
178 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 383 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
179 384
385 sensor_settings[VFLIP_IDX] = val;
386
387 /* The mt9m111 is flipped by default */
388 val = !val;
389
180 /* Set the correct page map */ 390 /* Set the correct page map */
181 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 391 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
182 if (err < 0) 392 if (err < 0)
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
186 if (err < 0) 396 if (err < 0)
187 return err; 397 return err;
188 398
189 data[0] = (data[0] & 0xfe) | val; 399 data[1] = (data[1] & 0xfe) | val;
190 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 400 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
191 data, 2); 401 data, 2);
192 return err; 402 return err;
193} 403}
194 404
195int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 405static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
196{ 406{
197 int err;
198 u8 data[2] = {0x00, 0x00};
199 struct sd *sd = (struct sd *) gspca_dev; 407 struct sd *sd = (struct sd *) gspca_dev;
408 s32 *sensor_settings = sd->sensor_priv;
200 409
201 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 410 *val = sensor_settings[HFLIP_IDX];
202 data, 2);
203 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
204 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 411 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
205 412
206 return err; 413 return 0;
207} 414}
208 415
209int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 416static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
210{ 417{
211 int err; 418 int err;
212 u8 data[2] = {0x00, 0x00}; 419 u8 data[2] = {0x00, 0x00};
213 struct sd *sd = (struct sd *) gspca_dev; 420 struct sd *sd = (struct sd *) gspca_dev;
421 s32 *sensor_settings = sd->sensor_priv;
214 422
215 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 423 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
216 424
425 sensor_settings[HFLIP_IDX] = val;
426
427 /* The mt9m111 is flipped by default */
428 val = !val;
429
217 /* Set the correct page map */ 430 /* Set the correct page map */
218 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 431 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
219 if (err < 0) 432 if (err < 0)
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
223 if (err < 0) 436 if (err < 0)
224 return err; 437 return err;
225 438
226 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); 439 data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
227 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 440 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
228 data, 2); 441 data, 2);
229 return err; 442 return err;
230} 443}
231 444
232int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 445static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
233{ 446{
234 int err, tmp;
235 u8 data[2] = {0x00, 0x00};
236 struct sd *sd = (struct sd *) gspca_dev; 447 struct sd *sd = (struct sd *) gspca_dev;
448 s32 *sensor_settings = sd->sensor_priv;
237 449
238 err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); 450 *val = sensor_settings[GAIN_IDX];
239 tmp = ((data[1] << 8) | data[0]); 451 PDEBUG(D_V4L2, "Read gain %d", *val);
240 452
241 *val = ((tmp & (1 << 10)) * 2) | 453 return 0;
242 ((tmp & (1 << 9)) * 2) | 454}
243 ((tmp & (1 << 8)) * 2) |
244 (tmp & 0x7f);
245 455
246 PDEBUG(D_V4L2, "Read gain %d", *val); 456static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
457 __s32 val)
458{
459 struct sd *sd = (struct sd *) gspca_dev;
460 s32 *sensor_settings = sd->sensor_priv;
461 int err;
462 u8 data[2];
463
464 err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
465 if (err < 0)
466 return err;
467
468 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
469 data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
247 470
471 err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
472
473 PDEBUG(D_V4L2, "Set auto white balance %d", val);
248 return err; 474 return err;
249} 475}
250 476
251int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 477static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
478 __s32 *val) {
479 struct sd *sd = (struct sd *) gspca_dev;
480 s32 *sensor_settings = sd->sensor_priv;
481
482 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
483 PDEBUG(D_V4L2, "Read auto white balance %d", *val);
484 return 0;
485}
486
487static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
252{ 488{
253 int err, tmp; 489 int err, tmp;
254 u8 data[2] = {0x00, 0x00}; 490 u8 data[2] = {0x00, 0x00};
255 struct sd *sd = (struct sd *) gspca_dev; 491 struct sd *sd = (struct sd *) gspca_dev;
492 s32 *sensor_settings = sd->sensor_priv;
493
494 sensor_settings[GAIN_IDX] = val;
256 495
257 /* Set the correct page map */ 496 /* Set the correct page map */
258 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 497 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
275 else 514 else
276 tmp = val; 515 tmp = val;
277 516
278 data[1] = (tmp & 0xff00) >> 8; 517 data[1] = (tmp & 0xff);
279 data[0] = (tmp & 0xff); 518 data[0] = (tmp & 0xff00) >> 8;
280 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 519 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
281 data[1], data[0]); 520 data[1], data[0]);
282 521
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
286 return err; 525 return err;
287} 526}
288 527
528static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
529{
530 int err;
531 u8 data[2];
532 struct sd *sd = (struct sd *) gspca_dev;
533 s32 *sensor_settings = sd->sensor_priv;
534
535 sensor_settings[GREEN_BALANCE_IDX] = val;
536 data[1] = (val & 0xff);
537 data[0] = (val & 0xff00) >> 8;
538
539 PDEBUG(D_V4L2, "Set green balance %d", val);
540 err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
541 data, 2);
542 if (err < 0)
543 return err;
544
545 return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
546 data, 2);
547}
548
549static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
550{
551 struct sd *sd = (struct sd *) gspca_dev;
552 s32 *sensor_settings = sd->sensor_priv;
553
554 *val = sensor_settings[GREEN_BALANCE_IDX];
555 PDEBUG(D_V4L2, "Read green balance %d", *val);
556 return 0;
557}
558
559static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
560{
561 u8 data[2];
562 struct sd *sd = (struct sd *) gspca_dev;
563 s32 *sensor_settings = sd->sensor_priv;
564
565 sensor_settings[BLUE_BALANCE_IDX] = val;
566 data[1] = (val & 0xff);
567 data[0] = (val & 0xff00) >> 8;
568
569 PDEBUG(D_V4L2, "Set blue balance %d", val);
570
571 return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
572 data, 2);
573}
574
575static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
576{
577 struct sd *sd = (struct sd *) gspca_dev;
578 s32 *sensor_settings = sd->sensor_priv;
579
580 *val = sensor_settings[BLUE_BALANCE_IDX];
581 PDEBUG(D_V4L2, "Read blue balance %d", *val);
582 return 0;
583}
584
585static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
586{
587 u8 data[2];
588 struct sd *sd = (struct sd *) gspca_dev;
589 s32 *sensor_settings = sd->sensor_priv;
590
591 sensor_settings[RED_BALANCE_IDX] = val;
592 data[1] = (val & 0xff);
593 data[0] = (val & 0xff00) >> 8;
594
595 PDEBUG(D_V4L2, "Set red balance %d", val);
596
597 return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
598 data, 2);
599}
600
601static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
602{
603 struct sd *sd = (struct sd *) gspca_dev;
604 s32 *sensor_settings = sd->sensor_priv;
605
606 *val = sensor_settings[RED_BALANCE_IDX];
607 PDEBUG(D_V4L2, "Read red balance %d", *val);
608 return 0;
609}
610
289static void mt9m111_dump_registers(struct sd *sd) 611static void mt9m111_dump_registers(struct sd *sd)
290{ 612{
291 u8 address, value[2] = {0x00, 0x00}; 613 u8 address, value[2] = {0x00, 0x00};
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 00c6db02bdb7..b3de77823091 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -37,7 +37,6 @@
37#define MT9M111_SC_VBLANK_CONTEXT_A 0x08 37#define MT9M111_SC_VBLANK_CONTEXT_A 0x08
38#define MT9M111_SC_SHUTTER_WIDTH 0x09 38#define MT9M111_SC_SHUTTER_WIDTH 0x09
39#define MT9M111_SC_ROW_SPEED 0x0a 39#define MT9M111_SC_ROW_SPEED 0x0a
40
41#define MT9M111_SC_EXTRA_DELAY 0x0b 40#define MT9M111_SC_EXTRA_DELAY 0x0b
42#define MT9M111_SC_SHUTTER_DELAY 0x0c 41#define MT9M111_SC_SHUTTER_DELAY 0x0c
43#define MT9M111_SC_RESET 0x0d 42#define MT9M111_SC_RESET 0x0d
@@ -50,9 +49,6 @@
50#define MT9M111_SC_GREEN_2_GAIN 0x2e 49#define MT9M111_SC_GREEN_2_GAIN 0x2e
51#define MT9M111_SC_GLOBAL_GAIN 0x2f 50#define MT9M111_SC_GLOBAL_GAIN 0x2f
52 51
53#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
54#define MT9M111_RMB_MIRROR_COLS (1 << 1)
55
56#define MT9M111_CONTEXT_CONTROL 0xc8 52#define MT9M111_CONTEXT_CONTROL 0xc8
57#define MT9M111_PAGE_MAP 0xf0 53#define MT9M111_PAGE_MAP 0xf0
58#define MT9M111_BYTEWISE_ADDRESS 0xf1 54#define MT9M111_BYTEWISE_ADDRESS 0xf1
@@ -74,8 +70,37 @@
74#define MT9M111_COLORPIPE 0x01 70#define MT9M111_COLORPIPE 0x01
75#define MT9M111_CAMERA_CONTROL 0x02 71#define MT9M111_CAMERA_CONTROL 0x02
76 72
73#define MT9M111_RESET (1 << 0)
74#define MT9M111_RESTART (1 << 1)
75#define MT9M111_ANALOG_STANDBY (1 << 2)
76#define MT9M111_CHIP_ENABLE (1 << 3)
77#define MT9M111_CHIP_DISABLE (0 << 3)
78#define MT9M111_OUTPUT_DISABLE (1 << 4)
79#define MT9M111_SHOW_BAD_FRAMES (1 << 0)
80#define MT9M111_RESTART_BAD_FRAMES (1 << 1)
81#define MT9M111_SYNCHRONIZE_CHANGES (1 << 7)
82
83#define MT9M111_RMB_OVER_SIZED (1 << 0)
84#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
85#define MT9M111_RMB_MIRROR_COLS (1 << 1)
86#define MT9M111_RMB_ROW_SKIP_2X (1 << 2)
87#define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3)
88#define MT9M111_RMB_ROW_SKIP_4X (1 << 4)
89#define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5)
90
91#define MT9M111_COLOR_MATRIX_BYPASS (1 << 4)
92#define MT9M111_SEL_CONTEXT_B (1 << 3)
93
94#define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1)
95#define MT9M111_SOC_SOFT_STANDBY (1 << 0)
96
97#define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0)
98
77#define INITIAL_MAX_GAIN 64 99#define INITIAL_MAX_GAIN 64
78#define DEFAULT_GAIN 283 100#define MT9M111_DEFAULT_GAIN 283
101#define MT9M111_GREEN_GAIN_DEFAULT 0x20
102#define MT9M111_BLUE_GAIN_DEFAULT 0x20
103#define MT9M111_RED_GAIN_DEFAULT 0x20
79 104
80/*****************************************************************************/ 105/*****************************************************************************/
81 106
@@ -85,16 +110,10 @@ extern int dump_sensor;
85 110
86int mt9m111_probe(struct sd *sd); 111int mt9m111_probe(struct sd *sd);
87int mt9m111_init(struct sd *sd); 112int mt9m111_init(struct sd *sd);
88int mt9m111_power_down(struct sd *sd); 113int mt9m111_start(struct sd *sd);
114void mt9m111_disconnect(struct sd *sd);
89 115
90int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 116static const struct m5602_sensor mt9m111 = {
91int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
92int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
93int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
94int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
95int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
96
97const static struct m5602_sensor mt9m111 = {
98 .name = "MT9M111", 117 .name = "MT9M111",
99 118
100 .i2c_slave_id = 0xba, 119 .i2c_slave_id = 0xba,
@@ -102,7 +121,8 @@ const static struct m5602_sensor mt9m111 = {
102 121
103 .probe = mt9m111_probe, 122 .probe = mt9m111_probe,
104 .init = mt9m111_init, 123 .init = mt9m111_init,
105 .power_down = mt9m111_power_down 124 .disconnect = mt9m111_disconnect,
125 .start = mt9m111_start,
106}; 126};
107 127
108static const unsigned char preinit_mt9m111[][4] = 128static const unsigned char preinit_mt9m111[][4] =
@@ -117,7 +137,14 @@ static const unsigned char preinit_mt9m111[][4] =
117 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, 137 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
118 138
119 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, 139 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
120 {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, 140 {SENSOR, MT9M111_SC_RESET,
141 MT9M111_RESET |
142 MT9M111_RESTART |
143 MT9M111_ANALOG_STANDBY |
144 MT9M111_CHIP_DISABLE,
145 MT9M111_SHOW_BAD_FRAMES |
146 MT9M111_RESTART_BAD_FRAMES |
147 MT9M111_SYNCHRONIZE_CHANGES},
121 148
122 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, 149 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
123 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, 150 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
@@ -145,731 +172,42 @@ static const unsigned char init_mt9m111[][4] =
145 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 172 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
146 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 173 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
147 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 174 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
148 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
149 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
150 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
151 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, 175 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
152 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
153 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
154
155 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
156 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
157 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
158 {SENSOR, MT9M111_SC_RESET, 0xff, 0xde},
159 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
160 {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
161 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
162 176
163 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
164
165 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff},
166
167 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
168 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
169 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
170 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
171 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
172 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
173 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
174 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
175 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
176 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
179 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
180 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
181 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
182 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, 177 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
186 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, 178 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
187 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
188
189 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
190 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
191 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
192 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
193 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
194 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
195 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
196 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
197 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
198 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
199 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
200 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
201 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
202 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
203 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
204 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
205
206 {SENSOR, 0xcd, 0x00, 0x0e},
207 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
208 {SENSOR, 0xd0, 0x00, 0x40},
209 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
210 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
211 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
212 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
213 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
214 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
215 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
216 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
217 {SENSOR, 0x33, 0x03, 0x49},
218 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
219
220 {SENSOR, 0x33, 0x03, 0x49},
221 {SENSOR, 0x34, 0xc0, 0x19},
222 {SENSOR, 0x3f, 0x20, 0x20},
223 {SENSOR, 0x40, 0x20, 0x20},
224 {SENSOR, 0x5a, 0xc0, 0x0a},
225 {SENSOR, 0x70, 0x7b, 0x0a},
226 {SENSOR, 0x71, 0xff, 0x00},
227 {SENSOR, 0x72, 0x19, 0x0e},
228 {SENSOR, 0x73, 0x18, 0x0f},
229 {SENSOR, 0x74, 0x57, 0x32},
230 {SENSOR, 0x75, 0x56, 0x34},
231 {SENSOR, 0x76, 0x73, 0x35},
232 {SENSOR, 0x77, 0x30, 0x12},
233 {SENSOR, 0x78, 0x79, 0x02},
234 {SENSOR, 0x79, 0x75, 0x06},
235 {SENSOR, 0x7a, 0x77, 0x0a},
236 {SENSOR, 0x7b, 0x78, 0x09},
237 {SENSOR, 0x7c, 0x7d, 0x06},
238 {SENSOR, 0x7d, 0x31, 0x10},
239 {SENSOR, 0x7e, 0x00, 0x7e},
240 {SENSOR, 0x80, 0x59, 0x04},
241 {SENSOR, 0x81, 0x59, 0x04},
242 {SENSOR, 0x82, 0x57, 0x0a},
243 {SENSOR, 0x83, 0x58, 0x0b},
244 {SENSOR, 0x84, 0x47, 0x0c},
245 {SENSOR, 0x85, 0x48, 0x0e},
246 {SENSOR, 0x86, 0x5b, 0x02},
247 {SENSOR, 0x87, 0x00, 0x5c},
248 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
249 {SENSOR, 0x60, 0x00, 0x80},
250 {SENSOR, 0x61, 0x00, 0x00},
251 {SENSOR, 0x62, 0x00, 0x00},
252 {SENSOR, 0x63, 0x00, 0x00},
253 {SENSOR, 0x64, 0x00, 0x00},
254
255 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
256 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
257 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
258 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
259 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
260 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
261 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
262 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
263 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
264 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
265 {SENSOR, 0x30, 0x04, 0x00},
266
267 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
268 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
269 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
270 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
271 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
272 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
273 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
274 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
275 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
276 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
277 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
278 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
279 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
280 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
281 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
282 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
283 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
284 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
285 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
286 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
287 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
288 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
289 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
290 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
291 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
292 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
293 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
294
295 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
296 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
297 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
298 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
299 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
300 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
301 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
302 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
303 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
304 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
305 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
306 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
307 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
308 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
309 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
310 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
311 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
312 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
313 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
314 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
315 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
316 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
317 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
318 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
319
320 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
321 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
322 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
323 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
324 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
325 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
326 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
327 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
328 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
329 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
330 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, 179 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
331 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
332 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, 180 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
333 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
334 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
335 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, 181 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
336 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
337 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
338 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
339 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
340 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
341 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
342 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
343 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
344 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
345 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
346 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
347 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
348 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
349 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
350
351 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
352 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
353 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
354 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
355 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
356 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
357 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
358 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
359 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
360 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
361 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
362 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
363 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
364 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
365 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
366
367 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
368 {SENSOR, 0xcd, 0x00, 0x0e},
369 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
370 {SENSOR, 0xd0, 0x00, 0x40},
371 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
372 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
373 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
374 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
375 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
376 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
377 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
378 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
379 {SENSOR, 0x33, 0x03, 0x49},
380 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
381
382 {SENSOR, 0x33, 0x03, 0x49},
383 {SENSOR, 0x34, 0xc0, 0x19},
384 {SENSOR, 0x3f, 0x20, 0x20},
385 {SENSOR, 0x40, 0x20, 0x20},
386 {SENSOR, 0x5a, 0xc0, 0x0a},
387 {SENSOR, 0x70, 0x7b, 0x0a},
388 {SENSOR, 0x71, 0xff, 0x00},
389 {SENSOR, 0x72, 0x19, 0x0e},
390 {SENSOR, 0x73, 0x18, 0x0f},
391 {SENSOR, 0x74, 0x57, 0x32},
392 {SENSOR, 0x75, 0x56, 0x34},
393 {SENSOR, 0x76, 0x73, 0x35},
394 {SENSOR, 0x77, 0x30, 0x12},
395 {SENSOR, 0x78, 0x79, 0x02},
396 {SENSOR, 0x79, 0x75, 0x06},
397 {SENSOR, 0x7a, 0x77, 0x0a},
398 {SENSOR, 0x7b, 0x78, 0x09},
399 {SENSOR, 0x7c, 0x7d, 0x06},
400 {SENSOR, 0x7d, 0x31, 0x10},
401 {SENSOR, 0x7e, 0x00, 0x7e},
402 {SENSOR, 0x80, 0x59, 0x04},
403 {SENSOR, 0x81, 0x59, 0x04},
404 {SENSOR, 0x82, 0x57, 0x0a},
405 {SENSOR, 0x83, 0x58, 0x0b},
406 {SENSOR, 0x84, 0x47, 0x0c},
407 {SENSOR, 0x85, 0x48, 0x0e},
408 {SENSOR, 0x86, 0x5b, 0x02},
409 {SENSOR, 0x87, 0x00, 0x5c},
410 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
411 {SENSOR, 0x60, 0x00, 0x80},
412 {SENSOR, 0x61, 0x00, 0x00},
413 {SENSOR, 0x62, 0x00, 0x00},
414 {SENSOR, 0x63, 0x00, 0x00},
415 {SENSOR, 0x64, 0x00, 0x00},
416
417 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
418 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
419 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
420 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
421 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
422 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
423 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
424 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
425 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
426 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
427 {SENSOR, 0x30, 0x04, 0x00},
428
429 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
430 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
431 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
432 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
433 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
434 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
435 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
437 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
438 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
439 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
440 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
441 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
442 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
443 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
444 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
445 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
446 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
447 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
448 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
449 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
450 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
451 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
452 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
453 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
454 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
455 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
456 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
457 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
458
459 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
460 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
461 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
462 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
463 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
464 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
465 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
466
467 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
468 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
469 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
470 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
471 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
472 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
473 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, 182 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
474 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
475 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
476 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, 183 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
477 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
478 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
479 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
480 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
481 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
482 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
483 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
484 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
485 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, 184 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
486 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, 185 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
487 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
488 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
489 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, 186 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
490 187
491 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
492 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
493 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
494 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, 188 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
495 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, 189 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
496 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, 190 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
497 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, 191 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
498 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, 192 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
193 MT9M111_CP_OPERATING_MODE_CTL},
499 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, 194 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
500 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, 195 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
501 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, 196 MT9M111_2D_DEFECT_CORRECTION_ENABLE},
197 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
198 MT9M111_2D_DEFECT_CORRECTION_ENABLE},
502 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, 199 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
503 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, 200 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
504 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, 201 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
505 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, 202 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
506
507 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
508 {SENSOR, 0xcd, 0x00, 0x0e}, 203 {SENSOR, 0xcd, 0x00, 0x0e},
509 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
510 {SENSOR, 0xd0, 0x00, 0x40}, 204 {SENSOR, 0xd0, 0x00, 0x40},
511 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
512 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
513 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
514 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
515 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
516 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
517 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
518 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
519 {SENSOR, 0x33, 0x03, 0x49},
520 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
521
522 {SENSOR, 0x33, 0x03, 0x49},
523 {SENSOR, 0x34, 0xc0, 0x19},
524 {SENSOR, 0x3f, 0x20, 0x20},
525 {SENSOR, 0x40, 0x20, 0x20},
526 {SENSOR, 0x5a, 0xc0, 0x0a},
527 {SENSOR, 0x70, 0x7b, 0x0a},
528 {SENSOR, 0x71, 0xff, 0x00},
529 {SENSOR, 0x72, 0x19, 0x0e},
530 {SENSOR, 0x73, 0x18, 0x0f},
531 {SENSOR, 0x74, 0x57, 0x32},
532 {SENSOR, 0x75, 0x56, 0x34},
533 {SENSOR, 0x76, 0x73, 0x35},
534 {SENSOR, 0x77, 0x30, 0x12},
535 {SENSOR, 0x78, 0x79, 0x02},
536 {SENSOR, 0x79, 0x75, 0x06},
537 {SENSOR, 0x7a, 0x77, 0x0a},
538 {SENSOR, 0x7b, 0x78, 0x09},
539 {SENSOR, 0x7c, 0x7d, 0x06},
540 {SENSOR, 0x7d, 0x31, 0x10},
541 {SENSOR, 0x7e, 0x00, 0x7e},
542 {SENSOR, 0x80, 0x59, 0x04},
543 {SENSOR, 0x81, 0x59, 0x04},
544 {SENSOR, 0x82, 0x57, 0x0a},
545 {SENSOR, 0x83, 0x58, 0x0b},
546 {SENSOR, 0x84, 0x47, 0x0c},
547 {SENSOR, 0x85, 0x48, 0x0e},
548 {SENSOR, 0x86, 0x5b, 0x02},
549 {SENSOR, 0x87, 0x00, 0x5c},
550 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
551 {SENSOR, 0x60, 0x00, 0x80},
552 {SENSOR, 0x61, 0x00, 0x00},
553 {SENSOR, 0x62, 0x00, 0x00},
554 {SENSOR, 0x63, 0x00, 0x00},
555 {SENSOR, 0x64, 0x00, 0x00},
556 205
557 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
558 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
559 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
560 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
561 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
562 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
563 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
564 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
565 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
566 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
567 {SENSOR, 0x30, 0x04, 0x00},
568
569 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
570 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
571 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
572 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
573 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
574 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
575 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
576 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
577 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
578 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
579 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
580 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
581 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
582 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
583 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
584 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
585 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
586 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
587 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
588 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
589 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
590 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
591 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
592 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
593 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
594 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
595 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
596 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
597 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
598 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
599 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
600 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
601 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
602 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
603 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
604 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
605 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
606 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
607 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
608 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
609 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
610 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
611 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
612 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
613 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
614 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
615 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
616 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
617 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
618 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
619 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
620 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
621 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
622 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
623 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
624 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
625 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
626 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
627 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
628 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
629 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
630 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
631 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
632 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
633 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
634 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
635 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
636 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
637 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
638 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
639 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
640 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
641 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
642 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
643 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
644 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
645 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
646 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
647 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
648 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
649 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
650 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
651 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
652 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
653 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
654 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
655 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
656 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
657
658 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
659 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
660 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
661 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
662 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
663 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
664 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
665 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
666 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
667 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
668
669 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
670 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
671 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
672 {SENSOR, 0xcd, 0x00, 0x0e},
673 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
674 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
675 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
676 {SENSOR, 0xd0, 0x00, 0x40},
677 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, 206 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
678 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, 207 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
679 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
680 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
681 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
682 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
683 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
684 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
685 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
686 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, 208 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
687 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
688 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
689 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
690 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
691 {SENSOR, 0x33, 0x03, 0x49},
692 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
693 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
694 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
695
696 {SENSOR, 0x33, 0x03, 0x49},
697 {SENSOR, 0x34, 0xc0, 0x19},
698 {SENSOR, 0x3f, 0x20, 0x20},
699 {SENSOR, 0x40, 0x20, 0x20},
700 {SENSOR, 0x5a, 0xc0, 0x0a},
701 {SENSOR, 0x70, 0x7b, 0x0a},
702 {SENSOR, 0x71, 0xff, 0x00},
703 {SENSOR, 0x72, 0x19, 0x0e},
704 {SENSOR, 0x73, 0x18, 0x0f},
705 {SENSOR, 0x74, 0x57, 0x32},
706 {SENSOR, 0x75, 0x56, 0x34},
707 {SENSOR, 0x76, 0x73, 0x35},
708 {SENSOR, 0x77, 0x30, 0x12},
709 {SENSOR, 0x78, 0x79, 0x02},
710 {SENSOR, 0x79, 0x75, 0x06},
711 {SENSOR, 0x7a, 0x77, 0x0a},
712 {SENSOR, 0x7b, 0x78, 0x09},
713 {SENSOR, 0x7c, 0x7d, 0x06},
714 {SENSOR, 0x7d, 0x31, 0x10},
715 {SENSOR, 0x7e, 0x00, 0x7e},
716 {SENSOR, 0x80, 0x59, 0x04},
717 {SENSOR, 0x81, 0x59, 0x04},
718 {SENSOR, 0x82, 0x57, 0x0a},
719 {SENSOR, 0x83, 0x58, 0x0b},
720 {SENSOR, 0x84, 0x47, 0x0c},
721 {SENSOR, 0x85, 0x48, 0x0e},
722 {SENSOR, 0x86, 0x5b, 0x02},
723 {SENSOR, 0x87, 0x00, 0x5c},
724 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
725 {SENSOR, 0x60, 0x00, 0x80},
726 {SENSOR, 0x61, 0x00, 0x00},
727 {SENSOR, 0x62, 0x00, 0x00},
728 {SENSOR, 0x63, 0x00, 0x00},
729 {SENSOR, 0x64, 0x00, 0x00},
730 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
731 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
732 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
733 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
734 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
735 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
736 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
737 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
738 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
739 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
740 {SENSOR, 0x30, 0x04, 0x00},
741
742 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
743 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
744 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
745 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
746 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
747 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
748 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
749 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
750 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
751 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
752 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
753 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
754 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00},
755 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
756 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
757 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
758 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
759 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
760 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
761 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
762 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
763 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
764 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
765 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
766
767 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
768 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
769 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6},
770 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
771 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
772 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
773 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
774 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
775 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
776 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
777 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
778 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
779 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
780 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
781 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
782 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
783 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
784 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
785 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
786 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
787 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
788 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
789 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
790 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
791 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
792 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
793 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
794 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
795 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
796 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
797 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
798 209
799 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
800 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
801 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
802 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
803 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
804 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
805 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
806 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
807 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
808 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
809 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
810 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
811 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
812 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
813 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
814 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
815 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
816 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
817 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
818 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
819 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
820 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
821 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
822 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
823 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
824 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
825 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, 210 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
826 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
827 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
828 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
829 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
830 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
831 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
832 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
833 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
834 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
835 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
836 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
837 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
838 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
839 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
840 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
841 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
842 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
843 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
844
845 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
846 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
847 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
848 {SENSOR, 0xcd, 0x00, 0x0e},
849 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
850 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
851 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
852 {SENSOR, 0xd0, 0x00, 0x40},
853 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
854 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
855 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
856 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
857 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
858 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
859 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
860 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
861 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
862 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
863 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
864
865 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
866 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
867 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
868 {SENSOR, 0x33, 0x03, 0x49},
869 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
870 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
871 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
872
873 {SENSOR, 0x33, 0x03, 0x49}, 211 {SENSOR, 0x33, 0x03, 0x49},
874 {SENSOR, 0x34, 0xc0, 0x19}, 212 {SENSOR, 0x34, 0xc0, 0x19},
875 {SENSOR, 0x3f, 0x20, 0x20}, 213 {SENSOR, 0x3f, 0x20, 0x20},
@@ -898,25 +236,29 @@ static const unsigned char init_mt9m111[][4] =
898 {SENSOR, 0x85, 0x48, 0x0e}, 236 {SENSOR, 0x85, 0x48, 0x0e},
899 {SENSOR, 0x86, 0x5b, 0x02}, 237 {SENSOR, 0x86, 0x5b, 0x02},
900 {SENSOR, 0x87, 0x00, 0x5c}, 238 {SENSOR, 0x87, 0x00, 0x5c},
901 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, 239 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
902 {SENSOR, 0x60, 0x00, 0x80}, 240 {SENSOR, 0x60, 0x00, 0x80},
903 {SENSOR, 0x61, 0x00, 0x00}, 241 {SENSOR, 0x61, 0x00, 0x00},
904 {SENSOR, 0x62, 0x00, 0x00}, 242 {SENSOR, 0x62, 0x00, 0x00},
905 {SENSOR, 0x63, 0x00, 0x00}, 243 {SENSOR, 0x63, 0x00, 0x00},
906 {SENSOR, 0x64, 0x00, 0x00}, 244 {SENSOR, 0x64, 0x00, 0x00},
907 245
908 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, 246 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
909 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, 247 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
910 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, 248 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
911 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, 249 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
912 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, 250 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
913 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, 251 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
914 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, 252 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
915 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, 253 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
916 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, 254 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
917 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
918 {SENSOR, 0x30, 0x04, 0x00}, 255 {SENSOR, 0x30, 0x04, 0x00},
256 /* Set number of blank rows chosen to 400 */
257 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
258};
919 259
260static const unsigned char start_mt9m111[][4] =
261{
920 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 262 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
921 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 263 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
922 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 264 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -928,25 +270,6 @@ static const unsigned char init_mt9m111[][4] =
928 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 270 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
929 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 271 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
930 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 272 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
931 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
932 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
933 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
934 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
935 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
936 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
937 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
938 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
939 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
940 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
941 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
942 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
943 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
944
945 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
946 /* Set number of blank rows chosen to 400 */
947 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
948 /* Set the global gain to 283 (of 512) */
949 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63}
950}; 273};
951 274
952#endif 275#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
new file mode 100644
index 000000000000..7aafeb7cfa07
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -0,0 +1,227 @@
1/*
2 * Driver for the ov7660 sensor
3 *
4 * Copyright (C) 2009 Erik Andrén
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_ov7660.h"
20
21static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
22static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23
24const static struct ctrl ov7660_ctrls[] = {
25#define GAIN_IDX 1
26 {
27 {
28 .id = V4L2_CID_GAIN,
29 .type = V4L2_CTRL_TYPE_INTEGER,
30 .name = "gain",
31 .minimum = 0x00,
32 .maximum = 0xff,
33 .step = 0x1,
34 .default_value = OV7660_DEFAULT_GAIN,
35 .flags = V4L2_CTRL_FLAG_SLIDER
36 },
37 .set = ov7660_set_gain,
38 .get = ov7660_get_gain
39 },
40};
41
42static struct v4l2_pix_format ov7660_modes[] = {
43 {
44 640,
45 480,
46 V4L2_PIX_FMT_SBGGR8,
47 V4L2_FIELD_NONE,
48 .sizeimage =
49 640 * 480,
50 .bytesperline = 640,
51 .colorspace = V4L2_COLORSPACE_SRGB,
52 .priv = 0
53 }
54};
55
56static void ov7660_dump_registers(struct sd *sd);
57
58int ov7660_probe(struct sd *sd)
59{
60 int err = 0, i;
61 u8 prod_id = 0, ver_id = 0;
62
63 s32 *sensor_settings;
64
65 if (force_sensor) {
66 if (force_sensor == OV7660_SENSOR) {
67 info("Forcing an %s sensor", ov7660.name);
68 goto sensor_found;
69 }
70 /* If we want to force another sensor,
71 don't try to probe this one */
72 return -ENODEV;
73 }
74
75 /* Do the preinit */
76 for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
77 u8 data[2];
78
79 if (preinit_ov7660[i][0] == BRIDGE) {
80 err = m5602_write_bridge(sd,
81 preinit_ov7660[i][1],
82 preinit_ov7660[i][2]);
83 } else {
84 data[0] = preinit_ov7660[i][2];
85 err = m5602_write_sensor(sd,
86 preinit_ov7660[i][1], data, 1);
87 }
88 }
89 if (err < 0)
90 return err;
91
92 if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
93 return -ENODEV;
94
95 if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
96 return -ENODEV;
97
98 info("Sensor reported 0x%x%x", prod_id, ver_id);
99
100 if ((prod_id == 0x76) && (ver_id == 0x60)) {
101 info("Detected a ov7660 sensor");
102 goto sensor_found;
103 }
104 return -ENODEV;
105
106sensor_found:
107 sensor_settings = kmalloc(
108 ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
109 if (!sensor_settings)
110 return -ENOMEM;
111
112 sd->gspca_dev.cam.cam_mode = ov7660_modes;
113 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
114 sd->desc->ctrls = ov7660_ctrls;
115 sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
116
117 for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
118 sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
119 sd->sensor_priv = sensor_settings;
120
121 return 0;
122}
123
124int ov7660_init(struct sd *sd)
125{
126 int i, err = 0;
127 s32 *sensor_settings = sd->sensor_priv;
128
129 /* Init the sensor */
130 for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
131 u8 data[2];
132
133 if (init_ov7660[i][0] == BRIDGE) {
134 err = m5602_write_bridge(sd,
135 init_ov7660[i][1],
136 init_ov7660[i][2]);
137 } else {
138 data[0] = init_ov7660[i][2];
139 err = m5602_write_sensor(sd,
140 init_ov7660[i][1], data, 1);
141 }
142 }
143
144 if (dump_sensor)
145 ov7660_dump_registers(sd);
146
147 err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
148 if (err < 0)
149 return err;
150
151 return err;
152}
153
154int ov7660_start(struct sd *sd)
155{
156 return 0;
157}
158
159int ov7660_stop(struct sd *sd)
160{
161 return 0;
162}
163
164void ov7660_disconnect(struct sd *sd)
165{
166 ov7660_stop(sd);
167
168 sd->sensor = NULL;
169 kfree(sd->sensor_priv);
170}
171
172static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
173{
174 struct sd *sd = (struct sd *) gspca_dev;
175 s32 *sensor_settings = sd->sensor_priv;
176
177 *val = sensor_settings[GAIN_IDX];
178 PDEBUG(D_V4L2, "Read gain %d", *val);
179 return 0;
180}
181
182static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
183{
184 int err;
185 u8 i2c_data;
186 struct sd *sd = (struct sd *) gspca_dev;
187 s32 *sensor_settings = sd->sensor_priv;
188
189 PDEBUG(D_V4L2, "Setting gain to %d", val);
190
191 sensor_settings[GAIN_IDX] = val;
192
193 err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
194 return err;
195}
196
197static void ov7660_dump_registers(struct sd *sd)
198{
199 int address;
200 info("Dumping the ov7660 register state");
201 for (address = 0; address < 0xa9; address++) {
202 u8 value;
203 m5602_read_sensor(sd, address, &value, 1);
204 info("register 0x%x contains 0x%x",
205 address, value);
206 }
207
208 info("ov7660 register state dump complete");
209
210 info("Probing for which registers that are read/write");
211 for (address = 0; address < 0xff; address++) {
212 u8 old_value, ctrl_value;
213 u8 test_value[2] = {0xff, 0xff};
214
215 m5602_read_sensor(sd, address, &old_value, 1);
216 m5602_write_sensor(sd, address, test_value, 1);
217 m5602_read_sensor(sd, address, &ctrl_value, 1);
218
219 if (ctrl_value == test_value[0])
220 info("register 0x%x is writeable", address);
221 else
222 info("register 0x%x is read only", address);
223
224 /* Restore original value */
225 m5602_write_sensor(sd, address, &old_value, 1);
226 }
227}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
new file mode 100644
index 000000000000..3f2c169a93ea
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -0,0 +1,279 @@
1/*
2 * Driver for the ov7660 sensor
3 *
4 * Copyright (C) 2009 Erik Andrén
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_OV7660_H_
20#define M5602_OV7660_H_
21
22#include "m5602_sensor.h"
23
24#define OV7660_GAIN 0x00
25#define OV7660_BLUE_GAIN 0x01
26#define OV7660_RED_GAIN 0x02
27#define OV7660_VREF 0x03
28#define OV7660_COM1 0x04
29#define OV7660_BAVE 0x05
30#define OV7660_GEAVE 0x06
31#define OV7660_AECHH 0x07
32#define OV7660_RAVE 0x08
33#define OV7660_COM2 0x09
34#define OV7660_PID 0x0a
35#define OV7660_VER 0x0b
36#define OV7660_COM3 0x0c
37#define OV7660_COM4 0x0d
38#define OV7660_COM5 0x0e
39#define OV7660_COM6 0x0f
40#define OV7660_AECH 0x10
41#define OV7660_CLKRC 0x11
42#define OV7660_COM7 0x12
43#define OV7660_COM8 0x13
44#define OV7660_COM9 0x14
45#define OV7660_COM10 0x15
46#define OV7660_RSVD16 0x16
47#define OV7660_HSTART 0x17
48#define OV7660_HSTOP 0x18
49#define OV7660_VSTART 0x19
50#define OV7660_VSTOP 0x1a
51#define OV7660_PSHFT 0x1b
52#define OV7660_MIDH 0x1c
53#define OV7660_MIDL 0x1d
54#define OV7660_MVFP 0x1e
55#define OV7660_LAEC 0x1f
56#define OV7660_BOS 0x20
57#define OV7660_GBOS 0x21
58#define OV7660_GROS 0x22
59#define OV7660_ROS 0x23
60#define OV7660_AEW 0x24
61#define OV7660_AEB 0x25
62#define OV7660_VPT 0x26
63#define OV7660_BBIAS 0x27
64#define OV7660_GbBIAS 0x28
65#define OV7660_RSVD29 0x29
66#define OV7660_RBIAS 0x2c
67#define OV7660_HREF 0x32
68#define OV7660_ADC 0x37
69#define OV7660_OFON 0x39
70#define OV7660_TSLB 0x3a
71#define OV7660_COM12 0x3c
72#define OV7660_COM13 0x3d
73#define OV7660_LCC1 0x62
74#define OV7660_LCC2 0x63
75#define OV7660_LCC3 0x64
76#define OV7660_LCC4 0x65
77#define OV7660_LCC5 0x66
78#define OV7660_HV 0x69
79#define OV7660_RSVDA1 0xa1
80
81#define OV7660_DEFAULT_GAIN 0x0e
82#define OV7660_DEFAULT_RED_GAIN 0x80
83#define OV7660_DEFAULT_BLUE_GAIN 0x80
84#define OV7660_DEFAULT_SATURATION 0x00
85#define OV7660_DEFAULT_EXPOSURE 0x20
86
87/* Kernel module parameters */
88extern int force_sensor;
89extern int dump_sensor;
90
91int ov7660_probe(struct sd *sd);
92int ov7660_init(struct sd *sd);
93int ov7660_start(struct sd *sd);
94int ov7660_stop(struct sd *sd);
95void ov7660_disconnect(struct sd *sd);
96
97const static struct m5602_sensor ov7660 = {
98 .name = "ov7660",
99 .i2c_slave_id = 0x42,
100 .i2c_regW = 1,
101 .probe = ov7660_probe,
102 .init = ov7660_init,
103 .start = ov7660_start,
104 .stop = ov7660_stop,
105 .disconnect = ov7660_disconnect,
106};
107
108static const unsigned char preinit_ov7660[][4] =
109{
110 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
111 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
112 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
113 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
114 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
115 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
116 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
117 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
118 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
119 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
120 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
121
122 {SENSOR, OV7660_OFON, 0x0c},
123 {SENSOR, OV7660_COM2, 0x11},
124 {SENSOR, OV7660_COM7, 0x05},
125
126 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
127 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
128 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
129 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
130 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
131 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
132 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
133 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
134 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
135 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
136 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
137 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
138 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
139 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
140 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
141};
142
143static const unsigned char init_ov7660[][4] =
144{
145 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
146 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
147 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
148 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
149 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
150 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
151 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
152 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
153 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
154 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
155 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
156
157 {SENSOR, OV7660_OFON, 0x0c},
158 {SENSOR, OV7660_COM2, 0x11},
159 {SENSOR, OV7660_COM7, 0x05},
160
161 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
162 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
163 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
164 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
165 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
166 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
167 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
168 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
169 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
170 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
171 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
172 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
173 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
174 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
175 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
176
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
179
180 {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
181 {SENSOR, OV7660_COM1, 0x00},
182
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
186 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
187 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
188 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
189 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
190
191 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
192 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
193 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
194 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
195 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
196 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
197 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
198 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
199
200 {SENSOR, OV7660_COM7, 0x80},
201 {SENSOR, OV7660_CLKRC, 0x80},
202 {SENSOR, OV7660_BLUE_GAIN, 0x80},
203 {SENSOR, OV7660_RED_GAIN, 0x80},
204 {SENSOR, OV7660_COM9, 0x4c},
205 {SENSOR, OV7660_OFON, 0x43},
206 {SENSOR, OV7660_COM12, 0x28},
207 {SENSOR, OV7660_COM8, 0x00},
208 {SENSOR, OV7660_COM10, 0x40},
209 {SENSOR, OV7660_HSTART, 0x0c},
210 {SENSOR, OV7660_HSTOP, 0x61},
211 {SENSOR, OV7660_HREF, 0xa4},
212 {SENSOR, OV7660_PSHFT, 0x0b},
213 {SENSOR, OV7660_VSTART, 0x01},
214 {SENSOR, OV7660_VSTOP, 0x7a},
215 {SENSOR, OV7660_VREF, 0x00},
216 {SENSOR, OV7660_COM7, 0x05},
217 {SENSOR, OV7660_COM6, 0x4b},
218 {SENSOR, OV7660_BBIAS, 0x98},
219 {SENSOR, OV7660_GbBIAS, 0x98},
220 {SENSOR, OV7660_RSVD29, 0x98},
221 {SENSOR, OV7660_RBIAS, 0x98},
222 {SENSOR, OV7660_COM1, 0x00},
223 {SENSOR, OV7660_AECH, 0x00},
224 {SENSOR, OV7660_AECHH, 0x00},
225 {SENSOR, OV7660_ADC, 0x04},
226 {SENSOR, OV7660_COM13, 0x00},
227 {SENSOR, OV7660_RSVDA1, 0x23},
228 {SENSOR, OV7660_TSLB, 0x0d},
229 {SENSOR, OV7660_HV, 0x80},
230 {SENSOR, OV7660_LCC1, 0x00},
231 {SENSOR, OV7660_LCC2, 0x00},
232 {SENSOR, OV7660_LCC3, 0x10},
233 {SENSOR, OV7660_LCC4, 0x40},
234 {SENSOR, OV7660_LCC5, 0x01},
235
236 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
237 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
238 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
239 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
240 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
241 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
242 {BRIDGE, M5602_XB_SIG_INI, 0x01},
243 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
244 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
245 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
246 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
247 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
248 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
249 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
251 {BRIDGE, M5602_XB_SIG_INI, 0x00},
252 {BRIDGE, M5602_XB_SIG_INI, 0x02},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */
257 {BRIDGE, M5602_XB_SIG_INI, 0x00},
258
259 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
260 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
261
262 {SENSOR, OV7660_AECH, 0x20},
263 {SENSOR, OV7660_COM1, 0x00},
264 {SENSOR, OV7660_OFON, 0x0c},
265 {SENSOR, OV7660_COM2, 0x11},
266 {SENSOR, OV7660_COM7, 0x05},
267 {SENSOR, OV7660_BLUE_GAIN, 0x80},
268 {SENSOR, OV7660_RED_GAIN, 0x80},
269
270 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
271 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
272 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
273 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
274 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
275 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
276 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
277};
278
279#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index fc4548fd441d..c2739d6605a1 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,44 +18,87 @@
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20 20
21static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
22static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
23static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
26static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
27static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
28static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
29static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
30static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
31static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
32static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
33static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
34 __s32 *val);
35static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
36 __s32 val);
37static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
38static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
39static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
40static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
41
21/* Vertically and horizontally flips the image if matched, needed for machines 42/* Vertically and horizontally flips the image if matched, needed for machines
22 where the sensor is mounted upside down */ 43 where the sensor is mounted upside down */
23static 44static
24 const 45 const
25 struct dmi_system_id ov9650_flip_dmi_table[] = { 46 struct dmi_system_id ov9650_flip_dmi_table[] = {
26 { 47 {
27 .ident = "ASUS A6VC", 48 .ident = "ASUS A6Ja",
28 .matches = { 49 .matches = {
29 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
30 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
31 } 52 }
32 }, 53 },
33 { 54 {
34 .ident = "ASUS A6VM", 55 .ident = "ASUS A6JC",
35 .matches = { 56 .matches = {
36 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
37 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 58 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
38 } 59 }
39 }, 60 },
40 { 61 {
41 .ident = "ASUS A6JC", 62 .ident = "ASUS A6K",
42 .matches = { 63 .matches = {
43 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 64 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
44 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 65 DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
45 } 66 }
46 }, 67 },
47 { 68 {
48 .ident = "ASUS A6Ja", 69 .ident = "ASUS A6Kt",
49 .matches = { 70 .matches = {
50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 71 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J") 72 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
52 } 73 }
53 }, 74 },
54 { 75 {
55 .ident = "ASUS A6Kt", 76 .ident = "ASUS A6VA",
56 .matches = { 77 .matches = {
57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 78 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
58 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 79 DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
80 }
81 },
82 {
83
84 .ident = "ASUS A6VC",
85 .matches = {
86 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
87 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
88 }
89 },
90 {
91 .ident = "ASUS A6VM",
92 .matches = {
93 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
94 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
95 }
96 },
97 {
98 .ident = "ASUS A7V",
99 .matches = {
100 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
101 DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
59 } 102 }
60 }, 103 },
61 { 104 {
@@ -68,7 +111,7 @@ static
68 {} 111 {}
69}; 112};
70 113
71const static struct ctrl ov9650_ctrls[] = { 114static const struct ctrl ov9650_ctrls[] = {
72#define EXPOSURE_IDX 0 115#define EXPOSURE_IDX 0
73 { 116 {
74 { 117 {
@@ -102,6 +145,7 @@ const static struct ctrl ov9650_ctrls[] = {
102#define RED_BALANCE_IDX 2 145#define RED_BALANCE_IDX 2
103 { 146 {
104 { 147 {
148 .id = V4L2_CID_RED_BALANCE,
105 .type = V4L2_CTRL_TYPE_INTEGER, 149 .type = V4L2_CTRL_TYPE_INTEGER,
106 .name = "red balance", 150 .name = "red balance",
107 .minimum = 0x00, 151 .minimum = 0x00,
@@ -116,6 +160,7 @@ const static struct ctrl ov9650_ctrls[] = {
116#define BLUE_BALANCE_IDX 3 160#define BLUE_BALANCE_IDX 3
117 { 161 {
118 { 162 {
163 .id = V4L2_CID_BLUE_BALANCE,
119 .type = V4L2_CTRL_TYPE_INTEGER, 164 .type = V4L2_CTRL_TYPE_INTEGER,
120 .name = "blue balance", 165 .name = "blue balance",
121 .minimum = 0x00, 166 .minimum = 0x00,
@@ -182,7 +227,22 @@ const static struct ctrl ov9650_ctrls[] = {
182 }, 227 },
183 .set = ov9650_set_auto_gain, 228 .set = ov9650_set_auto_gain,
184 .get = ov9650_get_auto_gain 229 .get = ov9650_get_auto_gain
230 },
231#define AUTO_EXPOSURE_IDX 8
232 {
233 {
234 .id = V4L2_CID_EXPOSURE_AUTO,
235 .type = V4L2_CTRL_TYPE_BOOLEAN,
236 .name = "auto exposure",
237 .minimum = 0,
238 .maximum = 1,
239 .step = 1,
240 .default_value = 1
241 },
242 .set = ov9650_set_auto_exposure,
243 .get = ov9650_get_auto_exposure
185 } 244 }
245
186}; 246};
187 247
188static struct v4l2_pix_format ov9650_modes[] = { 248static struct v4l2_pix_format ov9650_modes[] = {
@@ -289,12 +349,6 @@ sensor_found:
289 for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) 349 for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
290 sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; 350 sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
291 sd->sensor_priv = sensor_settings; 351 sd->sensor_priv = sensor_settings;
292
293 if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
294 info("vflip quirk active");
295 sensor_settings[VFLIP_IDX] = 1;
296 }
297
298 return 0; 352 return 0;
299} 353}
300 354
@@ -316,7 +370,8 @@ int ov9650_init(struct sd *sd)
316 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 370 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
317 } 371 }
318 372
319 err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); 373 err = ov9650_set_exposure(&sd->gspca_dev,
374 sensor_settings[EXPOSURE_IDX]);
320 if (err < 0) 375 if (err < 0)
321 return err; 376 return err;
322 377
@@ -324,11 +379,13 @@ int ov9650_init(struct sd *sd)
324 if (err < 0) 379 if (err < 0)
325 return err; 380 return err;
326 381
327 err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]); 382 err = ov9650_set_red_balance(&sd->gspca_dev,
383 sensor_settings[RED_BALANCE_IDX]);
328 if (err < 0) 384 if (err < 0)
329 return err; 385 return err;
330 386
331 err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]); 387 err = ov9650_set_blue_balance(&sd->gspca_dev,
388 sensor_settings[BLUE_BALANCE_IDX]);
332 if (err < 0) 389 if (err < 0)
333 return err; 390 return err;
334 391
@@ -340,11 +397,18 @@ int ov9650_init(struct sd *sd)
340 if (err < 0) 397 if (err < 0)
341 return err; 398 return err;
342 399
343 err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]); 400 err = ov9650_set_auto_exposure(&sd->gspca_dev,
401 sensor_settings[AUTO_EXPOSURE_IDX]);
402 if (err < 0)
403 return err;
404
405 err = ov9650_set_auto_white_balance(&sd->gspca_dev,
406 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
344 if (err < 0) 407 if (err < 0)
345 return err; 408 return err;
346 409
347 err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]); 410 err = ov9650_set_auto_gain(&sd->gspca_dev,
411 sensor_settings[AUTO_GAIN_CTRL_IDX]);
348 return err; 412 return err;
349} 413}
350 414
@@ -360,7 +424,10 @@ int ov9650_start(struct sd *sd)
360 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 424 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
361 int hor_offs = OV9650_LEFT_OFFSET; 425 int hor_offs = OV9650_LEFT_OFFSET;
362 426
363 if (sensor_settings[VFLIP_IDX]) 427 if ((!dmi_check_system(ov9650_flip_dmi_table) &&
428 sensor_settings[VFLIP_IDX]) ||
429 (dmi_check_system(ov9650_flip_dmi_table) &&
430 !sensor_settings[VFLIP_IDX]))
364 ver_offs--; 431 ver_offs--;
365 432
366 if (width <= 320) 433 if (width <= 320)
@@ -406,6 +473,14 @@ int ov9650_start(struct sd *sd)
406 if (err < 0) 473 if (err < 0)
407 return err; 474 return err;
408 475
476 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
477 if (err < 0)
478 return err;
479
480 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
481 if (err < 0)
482 return err;
483
409 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 484 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
410 (hor_offs >> 8) & 0xff); 485 (hor_offs >> 8) & 0xff);
411 if (err < 0) 486 if (err < 0)
@@ -425,6 +500,10 @@ int ov9650_start(struct sd *sd)
425 if (err < 0) 500 if (err < 0)
426 return err; 501 return err;
427 502
503 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
504 if (err < 0)
505 return err;
506
428 switch (width) { 507 switch (width) {
429 case 640: 508 case 640:
430 PDEBUG(D_V4L2, "Configuring camera for VGA mode"); 509 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
@@ -467,32 +546,15 @@ int ov9650_stop(struct sd *sd)
467 return m5602_write_sensor(sd, OV9650_COM2, &data, 1); 546 return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
468} 547}
469 548
470int ov9650_power_down(struct sd *sd)
471{
472 int i, err = 0;
473 for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
474 u8 data = power_down_ov9650[i][2];
475 if (power_down_ov9650[i][0] == SENSOR)
476 err = m5602_write_sensor(sd,
477 power_down_ov9650[i][1], &data, 1);
478 else
479 err = m5602_write_bridge(sd, power_down_ov9650[i][1],
480 data);
481 }
482
483 return err;
484}
485
486void ov9650_disconnect(struct sd *sd) 549void ov9650_disconnect(struct sd *sd)
487{ 550{
488 ov9650_stop(sd); 551 ov9650_stop(sd);
489 ov9650_power_down(sd);
490 552
491 sd->sensor = NULL; 553 sd->sensor = NULL;
492 kfree(sd->sensor_priv); 554 kfree(sd->sensor_priv);
493} 555}
494 556
495int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 557static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
496{ 558{
497 struct sd *sd = (struct sd *) gspca_dev; 559 struct sd *sd = (struct sd *) gspca_dev;
498 s32 *sensor_settings = sd->sensor_priv; 560 s32 *sensor_settings = sd->sensor_priv;
@@ -502,7 +564,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
502 return 0; 564 return 0;
503} 565}
504 566
505int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 567static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
506{ 568{
507 struct sd *sd = (struct sd *) gspca_dev; 569 struct sd *sd = (struct sd *) gspca_dev;
508 s32 *sensor_settings = sd->sensor_priv; 570 s32 *sensor_settings = sd->sensor_priv;
@@ -532,7 +594,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
532 return err; 594 return err;
533} 595}
534 596
535int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 597static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
536{ 598{
537 struct sd *sd = (struct sd *) gspca_dev; 599 struct sd *sd = (struct sd *) gspca_dev;
538 s32 *sensor_settings = sd->sensor_priv; 600 s32 *sensor_settings = sd->sensor_priv;
@@ -542,7 +604,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
542 return 0; 604 return 0;
543} 605}
544 606
545int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 607static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
546{ 608{
547 int err; 609 int err;
548 u8 i2c_data; 610 u8 i2c_data;
@@ -573,7 +635,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
573 return err; 635 return err;
574} 636}
575 637
576int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 638static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
577{ 639{
578 struct sd *sd = (struct sd *) gspca_dev; 640 struct sd *sd = (struct sd *) gspca_dev;
579 s32 *sensor_settings = sd->sensor_priv; 641 s32 *sensor_settings = sd->sensor_priv;
@@ -583,7 +645,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
583 return 0; 645 return 0;
584} 646}
585 647
586int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 648static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
587{ 649{
588 int err; 650 int err;
589 u8 i2c_data; 651 u8 i2c_data;
@@ -599,7 +661,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
599 return err; 661 return err;
600} 662}
601 663
602int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 664static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
603{ 665{
604 struct sd *sd = (struct sd *) gspca_dev; 666 struct sd *sd = (struct sd *) gspca_dev;
605 s32 *sensor_settings = sd->sensor_priv; 667 s32 *sensor_settings = sd->sensor_priv;
@@ -610,7 +672,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
610 return 0; 672 return 0;
611} 673}
612 674
613int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 675static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
614{ 676{
615 int err; 677 int err;
616 u8 i2c_data; 678 u8 i2c_data;
@@ -626,7 +688,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
626 return err; 688 return err;
627} 689}
628 690
629int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 691static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
630{ 692{
631 struct sd *sd = (struct sd *) gspca_dev; 693 struct sd *sd = (struct sd *) gspca_dev;
632 s32 *sensor_settings = sd->sensor_priv; 694 s32 *sensor_settings = sd->sensor_priv;
@@ -636,7 +698,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
636 return 0; 698 return 0;
637} 699}
638 700
639int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 701static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
640{ 702{
641 int err; 703 int err;
642 u8 i2c_data; 704 u8 i2c_data;
@@ -646,13 +708,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
646 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 708 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
647 709
648 sensor_settings[HFLIP_IDX] = val; 710 sensor_settings[HFLIP_IDX] = val;
649 i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4); 711
712 if (!dmi_check_system(ov9650_flip_dmi_table))
713 i2c_data = ((val & 0x01) << 5) |
714 (sensor_settings[VFLIP_IDX] << 4);
715 else
716 i2c_data = ((val & 0x01) << 5) |
717 (!sensor_settings[VFLIP_IDX] << 4);
718
650 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 719 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
651 720
652 return err; 721 return err;
653} 722}
654 723
655int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 724static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
656{ 725{
657 struct sd *sd = (struct sd *) gspca_dev; 726 struct sd *sd = (struct sd *) gspca_dev;
658 s32 *sensor_settings = sd->sensor_priv; 727 s32 *sensor_settings = sd->sensor_priv;
@@ -663,7 +732,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
663 return 0; 732 return 0;
664} 733}
665 734
666int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 735static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
667{ 736{
668 int err; 737 int err;
669 u8 i2c_data; 738 u8 i2c_data;
@@ -673,6 +742,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
673 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 742 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
674 sensor_settings[VFLIP_IDX] = val; 743 sensor_settings[VFLIP_IDX] = val;
675 744
745 if (dmi_check_system(ov9650_flip_dmi_table))
746 val = !val;
747
676 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); 748 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
677 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 749 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
678 if (err < 0) 750 if (err < 0)
@@ -685,48 +757,38 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
685 return err; 757 return err;
686} 758}
687 759
688int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 760static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
689{ 761{
690 struct sd *sd = (struct sd *) gspca_dev; 762 struct sd *sd = (struct sd *) gspca_dev;
691 s32 *sensor_settings = sd->sensor_priv; 763 s32 *sensor_settings = sd->sensor_priv;
692 764
693 *val = sensor_settings[GAIN_IDX]; 765 *val = sensor_settings[AUTO_EXPOSURE_IDX];
694 PDEBUG(D_V4L2, "Read gain %d", *val); 766 PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
695
696 return 0; 767 return 0;
697} 768}
698 769
699int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 770static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
771 __s32 val)
700{ 772{
701 int err; 773 int err;
702 u8 i2c_data; 774 u8 i2c_data;
703 struct sd *sd = (struct sd *) gspca_dev; 775 struct sd *sd = (struct sd *) gspca_dev;
704 s32 *sensor_settings = sd->sensor_priv; 776 s32 *sensor_settings = sd->sensor_priv;
705 777
706 PDEBUG(D_V4L2, "Set gain to %d", val); 778 PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
707
708 sensor_settings[GAIN_IDX] = val;
709 779
710 /* Read the OV9650_VREF register first to avoid 780 sensor_settings[AUTO_EXPOSURE_IDX] = val;
711 corrupting the VREF high and low bits */ 781 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
712 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
713 if (err < 0)
714 return err;
715
716 /* Mask away all uninteresting bits */
717 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
718 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
719 if (err < 0) 782 if (err < 0)
720 return err; 783 return err;
721 784
722 /* The 8 LSBs */ 785 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
723 i2c_data = val & 0xff;
724 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
725 786
726 return err; 787 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
727} 788}
728 789
729int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) 790static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
791 __s32 *val)
730{ 792{
731 struct sd *sd = (struct sd *) gspca_dev; 793 struct sd *sd = (struct sd *) gspca_dev;
732 s32 *sensor_settings = sd->sensor_priv; 794 s32 *sensor_settings = sd->sensor_priv;
@@ -735,7 +797,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
735 return 0; 797 return 0;
736} 798}
737 799
738int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) 800static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
801 __s32 val)
739{ 802{
740 int err; 803 int err;
741 u8 i2c_data; 804 u8 i2c_data;
@@ -755,7 +818,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
755 return err; 818 return err;
756} 819}
757 820
758int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 821static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
759{ 822{
760 struct sd *sd = (struct sd *) gspca_dev; 823 struct sd *sd = (struct sd *) gspca_dev;
761 s32 *sensor_settings = sd->sensor_priv; 824 s32 *sensor_settings = sd->sensor_priv;
@@ -765,7 +828,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
765 return 0; 828 return 0;
766} 829}
767 830
768int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 831static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
769{ 832{
770 int err; 833 int err;
771 u8 i2c_data; 834 u8 i2c_data;
@@ -780,9 +843,8 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
780 return err; 843 return err;
781 844
782 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 845 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
783 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
784 846
785 return err; 847 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
786} 848}
787 849
788static void ov9650_dump_registers(struct sd *sd) 850static void ov9650_dump_registers(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index fcc54e4c0f4f..c98c40d69e05 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -120,6 +120,10 @@
120#define OV9650_SOFT_SLEEP (1 << 4) 120#define OV9650_SOFT_SLEEP (1 << 4)
121#define OV9650_OUTPUT_DRIVE_2X (1 << 0) 121#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
122 122
123#define OV9650_DENOISE_ENABLE (1 << 5)
124#define OV9650_WHITE_PIXEL_ENABLE (1 << 1)
125#define OV9650_WHITE_PIXEL_OPTION (1 << 0)
126
123#define OV9650_LEFT_OFFSET 0x62 127#define OV9650_LEFT_OFFSET 0x62
124 128
125#define GAIN_DEFAULT 0x14 129#define GAIN_DEFAULT 0x14
@@ -137,29 +141,9 @@ int ov9650_probe(struct sd *sd);
137int ov9650_init(struct sd *sd); 141int ov9650_init(struct sd *sd);
138int ov9650_start(struct sd *sd); 142int ov9650_start(struct sd *sd);
139int ov9650_stop(struct sd *sd); 143int ov9650_stop(struct sd *sd);
140int ov9650_power_down(struct sd *sd);
141void ov9650_disconnect(struct sd *sd); 144void ov9650_disconnect(struct sd *sd);
142 145
143int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 146static const struct m5602_sensor ov9650 = {
144int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
145int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
146int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
147int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
148int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
149int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
150int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
151int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
152int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
153int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
154int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
155int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
156int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
157int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
158int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
159int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
160int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
161
162const static struct m5602_sensor ov9650 = {
163 .name = "OV9650", 147 .name = "OV9650",
164 .i2c_slave_id = 0x60, 148 .i2c_slave_id = 0x60,
165 .i2c_regW = 1, 149 .i2c_regW = 1,
@@ -167,7 +151,6 @@ const static struct m5602_sensor ov9650 = {
167 .init = ov9650_init, 151 .init = ov9650_init,
168 .start = ov9650_start, 152 .start = ov9650_start,
169 .stop = ov9650_stop, 153 .stop = ov9650_stop,
170 .power_down = ov9650_power_down,
171 .disconnect = ov9650_disconnect, 154 .disconnect = ov9650_disconnect,
172}; 155};
173 156
@@ -219,7 +202,7 @@ static const unsigned char init_ov9650[][3] =
219 /* Reset chip */ 202 /* Reset chip */
220 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 203 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
221 /* One extra reset is needed in order to make the sensor behave 204 /* One extra reset is needed in order to make the sensor behave
222 properly when resuming from ram */ 205 properly when resuming from ram, could be a timing issue */
223 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 206 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
224 207
225 /* Enable double clock */ 208 /* Enable double clock */
@@ -229,8 +212,7 @@ static const unsigned char init_ov9650[][3] =
229 212
230 /* Set fast AGC/AEC algorithm with unlimited step size */ 213 /* Set fast AGC/AEC algorithm with unlimited step size */
231 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | 214 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
232 OV9650_AEC_UNLIM_STEP_SIZE | 215 OV9650_AEC_UNLIM_STEP_SIZE},
233 OV9650_AWB_EN | OV9650_AGC_EN},
234 216
235 {SENSOR, OV9650_CHLF, 0x10}, 217 {SENSOR, OV9650_CHLF, 0x10},
236 {SENSOR, OV9650_ARBLM, 0xbf}, 218 {SENSOR, OV9650_ARBLM, 0xbf},
@@ -301,8 +283,11 @@ static const unsigned char init_ov9650[][3] =
301 {SENSOR, OV9650_VREF, 0x10}, 283 {SENSOR, OV9650_VREF, 0x10},
302 {SENSOR, OV9650_ADC, 0x04}, 284 {SENSOR, OV9650_ADC, 0x04},
303 {SENSOR, OV9650_HV, 0x40}, 285 {SENSOR, OV9650_HV, 0x40},
286
304 /* Enable denoise, and white-pixel erase */ 287 /* Enable denoise, and white-pixel erase */
305 {SENSOR, OV9650_COM22, 0x23}, 288 {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
289 OV9650_WHITE_PIXEL_ENABLE |
290 OV9650_WHITE_PIXEL_OPTION},
306 291
307 /* Enable VARIOPIXEL */ 292 /* Enable VARIOPIXEL */
308 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, 293 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
@@ -312,26 +297,6 @@ static const unsigned char init_ov9650[][3] =
312 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, 297 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
313}; 298};
314 299
315static const unsigned char power_down_ov9650[][3] =
316{
317 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
318 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
319 {SENSOR, OV9650_COM7, 0x80},
320 {SENSOR, OV9650_OFON, 0xf4},
321 {SENSOR, OV9650_MVFP, 0x80},
322 {SENSOR, OV9650_DBLV, 0x3f},
323 {SENSOR, OV9650_RSVD36, 0x49},
324 {SENSOR, OV9650_COM7, 0x05},
325
326 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
327 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
328 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
329 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
330 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
331 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
332 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
333};
334
335static const unsigned char res_init_ov9650[][3] = 300static const unsigned char res_init_ov9650[][3] =
336{ 301{
337 {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, 302 {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index eaddf488bad1..8d74d8065b79 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,29 @@
18 18
19#include "m5602_po1030.h" 19#include "m5602_po1030.h"
20 20
21static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
22static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
23static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
26static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
27static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
28static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
29static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
30static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
31static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
32static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
36 __s32 val);
37static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
38 __s32 *val);
39static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
40 __s32 val);
41static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
42 __s32 *val);
43
21static struct v4l2_pix_format po1030_modes[] = { 44static struct v4l2_pix_format po1030_modes[] = {
22 { 45 {
23 640, 46 640,
@@ -27,11 +50,12 @@ static struct v4l2_pix_format po1030_modes[] = {
27 .sizeimage = 640 * 480, 50 .sizeimage = 640 * 480,
28 .bytesperline = 640, 51 .bytesperline = 640,
29 .colorspace = V4L2_COLORSPACE_SRGB, 52 .colorspace = V4L2_COLORSPACE_SRGB,
30 .priv = 0 53 .priv = 2
31 } 54 }
32}; 55};
33 56
34const static struct ctrl po1030_ctrls[] = { 57static const struct ctrl po1030_ctrls[] = {
58#define GAIN_IDX 0
35 { 59 {
36 { 60 {
37 .id = V4L2_CID_GAIN, 61 .id = V4L2_CID_GAIN,
@@ -45,7 +69,9 @@ const static struct ctrl po1030_ctrls[] = {
45 }, 69 },
46 .set = po1030_set_gain, 70 .set = po1030_set_gain,
47 .get = po1030_get_gain 71 .get = po1030_get_gain
48 }, { 72 },
73#define EXPOSURE_IDX 1
74 {
49 { 75 {
50 .id = V4L2_CID_EXPOSURE, 76 .id = V4L2_CID_EXPOSURE,
51 .type = V4L2_CTRL_TYPE_INTEGER, 77 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -58,7 +84,9 @@ const static struct ctrl po1030_ctrls[] = {
58 }, 84 },
59 .set = po1030_set_exposure, 85 .set = po1030_set_exposure,
60 .get = po1030_get_exposure 86 .get = po1030_get_exposure
61 }, { 87 },
88#define RED_BALANCE_IDX 2
89 {
62 { 90 {
63 .id = V4L2_CID_RED_BALANCE, 91 .id = V4L2_CID_RED_BALANCE,
64 .type = V4L2_CTRL_TYPE_INTEGER, 92 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -71,7 +99,9 @@ const static struct ctrl po1030_ctrls[] = {
71 }, 99 },
72 .set = po1030_set_red_balance, 100 .set = po1030_set_red_balance,
73 .get = po1030_get_red_balance 101 .get = po1030_get_red_balance
74 }, { 102 },
103#define BLUE_BALANCE_IDX 3
104 {
75 { 105 {
76 .id = V4L2_CID_BLUE_BALANCE, 106 .id = V4L2_CID_BLUE_BALANCE,
77 .type = V4L2_CTRL_TYPE_INTEGER, 107 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -84,7 +114,9 @@ const static struct ctrl po1030_ctrls[] = {
84 }, 114 },
85 .set = po1030_set_blue_balance, 115 .set = po1030_set_blue_balance,
86 .get = po1030_get_blue_balance 116 .get = po1030_get_blue_balance
87 }, { 117 },
118#define HFLIP_IDX 4
119 {
88 { 120 {
89 .id = V4L2_CID_HFLIP, 121 .id = V4L2_CID_HFLIP,
90 .type = V4L2_CTRL_TYPE_BOOLEAN, 122 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -96,7 +128,9 @@ const static struct ctrl po1030_ctrls[] = {
96 }, 128 },
97 .set = po1030_set_hflip, 129 .set = po1030_set_hflip,
98 .get = po1030_get_hflip 130 .get = po1030_get_hflip
99 }, { 131 },
132#define VFLIP_IDX 5
133 {
100 { 134 {
101 .id = V4L2_CID_VFLIP, 135 .id = V4L2_CID_VFLIP,
102 .type = V4L2_CTRL_TYPE_BOOLEAN, 136 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -108,14 +142,58 @@ const static struct ctrl po1030_ctrls[] = {
108 }, 142 },
109 .set = po1030_set_vflip, 143 .set = po1030_set_vflip,
110 .get = po1030_get_vflip 144 .get = po1030_get_vflip
111 } 145 },
146#define AUTO_WHITE_BALANCE_IDX 6
147 {
148 {
149 .id = V4L2_CID_AUTO_WHITE_BALANCE,
150 .type = V4L2_CTRL_TYPE_BOOLEAN,
151 .name = "auto white balance",
152 .minimum = 0,
153 .maximum = 1,
154 .step = 1,
155 .default_value = 0,
156 },
157 .set = po1030_set_auto_white_balance,
158 .get = po1030_get_auto_white_balance
159 },
160#define AUTO_EXPOSURE_IDX 7
161 {
162 {
163 .id = V4L2_CID_EXPOSURE_AUTO,
164 .type = V4L2_CTRL_TYPE_BOOLEAN,
165 .name = "auto exposure",
166 .minimum = 0,
167 .maximum = 1,
168 .step = 1,
169 .default_value = 0,
170 },
171 .set = po1030_set_auto_exposure,
172 .get = po1030_get_auto_exposure
173 },
174#define GREEN_BALANCE_IDX 8
175 {
176 {
177 .id = M5602_V4L2_CID_GREEN_BALANCE,
178 .type = V4L2_CTRL_TYPE_INTEGER,
179 .name = "green balance",
180 .minimum = 0x00,
181 .maximum = 0xff,
182 .step = 0x1,
183 .default_value = PO1030_GREEN_GAIN_DEFAULT,
184 .flags = V4L2_CTRL_FLAG_SLIDER
185 },
186 .set = po1030_set_green_balance,
187 .get = po1030_get_green_balance
188 },
112}; 189};
113 190
114static void po1030_dump_registers(struct sd *sd); 191static void po1030_dump_registers(struct sd *sd);
115 192
116int po1030_probe(struct sd *sd) 193int po1030_probe(struct sd *sd)
117{ 194{
118 u8 prod_id = 0, ver_id = 0, i; 195 u8 dev_id_h = 0, i;
196 s32 *sensor_settings;
119 197
120 if (force_sensor) { 198 if (force_sensor) {
121 if (force_sensor == PO1030_SENSOR) { 199 if (force_sensor == PO1030_SENSOR) {
@@ -139,28 +217,36 @@ int po1030_probe(struct sd *sd)
139 m5602_write_bridge(sd, preinit_po1030[i][1], data); 217 m5602_write_bridge(sd, preinit_po1030[i][1], data);
140 } 218 }
141 219
142 if (m5602_read_sensor(sd, 0x3, &prod_id, 1)) 220 if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
143 return -ENODEV; 221 return -ENODEV;
144 222
145 if (m5602_read_sensor(sd, 0x4, &ver_id, 1)) 223 if (dev_id_h == 0x30) {
146 return -ENODEV;
147
148 if ((prod_id == 0x02) && (ver_id == 0xef)) {
149 info("Detected a po1030 sensor"); 224 info("Detected a po1030 sensor");
150 goto sensor_found; 225 goto sensor_found;
151 } 226 }
152 return -ENODEV; 227 return -ENODEV;
153 228
154sensor_found: 229sensor_found:
230 sensor_settings = kmalloc(
231 ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
232 if (!sensor_settings)
233 return -ENOMEM;
234
155 sd->gspca_dev.cam.cam_mode = po1030_modes; 235 sd->gspca_dev.cam.cam_mode = po1030_modes;
156 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); 236 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
157 sd->desc->ctrls = po1030_ctrls; 237 sd->desc->ctrls = po1030_ctrls;
158 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); 238 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
239
240 for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
241 sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
242 sd->sensor_priv = sensor_settings;
243
159 return 0; 244 return 0;
160} 245}
161 246
162int po1030_init(struct sd *sd) 247int po1030_init(struct sd *sd)
163{ 248{
249 s32 *sensor_settings = sd->sensor_priv;
164 int i, err = 0; 250 int i, err = 0;
165 251
166 /* Init the sensor */ 252 /* Init the sensor */
@@ -185,47 +271,206 @@ int po1030_init(struct sd *sd)
185 return -EINVAL; 271 return -EINVAL;
186 } 272 }
187 } 273 }
274 if (err < 0)
275 return err;
188 276
189 if (dump_sensor) 277 if (dump_sensor)
190 po1030_dump_registers(sd); 278 po1030_dump_registers(sd);
191 279
280 err = po1030_set_exposure(&sd->gspca_dev,
281 sensor_settings[EXPOSURE_IDX]);
282 if (err < 0)
283 return err;
284
285 err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
286 if (err < 0)
287 return err;
288
289 err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
290 if (err < 0)
291 return err;
292
293 err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
294 if (err < 0)
295 return err;
296
297 err = po1030_set_red_balance(&sd->gspca_dev,
298 sensor_settings[RED_BALANCE_IDX]);
299 if (err < 0)
300 return err;
301
302 err = po1030_set_blue_balance(&sd->gspca_dev,
303 sensor_settings[BLUE_BALANCE_IDX]);
304 if (err < 0)
305 return err;
306
307 err = po1030_set_green_balance(&sd->gspca_dev,
308 sensor_settings[GREEN_BALANCE_IDX]);
309 if (err < 0)
310 return err;
311
312 err = po1030_set_auto_white_balance(&sd->gspca_dev,
313 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
314 if (err < 0)
315 return err;
316
317 err = po1030_set_auto_exposure(&sd->gspca_dev,
318 sensor_settings[AUTO_EXPOSURE_IDX]);
192 return err; 319 return err;
193} 320}
194 321
195int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 322int po1030_start(struct sd *sd)
196{ 323{
197 struct sd *sd = (struct sd *) gspca_dev; 324 struct cam *cam = &sd->gspca_dev.cam;
198 u8 i2c_data; 325 int i, err = 0;
199 int err; 326 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
327 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
328 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
329 u8 data;
330
331 switch (width) {
332 case 320:
333 data = PO1030_SUBSAMPLING;
334 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
335 if (err < 0)
336 return err;
337
338 data = ((width + 3) >> 8) & 0xff;
339 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
340 if (err < 0)
341 return err;
342
343 data = (width + 3) & 0xff;
344 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
345 if (err < 0)
346 return err;
347
348 data = ((height + 1) >> 8) & 0xff;
349 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
350 if (err < 0)
351 return err;
352
353 data = (height + 1) & 0xff;
354 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
355
356 height += 6;
357 width -= 1;
358 break;
359
360 case 640:
361 data = 0;
362 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
363 if (err < 0)
364 return err;
365
366 data = ((width + 7) >> 8) & 0xff;
367 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
368 if (err < 0)
369 return err;
370
371 data = (width + 7) & 0xff;
372 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
373 if (err < 0)
374 return err;
375
376 data = ((height + 3) >> 8) & 0xff;
377 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
378 if (err < 0)
379 return err;
380
381 data = (height + 3) & 0xff;
382 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
383
384 height += 12;
385 width -= 2;
386 break;
387 }
388 err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
389 if (err < 0)
390 return err;
200 391
201 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H, 392 err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
202 &i2c_data, 1);
203 if (err < 0) 393 if (err < 0)
204 return err; 394 return err;
205 *val = (i2c_data << 8);
206 395
207 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M, 396 err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
208 &i2c_data, 1); 397 if (err < 0)
209 *val |= i2c_data; 398 return err;
210 399
211 PDEBUG(D_V4L2, "Exposure read as %d", *val); 400 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
401 if (err < 0)
402 return err;
403
404 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
405 ((ver_offs >> 8) & 0xff));
406 if (err < 0)
407 return err;
408
409 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
410 if (err < 0)
411 return err;
412
413 for (i = 0; i < 2 && !err; i++)
414 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
415 if (err < 0)
416 return err;
417
418 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
419 if (err < 0)
420 return err;
421
422 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
423 if (err < 0)
424 return err;
425
426 for (i = 0; i < 2 && !err; i++)
427 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
428
429 for (i = 0; i < 2 && !err; i++)
430 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
431
432 for (i = 0; i < 2 && !err; i++)
433 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
434 if (err < 0)
435 return err;
436
437 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
438 if (err < 0)
439 return err;
212 440
441 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
442 if (err < 0)
443 return err;
444
445 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
213 return err; 446 return err;
214} 447}
215 448
216int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 449static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
217{ 450{
218 struct sd *sd = (struct sd *) gspca_dev; 451 struct sd *sd = (struct sd *) gspca_dev;
452 s32 *sensor_settings = sd->sensor_priv;
453
454 *val = sensor_settings[EXPOSURE_IDX];
455 PDEBUG(D_V4L2, "Exposure read as %d", *val);
456 return 0;
457}
458
459static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
460{
461 struct sd *sd = (struct sd *) gspca_dev;
462 s32 *sensor_settings = sd->sensor_priv;
219 u8 i2c_data; 463 u8 i2c_data;
220 int err; 464 int err;
221 465
466 sensor_settings[EXPOSURE_IDX] = val;
222 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); 467 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
223 468
224 i2c_data = ((val & 0xff00) >> 8); 469 i2c_data = ((val & 0xff00) >> 8);
225 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", 470 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
226 i2c_data); 471 i2c_data);
227 472
228 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H, 473 err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
229 &i2c_data, 1); 474 &i2c_data, 1);
230 if (err < 0) 475 if (err < 0)
231 return err; 476 return err;
@@ -233,167 +478,256 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
233 i2c_data = (val & 0xff); 478 i2c_data = (val & 0xff);
234 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", 479 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
235 i2c_data); 480 i2c_data);
236 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M, 481 err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
237 &i2c_data, 1); 482 &i2c_data, 1);
238 483
239 return err; 484 return err;
240} 485}
241 486
242int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 487static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
243{ 488{
244 struct sd *sd = (struct sd *) gspca_dev; 489 struct sd *sd = (struct sd *) gspca_dev;
245 u8 i2c_data; 490 s32 *sensor_settings = sd->sensor_priv;
246 int err;
247 491
248 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, 492 *val = sensor_settings[GAIN_IDX];
249 &i2c_data, 1);
250 *val = i2c_data;
251 PDEBUG(D_V4L2, "Read global gain %d", *val); 493 PDEBUG(D_V4L2, "Read global gain %d", *val);
252 494 return 0;
253 return err;
254} 495}
255 496
256int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 497static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
257{ 498{
258 struct sd *sd = (struct sd *) gspca_dev; 499 struct sd *sd = (struct sd *) gspca_dev;
500 s32 *sensor_settings = sd->sensor_priv;
259 u8 i2c_data; 501 u8 i2c_data;
260 int err; 502 int err;
261 503
262 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, 504 sensor_settings[GAIN_IDX] = val;
505
506 i2c_data = val & 0xff;
507 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
508 err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
263 &i2c_data, 1); 509 &i2c_data, 1);
510 return err;
511}
264 512
265 *val = (i2c_data >> 7) & 0x01 ; 513static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
514{
515 struct sd *sd = (struct sd *) gspca_dev;
516 s32 *sensor_settings = sd->sensor_priv;
266 517
518 *val = sensor_settings[HFLIP_IDX];
267 PDEBUG(D_V4L2, "Read hflip %d", *val); 519 PDEBUG(D_V4L2, "Read hflip %d", *val);
268 520
269 return err; 521 return 0;
270} 522}
271 523
272int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 524static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
273{ 525{
274 struct sd *sd = (struct sd *) gspca_dev; 526 struct sd *sd = (struct sd *) gspca_dev;
527 s32 *sensor_settings = sd->sensor_priv;
275 u8 i2c_data; 528 u8 i2c_data;
276 int err; 529 int err;
277 530
531 sensor_settings[HFLIP_IDX] = val;
532
278 PDEBUG(D_V4L2, "Set hflip %d", val); 533 PDEBUG(D_V4L2, "Set hflip %d", val);
279 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); 534 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
280 if (err < 0) 535 if (err < 0)
281 return err; 536 return err;
282 537
283 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); 538 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
284 539
285 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, 540 err = m5602_write_sensor(sd, PO1030_CONTROL2,
286 &i2c_data, 1); 541 &i2c_data, 1);
287 542
288 return err; 543 return err;
289} 544}
290 545
291int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 546static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
292{ 547{
293 struct sd *sd = (struct sd *) gspca_dev; 548 struct sd *sd = (struct sd *) gspca_dev;
294 u8 i2c_data; 549 s32 *sensor_settings = sd->sensor_priv;
295 int err;
296
297 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
298 &i2c_data, 1);
299
300 *val = (i2c_data >> 6) & 0x01;
301 550
551 *val = sensor_settings[VFLIP_IDX];
302 PDEBUG(D_V4L2, "Read vflip %d", *val); 552 PDEBUG(D_V4L2, "Read vflip %d", *val);
303 553
304 return err; 554 return 0;
305} 555}
306 556
307int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 557static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
308{ 558{
309 struct sd *sd = (struct sd *) gspca_dev; 559 struct sd *sd = (struct sd *) gspca_dev;
560 s32 *sensor_settings = sd->sensor_priv;
310 u8 i2c_data; 561 u8 i2c_data;
311 int err; 562 int err;
312 563
564 sensor_settings[VFLIP_IDX] = val;
565
313 PDEBUG(D_V4L2, "Set vflip %d", val); 566 PDEBUG(D_V4L2, "Set vflip %d", val);
314 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); 567 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
315 if (err < 0) 568 if (err < 0)
316 return err; 569 return err;
317 570
318 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); 571 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
319 572
320 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, 573 err = m5602_write_sensor(sd, PO1030_CONTROL2,
321 &i2c_data, 1); 574 &i2c_data, 1);
322 575
323 return err; 576 return err;
324} 577}
325 578
326int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) 579static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
580{
581 struct sd *sd = (struct sd *) gspca_dev;
582 s32 *sensor_settings = sd->sensor_priv;
583
584 *val = sensor_settings[RED_BALANCE_IDX];
585 PDEBUG(D_V4L2, "Read red gain %d", *val);
586 return 0;
587}
588
589static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
327{ 590{
328 struct sd *sd = (struct sd *) gspca_dev; 591 struct sd *sd = (struct sd *) gspca_dev;
592 s32 *sensor_settings = sd->sensor_priv;
329 u8 i2c_data; 593 u8 i2c_data;
330 int err; 594 int err;
331 595
596 sensor_settings[RED_BALANCE_IDX] = val;
597
332 i2c_data = val & 0xff; 598 i2c_data = val & 0xff;
333 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); 599 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
334 err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, 600 err = m5602_write_sensor(sd, PO1030_RED_GAIN,
335 &i2c_data, 1); 601 &i2c_data, 1);
336 return err; 602 return err;
337} 603}
338 604
339int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 605static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
340{ 606{
341 struct sd *sd = (struct sd *) gspca_dev; 607 struct sd *sd = (struct sd *) gspca_dev;
342 u8 i2c_data; 608 s32 *sensor_settings = sd->sensor_priv;
343 int err;
344 609
345 err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN, 610 *val = sensor_settings[BLUE_BALANCE_IDX];
346 &i2c_data, 1); 611 PDEBUG(D_V4L2, "Read blue gain %d", *val);
347 *val = i2c_data; 612
348 PDEBUG(D_V4L2, "Read red gain %d", *val); 613 return 0;
349 return err;
350} 614}
351 615
352int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 616static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
353{ 617{
354 struct sd *sd = (struct sd *) gspca_dev; 618 struct sd *sd = (struct sd *) gspca_dev;
619 s32 *sensor_settings = sd->sensor_priv;
355 u8 i2c_data; 620 u8 i2c_data;
356 int err; 621 int err;
357 622
623 sensor_settings[BLUE_BALANCE_IDX] = val;
624
358 i2c_data = val & 0xff; 625 i2c_data = val & 0xff;
359 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); 626 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
360 err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, 627 err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
361 &i2c_data, 1); 628 &i2c_data, 1);
629
362 return err; 630 return err;
363} 631}
364 632
365int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 633static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
366{ 634{
367 struct sd *sd = (struct sd *) gspca_dev; 635 struct sd *sd = (struct sd *) gspca_dev;
636 s32 *sensor_settings = sd->sensor_priv;
637
638 *val = sensor_settings[GREEN_BALANCE_IDX];
639 PDEBUG(D_V4L2, "Read green gain %d", *val);
640
641 return 0;
642}
643
644static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
645{
646 struct sd *sd = (struct sd *) gspca_dev;
647 s32 *sensor_settings = sd->sensor_priv;
368 u8 i2c_data; 648 u8 i2c_data;
369 int err; 649 int err;
370 650
371 err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN, 651 sensor_settings[GREEN_BALANCE_IDX] = val;
652 i2c_data = val & 0xff;
653 PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
654
655 err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
656 &i2c_data, 1);
657 if (err < 0)
658 return err;
659
660 return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
372 &i2c_data, 1); 661 &i2c_data, 1);
373 *val = i2c_data; 662}
374 PDEBUG(D_V4L2, "Read blue gain %d", *val);
375 663
376 return err; 664static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
665 __s32 *val)
666{
667 struct sd *sd = (struct sd *) gspca_dev;
668 s32 *sensor_settings = sd->sensor_priv;
669
670 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
671 PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
672
673 return 0;
377} 674}
378 675
379int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 676static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
677 __s32 val)
380{ 678{
381 struct sd *sd = (struct sd *) gspca_dev; 679 struct sd *sd = (struct sd *) gspca_dev;
680 s32 *sensor_settings = sd->sensor_priv;
382 u8 i2c_data; 681 u8 i2c_data;
383 int err; 682 int err;
384 i2c_data = val & 0xff;
385 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
386 err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
387 &i2c_data, 1);
388 683
684 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
685
686 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
687 if (err < 0)
688 return err;
689
690 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
691 i2c_data = (i2c_data & 0xfe) | (val & 0x01);
692 err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
389 return err; 693 return err;
390} 694}
391 695
392int po1030_power_down(struct sd *sd) 696static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
697 __s32 *val)
393{ 698{
699 struct sd *sd = (struct sd *) gspca_dev;
700 s32 *sensor_settings = sd->sensor_priv;
701
702 *val = sensor_settings[AUTO_EXPOSURE_IDX];
703 PDEBUG(D_V4L2, "Auto exposure is %d", *val);
394 return 0; 704 return 0;
395} 705}
396 706
707static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
708 __s32 val)
709{
710 struct sd *sd = (struct sd *) gspca_dev;
711 s32 *sensor_settings = sd->sensor_priv;
712 u8 i2c_data;
713 int err;
714
715 sensor_settings[AUTO_EXPOSURE_IDX] = val;
716 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
717 if (err < 0)
718 return err;
719
720 PDEBUG(D_V4L2, "Set auto exposure to %d", val);
721 i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
722 return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
723}
724
725void po1030_disconnect(struct sd *sd)
726{
727 sd->sensor = NULL;
728 kfree(sd->sensor_priv);
729}
730
397static void po1030_dump_registers(struct sd *sd) 731static void po1030_dump_registers(struct sd *sd)
398{ 732{
399 int address; 733 int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index c10b12335818..1ea380b2bbe7 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -25,98 +25,123 @@
25 25
26/*****************************************************************************/ 26/*****************************************************************************/
27 27
28#define PO1030_REG_DEVID_H 0x00 28#define PO1030_DEVID_H 0x00
29#define PO1030_REG_DEVID_L 0x01 29#define PO1030_DEVID_L 0x01
30#define PO1030_REG_FRAMEWIDTH_H 0x04 30#define PO1030_FRAMEWIDTH_H 0x04
31#define PO1030_REG_FRAMEWIDTH_L 0x05 31#define PO1030_FRAMEWIDTH_L 0x05
32#define PO1030_REG_FRAMEHEIGHT_H 0x06 32#define PO1030_FRAMEHEIGHT_H 0x06
33#define PO1030_REG_FRAMEHEIGHT_L 0x07 33#define PO1030_FRAMEHEIGHT_L 0x07
34#define PO1030_REG_WINDOWX_H 0x08 34#define PO1030_WINDOWX_H 0x08
35#define PO1030_REG_WINDOWX_L 0x09 35#define PO1030_WINDOWX_L 0x09
36#define PO1030_REG_WINDOWY_H 0x0a 36#define PO1030_WINDOWY_H 0x0a
37#define PO1030_REG_WINDOWY_L 0x0b 37#define PO1030_WINDOWY_L 0x0b
38#define PO1030_REG_WINDOWWIDTH_H 0x0c 38#define PO1030_WINDOWWIDTH_H 0x0c
39#define PO1030_REG_WINDOWWIDTH_L 0x0d 39#define PO1030_WINDOWWIDTH_L 0x0d
40#define PO1030_REG_WINDOWHEIGHT_H 0x0e 40#define PO1030_WINDOWHEIGHT_H 0x0e
41#define PO1030_REG_WINDOWHEIGHT_L 0x0f 41#define PO1030_WINDOWHEIGHT_L 0x0f
42 42
43#define PO1030_REG_GLOBALIBIAS 0x12 43#define PO1030_GLOBALIBIAS 0x12
44#define PO1030_REG_PIXELIBIAS 0x13 44#define PO1030_PIXELIBIAS 0x13
45 45
46#define PO1030_REG_GLOBALGAIN 0x15 46#define PO1030_GLOBALGAIN 0x15
47#define PO1030_REG_RED_GAIN 0x16 47#define PO1030_RED_GAIN 0x16
48#define PO1030_REG_GREEN_1_GAIN 0x17 48#define PO1030_GREEN_1_GAIN 0x17
49#define PO1030_REG_BLUE_GAIN 0x18 49#define PO1030_BLUE_GAIN 0x18
50#define PO1030_REG_GREEN_2_GAIN 0x19 50#define PO1030_GREEN_2_GAIN 0x19
51 51
52#define PO1030_REG_INTEGLINES_H 0x1a 52#define PO1030_INTEGLINES_H 0x1a
53#define PO1030_REG_INTEGLINES_M 0x1b 53#define PO1030_INTEGLINES_M 0x1b
54#define PO1030_REG_INTEGLINES_L 0x1c 54#define PO1030_INTEGLINES_L 0x1c
55 55
56#define PO1030_REG_CONTROL1 0x1d 56#define PO1030_CONTROL1 0x1d
57#define PO1030_REG_CONTROL2 0x1e 57#define PO1030_CONTROL2 0x1e
58#define PO1030_REG_CONTROL3 0x1f 58#define PO1030_CONTROL3 0x1f
59#define PO1030_REG_CONTROL4 0x20 59#define PO1030_CONTROL4 0x20
60 60
61#define PO1030_REG_PERIOD50_H 0x23 61#define PO1030_PERIOD50_H 0x23
62#define PO1030_REG_PERIOD50_L 0x24 62#define PO1030_PERIOD50_L 0x24
63#define PO1030_REG_PERIOD60_H 0x25 63#define PO1030_PERIOD60_H 0x25
64#define PO1030_REG_PERIOD60_L 0x26 64#define PO1030_PERIOD60_L 0x26
65#define PO1030_REG_REGCLK167 0x27 65#define PO1030_REGCLK167 0x27
66#define PO1030_REG_DELTA50 0x28 66#define PO1030_FLICKER_DELTA50 0x28
67#define PO1030_REG_DELTA60 0x29 67#define PO1030_FLICKERDELTA60 0x29
68 68
69#define PO1030_REG_ADCOFFSET 0x2c 69#define PO1030_ADCOFFSET 0x2c
70 70
71/* Gamma Correction Coeffs */ 71/* Gamma Correction Coeffs */
72#define PO1030_REG_GC0 0x2d 72#define PO1030_GC0 0x2d
73#define PO1030_REG_GC1 0x2e 73#define PO1030_GC1 0x2e
74#define PO1030_REG_GC2 0x2f 74#define PO1030_GC2 0x2f
75#define PO1030_REG_GC3 0x30 75#define PO1030_GC3 0x30
76#define PO1030_REG_GC4 0x31 76#define PO1030_GC4 0x31
77#define PO1030_REG_GC5 0x32 77#define PO1030_GC5 0x32
78#define PO1030_REG_GC6 0x33 78#define PO1030_GC6 0x33
79#define PO1030_REG_GC7 0x34 79#define PO1030_GC7 0x34
80 80
81/* Color Transform Matrix */ 81/* Color Transform Matrix */
82#define PO1030_REG_CT0 0x35 82#define PO1030_CT0 0x35
83#define PO1030_REG_CT1 0x36 83#define PO1030_CT1 0x36
84#define PO1030_REG_CT2 0x37 84#define PO1030_CT2 0x37
85#define PO1030_REG_CT3 0x38 85#define PO1030_CT3 0x38
86#define PO1030_REG_CT4 0x39 86#define PO1030_CT4 0x39
87#define PO1030_REG_CT5 0x3a 87#define PO1030_CT5 0x3a
88#define PO1030_REG_CT6 0x3b 88#define PO1030_CT6 0x3b
89#define PO1030_REG_CT7 0x3c 89#define PO1030_CT7 0x3c
90#define PO1030_REG_CT8 0x3d 90#define PO1030_CT8 0x3d
91 91
92#define PO1030_REG_AUTOCTRL1 0x3e 92#define PO1030_AUTOCTRL1 0x3e
93#define PO1030_REG_AUTOCTRL2 0x3f 93#define PO1030_AUTOCTRL2 0x3f
94 94
95#define PO1030_REG_YTARGET 0x40 95#define PO1030_YTARGET 0x40
96#define PO1030_REG_GLOBALGAINMIN 0x41 96#define PO1030_GLOBALGAINMIN 0x41
97#define PO1030_REG_GLOBALGAINMAX 0x42 97#define PO1030_GLOBALGAINMAX 0x42
98
99#define PO1030_AWB_RED_TUNING 0x47
100#define PO1030_AWB_BLUE_TUNING 0x48
98 101
99/* Output format control */ 102/* Output format control */
100#define PO1030_REG_OUTFORMCTRL1 0x5a 103#define PO1030_OUTFORMCTRL1 0x5a
101#define PO1030_REG_OUTFORMCTRL2 0x5b 104#define PO1030_OUTFORMCTRL2 0x5b
102#define PO1030_REG_OUTFORMCTRL3 0x5c 105#define PO1030_OUTFORMCTRL3 0x5c
103#define PO1030_REG_OUTFORMCTRL4 0x5d 106#define PO1030_OUTFORMCTRL4 0x5d
104#define PO1030_REG_OUTFORMCTRL5 0x5e 107#define PO1030_OUTFORMCTRL5 0x5e
105 108
106/* Imaging coefficients */ 109#define PO1030_EDGE_ENH_OFF 0x5f
107#define PO1030_REG_YBRIGHT 0x73 110#define PO1030_EGA 0x60
108#define PO1030_REG_YCONTRAST 0x74
109#define PO1030_REG_YSATURATION 0x75
110 111
111#define PO1030_HFLIP (1 << 7) 112#define PO1030_Cb_U_GAIN 0x63
112#define PO1030_VFLIP (1 << 6) 113#define PO1030_Cr_V_GAIN 0x64
114
115#define PO1030_YCONTRAST 0x74
116#define PO1030_YSATURATION 0x75
117
118#define PO1030_HFLIP (1 << 7)
119#define PO1030_VFLIP (1 << 6)
120
121#define PO1030_HREF_ENABLE (1 << 6)
122
123#define PO1030_RAW_RGB_BAYER 0x4
124
125#define PO1030_FRAME_EQUAL (1 << 3)
126#define PO1030_AUTO_SUBSAMPLING (1 << 4)
127
128#define PO1030_WEIGHT_WIN_2X (1 << 3)
129
130#define PO1030_SHUTTER_MODE (1 << 6)
131#define PO1030_AUTO_SUBSAMPLING (1 << 4)
132#define PO1030_FRAME_EQUAL (1 << 3)
133
134#define PO1030_SENSOR_RESET (1 << 5)
135
136#define PO1030_SUBSAMPLING (1 << 6)
113 137
114/*****************************************************************************/ 138/*****************************************************************************/
115 139
116#define PO1030_GLOBAL_GAIN_DEFAULT 0x12 140#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
117#define PO1030_EXPOSURE_DEFAULT 0x0085 141#define PO1030_EXPOSURE_DEFAULT 0x0085
118#define PO1030_BLUE_GAIN_DEFAULT 0x40 142#define PO1030_BLUE_GAIN_DEFAULT 0x36
119#define PO1030_RED_GAIN_DEFAULT 0x40 143#define PO1030_RED_GAIN_DEFAULT 0x36
144#define PO1030_GREEN_GAIN_DEFAULT 0x40
120 145
121/*****************************************************************************/ 146/*****************************************************************************/
122 147
@@ -126,20 +151,8 @@ extern int dump_sensor;
126 151
127int po1030_probe(struct sd *sd); 152int po1030_probe(struct sd *sd);
128int po1030_init(struct sd *sd); 153int po1030_init(struct sd *sd);
129int po1030_power_down(struct sd *sd); 154int po1030_start(struct sd *sd);
130 155void po1030_disconnect(struct sd *sd);
131int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
132int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
133int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
134int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
135int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
136int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
137int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
138int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
139int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
140int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
141int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
142int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
143 156
144static const struct m5602_sensor po1030 = { 157static const struct m5602_sensor po1030 = {
145 .name = "PO1030", 158 .name = "PO1030",
@@ -149,7 +162,8 @@ static const struct m5602_sensor po1030 = {
149 162
150 .probe = po1030_probe, 163 .probe = po1030_probe,
151 .init = po1030_init, 164 .init = po1030_init,
152 .power_down = po1030_power_down, 165 .start = po1030_start,
166 .disconnect = po1030_disconnect,
153}; 167};
154 168
155static const unsigned char preinit_po1030[][3] = 169static const unsigned char preinit_po1030[][3] =
@@ -159,248 +173,103 @@ static const unsigned char preinit_po1030[][3] =
159 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 173 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
160 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 174 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
161 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 175 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
162 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
163 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 176 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
164 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
165 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 177 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
166
167 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
168
169 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
170 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
171 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
172 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
173 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
174 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
175 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
176 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
177 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
178 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 178 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
179 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
180 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
181 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
182 {BRIDGE, M5602_XB_SIG_INI, 0x01},
183 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
184 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
185 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
186 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
187 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
188 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
189 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
190 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
191 {BRIDGE, M5602_XB_SIG_INI, 0x00},
192 {BRIDGE, M5602_XB_SIG_INI, 0x02},
193 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
194 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
195 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
196 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
197 {BRIDGE, M5602_XB_SIG_INI, 0x00},
198
199 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
200
201 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 179 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
202 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 180 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
203 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 181 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
204 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 182 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
205 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 183 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
184
185 {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
186
206 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 187 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
207 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 188 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
208 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 189 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
209 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 190 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
210 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
211 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 191 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
212 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 192 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
213 {BRIDGE, M5602_XB_GPIO_DAT, 0x00} 193 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}
214}; 194};
215 195
216static const unsigned char init_po1030[][4] = 196static const unsigned char init_po1030[][3] =
217{ 197{
218 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, 198 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
219 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, 199 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
220 /*sequence 1*/
221 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 200 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
222 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 201 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
223 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 202 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
224 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
225
226 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 203 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
227 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
228 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 204 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
229 /*end of sequence 1*/
230
231 /*sequence 2 (same as stop sequence)*/
232 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
233 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
234 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
235 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
236 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
237 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
238
239 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
240 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
241 /*end of sequence 2*/
242 205
243 /*sequence 5*/ 206 {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
244 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
245 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
246 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
247 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
248 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
249 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
250 {BRIDGE, M5602_XB_SIG_INI, 0x01},
251 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
252 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
257 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
258 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
259 {BRIDGE, M5602_XB_SIG_INI, 0x00},
260 {BRIDGE, M5602_XB_SIG_INI, 0x02},
261 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
262 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
263 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
264 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
265 {BRIDGE, M5602_XB_SIG_INI, 0x00},
266 /*end of sequence 5*/
267
268 /*sequence 2 stop */
269 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
270 207
271 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 208 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
272 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 209 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
273 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 210 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
211 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
274 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 212 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
275 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 213 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
276 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 214 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
277 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 215 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
278 /*end of sequence 2 stop */
279
280/* ---------------------------------
281 * end of init - begin of start
282 * --------------------------------- */
283
284 /*sequence 3*/
285 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
286 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
287 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
288 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
289 /*end of sequence 3*/
290 /*sequence 4*/
291 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 216 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
292 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 217 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
293 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
294 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
295 218
296 {SENSOR, PO1030_REG_AUTOCTRL2, 0x04}, 219 {SENSOR, PO1030_AUTOCTRL2, 0x04},
220
221 {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
222 {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
223
224 {SENSOR, PO1030_CONTROL2, 0x03},
225 {SENSOR, 0x21, 0x90},
226 {SENSOR, PO1030_YTARGET, 0x60},
227 {SENSOR, 0x59, 0x13},
228 {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
229 {SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
230 {SENSOR, PO1030_EGA, 0x80},
231 {SENSOR, 0x78, 0x14},
232 {SENSOR, 0x6f, 0x01},
233 {SENSOR, PO1030_GLOBALGAINMAX, 0x14},
234 {SENSOR, PO1030_Cb_U_GAIN, 0x38},
235 {SENSOR, PO1030_Cr_V_GAIN, 0x38},
236 {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
237 PO1030_AUTO_SUBSAMPLING |
238 PO1030_FRAME_EQUAL},
239 {SENSOR, PO1030_GC0, 0x10},
240 {SENSOR, PO1030_GC1, 0x20},
241 {SENSOR, PO1030_GC2, 0x40},
242 {SENSOR, PO1030_GC3, 0x60},
243 {SENSOR, PO1030_GC4, 0x80},
244 {SENSOR, PO1030_GC5, 0xa0},
245 {SENSOR, PO1030_GC6, 0xc0},
246 {SENSOR, PO1030_GC7, 0xff},
297 247
298 /* Set the width to 751 */ 248 /* Set the width to 751 */
299 {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, 249 {SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
300 {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}, 250 {SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
301 251
302 /* Set the height to 540 */ 252 /* Set the height to 540 */
303 {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02}, 253 {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
304 {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c}, 254 {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
305 255
306 /* Set the x window to 1 */ 256 /* Set the x window to 1 */
307 {SENSOR, PO1030_REG_WINDOWX_H, 0x00}, 257 {SENSOR, PO1030_WINDOWX_H, 0x00},
308 {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, 258 {SENSOR, PO1030_WINDOWX_L, 0x01},
309 259
310 /* Set the y window to 1 */ 260 /* Set the y window to 1 */
311 {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, 261 {SENSOR, PO1030_WINDOWY_H, 0x00},
312 {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, 262 {SENSOR, PO1030_WINDOWY_L, 0x01},
313
314 {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
315 {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
316 {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01},
317 {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3},
318
319 {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
320 {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
321 {SENSOR, PO1030_REG_AUTOCTRL1, 0x08},
322 {SENSOR, PO1030_REG_CONTROL2, 0x03},
323 {SENSOR, 0x21, 0x90},
324 {SENSOR, PO1030_REG_YTARGET, 0x60},
325 {SENSOR, 0x59, 0x13},
326 {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40},
327 {SENSOR, 0x5f, 0x00},
328 {SENSOR, 0x60, 0x80},
329 {SENSOR, 0x78, 0x14},
330 {SENSOR, 0x6f, 0x01},
331 {SENSOR, PO1030_REG_CONTROL1, 0x18},
332 {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14},
333 {SENSOR, 0x63, 0x38},
334 {SENSOR, 0x64, 0x38},
335 {SENSOR, PO1030_REG_CONTROL1, 0x58},
336 {SENSOR, PO1030_REG_RED_GAIN, 0x30},
337 {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30},
338 {SENSOR, PO1030_REG_BLUE_GAIN, 0x30},
339 {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30},
340 {SENSOR, PO1030_REG_GC0, 0x10},
341 {SENSOR, PO1030_REG_GC1, 0x20},
342 {SENSOR, PO1030_REG_GC2, 0x40},
343 {SENSOR, PO1030_REG_GC3, 0x60},
344 {SENSOR, PO1030_REG_GC4, 0x80},
345 {SENSOR, PO1030_REG_GC5, 0xa0},
346 {SENSOR, PO1030_REG_GC6, 0xc0},
347 {SENSOR, PO1030_REG_GC7, 0xff},
348 /*end of sequence 4*/
349 /*sequence 5*/
350 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
351 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
352 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
353 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
354 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
355 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
356 {BRIDGE, M5602_XB_SIG_INI, 0x01},
357 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
358 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
359 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
360 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
361 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
362 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
363 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
364 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
365 {BRIDGE, M5602_XB_SIG_INI, 0x00},
366 {BRIDGE, M5602_XB_SIG_INI, 0x00},
367 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
368 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
369 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
370 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
371 {BRIDGE, M5602_XB_SIG_INI, 0x00},
372 /*end of sequence 5*/
373
374 /*sequence 6*/
375 /* Changing 40 in f0 the image becomes green in bayer mode and red in
376 * rgb mode */
377 {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
378 /* in changing 40 in f0 the image becomes green in bayer mode and red in
379 * rgb mode */
380 {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
381 263
382 /* with a very low lighted environment increase the exposure but 264 /* with a very low lighted environment increase the exposure but
383 * decrease the FPS (Frame Per Second) */ 265 * decrease the FPS (Frame Per Second) */
384 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 266 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
385 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 267 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
386 268
387 /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in 269 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
388 * low lighted environment (f0 is more than ff ?)*/ 270 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
389 {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2) 271 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
390 & 0xff)}, 272 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
391
392 /* Controls middle exposure, use only in high lighted environment */
393 {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
394
395 /* Controls clarity (not sure) */
396 {SENSOR, PO1030_REG_INTEGLINES_L, 0x00},
397 /* Controls gain (the image is more lighted) */
398 {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
399
400 /* Sets the width */
401 {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
402 {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}
403 /*end of sequence 6*/
404}; 273};
405 274
406#endif 275#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 4306d596056d..191bcd718979 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,19 @@
18 18
19#include "m5602_s5k4aa.h" 19#include "m5602_s5k4aa.h"
20 20
21static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
22static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
23static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
24static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
25static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
26static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
27static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
28static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
29static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val);
30static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val);
31static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
32static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
33
21static 34static
22 const 35 const
23 struct dmi_system_id s5k4aa_vflip_dmi_table[] = { 36 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
@@ -46,6 +59,18 @@ static
46 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 59 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
47 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") 60 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
48 } 61 }
62 }, {
63 .ident = "MSI L735",
64 .matches = {
65 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
66 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
67 }
68 }, {
69 .ident = "Lenovo Y300",
70 .matches = {
71 DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"),
72 DMI_MATCH(DMI_PRODUCT_NAME, "Y300")
73 }
49 }, 74 },
50 { } 75 { }
51}; 76};
@@ -61,10 +86,22 @@ static struct v4l2_pix_format s5k4aa_modes[] = {
61 .bytesperline = 640, 86 .bytesperline = 640,
62 .colorspace = V4L2_COLORSPACE_SRGB, 87 .colorspace = V4L2_COLORSPACE_SRGB,
63 .priv = 0 88 .priv = 0
89 },
90 {
91 1280,
92 1024,
93 V4L2_PIX_FMT_SBGGR8,
94 V4L2_FIELD_NONE,
95 .sizeimage =
96 1280 * 1024,
97 .bytesperline = 1280,
98 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0
64 } 100 }
65}; 101};
66 102
67const static struct ctrl s5k4aa_ctrls[] = { 103static const struct ctrl s5k4aa_ctrls[] = {
104#define VFLIP_IDX 0
68 { 105 {
69 { 106 {
70 .id = V4L2_CID_VFLIP, 107 .id = V4L2_CID_VFLIP,
@@ -77,8 +114,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
77 }, 114 },
78 .set = s5k4aa_set_vflip, 115 .set = s5k4aa_set_vflip,
79 .get = s5k4aa_get_vflip 116 .get = s5k4aa_get_vflip
80 117 },
81 }, { 118#define HFLIP_IDX 1
119 {
82 { 120 {
83 .id = V4L2_CID_HFLIP, 121 .id = V4L2_CID_HFLIP,
84 .type = V4L2_CTRL_TYPE_BOOLEAN, 122 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -90,8 +128,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
90 }, 128 },
91 .set = s5k4aa_set_hflip, 129 .set = s5k4aa_set_hflip,
92 .get = s5k4aa_get_hflip 130 .get = s5k4aa_get_hflip
93 131 },
94 }, { 132#define GAIN_IDX 2
133 {
95 { 134 {
96 .id = V4L2_CID_GAIN, 135 .id = V4L2_CID_GAIN,
97 .type = V4L2_CTRL_TYPE_INTEGER, 136 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -99,12 +138,14 @@ const static struct ctrl s5k4aa_ctrls[] = {
99 .minimum = 0, 138 .minimum = 0,
100 .maximum = 127, 139 .maximum = 127,
101 .step = 1, 140 .step = 1,
102 .default_value = 0xa0, 141 .default_value = S5K4AA_DEFAULT_GAIN,
103 .flags = V4L2_CTRL_FLAG_SLIDER 142 .flags = V4L2_CTRL_FLAG_SLIDER
104 }, 143 },
105 .set = s5k4aa_set_gain, 144 .set = s5k4aa_set_gain,
106 .get = s5k4aa_get_gain 145 .get = s5k4aa_get_gain
107 }, { 146 },
147#define EXPOSURE_IDX 3
148 {
108 { 149 {
109 .id = V4L2_CID_EXPOSURE, 150 .id = V4L2_CID_EXPOSURE,
110 .type = V4L2_CTRL_TYPE_INTEGER, 151 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -117,7 +158,36 @@ const static struct ctrl s5k4aa_ctrls[] = {
117 }, 158 },
118 .set = s5k4aa_set_exposure, 159 .set = s5k4aa_set_exposure,
119 .get = s5k4aa_get_exposure 160 .get = s5k4aa_get_exposure
120 } 161 },
162#define NOISE_SUPP_IDX 4
163 {
164 {
165 .id = V4L2_CID_PRIVATE_BASE,
166 .type = V4L2_CTRL_TYPE_BOOLEAN,
167 .name = "Noise suppression (smoothing)",
168 .minimum = 0,
169 .maximum = 1,
170 .step = 1,
171 .default_value = 1,
172 },
173 .set = s5k4aa_set_noise,
174 .get = s5k4aa_get_noise
175 },
176#define BRIGHTNESS_IDX 5
177 {
178 {
179 .id = V4L2_CID_BRIGHTNESS,
180 .type = V4L2_CTRL_TYPE_INTEGER,
181 .name = "Brightness",
182 .minimum = 0,
183 .maximum = 0x1f,
184 .step = 1,
185 .default_value = S5K4AA_DEFAULT_BRIGHTNESS,
186 },
187 .set = s5k4aa_set_brightness,
188 .get = s5k4aa_get_brightness
189 },
190
121}; 191};
122 192
123static void s5k4aa_dump_registers(struct sd *sd); 193static void s5k4aa_dump_registers(struct sd *sd);
@@ -127,6 +197,7 @@ int s5k4aa_probe(struct sd *sd)
127 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 197 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
128 const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; 198 const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
129 int i, err = 0; 199 int i, err = 0;
200 s32 *sensor_settings;
130 201
131 if (force_sensor) { 202 if (force_sensor) {
132 if (force_sensor == S5K4AA_SENSOR) { 203 if (force_sensor == S5K4AA_SENSOR) {
@@ -185,10 +256,20 @@ int s5k4aa_probe(struct sd *sd)
185 info("Detected a s5k4aa sensor"); 256 info("Detected a s5k4aa sensor");
186 257
187sensor_found: 258sensor_found:
259 sensor_settings = kmalloc(
260 ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL);
261 if (!sensor_settings)
262 return -ENOMEM;
263
188 sd->gspca_dev.cam.cam_mode = s5k4aa_modes; 264 sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
189 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); 265 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
190 sd->desc->ctrls = s5k4aa_ctrls; 266 sd->desc->ctrls = s5k4aa_ctrls;
191 sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); 267 sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
268
269 for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++)
270 sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
271 sd->sensor_priv = sensor_settings;
272
192 return 0; 273 return 0;
193} 274}
194 275
@@ -197,9 +278,45 @@ int s5k4aa_start(struct sd *sd)
197 int i, err = 0; 278 int i, err = 0;
198 u8 data[2]; 279 u8 data[2];
199 struct cam *cam = &sd->gspca_dev.cam; 280 struct cam *cam = &sd->gspca_dev.cam;
281 s32 *sensor_settings = sd->sensor_priv;
282
283 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
284 case 1280:
285 PDEBUG(D_V4L2, "Configuring camera for SXGA mode");
286
287 for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
288 switch (SXGA_s5k4aa[i][0]) {
289 case BRIDGE:
290 err = m5602_write_bridge(sd,
291 SXGA_s5k4aa[i][1],
292 SXGA_s5k4aa[i][2]);
293 break;
294
295 case SENSOR:
296 data[0] = SXGA_s5k4aa[i][2];
297 err = m5602_write_sensor(sd,
298 SXGA_s5k4aa[i][1],
299 data, 1);
300 break;
301
302 case SENSOR_LONG:
303 data[0] = SXGA_s5k4aa[i][2];
304 data[1] = SXGA_s5k4aa[i][3];
305 err = m5602_write_sensor(sd,
306 SXGA_s5k4aa[i][1],
307 data, 2);
308 break;
309
310 default:
311 err("Invalid stream command, exiting init");
312 return -EINVAL;
313 }
314 }
315 err = s5k4aa_set_noise(&sd->gspca_dev, 0);
316 if (err < 0)
317 return err;
318 break;
200 319
201 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
202 {
203 case 640: 320 case 640:
204 PDEBUG(D_V4L2, "Configuring camera for VGA mode"); 321 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
205 322
@@ -231,8 +348,37 @@ int s5k4aa_start(struct sd *sd)
231 return -EINVAL; 348 return -EINVAL;
232 } 349 }
233 } 350 }
351 err = s5k4aa_set_noise(&sd->gspca_dev, 1);
352 if (err < 0)
353 return err;
354 break;
234 } 355 }
235 return err; 356 if (err < 0)
357 return err;
358
359 err = s5k4aa_set_exposure(&sd->gspca_dev,
360 sensor_settings[EXPOSURE_IDX]);
361 if (err < 0)
362 return err;
363
364 err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
365 if (err < 0)
366 return err;
367
368 err = s5k4aa_set_brightness(&sd->gspca_dev,
369 sensor_settings[BRIGHTNESS_IDX]);
370 if (err < 0)
371 return err;
372
373 err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
374 if (err < 0)
375 return err;
376
377 err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
378 if (err < 0)
379 return err;
380
381 return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
236} 382}
237 383
238int s5k4aa_init(struct sd *sd) 384int s5k4aa_init(struct sd *sd)
@@ -270,62 +416,28 @@ int s5k4aa_init(struct sd *sd)
270 if (dump_sensor) 416 if (dump_sensor)
271 s5k4aa_dump_registers(sd); 417 s5k4aa_dump_registers(sd);
272 418
273 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { 419 return err;
274 u8 data = 0x02;
275 info("vertical flip quirk active");
276 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
277 m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
278 data |= S5K4AA_RM_V_FLIP;
279 data &= ~S5K4AA_RM_H_FLIP;
280 m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
281
282 /* Decrement COLSTART to preserve color order (BGGR) */
283 m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
284 data--;
285 m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
286
287 /* Increment ROWSTART to preserve color order (BGGR) */
288 m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
289 data++;
290 m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
291 }
292
293 return (err < 0) ? err : 0;
294}
295
296int s5k4aa_power_down(struct sd *sd)
297{
298 return 0;
299} 420}
300 421
301int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 422static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
302{ 423{
303 struct sd *sd = (struct sd *) gspca_dev; 424 struct sd *sd = (struct sd *) gspca_dev;
304 u8 data = S5K4AA_PAGE_MAP_2; 425 s32 *sensor_settings = sd->sensor_priv;
305 int err;
306
307 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
308 if (err < 0)
309 return err;
310 426
311 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 427 *val = sensor_settings[EXPOSURE_IDX];
312 if (err < 0)
313 return err;
314
315 *val = data << 8;
316 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
317 *val |= data;
318 PDEBUG(D_V4L2, "Read exposure %d", *val); 428 PDEBUG(D_V4L2, "Read exposure %d", *val);
319 429
320 return err; 430 return 0;
321} 431}
322 432
323int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 433static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
324{ 434{
325 struct sd *sd = (struct sd *) gspca_dev; 435 struct sd *sd = (struct sd *) gspca_dev;
436 s32 *sensor_settings = sd->sensor_priv;
326 u8 data = S5K4AA_PAGE_MAP_2; 437 u8 data = S5K4AA_PAGE_MAP_2;
327 int err; 438 int err;
328 439
440 sensor_settings[EXPOSURE_IDX] = val;
329 PDEBUG(D_V4L2, "Set exposure to %d", val); 441 PDEBUG(D_V4L2, "Set exposure to %d", val);
330 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 442 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
331 if (err < 0) 443 if (err < 0)
@@ -340,29 +452,26 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
340 return err; 452 return err;
341} 453}
342 454
343int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 455static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
344{ 456{
345 struct sd *sd = (struct sd *) gspca_dev; 457 struct sd *sd = (struct sd *) gspca_dev;
346 u8 data = S5K4AA_PAGE_MAP_2; 458 s32 *sensor_settings = sd->sensor_priv;
347 int err;
348
349 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
350 if (err < 0)
351 return err;
352 459
353 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 460 *val = sensor_settings[VFLIP_IDX];
354 *val = (data & S5K4AA_RM_V_FLIP) >> 7;
355 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 461 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
356 462
357 return err; 463 return 0;
358} 464}
359 465
360int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 466static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
361{ 467{
362 struct sd *sd = (struct sd *) gspca_dev; 468 struct sd *sd = (struct sd *) gspca_dev;
469 s32 *sensor_settings = sd->sensor_priv;
363 u8 data = S5K4AA_PAGE_MAP_2; 470 u8 data = S5K4AA_PAGE_MAP_2;
364 int err; 471 int err;
365 472
473 sensor_settings[VFLIP_IDX] = val;
474
366 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 475 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
367 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 476 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
368 if (err < 0) 477 if (err < 0)
@@ -370,56 +479,48 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
370 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 479 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
371 if (err < 0) 480 if (err < 0)
372 return err; 481 return err;
373 data = ((data & ~S5K4AA_RM_V_FLIP) 482
374 | ((val & 0x01) << 7)); 483 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
375 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
376 if (err < 0) 484 if (err < 0)
377 return err; 485 return err;
378 486
379 if (val) { 487 if (dmi_check_system(s5k4aa_vflip_dmi_table))
380 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 488 val = !val;
381 if (err < 0)
382 return err;
383
384 data++;
385 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
386 } else {
387 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
388 if (err < 0)
389 return err;
390 489
391 data--; 490 data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7));
392 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 491 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
393 } 492 if (err < 0)
493 return err;
394 494
495 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
496 if (err < 0)
497 return err;
498 data = (data & 0xfe) | !val;
499 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
395 return err; 500 return err;
396} 501}
397 502
398int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 503static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
399{ 504{
400 struct sd *sd = (struct sd *) gspca_dev; 505 struct sd *sd = (struct sd *) gspca_dev;
401 u8 data = S5K4AA_PAGE_MAP_2; 506 s32 *sensor_settings = sd->sensor_priv;
402 int err;
403
404 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
405 if (err < 0)
406 return err;
407 507
408 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 508 *val = sensor_settings[HFLIP_IDX];
409 *val = (data & S5K4AA_RM_H_FLIP) >> 6;
410 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 509 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
411 510
412 return err; 511 return 0;
413} 512}
414 513
415int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 514static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
416{ 515{
417 struct sd *sd = (struct sd *) gspca_dev; 516 struct sd *sd = (struct sd *) gspca_dev;
517 s32 *sensor_settings = sd->sensor_priv;
418 u8 data = S5K4AA_PAGE_MAP_2; 518 u8 data = S5K4AA_PAGE_MAP_2;
419 int err; 519 int err;
420 520
421 PDEBUG(D_V4L2, "Set horizontal flip to %d", 521 sensor_settings[HFLIP_IDX] = val;
422 val); 522
523 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
423 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 524 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
424 if (err < 0) 525 if (err < 0)
425 return err; 526 return err;
@@ -427,62 +528,116 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
427 if (err < 0) 528 if (err < 0)
428 return err; 529 return err;
429 530
531 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
532 if (err < 0)
533 return err;
534
535 if (dmi_check_system(s5k4aa_vflip_dmi_table))
536 val = !val;
537
430 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); 538 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
431 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 539 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
432 if (err < 0) 540 if (err < 0)
433 return err; 541 return err;
434 542
435 if (val) { 543 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
436 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 544 if (err < 0)
437 if (err < 0) 545 return err;
438 return err; 546 data = (data & 0xfe) | !val;
439 data++; 547 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
440 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
441 if (err < 0)
442 return err;
443 } else {
444 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
445 if (err < 0)
446 return err;
447 data--;
448 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
449 }
450
451 return err; 548 return err;
452} 549}
453 550
454int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 551static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
552{
553 struct sd *sd = (struct sd *) gspca_dev;
554 s32 *sensor_settings = sd->sensor_priv;
555
556 *val = sensor_settings[GAIN_IDX];
557 PDEBUG(D_V4L2, "Read gain %d", *val);
558 return 0;
559}
560
561static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
455{ 562{
456 struct sd *sd = (struct sd *) gspca_dev; 563 struct sd *sd = (struct sd *) gspca_dev;
564 s32 *sensor_settings = sd->sensor_priv;
457 u8 data = S5K4AA_PAGE_MAP_2; 565 u8 data = S5K4AA_PAGE_MAP_2;
458 int err; 566 int err;
459 567
568 sensor_settings[GAIN_IDX] = val;
569
570 PDEBUG(D_V4L2, "Set gain to %d", val);
460 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 571 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
461 if (err < 0) 572 if (err < 0)
462 return err; 573 return err;
463 574
464 err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); 575 data = val & 0xff;
465 *val = data; 576 err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1);
466 PDEBUG(D_V4L2, "Read gain %d", *val);
467 577
468 return err; 578 return err;
469} 579}
470 580
471int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) 581static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
582{
583 struct sd *sd = (struct sd *) gspca_dev;
584 s32 *sensor_settings = sd->sensor_priv;
585
586 *val = sensor_settings[BRIGHTNESS_IDX];
587 PDEBUG(D_V4L2, "Read brightness %d", *val);
588 return 0;
589}
590
591static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
472{ 592{
473 struct sd *sd = (struct sd *) gspca_dev; 593 struct sd *sd = (struct sd *) gspca_dev;
594 s32 *sensor_settings = sd->sensor_priv;
474 u8 data = S5K4AA_PAGE_MAP_2; 595 u8 data = S5K4AA_PAGE_MAP_2;
475 int err; 596 int err;
476 597
477 PDEBUG(D_V4L2, "Set gain to %d", val); 598 sensor_settings[BRIGHTNESS_IDX] = val;
599
600 PDEBUG(D_V4L2, "Set brightness to %d", val);
478 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 601 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
479 if (err < 0) 602 if (err < 0)
480 return err; 603 return err;
481 604
482 data = val & 0xff; 605 data = val & 0xff;
483 err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); 606 return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1);
607}
484 608
485 return err; 609static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val)
610{
611 struct sd *sd = (struct sd *) gspca_dev;
612 s32 *sensor_settings = sd->sensor_priv;
613
614 *val = sensor_settings[NOISE_SUPP_IDX];
615 PDEBUG(D_V4L2, "Read noise %d", *val);
616 return 0;
617}
618
619static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
620{
621 struct sd *sd = (struct sd *) gspca_dev;
622 s32 *sensor_settings = sd->sensor_priv;
623 u8 data = S5K4AA_PAGE_MAP_2;
624 int err;
625
626 sensor_settings[NOISE_SUPP_IDX] = val;
627
628 PDEBUG(D_V4L2, "Set noise to %d", val);
629 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
630 if (err < 0)
631 return err;
632
633 data = val & 0x01;
634 return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1);
635}
636
637void s5k4aa_disconnect(struct sd *sd)
638{
639 sd->sensor = NULL;
640 kfree(sd->sensor_priv);
486} 641}
487 642
488static void s5k4aa_dump_registers(struct sd *sd) 643static void s5k4aa_dump_registers(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index ca854d4f9475..4440da4e7f0f 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -47,8 +47,9 @@
47#define S5K4AA_H_BLANK_LO__ 0x1e 47#define S5K4AA_H_BLANK_LO__ 0x1e
48#define S5K4AA_EXPOSURE_HI 0x17 48#define S5K4AA_EXPOSURE_HI 0x17
49#define S5K4AA_EXPOSURE_LO 0x18 49#define S5K4AA_EXPOSURE_LO 0x18
50#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ 50#define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */
51#define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ 51#define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */
52#define S5K4AA_NOISE_SUPP 0x37
52 53
53#define S5K4AA_RM_ROW_SKIP_4X 0x08 54#define S5K4AA_RM_ROW_SKIP_4X 0x08
54#define S5K4AA_RM_ROW_SKIP_2X 0x04 55#define S5K4AA_RM_ROW_SKIP_2X 0x04
@@ -57,6 +58,9 @@
57#define S5K4AA_RM_H_FLIP 0x40 58#define S5K4AA_RM_H_FLIP 0x40
58#define S5K4AA_RM_V_FLIP 0x80 59#define S5K4AA_RM_V_FLIP 0x80
59 60
61#define S5K4AA_DEFAULT_GAIN 0x5f
62#define S5K4AA_DEFAULT_BRIGHTNESS 0x10
63
60/*****************************************************************************/ 64/*****************************************************************************/
61 65
62/* Kernel module parameters */ 66/* Kernel module parameters */
@@ -66,25 +70,17 @@ extern int dump_sensor;
66int s5k4aa_probe(struct sd *sd); 70int s5k4aa_probe(struct sd *sd);
67int s5k4aa_init(struct sd *sd); 71int s5k4aa_init(struct sd *sd);
68int s5k4aa_start(struct sd *sd); 72int s5k4aa_start(struct sd *sd);
69int s5k4aa_power_down(struct sd *sd); 73void s5k4aa_disconnect(struct sd *sd);
70
71int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
72int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
73int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
74int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
75int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
76int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
77int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
78int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
79 74
80static const struct m5602_sensor s5k4aa = { 75static const struct m5602_sensor s5k4aa = {
81 .name = "S5K4AA", 76 .name = "S5K4AA",
77 .i2c_slave_id = 0x5a,
78 .i2c_regW = 2,
79
82 .probe = s5k4aa_probe, 80 .probe = s5k4aa_probe,
83 .init = s5k4aa_init, 81 .init = s5k4aa_init,
84 .start = s5k4aa_start, 82 .start = s5k4aa_start,
85 .power_down = s5k4aa_power_down, 83 .disconnect = s5k4aa_disconnect,
86 .i2c_slave_id = 0x5a,
87 .i2c_regW = 2,
88}; 84};
89 85
90static const unsigned char preinit_s5k4aa[][4] = 86static const unsigned char preinit_s5k4aa[][4] =
@@ -179,30 +175,12 @@ static const unsigned char init_s5k4aa[][4] =
179 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 175 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
180 {SENSOR, 0x0c, 0x05, 0x00}, 176 {SENSOR, 0x0c, 0x05, 0x00},
181 {SENSOR, 0x02, 0x0e, 0x00}, 177 {SENSOR, 0x02, 0x0e, 0x00},
182 {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00},
183 {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00},
184 {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00},
185 {SENSOR, 0x11, 0x00, 0x00},
186 {SENSOR, 0x12, 0x00, 0x00},
187 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
188 {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, 178 {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
189 {SENSOR, 0x37, 0x00, 0x00}, 179 {SENSOR, 0x37, 0x00, 0x00},
190 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, 180};
191 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
192 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
193 {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
194 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
195 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00},
196 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
197 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00},
198 {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
199 {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00},
200 {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00},
201 {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00},
202 {SENSOR, 0x11, 0x04, 0x00},
203 {SENSOR, 0x12, 0xc3, 0x00},
204 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
205 181
182static const unsigned char VGA_s5k4aa[][4] =
183{
206 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 184 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
207 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 185 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
208 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 186 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -238,7 +216,7 @@ static const unsigned char init_s5k4aa[][4] =
238 {SENSOR, 0x37, 0x01, 0x00}, 216 {SENSOR, 0x37, 0x01, 0x00},
239 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ 217 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
240 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, 218 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
241 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, 219 {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
242 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, 220 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
243 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, 221 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
244 /* window_height_hi, window_height_lo : 960 = 0x03c0 */ 222 /* window_height_hi, window_height_lo : 960 = 0x03c0 */
@@ -255,12 +233,9 @@ static const unsigned char init_s5k4aa[][4] =
255 {SENSOR, 0x12, 0xc3, 0x00}, 233 {SENSOR, 0x12, 0xc3, 0x00},
256 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 234 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
257 {SENSOR, 0x02, 0x0e, 0x00}, 235 {SENSOR, 0x02, 0x0e, 0x00},
258 {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
259 {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
260 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
261}; 236};
262 237
263static const unsigned char VGA_s5k4aa[][4] = 238static const unsigned char SXGA_s5k4aa[][4] =
264{ 239{
265 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 240 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
266 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 241 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
@@ -273,50 +248,42 @@ static const unsigned char VGA_s5k4aa[][4] =
273 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 248 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
274 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 249 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
275 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
276 /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ 251 /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
277 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, 252 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
278 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, 253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
279 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
280 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
281 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 256 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
282 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, 257 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
283 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 258 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
284 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 259 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
285 /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ 260 /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
286 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 261 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
287 {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, 262 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
288 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 263 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
289 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 264 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
290 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ 265 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
291 266
292 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 267 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
293 {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X 268 {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
294 | S5K4AA_RM_COL_SKIP_2X, 0x00},
295 /* 0x37 : Fix image stability when light is too bright and improves
296 * image quality in 640x480, but worsens it in 1280x1024 */
297 {SENSOR, 0x37, 0x01, 0x00}, 269 {SENSOR, 0x37, 0x01, 0x00},
298 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
299 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, 270 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
300 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, 271 {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
301 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, 272 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
302 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, 273 {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
303 /* window_height_hi, window_height_lo : 960 = 0x03c0 */ 274 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
304 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, 275 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
305 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
306 /* window_width_hi, window_width_lo : 1280 = 0x0500 */
307 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, 276 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
308 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, 277 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
309 {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, 278 {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
310 {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ 279 {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
311 {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, 280 {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
312 {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, 281 {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
313 {SENSOR, 0x11, 0x04, 0x00}, 282 {SENSOR, 0x11, 0x04, 0x00},
314 {SENSOR, 0x12, 0xc3, 0x00}, 283 {SENSOR, 0x12, 0xc3, 0x00},
315 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 284 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
316 {SENSOR, 0x02, 0x0e, 0x00}, 285 {SENSOR, 0x02, 0x0e, 0x00},
317 {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
318 {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
319 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
320}; 286};
321 287
288
322#endif 289#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 42c86aa4dc8d..7127321ace8c 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -16,8 +16,20 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/kthread.h>
19#include "m5602_s5k83a.h" 20#include "m5602_s5k83a.h"
20 21
22static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
25static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
26static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
27static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
28static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
29static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
30static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
31static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
32
21static struct v4l2_pix_format s5k83a_modes[] = { 33static struct v4l2_pix_format s5k83a_modes[] = {
22 { 34 {
23 640, 35 640,
@@ -32,68 +44,77 @@ static struct v4l2_pix_format s5k83a_modes[] = {
32 } 44 }
33}; 45};
34 46
35const static struct ctrl s5k83a_ctrls[] = { 47static const struct ctrl s5k83a_ctrls[] = {
48#define GAIN_IDX 0
36 { 49 {
37 { 50 {
38 .id = V4L2_CID_BRIGHTNESS, 51 .id = V4L2_CID_GAIN,
39 .type = V4L2_CTRL_TYPE_INTEGER, 52 .type = V4L2_CTRL_TYPE_INTEGER,
40 .name = "brightness", 53 .name = "gain",
41 .minimum = 0x00, 54 .minimum = 0x00,
42 .maximum = 0xff, 55 .maximum = 0xff,
43 .step = 0x01, 56 .step = 0x01,
44 .default_value = S5K83A_DEFAULT_BRIGHTNESS, 57 .default_value = S5K83A_DEFAULT_GAIN,
45 .flags = V4L2_CTRL_FLAG_SLIDER 58 .flags = V4L2_CTRL_FLAG_SLIDER
46 }, 59 },
47 .set = s5k83a_set_brightness, 60 .set = s5k83a_set_gain,
48 .get = s5k83a_get_brightness 61 .get = s5k83a_get_gain
49 62
50 }, { 63 },
64#define BRIGHTNESS_IDX 1
65 {
51 { 66 {
52 .id = V4L2_CID_WHITENESS, 67 .id = V4L2_CID_BRIGHTNESS,
53 .type = V4L2_CTRL_TYPE_INTEGER, 68 .type = V4L2_CTRL_TYPE_INTEGER,
54 .name = "whiteness", 69 .name = "brightness",
55 .minimum = 0x00, 70 .minimum = 0x00,
56 .maximum = 0xff, 71 .maximum = 0xff,
57 .step = 0x01, 72 .step = 0x01,
58 .default_value = S5K83A_DEFAULT_WHITENESS, 73 .default_value = S5K83A_DEFAULT_BRIGHTNESS,
59 .flags = V4L2_CTRL_FLAG_SLIDER 74 .flags = V4L2_CTRL_FLAG_SLIDER
60 }, 75 },
61 .set = s5k83a_set_whiteness, 76 .set = s5k83a_set_brightness,
62 .get = s5k83a_get_whiteness, 77 .get = s5k83a_get_brightness,
63 }, { 78 },
79#define EXPOSURE_IDX 2
80 {
64 { 81 {
65 .id = V4L2_CID_GAIN, 82 .id = V4L2_CID_EXPOSURE,
66 .type = V4L2_CTRL_TYPE_INTEGER, 83 .type = V4L2_CTRL_TYPE_INTEGER,
67 .name = "gain", 84 .name = "exposure",
68 .minimum = 0x00, 85 .minimum = 0x00,
69 .maximum = S5K83A_MAXIMUM_GAIN, 86 .maximum = S5K83A_MAXIMUM_EXPOSURE,
70 .step = 0x01, 87 .step = 0x01,
71 .default_value = S5K83A_DEFAULT_GAIN, 88 .default_value = S5K83A_DEFAULT_EXPOSURE,
72 .flags = V4L2_CTRL_FLAG_SLIDER 89 .flags = V4L2_CTRL_FLAG_SLIDER
73 }, 90 },
74 .set = s5k83a_set_gain, 91 .set = s5k83a_set_exposure,
75 .get = s5k83a_get_gain 92 .get = s5k83a_get_exposure
76 }, { 93 },
94#define HFLIP_IDX 3
95 {
77 { 96 {
78 .id = V4L2_CID_HFLIP, 97 .id = V4L2_CID_HFLIP,
79 .type = V4L2_CTRL_TYPE_BOOLEAN, 98 .type = V4L2_CTRL_TYPE_BOOLEAN,
80 .name = "horizontal flip", 99 .name = "horizontal flip",
81 .minimum = 0, 100 .minimum = 0,
82 .maximum = 1, 101 .maximum = 1,
83 .step = 1, 102 .step = 1,
84 .default_value = 0 103 .default_value = 0
85 }, 104 },
86 .set = s5k83a_set_hflip, 105 .set = s5k83a_set_hflip,
87 .get = s5k83a_get_hflip 106 .get = s5k83a_get_hflip
88 }, { 107 },
108#define VFLIP_IDX 4
109 {
89 { 110 {
90 .id = V4L2_CID_VFLIP, 111 .id = V4L2_CID_VFLIP,
91 .type = V4L2_CTRL_TYPE_BOOLEAN, 112 .type = V4L2_CTRL_TYPE_BOOLEAN,
92 .name = "vertical flip", 113 .name = "vertical flip",
93 .minimum = 0, 114 .minimum = 0,
94 .maximum = 1, 115 .maximum = 1,
95 .step = 1, 116 .step = 1,
96 .default_value = 0 117 .default_value = 0
97 }, 118 },
98 .set = s5k83a_set_vflip, 119 .set = s5k83a_set_vflip,
99 .get = s5k83a_get_vflip 120 .get = s5k83a_get_vflip
@@ -101,9 +122,14 @@ const static struct ctrl s5k83a_ctrls[] = {
101}; 122};
102 123
103static void s5k83a_dump_registers(struct sd *sd); 124static void s5k83a_dump_registers(struct sd *sd);
125static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
126static int s5k83a_set_led_indication(struct sd *sd, u8 val);
127static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
128 __s32 vflip, __s32 hflip);
104 129
105int s5k83a_probe(struct sd *sd) 130int s5k83a_probe(struct sd *sd)
106{ 131{
132 struct s5k83a_priv *sens_priv;
107 u8 prod_id = 0, ver_id = 0; 133 u8 prod_id = 0, ver_id = 0;
108 int i, err = 0; 134 int i, err = 0;
109 135
@@ -145,16 +171,36 @@ int s5k83a_probe(struct sd *sd)
145 info("Detected a s5k83a sensor"); 171 info("Detected a s5k83a sensor");
146 172
147sensor_found: 173sensor_found:
174 sens_priv = kmalloc(
175 sizeof(struct s5k83a_priv), GFP_KERNEL);
176 if (!sens_priv)
177 return -ENOMEM;
178
179 sens_priv->settings =
180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181 if (!sens_priv->settings)
182 return -ENOMEM;
183
148 sd->gspca_dev.cam.cam_mode = s5k83a_modes; 184 sd->gspca_dev.cam.cam_mode = s5k83a_modes;
149 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); 185 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
150 sd->desc->ctrls = s5k83a_ctrls; 186 sd->desc->ctrls = s5k83a_ctrls;
151 sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); 187 sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
188
189 /* null the pointer! thread is't running now */
190 sens_priv->rotation_thread = NULL;
191
192 for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
193 sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
194
195 sd->sensor_priv = sens_priv;
152 return 0; 196 return 0;
153} 197}
154 198
155int s5k83a_init(struct sd *sd) 199int s5k83a_init(struct sd *sd)
156{ 200{
157 int i, err = 0; 201 int i, err = 0;
202 s32 *sensor_settings =
203 ((struct s5k83a_priv *) sd->sensor_priv)->settings;
158 204
159 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { 205 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
160 u8 data[2] = {0x00, 0x00}; 206 u8 data[2] = {0x00, 0x00};
@@ -187,87 +233,138 @@ int s5k83a_init(struct sd *sd)
187 if (dump_sensor) 233 if (dump_sensor)
188 s5k83a_dump_registers(sd); 234 s5k83a_dump_registers(sd);
189 235
190 return (err < 0) ? err : 0; 236 err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
191} 237 if (err < 0)
238 return err;
192 239
193int s5k83a_start(struct sd *sd) 240 err = s5k83a_set_brightness(&sd->gspca_dev,
194{ 241 sensor_settings[BRIGHTNESS_IDX]);
195 return s5k83a_set_led_indication(sd, 1); 242 if (err < 0)
196} 243 return err;
197 244
198int s5k83a_stop(struct sd *sd) 245 err = s5k83a_set_exposure(&sd->gspca_dev,
199{ 246 sensor_settings[EXPOSURE_IDX]);
200 return s5k83a_set_led_indication(sd, 0); 247 if (err < 0)
248 return err;
249
250 err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
251 if (err < 0)
252 return err;
253
254 err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
255
256 return err;
201} 257}
202 258
203int s5k83a_power_down(struct sd *sd) 259static int rotation_thread_function(void *data)
204{ 260{
261 struct sd *sd = (struct sd *) data;
262 struct s5k83a_priv *sens_priv = sd->sensor_priv;
263 u8 reg, previous_rotation = 0;
264 __s32 vflip, hflip;
265
266 set_current_state(TASK_INTERRUPTIBLE);
267 while (!schedule_timeout(100)) {
268 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
269 break;
270
271 s5k83a_get_rotation(sd, &reg);
272 if (previous_rotation != reg) {
273 previous_rotation = reg;
274 info("Camera was flipped");
275
276 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
277 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
278
279 if (reg) {
280 vflip = !vflip;
281 hflip = !hflip;
282 }
283 s5k83a_set_flip_real((struct gspca_dev *) sd,
284 vflip, hflip);
285 }
286
287 mutex_unlock(&sd->gspca_dev.usb_lock);
288 set_current_state(TASK_INTERRUPTIBLE);
289 }
290
291 /* return to "front" flip */
292 if (previous_rotation) {
293 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
294 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
295 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
296 }
297
298 sens_priv->rotation_thread = NULL;
205 return 0; 299 return 0;
206} 300}
207 301
208static void s5k83a_dump_registers(struct sd *sd) 302int s5k83a_start(struct sd *sd)
209{ 303{
210 int address; 304 int i, err = 0;
211 u8 page, old_page; 305 struct s5k83a_priv *sens_priv = sd->sensor_priv;
212 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
213 306
214 for (page = 0; page < 16; page++) { 307 /* Create another thread, polling the GPIO ports of the camera to check
215 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 308 if it got rotated. This is how the windows driver does it so we have
216 info("Dumping the s5k83a register state for page 0x%x", page); 309 to assume that there is no better way of accomplishing this */
217 for (address = 0; address <= 0xff; address++) { 310 sens_priv->rotation_thread = kthread_create(rotation_thread_function,
218 u8 val = 0; 311 sd, "rotation thread");
219 m5602_read_sensor(sd, address, &val, 1); 312 wake_up_process(sens_priv->rotation_thread);
220 info("register 0x%x contains 0x%x", 313
221 address, val); 314 /* Preinit the sensor */
222 } 315 for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
316 u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
317 if (start_s5k83a[i][0] == SENSOR)
318 err = m5602_write_sensor(sd, start_s5k83a[i][1],
319 data, 2);
320 else
321 err = m5602_write_bridge(sd, start_s5k83a[i][1],
322 data[0]);
223 } 323 }
224 info("s5k83a register state dump complete"); 324 if (err < 0)
325 return err;
225 326
226 for (page = 0; page < 16; page++) { 327 return s5k83a_set_led_indication(sd, 1);
227 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 328}
228 info("Probing for which registers that are read/write "
229 "for page 0x%x", page);
230 for (address = 0; address <= 0xff; address++) {
231 u8 old_val, ctrl_val, test_val = 0xff;
232 329
233 m5602_read_sensor(sd, address, &old_val, 1); 330int s5k83a_stop(struct sd *sd)
234 m5602_write_sensor(sd, address, &test_val, 1); 331{
235 m5602_read_sensor(sd, address, &ctrl_val, 1); 332 struct s5k83a_priv *sens_priv = sd->sensor_priv;
236 333
237 if (ctrl_val == test_val) 334 if (sens_priv->rotation_thread)
238 info("register 0x%x is writeable", address); 335 kthread_stop(sens_priv->rotation_thread);
239 else
240 info("register 0x%x is read only", address);
241 336
242 /* Restore original val */ 337 return s5k83a_set_led_indication(sd, 0);
243 m5602_write_sensor(sd, address, &old_val, 1);
244 }
245 }
246 info("Read/write register probing complete");
247 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
248} 338}
249 339
250int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 340void s5k83a_disconnect(struct sd *sd)
251{ 341{
252 int err; 342 struct s5k83a_priv *sens_priv = sd->sensor_priv;
253 u8 data[2];
254 struct sd *sd = (struct sd *) gspca_dev;
255 343
256 err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 344 s5k83a_stop(sd);
257 if (err < 0) 345
258 return err; 346 sd->sensor = NULL;
347 kfree(sens_priv->settings);
348 kfree(sens_priv);
349}
259 350
260 data[1] = data[1] << 1; 351static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
261 *val = data[1]; 352{
353 struct sd *sd = (struct sd *) gspca_dev;
354 struct s5k83a_priv *sens_priv = sd->sensor_priv;
262 355
263 return err; 356 *val = sens_priv->settings[GAIN_IDX];
357 return 0;
264} 358}
265 359
266int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 360static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
267{ 361{
268 int err; 362 int err;
269 u8 data[2]; 363 u8 data[2];
270 struct sd *sd = (struct sd *) gspca_dev; 364 struct sd *sd = (struct sd *) gspca_dev;
365 struct s5k83a_priv *sens_priv = sd->sensor_priv;
366
367 sens_priv->settings[GAIN_IDX] = val;
271 368
272 data[0] = 0x00; 369 data[0] = 0x00;
273 data[1] = 0x20; 370 data[1] = 0x20;
@@ -283,89 +380,69 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
283 380
284 /* FIXME: This is not sane, we need to figure out the composition 381 /* FIXME: This is not sane, we need to figure out the composition
285 of these registers */ 382 of these registers */
286 data[0] = val >> 3; /* brightness, high 5 bits */ 383 data[0] = val >> 3; /* gain, high 5 bits */
287 data[1] = val >> 1; /* brightness, high 7 bits */ 384 data[1] = val >> 1; /* gain, high 7 bits */
288 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 385 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
289 386
290 return err; 387 return err;
291} 388}
292 389
293int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) 390static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
294{ 391{
295 int err;
296 u8 data;
297 struct sd *sd = (struct sd *) gspca_dev; 392 struct sd *sd = (struct sd *) gspca_dev;
393 struct s5k83a_priv *sens_priv = sd->sensor_priv;
298 394
299 err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1); 395 *val = sens_priv->settings[BRIGHTNESS_IDX];
300 if (err < 0) 396 return 0;
301 return err;
302
303 *val = data;
304
305 return err;
306} 397}
307 398
308int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) 399static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
309{ 400{
310 int err; 401 int err;
311 u8 data[1]; 402 u8 data[1];
312 struct sd *sd = (struct sd *) gspca_dev; 403 struct sd *sd = (struct sd *) gspca_dev;
404 struct s5k83a_priv *sens_priv = sd->sensor_priv;
313 405
406 sens_priv->settings[BRIGHTNESS_IDX] = val;
314 data[0] = val; 407 data[0] = val;
315 err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1); 408 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
316
317 return err; 409 return err;
318} 410}
319 411
320int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 412static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
321{ 413{
322 int err;
323 u8 data[2];
324 struct sd *sd = (struct sd *) gspca_dev; 414 struct sd *sd = (struct sd *) gspca_dev;
415 struct s5k83a_priv *sens_priv = sd->sensor_priv;
325 416
326 err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2); 417 *val = sens_priv->settings[EXPOSURE_IDX];
327 if (err < 0) 418 return 0;
328 return err;
329
330 data[1] = data[1] & 0x3f;
331 if (data[1] > S5K83A_MAXIMUM_GAIN)
332 data[1] = S5K83A_MAXIMUM_GAIN;
333
334 *val = data[1];
335
336 return err;
337} 419}
338 420
339int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) 421static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
340{ 422{
341 int err; 423 int err;
342 u8 data[2]; 424 u8 data[2];
343 struct sd *sd = (struct sd *) gspca_dev; 425 struct sd *sd = (struct sd *) gspca_dev;
426 struct s5k83a_priv *sens_priv = sd->sensor_priv;
344 427
428 sens_priv->settings[EXPOSURE_IDX] = val;
345 data[0] = 0; 429 data[0] = 0;
346 data[1] = val; 430 data[1] = val;
347 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); 431 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
348 return err; 432 return err;
349} 433}
350 434
351int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 435static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
352{ 436{
353 int err;
354 u8 data[1];
355 struct sd *sd = (struct sd *) gspca_dev; 437 struct sd *sd = (struct sd *) gspca_dev;
438 struct s5k83a_priv *sens_priv = sd->sensor_priv;
356 439
357 data[0] = 0x05; 440 *val = sens_priv->settings[VFLIP_IDX];
358 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 441 return 0;
359 if (err < 0)
360 return err;
361
362 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
363 *val = (data[0] | 0x40) ? 1 : 0;
364
365 return err;
366} 442}
367 443
368int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 444static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
445 __s32 vflip, __s32 hflip)
369{ 446{
370 int err; 447 int err;
371 u8 data[1]; 448 u8 data[1];
@@ -376,69 +453,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
376 if (err < 0) 453 if (err < 0)
377 return err; 454 return err;
378 455
379 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); 456 /* six bit is vflip, seven is hflip */
380 if (err < 0) 457 data[0] = S5K83A_FLIP_MASK;
381 return err; 458 data[0] = (vflip) ? data[0] | 0x40 : data[0];
459 data[0] = (hflip) ? data[0] | 0x80 : data[0];
382 460
383 /* set or zero six bit, seven is hflip */
384 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
385 : (data[0] & 0x80) | S5K83A_FLIP_MASK;
386 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); 461 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
387 if (err < 0) 462 if (err < 0)
388 return err; 463 return err;
389 464
390 data[0] = (val) ? 0x0b : 0x0a; 465 data[0] = (vflip) ? 0x0b : 0x0a;
391 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); 466 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
467 if (err < 0)
468 return err;
392 469
470 data[0] = (hflip) ? 0x0a : 0x0b;
471 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
393 return err; 472 return err;
394} 473}
395 474
396int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 475static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
397{ 476{
398 int err; 477 int err;
399 u8 data[1]; 478 u8 reg;
479 __s32 hflip;
400 struct sd *sd = (struct sd *) gspca_dev; 480 struct sd *sd = (struct sd *) gspca_dev;
481 struct s5k83a_priv *sens_priv = sd->sensor_priv;
401 482
402 data[0] = 0x05; 483 sens_priv->settings[VFLIP_IDX] = val;
403 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 484
485 s5k83a_get_hflip(gspca_dev, &hflip);
486
487 err = s5k83a_get_rotation(sd, &reg);
404 if (err < 0) 488 if (err < 0)
405 return err; 489 return err;
490 if (reg) {
491 val = !val;
492 hflip = !hflip;
493 }
406 494
407 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); 495 err = s5k83a_set_flip_real(gspca_dev, val, hflip);
408 *val = (data[0] | 0x80) ? 1 : 0;
409
410 return err; 496 return err;
411} 497}
412 498
413int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 499static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
500{
501 struct sd *sd = (struct sd *) gspca_dev;
502 struct s5k83a_priv *sens_priv = sd->sensor_priv;
503
504 *val = sens_priv->settings[HFLIP_IDX];
505 return 0;
506}
507
508static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
414{ 509{
415 int err; 510 int err;
416 u8 data[1]; 511 u8 reg;
512 __s32 vflip;
417 struct sd *sd = (struct sd *) gspca_dev; 513 struct sd *sd = (struct sd *) gspca_dev;
514 struct s5k83a_priv *sens_priv = sd->sensor_priv;
418 515
419 data[0] = 0x05; 516 sens_priv->settings[HFLIP_IDX] = val;
420 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
421 if (err < 0)
422 return err;
423 517
424 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); 518 s5k83a_get_vflip(gspca_dev, &vflip);
425 if (err < 0)
426 return err;
427 519
428 /* set or zero seven bit, six is vflip */ 520 err = s5k83a_get_rotation(sd, &reg);
429 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
430 : (data[0] & 0x40) | S5K83A_FLIP_MASK;
431 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
432 if (err < 0) 521 if (err < 0)
433 return err; 522 return err;
523 if (reg) {
524 val = !val;
525 vflip = !vflip;
526 }
434 527
435 data[0] = (val) ? 0x0a : 0x0b; 528 err = s5k83a_set_flip_real(gspca_dev, vflip, val);
436 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
437
438 return err; 529 return err;
439} 530}
440 531
441int s5k83a_set_led_indication(struct sd *sd, u8 val) 532static int s5k83a_set_led_indication(struct sd *sd, u8 val)
442{ 533{
443 int err = 0; 534 int err = 0;
444 u8 data[1]; 535 u8 data[1];
@@ -454,5 +545,55 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val)
454 545
455 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); 546 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
456 547
457 return (err < 0) ? err : 0; 548 return err;
549}
550
551/* Get camera rotation on Acer notebooks */
552static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
553{
554 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
555 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
556 return err;
557}
558
559static void s5k83a_dump_registers(struct sd *sd)
560{
561 int address;
562 u8 page, old_page;
563 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
564
565 for (page = 0; page < 16; page++) {
566 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
567 info("Dumping the s5k83a register state for page 0x%x", page);
568 for (address = 0; address <= 0xff; address++) {
569 u8 val = 0;
570 m5602_read_sensor(sd, address, &val, 1);
571 info("register 0x%x contains 0x%x",
572 address, val);
573 }
574 }
575 info("s5k83a register state dump complete");
576
577 for (page = 0; page < 16; page++) {
578 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
579 info("Probing for which registers that are read/write "
580 "for page 0x%x", page);
581 for (address = 0; address <= 0xff; address++) {
582 u8 old_val, ctrl_val, test_val = 0xff;
583
584 m5602_read_sensor(sd, address, &old_val, 1);
585 m5602_write_sensor(sd, address, &test_val, 1);
586 m5602_read_sensor(sd, address, &ctrl_val, 1);
587
588 if (ctrl_val == test_val)
589 info("register 0x%x is writeable", address);
590 else
591 info("register 0x%x is read only", address);
592
593 /* Restore original val */
594 m5602_write_sensor(sd, address, &old_val, 1);
595 }
596 }
597 info("Read/write register probing complete");
598 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
458} 599}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 819ab25272be..7814b078acde 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -21,20 +21,21 @@
21 21
22#include "m5602_sensor.h" 22#include "m5602_sensor.h"
23 23
24#define S5K83A_FLIP 0x01 24#define S5K83A_FLIP 0x01
25#define S5K83A_HFLIP_TUNE 0x03 25#define S5K83A_HFLIP_TUNE 0x03
26#define S5K83A_VFLIP_TUNE 0x05 26#define S5K83A_VFLIP_TUNE 0x05
27#define S5K83A_WHITENESS 0x0a 27#define S5K83A_BRIGHTNESS 0x0a
28#define S5K83A_GAIN 0x18 28#define S5K83A_EXPOSURE 0x18
29#define S5K83A_BRIGHTNESS 0x1b 29#define S5K83A_GAIN 0x1b
30#define S5K83A_PAGE_MAP 0xec 30#define S5K83A_PAGE_MAP 0xec
31 31
32#define S5K83A_DEFAULT_BRIGHTNESS 0x71 32#define S5K83A_DEFAULT_GAIN 0x71
33#define S5K83A_DEFAULT_WHITENESS 0x7e 33#define S5K83A_DEFAULT_BRIGHTNESS 0x7e
34#define S5K83A_DEFAULT_GAIN 0x00 34#define S5K83A_DEFAULT_EXPOSURE 0x00
35#define S5K83A_MAXIMUM_GAIN 0x3c 35#define S5K83A_MAXIMUM_EXPOSURE 0x3c
36#define S5K83A_FLIP_MASK 0x10 36#define S5K83A_FLIP_MASK 0x10
37#define S5K83A_GPIO_LED_MASK 0x10 37#define S5K83A_GPIO_LED_MASK 0x10
38#define S5K83A_GPIO_ROTATION_MASK 0x40
38 39
39/*****************************************************************************/ 40/*****************************************************************************/
40 41
@@ -46,20 +47,7 @@ int s5k83a_probe(struct sd *sd);
46int s5k83a_init(struct sd *sd); 47int s5k83a_init(struct sd *sd);
47int s5k83a_start(struct sd *sd); 48int s5k83a_start(struct sd *sd);
48int s5k83a_stop(struct sd *sd); 49int s5k83a_stop(struct sd *sd);
49int s5k83a_power_down(struct sd *sd); 50void s5k83a_disconnect(struct sd *sd);
50
51int s5k83a_set_led_indication(struct sd *sd, u8 val);
52
53int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
54int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
55int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
56int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val);
57int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
58int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
59int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
60int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
61int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
62int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
63 51
64static const struct m5602_sensor s5k83a = { 52static const struct m5602_sensor s5k83a = {
65 .name = "S5K83A", 53 .name = "S5K83A",
@@ -67,11 +55,18 @@ static const struct m5602_sensor s5k83a = {
67 .init = s5k83a_init, 55 .init = s5k83a_init,
68 .start = s5k83a_start, 56 .start = s5k83a_start,
69 .stop = s5k83a_stop, 57 .stop = s5k83a_stop,
70 .power_down = s5k83a_power_down, 58 .disconnect = s5k83a_disconnect,
71 .i2c_slave_id = 0x5a, 59 .i2c_slave_id = 0x5a,
72 .i2c_regW = 2, 60 .i2c_regW = 2,
73}; 61};
74 62
63struct s5k83a_priv {
64 /* We use another thread periodically
65 probing the orientation of the camera */
66 struct task_struct *rotation_thread;
67 s32 *settings;
68};
69
75static const unsigned char preinit_s5k83a[][4] = 70static const unsigned char preinit_s5k83a[][4] =
76{ 71{
77 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, 72 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
@@ -108,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] =
108 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, 103 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
109 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, 104 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
110 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, 105 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
111
112 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}
113}; 106};
114 107
115/* This could probably be considerably shortened. 108/* This could probably be considerably shortened.
@@ -117,86 +110,8 @@ static const unsigned char preinit_s5k83a[][4] =
117*/ 110*/
118static const unsigned char init_s5k83a[][4] = 111static const unsigned char init_s5k83a[][4] =
119{ 112{
120 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, 113 /* The following sequence is useless after a clean boot
121 {SENSOR, 0xaf, 0x01, 0x00}, 114 but is necessary after resume from suspend */
122 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
123 {SENSOR, 0x7b, 0xff, 0x00},
124 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
125 {SENSOR, 0x01, 0x50, 0x00},
126 {SENSOR, 0x12, 0x20, 0x00},
127 {SENSOR, 0x17, 0x40, 0x00},
128 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
129 {SENSOR, 0x1c, 0x00, 0x00},
130 {SENSOR, 0x02, 0x70, 0x00},
131 {SENSOR, 0x03, 0x0b, 0x00},
132 {SENSOR, 0x04, 0xf0, 0x00},
133 {SENSOR, 0x05, 0x0b, 0x00},
134 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
135
136 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
137 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
138 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
139 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
140 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
141 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
142 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
143 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
144 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
145 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
146 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
147 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
148 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
149 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
150 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
151 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
152 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
153 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
154 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
155 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
156 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
157 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
158 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
159 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
160
161 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
162 {SENSOR, 0x06, 0x71, 0x00},
163 {SENSOR, 0x07, 0xe8, 0x00},
164 {SENSOR, 0x08, 0x02, 0x00},
165 {SENSOR, 0x09, 0x88, 0x00},
166 {SENSOR, 0x14, 0x00, 0x00},
167 {SENSOR, 0x15, 0x20, 0x00},
168 {SENSOR, 0x19, 0x00, 0x00},
169 {SENSOR, 0x1a, 0x98, 0x00},
170 {SENSOR, 0x0f, 0x02, 0x00},
171 {SENSOR, 0x10, 0xe5, 0x00},
172 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
173 {SENSOR_LONG, 0x14, 0x00, 0x20},
174 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
175 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
176
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
179 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
180 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
181 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
182 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
183 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
184 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
185 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
186 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
187 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
188 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
189 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
190 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
191 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
192 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
193 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
194 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
195 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
196 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
197 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
198
199 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
200 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, 115 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
201 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, 116 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
202 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, 117 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
@@ -216,7 +131,7 @@ static const unsigned char init_s5k83a[][4] =
216 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 131 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
217 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, 132 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
218 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, 133 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
219 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, 134 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
220 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, 135 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
221 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, 136 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
222 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, 137 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
@@ -225,109 +140,34 @@ static const unsigned char init_s5k83a[][4] =
225 140
226 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, 141 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
227 {SENSOR, 0xaf, 0x01, 0x00}, 142 {SENSOR, 0xaf, 0x01, 0x00},
228 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, 143 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
229 /* ff ( init value )is very dark) || 71 and f0 better */
230 {SENSOR, 0x7b, 0xff, 0x00}, 144 {SENSOR, 0x7b, 0xff, 0x00},
231 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, 145 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
232 {SENSOR, 0x01, 0x50, 0x00}, 146 {SENSOR, 0x01, 0x50, 0x00},
233 {SENSOR, 0x12, 0x20, 0x00}, 147 {SENSOR, 0x12, 0x20, 0x00},
234 {SENSOR, 0x17, 0x40, 0x00}, 148 {SENSOR, 0x17, 0x40, 0x00},
235 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
236 {SENSOR, 0x1c, 0x00, 0x00}, 149 {SENSOR, 0x1c, 0x00, 0x00},
237 {SENSOR, 0x02, 0x70, 0x00}, 150 {SENSOR, 0x02, 0x70, 0x00},
238 /* some values like 0x10 give a blue-purple image */
239 {SENSOR, 0x03, 0x0b, 0x00}, 151 {SENSOR, 0x03, 0x0b, 0x00},
240 {SENSOR, 0x04, 0xf0, 0x00}, 152 {SENSOR, 0x04, 0xf0, 0x00},
241 {SENSOR, 0x05, 0x0b, 0x00}, 153 {SENSOR, 0x05, 0x0b, 0x00},
242 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
243
244 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
245 /* under 80 don't work, highter depend on value */
246 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
247
248 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
249 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
250 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
251 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
252 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
257 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
258 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
259 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
260 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
261 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
262 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
263 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
264 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
265 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
266
267 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
268 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
269 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
270
271 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
272 {SENSOR, 0x06, 0x71, 0x00}, 154 {SENSOR, 0x06, 0x71, 0x00},
273 {SENSOR, 0x07, 0xe8, 0x00}, 155 {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
274 {SENSOR, 0x08, 0x02, 0x00}, 156 {SENSOR, 0x08, 0x02, 0x00},
275 {SENSOR, 0x09, 0x88, 0x00}, 157 {SENSOR, 0x09, 0x88, 0x00}, /* 648 */
276 {SENSOR, 0x14, 0x00, 0x00}, 158 {SENSOR, 0x14, 0x00, 0x00},
277 {SENSOR, 0x15, 0x20, 0x00}, 159 {SENSOR, 0x15, 0x20, 0x00}, /* 32 */
278 {SENSOR, 0x19, 0x00, 0x00}, 160 {SENSOR, 0x19, 0x00, 0x00},
279 {SENSOR, 0x1a, 0x98, 0x00}, 161 {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
280 {SENSOR, 0x0f, 0x02, 0x00}, 162 {SENSOR, 0x0f, 0x02, 0x00},
281 {SENSOR, 0x10, 0xe5, 0x00}, 163 {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
282 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, 164 /* normal colors
283 {SENSOR_LONG, 0x14, 0x00, 0x20}, 165 (this is value after boot, but after tries can be different) */
284 {SENSOR_LONG, 0x0d, 0x00, 0x7d}, 166 {SENSOR, 0x00, 0x06, 0x00},
285 {SENSOR_LONG, 0x1b, 0x0d, 0x05}, 167};
286
287 /* The following sequence is useless after a clean boot
288 but is necessary after resume from suspend */
289 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
290 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
291 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
292 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
293 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
294 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
295 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
296 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
297 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
298 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
299 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
300 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
301 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
302 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
303 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
304 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
305 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
306 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
307 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
308 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
309 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
310 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
311 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
312 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
313 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
314
315 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
316 {SENSOR, 0xaf, 0x01, 0x00},
317 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
318 {SENSOR, 0x7b, 0xff, 0x00},
319 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
320 {SENSOR, 0x01, 0x50, 0x00},
321 {SENSOR, 0x12, 0x20, 0x00},
322 {SENSOR, 0x17, 0x40, 0x00},
323 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
324 {SENSOR, 0x1c, 0x00, 0x00},
325 {SENSOR, 0x02, 0x70, 0x00},
326 {SENSOR, 0x03, 0x0b, 0x00},
327 {SENSOR, 0x04, 0xf0, 0x00},
328 {SENSOR, 0x05, 0x0b, 0x00},
329 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
330 168
169static const unsigned char start_s5k83a[][4] =
170{
331 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 171 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
332 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 172 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
333 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 173 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -340,7 +180,7 @@ static const unsigned char init_s5k83a[][4] =
340 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 180 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
341 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 181 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
342 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, 182 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
343 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, 183 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
344 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 184 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
345 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 185 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
346 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 186 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
@@ -348,50 +188,10 @@ static const unsigned char init_s5k83a[][4] =
348 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 188 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
349 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 189 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
350 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 190 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
351 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, 191 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
352 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 192 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
353 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 193 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
354 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 194 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
355
356 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
357 {SENSOR, 0x06, 0x71, 0x00},
358 {SENSOR, 0x07, 0xe8, 0x00},
359 {SENSOR, 0x08, 0x02, 0x00},
360 {SENSOR, 0x09, 0x88, 0x00},
361 {SENSOR, 0x14, 0x00, 0x00},
362 {SENSOR, 0x15, 0x20, 0x00},
363 {SENSOR, 0x19, 0x00, 0x00},
364 {SENSOR, 0x1a, 0x98, 0x00},
365 {SENSOR, 0x0f, 0x02, 0x00},
366
367 {SENSOR, 0x10, 0xe5, 0x00},
368 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
369 {SENSOR_LONG, 0x14, 0x00, 0x20},
370 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
371 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
372
373 /* normal colors
374 (this is value after boot, but after tries can be different) */
375 {SENSOR, 0x00, 0x06, 0x00},
376
377 /* set default brightness */
378 {SENSOR_LONG, 0x14, 0x00, 0x20},
379 {SENSOR_LONG, 0x0d, 0x01, 0x00},
380 {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3,
381 S5K83A_DEFAULT_BRIGHTNESS >> 1},
382
383 /* set default whiteness */
384 {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00},
385
386 /* set default gain */
387 {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN},
388
389 /* set default flip */
390 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
391 {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
392 {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
393 {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
394
395}; 195};
396 196
397#endif 197#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 0d3026936f2e..edff4f1f586f 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -21,13 +21,17 @@
21 21
22#include "m5602_bridge.h" 22#include "m5602_bridge.h"
23 23
24#define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0)
25#define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1)
26
24/* Enumerates all supported sensors */ 27/* Enumerates all supported sensors */
25enum sensors { 28enum sensors {
26 OV9650_SENSOR = 1, 29 OV9650_SENSOR = 1,
27 S5K83A_SENSOR = 2, 30 S5K83A_SENSOR = 2,
28 S5K4AA_SENSOR = 3, 31 S5K4AA_SENSOR = 3,
29 MT9M111_SENSOR = 4, 32 MT9M111_SENSOR = 4,
30 PO1030_SENSOR = 5 33 PO1030_SENSOR = 5,
34 OV7660_SENSOR = 6,
31}; 35};
32 36
33/* Enumerates all possible instruction types */ 37/* Enumerates all possible instruction types */
@@ -61,9 +65,6 @@ struct m5602_sensor {
61 65
62 /* Executed when the device is disconnected */ 66 /* Executed when the device is disconnected */
63 void (*disconnect)(struct sd *sd); 67 void (*disconnect)(struct sd *sd);
64
65 /* Performs a power down sequence */
66 int (*power_down)(struct sd *sd);
67}; 68};
68 69
69#endif 70#endif
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 2a901a4a6f00..30132513400c 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = {
321/* -- module initialisation -- */ 321/* -- module initialisation -- */
322static const __devinitdata struct usb_device_id device_table[] = { 322static const __devinitdata struct usb_device_id device_table[] = {
323 {USB_DEVICE(0x08ca, 0x0111)}, 323 {USB_DEVICE(0x08ca, 0x0111)},
324 {USB_DEVICE(0x093a, 0x010f)},
324 {} 325 {}
325}; 326};
326MODULE_DEVICE_TABLE(usb, device_table); 327MODULE_DEVICE_TABLE(usb, device_table);
@@ -347,8 +348,11 @@ static struct usb_driver sd_driver = {
347/* -- module insert / remove -- */ 348/* -- module insert / remove -- */
348static int __init sd_mod_init(void) 349static int __init sd_mod_init(void)
349{ 350{
350 if (usb_register(&sd_driver) < 0) 351 int ret;
351 return -1; 352
353 ret = usb_register(&sd_driver);
354 if (ret < 0)
355 return ret;
352 PDEBUG(D_PROBE, "registered"); 356 PDEBUG(D_PROBE, "registered");
353 return 0; 357 return 0;
354} 358}
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 1fff37b79891..188866ac6cef 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10;
50struct sd { 50struct sd {
51 struct gspca_dev gspca_dev; /* !! must be the first item */ 51 struct gspca_dev gspca_dev; /* !! must be the first item */
52 52
53 char bridge;
54#define BRIDGE_OV511 0
55#define BRIDGE_OV511PLUS 1
56#define BRIDGE_OV518 2
57#define BRIDGE_OV518PLUS 3
58#define BRIDGE_OV519 4
59
53 /* Determined by sensor type */ 60 /* Determined by sensor type */
54 __u8 sif; 61 __u8 sif;
55 62
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 94static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 95static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 96static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
97static void setbrightness(struct gspca_dev *gspca_dev);
98static void setcontrast(struct gspca_dev *gspca_dev);
99static void setcolors(struct gspca_dev *gspca_dev);
90 100
91static struct ctrl sd_ctrls[] = { 101static struct ctrl sd_ctrls[] = {
92 { 102 {
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
164 }, 174 },
165}; 175};
166 176
167static const struct v4l2_pix_format vga_mode[] = { 177static const struct v4l2_pix_format ov519_vga_mode[] = {
168 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 178 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
169 .bytesperline = 320, 179 .bytesperline = 320,
170 .sizeimage = 320 * 240 * 3 / 8 + 590, 180 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = {
176 .colorspace = V4L2_COLORSPACE_JPEG, 186 .colorspace = V4L2_COLORSPACE_JPEG,
177 .priv = 0}, 187 .priv = 0},
178}; 188};
179static const struct v4l2_pix_format sif_mode[] = { 189static const struct v4l2_pix_format ov519_sif_mode[] = {
180 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
181 .bytesperline = 176, 191 .bytesperline = 176,
182 .sizeimage = 176 * 144 * 3 / 8 + 590, 192 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = {
189 .priv = 0}, 199 .priv = 0},
190}; 200};
191 201
202static const struct v4l2_pix_format ov518_vga_mode[] = {
203 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
204 .bytesperline = 320,
205 .sizeimage = 320 * 240 * 3 / 8 + 590,
206 .colorspace = V4L2_COLORSPACE_JPEG,
207 .priv = 1},
208 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
209 .bytesperline = 640,
210 .sizeimage = 640 * 480 * 3 / 8 + 590,
211 .colorspace = V4L2_COLORSPACE_JPEG,
212 .priv = 0},
213};
214static const struct v4l2_pix_format ov518_sif_mode[] = {
215 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
216 .bytesperline = 176,
217 .sizeimage = 40000,
218 .colorspace = V4L2_COLORSPACE_JPEG,
219 .priv = 1},
220 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
221 .bytesperline = 352,
222 .sizeimage = 352 * 288 * 3 / 8 + 590,
223 .colorspace = V4L2_COLORSPACE_JPEG,
224 .priv = 0},
225};
226
227
228/* Registers common to OV511 / OV518 */
229#define R51x_SYS_RESET 0x50
230#define R51x_SYS_INIT 0x53
231#define R51x_SYS_SNAP 0x52
232#define R51x_SYS_CUST_ID 0x5F
233#define R51x_COMP_LUT_BEGIN 0x80
234
235/* OV511 Camera interface register numbers */
236#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
237#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
238
239/* OV518 Camera interface register numbers */
240#define R518_GPIO_OUT 0x56 /* OV518(+) only */
241#define R518_GPIO_CTL 0x57 /* OV518(+) only */
242
192/* OV519 Camera interface register numbers */ 243/* OV519 Camera interface register numbers */
193#define OV519_R10_H_SIZE 0x10 244#define OV519_R10_H_SIZE 0x10
194#define OV519_R11_V_SIZE 0x11 245#define OV519_R11_V_SIZE 0x11
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = {
224 275
225/* OV7610 registers */ 276/* OV7610 registers */
226#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ 277#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
278#define OV7610_REG_BLUE 0x01 /* blue channel balance */
279#define OV7610_REG_RED 0x02 /* red channel balance */
227#define OV7610_REG_SAT 0x03 /* saturation */ 280#define OV7610_REG_SAT 0x03 /* saturation */
228#define OV8610_REG_HUE 0x04 /* 04 reserved */ 281#define OV8610_REG_HUE 0x04 /* 04 reserved */
229#define OV7610_REG_CNT 0x05 /* Y contrast */ 282#define OV7610_REG_CNT 0x05 /* Y contrast */
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
846static int reg_w(struct sd *sd, __u16 index, __u8 value) 899static int reg_w(struct sd *sd, __u16 index, __u8 value)
847{ 900{
848 int ret; 901 int ret;
902 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1;
849 903
850 sd->gspca_dev.usb_buf[0] = value; 904 sd->gspca_dev.usb_buf[0] = value;
851 ret = usb_control_msg(sd->gspca_dev.dev, 905 ret = usb_control_msg(sd->gspca_dev.dev,
852 usb_sndctrlpipe(sd->gspca_dev.dev, 0), 906 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
853 1, /* REQ_IO (ov518/519) */ 907 req,
854 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 908 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
855 0, index, 909 0, index,
856 sd->gspca_dev.usb_buf, 1, 500); 910 sd->gspca_dev.usb_buf, 1, 500);
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
864static int reg_r(struct sd *sd, __u16 index) 918static int reg_r(struct sd *sd, __u16 index)
865{ 919{
866 int ret; 920 int ret;
921 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1;
867 922
868 ret = usb_control_msg(sd->gspca_dev.dev, 923 ret = usb_control_msg(sd->gspca_dev.dev,
869 usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 924 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
870 1, /* REQ_IO */ 925 req,
871 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 926 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
872 0, index, sd->gspca_dev.usb_buf, 1, 500); 927 0, index, sd->gspca_dev.usb_buf, 1, 500);
873 928
@@ -924,6 +979,28 @@ static int reg_w_mask(struct sd *sd,
924} 979}
925 980
926/* 981/*
982 * Writes multiple (n) byte value to a single register. Only valid with certain
983 * registers (0x30 and 0xc4 - 0xce).
984 */
985static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
986{
987 int ret;
988
989 *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
990
991 ret = usb_control_msg(sd->gspca_dev.dev,
992 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
993 1 /* REG_IO */,
994 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
995 0, index,
996 sd->gspca_dev.usb_buf, n, 500);
997 if (ret < 0)
998 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
999 return ret;
1000}
1001
1002
1003/*
927 * The OV518 I2C I/O procedure is different, hence, this function. 1004 * The OV518 I2C I/O procedure is different, hence, this function.
928 * This is normally only called from i2c_w(). Note that this function 1005 * This is normally only called from i2c_w(). Note that this function
929 * always succeeds regardless of whether the sensor is present and working. 1006 * always succeeds regardless of whether the sensor is present and working.
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd)
1014{ 1091{
1015 PDEBUG(D_STREAM, "stopping"); 1092 PDEBUG(D_STREAM, "stopping");
1016 sd->stopped = 1; 1093 sd->stopped = 1;
1017 return reg_w(sd, OV519_SYS_RESET1, 0x0f); 1094 switch (sd->bridge) {
1095 case BRIDGE_OV511:
1096 case BRIDGE_OV511PLUS:
1097 return reg_w(sd, R51x_SYS_RESET, 0x3d);
1098 case BRIDGE_OV518:
1099 case BRIDGE_OV518PLUS:
1100 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
1101 case BRIDGE_OV519:
1102 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
1103 }
1104
1105 return 0;
1018} 1106}
1019 1107
1020/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not 1108/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
1021 * actually stopped (for performance). */ 1109 * actually stopped (for performance). */
1022static inline int ov51x_restart(struct sd *sd) 1110static inline int ov51x_restart(struct sd *sd)
1023{ 1111{
1112 int rc;
1113
1024 PDEBUG(D_STREAM, "restarting"); 1114 PDEBUG(D_STREAM, "restarting");
1025 if (!sd->stopped) 1115 if (!sd->stopped)
1026 return 0; 1116 return 0;
1027 sd->stopped = 0; 1117 sd->stopped = 0;
1028 1118
1029 /* Reinitialize the stream */ 1119 /* Reinitialize the stream */
1030 return reg_w(sd, OV519_SYS_RESET1, 0x00); 1120 switch (sd->bridge) {
1121 case BRIDGE_OV511:
1122 case BRIDGE_OV511PLUS:
1123 return reg_w(sd, R51x_SYS_RESET, 0x00);
1124 case BRIDGE_OV518:
1125 case BRIDGE_OV518PLUS:
1126 rc = reg_w(sd, 0x2f, 0x80);
1127 if (rc < 0)
1128 return rc;
1129 return reg_w(sd, R51x_SYS_RESET, 0x00);
1130 case BRIDGE_OV519:
1131 return reg_w(sd, OV519_SYS_RESET1, 0x00);
1132 }
1133
1134 return 0;
1031} 1135}
1032 1136
1033/* This does an initial reset of an OmniVision sensor and ensures that I2C 1137/* This does an initial reset of an OmniVision sensor and ensures that I2C
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd)
1287/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1391/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1288static void ov51x_led_control(struct sd *sd, int on) 1392static void ov51x_led_control(struct sd *sd, int on)
1289{ 1393{
1290 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ 1394 switch (sd->bridge) {
1395 /* OV511 has no LED control */
1396 case BRIDGE_OV511PLUS:
1397 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
1398 break;
1399 case BRIDGE_OV518:
1400 case BRIDGE_OV518PLUS:
1401 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
1402 break;
1403 case BRIDGE_OV519:
1404 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1405 break;
1406 }
1291} 1407}
1292 1408
1293/* this function is called at probe time */ 1409/* OV518 quantization tables are 8x4 (instead of 8x8) */
1294static int sd_config(struct gspca_dev *gspca_dev, 1410static int ov518_upload_quan_tables(struct sd *sd)
1295 const struct usb_device_id *id) 1411{
1412 const unsigned char yQuanTable518[] = {
1413 5, 4, 5, 6, 6, 7, 7, 7,
1414 5, 5, 5, 5, 6, 7, 7, 7,
1415 6, 6, 6, 6, 7, 7, 7, 8,
1416 7, 7, 6, 7, 7, 7, 8, 8
1417 };
1418
1419 const unsigned char uvQuanTable518[] = {
1420 6, 6, 6, 7, 7, 7, 7, 7,
1421 6, 6, 6, 7, 7, 7, 7, 7,
1422 6, 6, 6, 7, 7, 7, 7, 8,
1423 7, 7, 7, 7, 7, 7, 8, 8
1424 };
1425
1426 const unsigned char *pYTable = yQuanTable518;
1427 const unsigned char *pUVTable = uvQuanTable518;
1428 unsigned char val0, val1;
1429 int i, rc, reg = R51x_COMP_LUT_BEGIN;
1430
1431 PDEBUG(D_PROBE, "Uploading quantization tables");
1432
1433 for (i = 0; i < 16; i++) {
1434 val0 = *pYTable++;
1435 val1 = *pYTable++;
1436 val0 &= 0x0f;
1437 val1 &= 0x0f;
1438 val0 |= val1 << 4;
1439 rc = reg_w(sd, reg, val0);
1440 if (rc < 0)
1441 return rc;
1442
1443 val0 = *pUVTable++;
1444 val1 = *pUVTable++;
1445 val0 &= 0x0f;
1446 val1 &= 0x0f;
1447 val0 |= val1 << 4;
1448 rc = reg_w(sd, reg + 16, val0);
1449 if (rc < 0)
1450 return rc;
1451
1452 reg++;
1453 }
1454
1455 return 0;
1456}
1457
1458/* This initializes the OV518/OV518+ and the sensor */
1459static int ov518_configure(struct gspca_dev *gspca_dev)
1296{ 1460{
1297 struct sd *sd = (struct sd *) gspca_dev; 1461 struct sd *sd = (struct sd *) gspca_dev;
1298 struct cam *cam; 1462 int rc;
1463
1464 /* For 518 and 518+ */
1465 static struct ov_regvals init_518[] = {
1466 { R51x_SYS_RESET, 0x40 },
1467 { R51x_SYS_INIT, 0xe1 },
1468 { R51x_SYS_RESET, 0x3e },
1469 { R51x_SYS_INIT, 0xe1 },
1470 { R51x_SYS_RESET, 0x00 },
1471 { R51x_SYS_INIT, 0xe1 },
1472 { 0x46, 0x00 },
1473 { 0x5d, 0x03 },
1474 };
1475
1476 static struct ov_regvals norm_518[] = {
1477 { R51x_SYS_SNAP, 0x02 }, /* Reset */
1478 { R51x_SYS_SNAP, 0x01 }, /* Enable */
1479 { 0x31, 0x0f },
1480 { 0x5d, 0x03 },
1481 { 0x24, 0x9f },
1482 { 0x25, 0x90 },
1483 { 0x20, 0x00 },
1484 { 0x51, 0x04 },
1485 { 0x71, 0x19 },
1486 { 0x2f, 0x80 },
1487 };
1488
1489 static struct ov_regvals norm_518_p[] = {
1490 { R51x_SYS_SNAP, 0x02 }, /* Reset */
1491 { R51x_SYS_SNAP, 0x01 }, /* Enable */
1492 { 0x31, 0x0f },
1493 { 0x5d, 0x03 },
1494 { 0x24, 0x9f },
1495 { 0x25, 0x90 },
1496 { 0x20, 0x60 },
1497 { 0x51, 0x02 },
1498 { 0x71, 0x19 },
1499 { 0x40, 0xff },
1500 { 0x41, 0x42 },
1501 { 0x46, 0x00 },
1502 { 0x33, 0x04 },
1503 { 0x21, 0x19 },
1504 { 0x3f, 0x10 },
1505 { 0x2f, 0x80 },
1506 };
1507
1508 /* First 5 bits of custom ID reg are a revision ID on OV518 */
1509 PDEBUG(D_PROBE, "Device revision %d",
1510 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
1511
1512 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
1513 if (rc < 0)
1514 return rc;
1515
1516 /* Set LED GPIO pin to output mode */
1517 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
1518 if (rc < 0)
1519 return rc;
1299 1520
1521 switch (sd->bridge) {
1522 case BRIDGE_OV518:
1523 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
1524 if (rc < 0)
1525 return rc;
1526 break;
1527 case BRIDGE_OV518PLUS:
1528 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
1529 if (rc < 0)
1530 return rc;
1531 break;
1532 }
1533
1534 rc = ov518_upload_quan_tables(sd);
1535 if (rc < 0) {
1536 PDEBUG(D_ERR, "Error uploading quantization tables");
1537 return rc;
1538 }
1539
1540 rc = reg_w(sd, 0x2f, 0x80);
1541 if (rc < 0)
1542 return rc;
1543
1544 return 0;
1545}
1546
1547static int ov519_configure(struct sd *sd)
1548{
1300 static const struct ov_regvals init_519[] = { 1549 static const struct ov_regvals init_519[] = {
1301 { 0x5a, 0x6d }, /* EnableSystem */ 1550 { 0x5a, 0x6d }, /* EnableSystem */
1302 { 0x53, 0x9b }, 1551 { 0x53, 0x9b },
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
1313 /* windows reads 0x55 at this point*/ 1562 /* windows reads 0x55 at this point*/
1314 }; 1563 };
1315 1564
1316 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) 1565 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
1566}
1567
1568/* this function is called at probe time */
1569static int sd_config(struct gspca_dev *gspca_dev,
1570 const struct usb_device_id *id)
1571{
1572 struct sd *sd = (struct sd *) gspca_dev;
1573 struct cam *cam;
1574 int ret = 0;
1575
1576 sd->bridge = id->driver_info;
1577
1578 switch (sd->bridge) {
1579 case BRIDGE_OV518:
1580 case BRIDGE_OV518PLUS:
1581 ret = ov518_configure(gspca_dev);
1582 break;
1583 case BRIDGE_OV519:
1584 ret = ov519_configure(sd);
1585 break;
1586 }
1587
1588 if (ret)
1317 goto error; 1589 goto error;
1590
1318 ov51x_led_control(sd, 0); /* turn LED off */ 1591 ov51x_led_control(sd, 0); /* turn LED off */
1319 1592
1320 /* Test for 76xx */ 1593 /* Test for 76xx */
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev,
1360 } 1633 }
1361 1634
1362 cam = &gspca_dev->cam; 1635 cam = &gspca_dev->cam;
1363 if (!sd->sif) { 1636 switch (sd->bridge) {
1364 cam->cam_mode = vga_mode; 1637 case BRIDGE_OV518:
1365 cam->nmodes = ARRAY_SIZE(vga_mode); 1638 case BRIDGE_OV518PLUS:
1366 } else { 1639 if (!sd->sif) {
1367 cam->cam_mode = sif_mode; 1640 cam->cam_mode = ov518_vga_mode;
1368 cam->nmodes = ARRAY_SIZE(sif_mode); 1641 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
1642 } else {
1643 cam->cam_mode = ov518_sif_mode;
1644 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
1645 }
1646 break;
1647 case BRIDGE_OV519:
1648 if (!sd->sif) {
1649 cam->cam_mode = ov519_vga_mode;
1650 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
1651 } else {
1652 cam->cam_mode = ov519_sif_mode;
1653 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
1654 }
1655 break;
1369 } 1656 }
1370 sd->brightness = BRIGHTNESS_DEF; 1657 sd->brightness = BRIGHTNESS_DEF;
1371 sd->contrast = CONTRAST_DEF; 1658 sd->contrast = CONTRAST_DEF;
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev)
1422 return 0; 1709 return 0;
1423} 1710}
1424 1711
1712/* Sets up the OV518/OV518+ with the given image parameters
1713 *
1714 * OV518 needs a completely different approach, until we can figure out what
1715 * the individual registers do. Also, only 15 FPS is supported now.
1716 *
1717 * Do not put any sensor-specific code in here (including I2C I/O functions)
1718 */
1719static int ov518_mode_init_regs(struct sd *sd)
1720{
1721 int hsegs, vsegs;
1722
1723 /******** Set the mode ********/
1724
1725 reg_w(sd, 0x2b, 0);
1726 reg_w(sd, 0x2c, 0);
1727 reg_w(sd, 0x2d, 0);
1728 reg_w(sd, 0x2e, 0);
1729 reg_w(sd, 0x3b, 0);
1730 reg_w(sd, 0x3c, 0);
1731 reg_w(sd, 0x3d, 0);
1732 reg_w(sd, 0x3e, 0);
1733
1734 if (sd->bridge == BRIDGE_OV518) {
1735 /* Set 8-bit (YVYU) input format */
1736 reg_w_mask(sd, 0x20, 0x08, 0x08);
1737
1738 /* Set 12-bit (4:2:0) output format */
1739 reg_w_mask(sd, 0x28, 0x80, 0xf0);
1740 reg_w_mask(sd, 0x38, 0x80, 0xf0);
1741 } else {
1742 reg_w(sd, 0x28, 0x80);
1743 reg_w(sd, 0x38, 0x80);
1744 }
1745
1746 hsegs = sd->gspca_dev.width / 16;
1747 vsegs = sd->gspca_dev.height / 4;
1748
1749 reg_w(sd, 0x29, hsegs);
1750 reg_w(sd, 0x2a, vsegs);
1751
1752 reg_w(sd, 0x39, hsegs);
1753 reg_w(sd, 0x3a, vsegs);
1754
1755 /* Windows driver does this here; who knows why */
1756 reg_w(sd, 0x2f, 0x80);
1757
1758 /******** Set the framerate (to 30 FPS) ********/
1759 if (sd->bridge == BRIDGE_OV518PLUS)
1760 sd->clockdiv = 1;
1761 else
1762 sd->clockdiv = 0;
1763
1764 /* Mode independent, but framerate dependent, regs */
1765 reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */
1766 reg_w(sd, 0x22, 0x18);
1767 reg_w(sd, 0x23, 0xff);
1768
1769 if (sd->bridge == BRIDGE_OV518PLUS)
1770 reg_w(sd, 0x21, 0x19);
1771 else
1772 reg_w(sd, 0x71, 0x17); /* Compression-related? */
1773
1774 /* FIXME: Sensor-specific */
1775 /* Bit 5 is what matters here. Of course, it is "reserved" */
1776 i2c_w(sd, 0x54, 0x23);
1777
1778 reg_w(sd, 0x2f, 0x80);
1779
1780 if (sd->bridge == BRIDGE_OV518PLUS) {
1781 reg_w(sd, 0x24, 0x94);
1782 reg_w(sd, 0x25, 0x90);
1783 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
1784 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
1785 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
1786 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
1787 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
1788 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
1789 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
1790 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
1791 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
1792 } else {
1793 reg_w(sd, 0x24, 0x9f);
1794 reg_w(sd, 0x25, 0x90);
1795 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
1796 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
1797 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
1798 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
1799 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
1800 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
1801 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
1802 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
1803 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
1804 }
1805
1806 reg_w(sd, 0x2f, 0x80);
1807
1808 return 0;
1809}
1810
1811
1425/* Sets up the OV519 with the given image parameters 1812/* Sets up the OV519 with the given image parameters
1426 * 1813 *
1427 * OV519 needs a completely different approach, until we can figure out what 1814 * OV519 needs a completely different approach, until we can figure out what
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd)
1740 hwebase = 0x3a; 2127 hwebase = 0x3a;
1741 vwsbase = 0x05; 2128 vwsbase = 0x05;
1742 vwebase = 0x06; 2129 vwebase = 0x06;
2130 if (qvga) {
2131 /* HDG: this fixes U and V getting swapped */
2132 hwsbase--;
2133 vwsbase--;
2134 }
1743 break; 2135 break;
1744 case SEN_OV7620: 2136 case SEN_OV7620:
1745 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ 2137 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd)
1855static int sd_start(struct gspca_dev *gspca_dev) 2247static int sd_start(struct gspca_dev *gspca_dev)
1856{ 2248{
1857 struct sd *sd = (struct sd *) gspca_dev; 2249 struct sd *sd = (struct sd *) gspca_dev;
1858 int ret; 2250 int ret = 0;
1859 2251
1860 ret = ov519_mode_init_regs(sd); 2252 switch (sd->bridge) {
2253 case BRIDGE_OV518:
2254 case BRIDGE_OV518PLUS:
2255 ret = ov518_mode_init_regs(sd);
2256 break;
2257 case BRIDGE_OV519:
2258 ret = ov519_mode_init_regs(sd);
2259 break;
2260 }
1861 if (ret < 0) 2261 if (ret < 0)
1862 goto out; 2262 goto out;
2263
1863 ret = set_ov_sensor_window(sd); 2264 ret = set_ov_sensor_window(sd);
1864 if (ret < 0) 2265 if (ret < 0)
1865 goto out; 2266 goto out;
1866 2267
2268 setcontrast(gspca_dev);
2269 setbrightness(gspca_dev);
2270 setcolors(gspca_dev);
2271
1867 ret = ov51x_restart(sd); 2272 ret = ov51x_restart(sd);
1868 if (ret < 0) 2273 if (ret < 0)
1869 goto out; 2274 goto out;
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1882 ov51x_led_control(sd, 0); 2287 ov51x_led_control(sd, 0);
1883} 2288}
1884 2289
1885static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2290static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2291 struct gspca_frame *frame, /* target */
2292 __u8 *data, /* isoc packet */
2293 int len) /* iso packet length */
2294{
2295 PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len);
2296
2297 if (len & 7) {
2298 len--;
2299 PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]);
2300 }
2301
2302 /* A false positive here is likely, until OVT gives me
2303 * the definitive SOF/EOF format */
2304 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
2305 gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
2306 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
2307 }
2308
2309 /* intermediate packet */
2310 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
2311}
2312
2313static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
1886 struct gspca_frame *frame, /* target */ 2314 struct gspca_frame *frame, /* target */
1887 __u8 *data, /* isoc packet */ 2315 __u8 *data, /* isoc packet */
1888 int len) /* iso packet length */ 2316 int len) /* iso packet length */
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1926 data, len); 2354 data, len);
1927} 2355}
1928 2356
2357static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2358 struct gspca_frame *frame, /* target */
2359 __u8 *data, /* isoc packet */
2360 int len) /* iso packet length */
2361{
2362 struct sd *sd = (struct sd *) gspca_dev;
2363
2364 switch (sd->bridge) {
2365 case BRIDGE_OV511:
2366 case BRIDGE_OV511PLUS:
2367 break;
2368 case BRIDGE_OV518:
2369 case BRIDGE_OV518PLUS:
2370 ov518_pkt_scan(gspca_dev, frame, data, len);
2371 break;
2372 case BRIDGE_OV519:
2373 ov519_pkt_scan(gspca_dev, frame, data, len);
2374 break;
2375 }
2376}
2377
1929/* -- management routines -- */ 2378/* -- management routines -- */
1930 2379
1931static void setbrightness(struct gspca_dev *gspca_dev) 2380static void setbrightness(struct gspca_dev *gspca_dev)
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1970 break; 2419 break;
1971 case SEN_OV6630: 2420 case SEN_OV6630:
1972 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); 2421 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
2422 break;
1973 case SEN_OV8610: { 2423 case SEN_OV8610: {
1974 static const __u8 ctab[] = { 2424 static const __u8 ctab[] = {
1975 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f 2425 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = {
2136 2586
2137/* -- module initialisation -- */ 2587/* -- module initialisation -- */
2138static const __devinitdata struct usb_device_id device_table[] = { 2588static const __devinitdata struct usb_device_id device_table[] = {
2139 {USB_DEVICE(0x041e, 0x4052)}, 2589 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
2140 {USB_DEVICE(0x041e, 0x405f)}, 2590 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
2141 {USB_DEVICE(0x041e, 0x4060)}, 2591 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
2142 {USB_DEVICE(0x041e, 0x4061)}, 2592 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
2143 {USB_DEVICE(0x041e, 0x4064)}, 2593 {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
2144 {USB_DEVICE(0x041e, 0x4068)}, 2594 {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
2145 {USB_DEVICE(0x045e, 0x028c)}, 2595 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
2146 {USB_DEVICE(0x054c, 0x0154)}, 2596 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
2147 {USB_DEVICE(0x054c, 0x0155)}, 2597 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
2148 {USB_DEVICE(0x05a9, 0x0519)}, 2598 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
2149 {USB_DEVICE(0x05a9, 0x0530)}, 2599 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
2150 {USB_DEVICE(0x05a9, 0x4519)}, 2600 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
2151 {USB_DEVICE(0x05a9, 0x8519)}, 2601 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
2602 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
2603 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
2152 {} 2604 {}
2153}; 2605};
2154 2606
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 19e0bc60de14..4b528b372911 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -60,10 +60,23 @@ struct sd {
60static struct ctrl sd_ctrls[] = { 60static struct ctrl sd_ctrls[] = {
61}; 61};
62 62
63static const struct v4l2_pix_format vga_mode[] = { 63static const struct v4l2_pix_format vga_yuyv_mode[] = {
64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
65 .bytesperline = 640 * 2, 65 .bytesperline = 640 * 2,
66 .sizeimage = 640 * 480 * 2, 66 .sizeimage = 640 * 480 * 2,
67 .colorspace = V4L2_COLORSPACE_SRGB,
68 .priv = 0},
69};
70
71static const struct v4l2_pix_format vga_jpeg_mode[] = {
72 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
73 .bytesperline = 320,
74 .sizeimage = 320 * 240 * 3 / 8 + 590,
75 .colorspace = V4L2_COLORSPACE_JPEG,
76 .priv = 1},
77 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
78 .bytesperline = 640,
79 .sizeimage = 640 * 480 * 3 / 8 + 590,
67 .colorspace = V4L2_COLORSPACE_JPEG, 80 .colorspace = V4L2_COLORSPACE_JPEG,
68 .priv = 0}, 81 .priv = 0},
69}; 82};
@@ -244,7 +257,7 @@ static const u8 bridge_init_ov965x[][2] = {
244}; 257};
245 258
246static const u8 sensor_init_ov965x[][2] = { 259static const u8 sensor_init_ov965x[][2] = {
247 {0x12, 0x80}, /* com7 - reset */ 260 {0x12, 0x80}, /* com7 - SSCB reset */
248 {0x00, 0x00}, /* gain */ 261 {0x00, 0x00}, /* gain */
249 {0x01, 0x80}, /* blue */ 262 {0x01, 0x80}, /* blue */
250 {0x02, 0x80}, /* red */ 263 {0x02, 0x80}, /* red */
@@ -254,10 +267,10 @@ static const u8 sensor_init_ov965x[][2] = {
254 {0x0e, 0x61}, /* com5 */ 267 {0x0e, 0x61}, /* com5 */
255 {0x0f, 0x42}, /* com6 */ 268 {0x0f, 0x42}, /* com6 */
256 {0x11, 0x00}, /* clkrc */ 269 {0x11, 0x00}, /* clkrc */
257 {0x12, 0x02}, /* com7 */ 270 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
258 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 271 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
259 {0x14, 0x28}, /* com9 */ 272 {0x14, 0x28}, /* com9 */
260 {0x16, 0x24}, /* rsvd16 */ 273 {0x16, 0x24}, /* reg16 */
261 {0x17, 0x1d}, /* hstart*/ 274 {0x17, 0x1d}, /* hstart*/
262 {0x18, 0xbd}, /* hstop */ 275 {0x18, 0xbd}, /* hstop */
263 {0x19, 0x01}, /* vstrt */ 276 {0x19, 0x01}, /* vstrt */
@@ -269,24 +282,24 @@ static const u8 sensor_init_ov965x[][2] = {
269 {0x27, 0x08}, /* bbias */ 282 {0x27, 0x08}, /* bbias */
270 {0x28, 0x08}, /* gbbias */ 283 {0x28, 0x08}, /* gbbias */
271 {0x29, 0x15}, /* gr com */ 284 {0x29, 0x15}, /* gr com */
272 {0x2a, 0x00}, 285 {0x2a, 0x00}, /* exhch */
273 {0x2b, 0x00}, 286 {0x2b, 0x00}, /* exhcl */
274 {0x2c, 0x08}, /* rbias */ 287 {0x2c, 0x08}, /* rbias */
275 {0x32, 0xff}, /* href */ 288 {0x32, 0xff}, /* href */
276 {0x33, 0x00}, /* chlf */ 289 {0x33, 0x00}, /* chlf */
277 {0x34, 0x3f}, /* arblm */ 290 {0x34, 0x3f}, /* aref1 */
278 {0x35, 0x00}, /* rsvd35 */ 291 {0x35, 0x00}, /* aref2 */
279 {0x36, 0xf8}, /* rsvd36 */ 292 {0x36, 0xf8}, /* aref3 */
280 {0x38, 0x72}, /* acom38 */ 293 {0x38, 0x72}, /* adc2 */
281 {0x39, 0x57}, /* ofon */ 294 {0x39, 0x57}, /* aref4 */
282 {0x3a, 0x80}, /* tslb */ 295 {0x3a, 0x80}, /* tslb - yuyv */
283 {0x3b, 0xc4}, 296 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
284 {0x3d, 0x99}, /* com13 */ 297 {0x3d, 0x99}, /* com13 */
285 {0x3f, 0xc1}, 298 {0x3f, 0xc1}, /* edge */
286 {0x40, 0xc0}, /* com15 */ 299 {0x40, 0xc0}, /* com15 */
287 {0x41, 0x40}, /* com16 */ 300 {0x41, 0x40}, /* com16 */
288 {0x42, 0xc0}, 301 {0x42, 0xc0}, /* com17 */
289 {0x43, 0x0a}, 302 {0x43, 0x0a}, /* rsvd */
290 {0x44, 0xf0}, 303 {0x44, 0xf0},
291 {0x45, 0x46}, 304 {0x45, 0x46},
292 {0x46, 0x62}, 305 {0x46, 0x62},
@@ -297,22 +310,22 @@ static const u8 sensor_init_ov965x[][2] = {
297 {0x4c, 0x7f}, 310 {0x4c, 0x7f},
298 {0x4d, 0x7f}, 311 {0x4d, 0x7f},
299 {0x4e, 0x7f}, 312 {0x4e, 0x7f},
300 {0x4f, 0x98}, 313 {0x4f, 0x98}, /* matrix */
301 {0x50, 0x98}, 314 {0x50, 0x98},
302 {0x51, 0x00}, 315 {0x51, 0x00},
303 {0x52, 0x28}, 316 {0x52, 0x28},
304 {0x53, 0x70}, 317 {0x53, 0x70},
305 {0x54, 0x98}, 318 {0x54, 0x98},
306 {0x58, 0x1a}, 319 {0x58, 0x1a}, /* matrix coef sign */
307 {0x59, 0x85}, 320 {0x59, 0x85}, /* AWB control */
308 {0x5a, 0xa9}, 321 {0x5a, 0xa9},
309 {0x5b, 0x64}, 322 {0x5b, 0x64},
310 {0x5c, 0x84}, 323 {0x5c, 0x84},
311 {0x5d, 0x53}, 324 {0x5d, 0x53},
312 {0x5e, 0x0e}, 325 {0x5e, 0x0e},
313 {0x5f, 0xf0}, 326 {0x5f, 0xf0}, /* AWB blue limit */
314 {0x60, 0xf0}, 327 {0x60, 0xf0}, /* AWB red limit */
315 {0x61, 0xf0}, 328 {0x61, 0xf0}, /* AWB green limit */
316 {0x62, 0x00}, /* lcc1 */ 329 {0x62, 0x00}, /* lcc1 */
317 {0x63, 0x00}, /* lcc2 */ 330 {0x63, 0x00}, /* lcc2 */
318 {0x64, 0x02}, /* lcc3 */ 331 {0x64, 0x02}, /* lcc3 */
@@ -324,15 +337,15 @@ static const u8 sensor_init_ov965x[][2] = {
324 {0x6d, 0x55}, 337 {0x6d, 0x55},
325 {0x6e, 0x00}, 338 {0x6e, 0x00},
326 {0x6f, 0x9d}, 339 {0x6f, 0x9d},
327 {0x70, 0x21}, 340 {0x70, 0x21}, /* dnsth */
328 {0x71, 0x78}, 341 {0x71, 0x78},
329 {0x72, 0x00}, 342 {0x72, 0x00}, /* poidx */
330 {0x73, 0x01}, 343 {0x73, 0x01}, /* pckdv */
331 {0x74, 0x3a}, 344 {0x74, 0x3a}, /* xindx */
332 {0x75, 0x35}, 345 {0x75, 0x35}, /* yindx */
333 {0x76, 0x01}, 346 {0x76, 0x01},
334 {0x77, 0x02}, 347 {0x77, 0x02},
335 {0x7a, 0x12}, 348 {0x7a, 0x12}, /* gamma curve */
336 {0x7b, 0x08}, 349 {0x7b, 0x08},
337 {0x7c, 0x16}, 350 {0x7c, 0x16},
338 {0x7d, 0x30}, 351 {0x7d, 0x30},
@@ -349,33 +362,33 @@ static const u8 sensor_init_ov965x[][2] = {
349 {0x88, 0xe6}, 362 {0x88, 0xe6},
350 {0x89, 0xf2}, 363 {0x89, 0xf2},
351 {0x8a, 0x03}, 364 {0x8a, 0x03},
352 {0x8c, 0x89}, 365 {0x8c, 0x89}, /* com19 */
353 {0x14, 0x28}, /* com9 */ 366 {0x14, 0x28}, /* com9 */
354 {0x90, 0x7d}, 367 {0x90, 0x7d},
355 {0x91, 0x7b}, 368 {0x91, 0x7b},
356 {0x9d, 0x03}, 369 {0x9d, 0x03}, /* lcc6 */
357 {0x9e, 0x04}, 370 {0x9e, 0x04}, /* lcc7 */
358 {0x9f, 0x7a}, 371 {0x9f, 0x7a},
359 {0xa0, 0x79}, 372 {0xa0, 0x79},
360 {0xa1, 0x40}, /* aechm */ 373 {0xa1, 0x40}, /* aechm */
361 {0xa4, 0x50}, 374 {0xa4, 0x50}, /* com21 */
362 {0xa5, 0x68}, /* com26 */ 375 {0xa5, 0x68}, /* com26 */
363 {0xa6, 0x4a}, 376 {0xa6, 0x4a}, /* AWB green */
364 {0xa8, 0xc1}, /* acoma8 */ 377 {0xa8, 0xc1}, /* refa8 */
365 {0xa9, 0xef}, /* acoma9 */ 378 {0xa9, 0xef}, /* refa9 */
366 {0xaa, 0x92}, 379 {0xaa, 0x92},
367 {0xab, 0x04}, 380 {0xab, 0x04},
368 {0xac, 0x80}, 381 {0xac, 0x80}, /* black level control */
369 {0xad, 0x80}, 382 {0xad, 0x80},
370 {0xae, 0x80}, 383 {0xae, 0x80},
371 {0xaf, 0x80}, 384 {0xaf, 0x80},
372 {0xb2, 0xf2}, 385 {0xb2, 0xf2},
373 {0xb3, 0x20}, 386 {0xb3, 0x20},
374 {0xb4, 0x20}, 387 {0xb4, 0x20}, /* ctrlb4 */
375 {0xb5, 0x00}, 388 {0xb5, 0x00},
376 {0xb6, 0xaf}, 389 {0xb6, 0xaf},
377 {0xbb, 0xae}, 390 {0xbb, 0xae},
378 {0xbc, 0x7f}, 391 {0xbc, 0x7f}, /* ADC channel offsets */
379 {0xdb, 0x7f}, 392 {0xdb, 0x7f},
380 {0xbe, 0x7f}, 393 {0xbe, 0x7f},
381 {0xbf, 0x7f}, 394 {0xbf, 0x7f},
@@ -384,7 +397,7 @@ static const u8 sensor_init_ov965x[][2] = {
384 {0xc2, 0x01}, 397 {0xc2, 0x01},
385 {0xc3, 0x4e}, 398 {0xc3, 0x4e},
386 {0xc6, 0x85}, 399 {0xc6, 0x85},
387 {0xc7, 0x80}, 400 {0xc7, 0x80}, /* com24 */
388 {0xc9, 0xe0}, 401 {0xc9, 0xe0},
389 {0xca, 0xe8}, 402 {0xca, 0xe8},
390 {0xcb, 0xf0}, 403 {0xcb, 0xf0},
@@ -399,11 +412,11 @@ static const u8 sensor_init_ov965x[][2] = {
399 {0x58, 0x1a}, 412 {0x58, 0x1a},
400 {0xff, 0x41}, /* read 41, write ff 00 */ 413 {0xff, 0x41}, /* read 41, write ff 00 */
401 {0x41, 0x40}, /* com16 */ 414 {0x41, 0x40}, /* com16 */
402 {0xc5, 0x03}, 415 {0xc5, 0x03}, /* 60 Hz banding filter */
403 {0x6a, 0x02}, 416 {0x6a, 0x02}, /* 50 Hz banding filter */
404 417
405 {0x12, 0x62}, /* com7 - VGA + CIF */ 418 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
406 {0x36, 0xfa}, /* rsvd36 */ 419 {0x36, 0xfa}, /* aref3 */
407 {0x69, 0x0a}, /* hv */ 420 {0x69, 0x0a}, /* hv */
408 {0x8c, 0x89}, /* com22 */ 421 {0x8c, 0x89}, /* com22 */
409 {0x14, 0x28}, /* com9 */ 422 {0x14, 0x28}, /* com9 */
@@ -442,8 +455,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
442 {0x52, 0x3c}, 455 {0x52, 0x3c},
443 {0x53, 0x00}, 456 {0x53, 0x00},
444 {0x54, 0x00}, 457 {0x54, 0x00},
445 {0x55, 0x00}, 458 {0x55, 0x00}, /* brightness */
446 {0x57, 0x00}, 459 {0x57, 0x00}, /* contrast 2 */
447 {0x5c, 0x00}, 460 {0x5c, 0x00},
448 {0x5a, 0xa0}, 461 {0x5a, 0xa0},
449 {0x5b, 0x78}, 462 {0x5b, 0x78},
@@ -489,9 +502,66 @@ static const u8 sensor_init_ov965x_2[][2] = {
489 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 502 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
490}; 503};
491 504
505static const u8 sensor_start_ov965x[][2] = {
506 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
507 {0x36, 0xfa}, /* aref3 */
508 {0x69, 0x0a}, /* hv */
509 {0x8c, 0x89}, /* com22 */
510 {0x14, 0x28}, /* com9 */
511 {0x3e, 0x0c}, /* com14 */
512 {0x41, 0x40}, /* com16 */
513 {0x72, 0x00},
514 {0x73, 0x00},
515 {0x74, 0x3a},
516 {0x75, 0x35},
517 {0x76, 0x01},
518 {0xc7, 0x80}, /* com24 */
519 {0x03, 0x12}, /* vref */
520 {0x17, 0x16}, /* hstart */
521 {0x18, 0x02}, /* hstop */
522 {0x19, 0x01}, /* vstrt */
523 {0x1a, 0x3d}, /* vstop */
524 {0x32, 0xff}, /* href */
525 {0xc0, 0xaa},
526 {}
527};
528
492static const u8 bridge_start_ov965x[][2] = { 529static const u8 bridge_start_ov965x[][2] = {
530 {0x94, 0xaa},
531 {0xf1, 0x60},
532 {0xe5, 0x04},
533 {0xc0, 0x50},
534 {0xc1, 0x3c},
535 {0x8c, 0x00},
536 {0x8d, 0x1c},
537 {0x34, 0x05},
538 {}
539};
540
541static const u8 bridge_start_ov965x_vga[][2] = {
542 {0xc2, 0x0c},
543 {0xc3, 0xf9},
544 {0xda, 0x01},
545 {0x50, 0x00},
546 {0x51, 0xa0},
547 {0x52, 0x3c},
548 {0x53, 0x00},
549 {0x54, 0x00},
550 {0x55, 0x00},
551 {0x57, 0x00},
552 {0x5c, 0x00},
553 {0x5a, 0xa0},
554 {0x5b, 0x78},
555 {0x35, 0x02},
556 {0xd9, 0x10},
557 {0x94, 0x11},
558 {}
559};
560
561static const u8 bridge_start_ov965x_cif[][2] = {
493 {0xc2, 0x4c}, 562 {0xc2, 0x4c},
494 {0xc3, 0xf9}, 563 {0xc3, 0xf9},
564 {0xda, 0x00},
495 {0x50, 0x00}, 565 {0x50, 0x00},
496 {0x51, 0xa0}, 566 {0x51, 0xa0},
497 {0x52, 0x78}, 567 {0x52, 0x78},
@@ -500,30 +570,54 @@ static const u8 bridge_start_ov965x[][2] = {
500 {0x55, 0x00}, 570 {0x55, 0x00},
501 {0x57, 0x00}, 571 {0x57, 0x00},
502 {0x5c, 0x00}, 572 {0x5c, 0x00},
503 {0x5a, 0x28}, 573 {0x5a, 0x50},
504 {0x5b, 0x1e}, 574 {0x5b, 0x3c},
505 {0x35, 0x00}, 575 {0x35, 0x02},
506 {0xd9, 0x21}, 576 {0xd9, 0x10},
507 {0x94, 0x11}, 577 {0x94, 0x11},
578 {}
508}; 579};
509 580
510static const u8 sensor_start_ov965x[][2] = { 581static const u8 sensor_start_ov965x_vga[][2] = {
511 {0x3b, 0xe4}, 582 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
583 {0x1e, 0x04}, /* mvfp */
584 {0x13, 0xe0}, /* com8 */
585 {0x00, 0x00},
586 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
587 {0x11, 0x03}, /* clkrc */
588 {0x6b, 0x5a}, /* dblv */
589 {0x6a, 0x05}, /* 50 Hz banding filter */
590 {0xc5, 0x07}, /* 60 Hz banding filter */
591 {0xa2, 0x4b}, /* bd50 */
592 {0xa3, 0x3e}, /* bd60 */
593
594 {0x2d, 0x00}, /* advfl */
595 {}
596};
597
598static const u8 sensor_start_ov965x_cif[][2] = {
599 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
512 {0x1e, 0x04}, /* mvfp */ 600 {0x1e, 0x04}, /* mvfp */
513 {0x13, 0xe0}, /* com8 */ 601 {0x13, 0xe0}, /* com8 */
514 {0x00, 0x00}, 602 {0x00, 0x00},
515 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 603 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
516 {0x11, 0x01}, /* clkrc */ 604 {0x11, 0x01}, /* clkrc */
517 {0x6b, 0x5a}, /* dblv */ 605 {0x6b, 0x5a}, /* dblv */
518 {0x6a, 0x02}, 606 {0x6a, 0x02}, /* 50 Hz banding filter */
519 {0xc5, 0x03}, 607 {0xc5, 0x03}, /* 60 Hz banding filter */
520 {0xa2, 0x96}, 608 {0xa2, 0x96}, /* bd50 */
521 {0xa3, 0x7d}, 609 {0xa3, 0x7d}, /* bd60 */
610
522 {0xff, 0x13}, /* read 13, write ff 00 */ 611 {0xff, 0x13}, /* read 13, write ff 00 */
523 {0x13, 0xe7}, 612 {0x13, 0xe7},
524 {0x3a, 0x80}, 613 {0x3a, 0x80}, /* tslb - yuyv */
614 {}
615};
616
617static const u8 sensor_start_ov965x_2[][2] = {
525 {0xff, 0x42}, /* read 42, write ff 00 */ 618 {0xff, 0x42}, /* read 42, write ff 00 */
526 {0x42, 0xc1}, 619 {0x42, 0xc1}, /* com17 - 50 Hz filter */
620 {}
527}; 621};
528 622
529 623
@@ -705,11 +799,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
705 799
706 cam = &gspca_dev->cam; 800 cam = &gspca_dev->cam;
707 801
708 cam->cam_mode = vga_mode; 802 if (sd->sensor == SENSOR_OV772X) {
709 cam->nmodes = ARRAY_SIZE(vga_mode); 803 cam->cam_mode = vga_yuyv_mode;
804 cam->nmodes = ARRAY_SIZE(vga_yuyv_mode);
710 805
711 cam->bulk_size = 16384; 806 cam->bulk = 1;
712 cam->bulk_nurbs = 2; 807 cam->bulk_size = 16384;
808 cam->bulk_nurbs = 2;
809 } else { /* ov965x */
810 cam->cam_mode = vga_jpeg_mode;
811 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
812 }
713 813
714 return 0; 814 return 0;
715} 815}
@@ -778,6 +878,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
778static int sd_start(struct gspca_dev *gspca_dev) 878static int sd_start(struct gspca_dev *gspca_dev)
779{ 879{
780 struct sd *sd = (struct sd *) gspca_dev; 880 struct sd *sd = (struct sd *) gspca_dev;
881 int mode;
781 882
782 switch (sd->sensor) { 883 switch (sd->sensor) {
783 case SENSOR_OV772X: 884 case SENSOR_OV772X:
@@ -786,13 +887,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
786 break; 887 break;
787 default: 888 default:
788/* case SENSOR_OV965X: */ 889/* case SENSOR_OV965X: */
789 reg_w_array(gspca_dev, bridge_start_ov965x, 890
790 ARRAY_SIZE(bridge_start_ov965x));
791 sccb_w_array(gspca_dev, sensor_start_ov965x, 891 sccb_w_array(gspca_dev, sensor_start_ov965x,
792 ARRAY_SIZE(sensor_start_ov965x)); 892 ARRAY_SIZE(sensor_start_ov965x));
893 reg_w_array(gspca_dev, bridge_start_ov965x,
894 ARRAY_SIZE(bridge_start_ov965x));
895 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
896 if (mode != 0) { /* 320x240 */
897 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
898 ARRAY_SIZE(bridge_start_ov965x_cif));
899 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
900 ARRAY_SIZE(sensor_start_ov965x_cif));
901 } else { /* 640x480 */
902 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
903 ARRAY_SIZE(bridge_start_ov965x_vga));
904 sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
905 ARRAY_SIZE(sensor_start_ov965x_vga));
906 }
907 sccb_w_array(gspca_dev, sensor_start_ov965x_2,
908 ARRAY_SIZE(sensor_start_ov965x_2));
909 ov534_reg_write(gspca_dev, 0xe0, 0x00);
793 ov534_reg_write(gspca_dev, 0xe0, 0x00); 910 ov534_reg_write(gspca_dev, 0xe0, 0x00);
794 ov534_set_led(gspca_dev, 1); 911 ov534_set_led(gspca_dev, 1);
795/*fixme: other sensor start omitted*/
796 } 912 }
797 return 0; 913 return 0;
798} 914}
@@ -832,9 +948,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
832 __u32 this_pts; 948 __u32 this_pts;
833 u16 this_fid; 949 u16 this_fid;
834 int remaining_len = len; 950 int remaining_len = len;
951 int payload_len;
835 952
953 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
836 do { 954 do {
837 len = min(remaining_len, 2040); /*fixme: was 2048*/ 955 len = min(remaining_len, payload_len);
838 956
839 /* Payloads are prefixed with a UVC-style header. We 957 /* Payloads are prefixed with a UVC-style header. We
840 consider a frame to start when the FID toggles, or the PTS 958 consider a frame to start when the FID toggles, or the PTS
@@ -864,30 +982,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
864 982
865 /* If PTS or FID has changed, start a new frame. */ 983 /* If PTS or FID has changed, start a new frame. */
866 if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 984 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
867 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 985 if (gspca_dev->last_packet_type == INTER_PACKET)
868 NULL, 0); 986 frame = gspca_frame_add(gspca_dev,
987 LAST_PACKET, frame,
988 NULL, 0);
869 sd->last_pts = this_pts; 989 sd->last_pts = this_pts;
870 sd->last_fid = this_fid; 990 sd->last_fid = this_fid;
871 } 991 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
872
873 /* Add the data from this payload */
874 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
875 data + 12, len - 12); 992 data + 12, len - 12);
876
877 /* If this packet is marked as EOF, end the frame */ 993 /* If this packet is marked as EOF, end the frame */
878 if (data[1] & UVC_STREAM_EOF) { 994 } else if (data[1] & UVC_STREAM_EOF) {
879 sd->last_pts = 0; 995 sd->last_pts = 0;
880
881 if (frame->data_end - frame->data !=
882 gspca_dev->width * gspca_dev->height * 2) {
883 PDEBUG(D_PACK, "short frame");
884 goto discard;
885 }
886
887 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 996 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
888 NULL, 0); 997 data + 12, len - 12);
998 } else {
999
1000 /* Add the data from this payload */
1001 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1002 data + 12, len - 12);
889 } 1003 }
890 1004
1005
891 /* Done this payload */ 1006 /* Done this payload */
892 goto scan_next; 1007 goto scan_next;
893 1008
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 153d0a91d4b5..cf3af8de6e97 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
877 cam->cam_mode = sif_mode; 877 cam->cam_mode = sif_mode;
878 cam->nmodes = ARRAY_SIZE(sif_mode); 878 cam->nmodes = ARRAY_SIZE(sif_mode);
879 } 879 }
880 cam->npkt = 36; /* 36 packets per ISOC message */
881
880 sd->brightness = BRIGHTNESS_DEF; 882 sd->brightness = BRIGHTNESS_DEF;
881 sd->gain = GAIN_DEF; 883 sd->gain = GAIN_DEF;
882 sd->exposure = EXPOSURE_DEF; 884 sd->exposure = EXPOSURE_DEF;
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index c72e19d3ac37..dc6a6f11354a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -62,7 +62,6 @@ struct sd {
62#define BRIDGE_SN9C105 1 62#define BRIDGE_SN9C105 1
63#define BRIDGE_SN9C110 2 63#define BRIDGE_SN9C110 2
64#define BRIDGE_SN9C120 3 64#define BRIDGE_SN9C120 3
65#define BRIDGE_SN9C325 4
66 u8 sensor; /* Type of image sensor chip */ 65 u8 sensor; /* Type of image sensor chip */
67#define SENSOR_HV7131R 0 66#define SENSOR_HV7131R 0
68#define SENSOR_MI0360 1 67#define SENSOR_MI0360 1
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = {
354 353
355static const u8 sn_ov7660[0x1c] = { 354static const u8 sn_ov7660[0x1c] = {
356/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 355/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
357 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 356 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
358/* reg8 reg9 rega regb regc regd rege regf */ 357/* reg8 reg9 rega regb regc regd rege regf */
359 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 358 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 359/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
361 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 360 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
362/* reg18 reg19 reg1a reg1b */ 361/* reg18 reg19 reg1a reg1b */
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = {
757 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 756 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
758 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 757 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
759 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ 758 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
759 {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
760/****** (some exchanges in the win trace) ******/ 760/****** (some exchanges in the win trace) ******/
761 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ 761 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
762 /* bits[3..0]reserved */ 762 /* bits[3..0]reserved */
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1065 struct sd *sd = (struct sd *) gspca_dev; 1065 struct sd *sd = (struct sd *) gspca_dev;
1066 const u8 *reg9a; 1066 const u8 *reg9a;
1067 static const u8 reg9a_def[] = 1067 static const u8 reg9a_def[] =
1068 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; 1068 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1069 static const u8 reg9a_sn9c325[] = 1069 static const u8 reg9a_spec[] =
1070 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; 1070 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1071 static const u8 regd4[] = {0x60, 0x00, 0x00}; 1071 static const u8 regd4[] = {0x60, 0x00, 0x00};
1072 1072
1073 reg_w1(gspca_dev, 0xf1, 0x00); 1073 reg_w1(gspca_dev, 0xf1, 0x00);
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1077 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 1077 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1078 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); 1078 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1079 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ 1079 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
1080 switch (sd->bridge) { 1080 switch (sd->sensor) {
1081 case BRIDGE_SN9C325: 1081 case SENSOR_OV7660:
1082 reg9a = reg9a_sn9c325; 1082 case SENSOR_SP80708:
1083 reg9a = reg9a_spec;
1083 break; 1084 break;
1084 default: 1085 default:
1085 reg9a = reg9a_def; 1086 reg9a = reg9a_def;
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1104 reg_w1(gspca_dev, 0x17, 0x64); 1105 reg_w1(gspca_dev, 0x17, 0x64);
1105 reg_w1(gspca_dev, 0x01, 0x42); 1106 reg_w1(gspca_dev, 0x01, 0x42);
1106 break; 1107 break;
1107/*jfm: from win trace */
1108 case SENSOR_OV7630: 1108 case SENSOR_OV7630:
1109 reg_w1(gspca_dev, 0x01, 0x61); 1109 reg_w1(gspca_dev, 0x01, 0x61);
1110 reg_w1(gspca_dev, 0x17, 0xe2); 1110 reg_w1(gspca_dev, 0x17, 0xe2);
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1114 case SENSOR_OV7648: 1114 case SENSOR_OV7648:
1115 reg_w1(gspca_dev, 0x01, 0x63); 1115 reg_w1(gspca_dev, 0x01, 0x63);
1116 reg_w1(gspca_dev, 0x17, 0x20); 1116 reg_w1(gspca_dev, 0x17, 0x20);
1117 reg_w1(gspca_dev, 0x01, 0x62);
1117 reg_w1(gspca_dev, 0x01, 0x42); 1118 reg_w1(gspca_dev, 0x01, 0x42);
1118 break; 1119 break;
1119/*jfm: from win trace */
1120 case SENSOR_OV7660: 1120 case SENSOR_OV7660:
1121 if (sd->bridge == BRIDGE_SN9C120) { 1121 reg_w1(gspca_dev, 0x01, 0x61);
1122 reg_w1(gspca_dev, 0x01, 0x61); 1122 reg_w1(gspca_dev, 0x17, 0x20);
1123 reg_w1(gspca_dev, 0x17, 0x20); 1123 reg_w1(gspca_dev, 0x01, 0x60);
1124 reg_w1(gspca_dev, 0x01, 0x60); 1124 reg_w1(gspca_dev, 0x01, 0x40);
1125 reg_w1(gspca_dev, 0x01, 0x40); 1125 break;
1126 break;
1127 }
1128 /* fall thru */
1129 case SENSOR_SP80708: 1126 case SENSOR_SP80708:
1130 reg_w1(gspca_dev, 0x01, 0x63); 1127 reg_w1(gspca_dev, 0x01, 0x63);
1131 reg_w1(gspca_dev, 0x17, 0x20); 1128 reg_w1(gspca_dev, 0x17, 0x20);
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1134 mdelay(100); 1131 mdelay(100);
1135 reg_w1(gspca_dev, 0x02, 0x62); 1132 reg_w1(gspca_dev, 0x02, 0x62);
1136 break; 1133 break;
1134/* case SENSOR_HV7131R: */
1135/* case SENSOR_MI0360: */
1136/* case SENSOR_MO4000: */
1137 default: 1137 default:
1138 reg_w1(gspca_dev, 0x01, 0x43); 1138 reg_w1(gspca_dev, 0x01, 0x43);
1139 reg_w1(gspca_dev, 0x17, 0x61); 1139 reg_w1(gspca_dev, 0x17, 0x61);
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1280 cam = &gspca_dev->cam; 1280 cam = &gspca_dev->cam;
1281 cam->cam_mode = vga_mode; 1281 cam->cam_mode = vga_mode;
1282 cam->nmodes = ARRAY_SIZE(vga_mode); 1282 cam->nmodes = ARRAY_SIZE(vga_mode);
1283 cam->npkt = 24; /* 24 packets per ISOC message */
1283 1284
1284 sd->bridge = id->driver_info >> 16; 1285 sd->bridge = id->driver_info >> 16;
1285 sd->sensor = id->driver_info >> 8; 1286 sd->sensor = id->driver_info >> 8;
@@ -1683,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1683 case SENSOR_OV7648: 1684 case SENSOR_OV7648:
1684 reg17 = 0x20; 1685 reg17 = 0x20;
1685 break; 1686 break;
1686/*jfm: from win trace */
1687 case SENSOR_OV7660: 1687 case SENSOR_OV7660:
1688 if (sd->bridge == BRIDGE_SN9C120) { 1688 reg17 = 0xa0;
1689 reg17 = 0xa0; 1689 break;
1690 break;
1691 }
1692 /* fall thru */
1693 default: 1690 default:
1694 reg17 = 0x60; 1691 reg17 = 0x60;
1695 break; 1692 break;
@@ -1714,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
1714 reg_w1(gspca_dev, 0x9a, 0x0a); 1711 reg_w1(gspca_dev, 0x9a, 0x0a);
1715 reg_w1(gspca_dev, 0x99, 0x60); 1712 reg_w1(gspca_dev, 0x99, 0x60);
1716 break; 1713 break;
1714 case SENSOR_OV7660:
1715 reg_w1(gspca_dev, 0x9a, 0x05);
1716 if (sd->bridge == BRIDGE_SN9C105)
1717 reg_w1(gspca_dev, 0x99, 0xff);
1718 else
1719 reg_w1(gspca_dev, 0x99, 0x5b);
1720 break;
1717 case SENSOR_SP80708: 1721 case SENSOR_SP80708:
1718 reg_w1(gspca_dev, 0x9a, 0x05); 1722 reg_w1(gspca_dev, 0x9a, 0x05);
1719 reg_w1(gspca_dev, 0x99, 0x59); 1723 reg_w1(gspca_dev, 0x99, 0x59);
1720 break; 1724 break;
1721 case SENSOR_OV7660:
1722 if (sd->bridge == BRIDGE_SN9C120) {
1723 reg_w1(gspca_dev, 0x9a, 0x05);
1724 break;
1725 }
1726 /* fall thru */
1727 default: 1725 default:
1728 reg_w1(gspca_dev, 0x9a, 0x08); 1726 reg_w1(gspca_dev, 0x9a, 0x08);
1729 reg_w1(gspca_dev, 0x99, 0x59); 1727 reg_w1(gspca_dev, 0x99, 0x59);
@@ -2193,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2193 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, 2191 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2194 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 2192 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2195 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, 2193 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2194 {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
2196 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 2195 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2197/* bw600.inf: 2196/* bw600.inf:
2198 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 2197 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
@@ -2211,7 +2210,12 @@ static const __devinitdata struct usb_device_id device_table[] = {
2211#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2210#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2212 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, 2211 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2213#endif 2212#endif
2213 {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
2214/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 2214/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2215 {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
2216 {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
2217 {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
2218 {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
2215/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 2219/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2216/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 2220/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2217 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 2221 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 6f38fa6d86b6..8806b2ff82be 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 __u8 packet[ISO_MAX_SIZE + 128];
36 /* !! no more than 128 ff in an ISO packet */
37
38 unsigned char brightness; 35 unsigned char brightness;
39 unsigned char contrast; 36 unsigned char contrast;
40 unsigned char colors; 37 unsigned char colors;
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
906{ 903{
907 struct sd *sd = (struct sd *) gspca_dev; 904 struct sd *sd = (struct sd *) gspca_dev;
908 int i; 905 int i;
909 __u8 *s, *d;
910 static __u8 ffd9[] = {0xff, 0xd9}; 906 static __u8 ffd9[] = {0xff, 0xd9};
911 907
912/* frames are jpeg 4.1.1 without 0xff escape */ 908/* frames are jpeg 4.1.1 without 0xff escape */
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
930 } 926 }
931 927
932 /* add 0x00 after 0xff */ 928 /* add 0x00 after 0xff */
933 for (i = len; --i >= 0; ) 929 i = 0;
934 if (data[i] == 0xff) 930 do {
935 break; 931 if (data[i] == 0xff) {
936 if (i < 0) { /* no 0xff */ 932 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
937 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 933 data, i + 1);
938 return; 934 len -= i;
939 } 935 data += i;
940 s = data; 936 *data = 0x00;
941 d = sd->packet; 937 i = 0;
942 for (i = 0; i < len; i++) { 938 }
943 *d++ = *s++; 939 i++;
944 if (s[-1] == 0xff) 940 } while (i < len);
945 *d++ = 0x00; 941 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
946 }
947 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
948 sd->packet, d - sd->packet);
949} 942}
950 943
951static void setbrightness(struct gspca_dev *gspca_dev) 944static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2acec58b1b97..ea8c9fe2e961 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -637,19 +637,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
637 cam->nmodes = ARRAY_SIZE(vga_mode) - 1; 637 cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
638 sd->brightness = BRIGHTNESS_DEF; 638 sd->brightness = BRIGHTNESS_DEF;
639 639
640 if (sd->subtype == Nxultra) {
641 if (write_vector(gspca_dev, spca505b_init_data))
642 return -EIO;
643 } else {
644 if (write_vector(gspca_dev, spca505_init_data))
645 return -EIO;
646 }
647 return 0; 640 return 0;
648} 641}
649 642
650/* this function is called at probe and resume time */ 643/* this function is called at probe and resume time */
651static int sd_init(struct gspca_dev *gspca_dev) 644static int sd_init(struct gspca_dev *gspca_dev)
652{ 645{
646 struct sd *sd = (struct sd *) gspca_dev;
647
648 if (write_vector(gspca_dev,
649 sd->subtype == Nxultra
650 ? spca505b_init_data
651 : spca505_init_data))
652 return -EIO;
653 return 0; 653 return 0;
654} 654}
655 655
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index adacf8437661..2ed2669bac3e 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SPCA508 chip based cameras subdriver 2 * SPCA508 chip based cameras subdriver
3 * 3 *
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -30,9 +30,9 @@ MODULE_LICENSE("GPL");
30struct sd { 30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */ 31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 32
33 unsigned char brightness; 33 u8 brightness;
34 34
35 char subtype; 35 u8 subtype;
36#define CreativeVista 0 36#define CreativeVista 0
37#define HamaUSBSightcam 1 37#define HamaUSBSightcam 1
38#define HamaUSBSightcam2 2 38#define HamaUSBSightcam2 2
@@ -86,58 +86,34 @@ static const struct v4l2_pix_format sif_mode[] = {
86}; 86};
87 87
88/* Frame packet header offsets for the spca508 */ 88/* Frame packet header offsets for the spca508 */
89#define SPCA508_OFFSET_TYPE 1
90#define SPCA508_OFFSET_COMPRESS 2
91#define SPCA508_OFFSET_FRAMSEQ 8
92#define SPCA508_OFFSET_WIN1LUM 11
93#define SPCA508_OFFSET_DATA 37 89#define SPCA508_OFFSET_DATA 37
94 90
95#define SPCA508_SNAPBIT 0x20
96#define SPCA508_SNAPCTRL 0x40
97/*************** I2c ****************/
98#define SPCA508_INDEX_I2C_BASE 0x8800
99
100/* 91/*
101 * Initialization data: this is the first set-up data written to the 92 * Initialization data: this is the first set-up data written to the
102 * device (before the open data). 93 * device (before the open data).
103 */ 94 */
104static const u16 spca508_init_data[][2] = 95static const u16 spca508_init_data[][2] =
105{ 96{
106 /* line URB value, index */ 97 {0x0000, 0x870b},
107 /* 44274 1804 */ {0x0000, 0x870b}, 98
108 99 {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
109 /* 44299 1805 */ {0x0020, 0x8112}, 100 {0x0003, 0x8111}, /* Reset compression & memory */
110 /* Video drop enable, ISO streaming disable */ 101 {0x0000, 0x8110}, /* Disable all outputs */
111 /* 44324 1806 */ {0x0003, 0x8111}, 102 /* READ {0x0000, 0x8114} -> 0000: 00 */
112 /* Reset compression & memory */ 103 {0x0000, 0x8114}, /* SW GPIO data */
113 /* 44349 1807 */ {0x0000, 0x8110}, 104 {0x0008, 0x8110}, /* Enable charge pump output */
114 /* Disable all outputs */ 105 {0x0002, 0x8116}, /* 200 kHz pump clock */
115 /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ 106 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
116 /* 44398 1809 */ {0x0000, 0x8114}, 107 {0x0003, 0x8111}, /* Reset compression & memory */
117 /* SW GPIO data */ 108 {0x0000, 0x8111}, /* Normal mode (not reset) */
118 /* 44423 1810 */ {0x0008, 0x8110}, 109 {0x0098, 0x8110},
119 /* Enable charge pump output */ 110 /* Enable charge pump output, sync.serial,external 2x clock */
120 /* 44527 1811 */ {0x0002, 0x8116}, 111 {0x000d, 0x8114}, /* SW GPIO data */
121 /* 200 kHz pump clock */ 112 {0x0002, 0x8116}, /* 200 kHz pump clock */
122 /* 44555 1812 */ 113 {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
123 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
124 /* 44590 1813 */ {0x0003, 0x8111},
125 /* Reset compression & memory */
126 /* 44615 1814 */ {0x0000, 0x8111},
127 /* Normal mode (not reset) */
128 /* 44640 1815 */ {0x0098, 0x8110},
129 /* Enable charge pump output, sync.serial,external 2x clock */
130 /* 44665 1816 */ {0x000d, 0x8114},
131 /* SW GPIO data */
132 /* 44690 1817 */ {0x0002, 0x8116},
133 /* 200 kHz pump clock */
134 /* 44715 1818 */ {0x0020, 0x8112},
135 /* Video drop enable, ISO streaming disable */
136/* --------------------------------------- */ 114/* --------------------------------------- */
137 /* 44740 1819 */ {0x000f, 0x8402}, 115 {0x000f, 0x8402}, /* memory bank */
138 /* memory bank */ 116 {0x0000, 0x8403}, /* ... address */
139 /* 44765 1820 */ {0x0000, 0x8403},
140 /* ... address */
141/* --------------------------------------- */ 117/* --------------------------------------- */
142/* 0x88__ is Synchronous Serial Interface. */ 118/* 0x88__ is Synchronous Serial Interface. */
143/* TBD: This table could be expressed more compactly */ 119/* TBD: This table could be expressed more compactly */
@@ -145,446 +121,384 @@ static const u16 spca508_init_data[][2] =
145/* TBD: Should see if the values in spca50x_i2c_data */ 121/* TBD: Should see if the values in spca50x_i2c_data */
146/* would work with the VQ110 instead of the values */ 122/* would work with the VQ110 instead of the values */
147/* below. */ 123/* below. */
148 /* 44790 1821 */ {0x00c0, 0x8804}, 124 {0x00c0, 0x8804}, /* SSI slave addr */
149 /* SSI slave addr */ 125 {0x0008, 0x8802}, /* 375 Khz SSI clock */
150 /* 44815 1822 */ {0x0008, 0x8802}, 126 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
151 /* 375 Khz SSI clock */ 127 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
152 /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 128 {0x0008, 0x8802}, /* 375 Khz SSI clock */
153 /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 129 {0x0012, 0x8801}, /* SSI reg addr */
154 /* 44888 1825 */ {0x0008, 0x8802}, 130 {0x0080, 0x8800}, /* SSI data to write */
155 /* 375 Khz SSI clock */ 131 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
156 /* 44913 1826 */ {0x0012, 0x8801}, 132 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
157 /* SSI reg addr */ 133 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
158 /* 44938 1827 */ {0x0080, 0x8800}, 134 {0x0008, 0x8802}, /* 375 Khz SSI clock */
159 /* SSI data to write */ 135 {0x0012, 0x8801}, /* SSI reg addr */
160 /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 136 {0x0000, 0x8800}, /* SSI data to write */
161 /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 137 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
162 /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 138 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
163 /* 45035 1831 */ {0x0008, 0x8802}, 139 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
164 /* 375 Khz SSI clock */ 140 {0x0008, 0x8802}, /* 375 Khz SSI clock */
165 /* 45060 1832 */ {0x0012, 0x8801}, 141 {0x0011, 0x8801}, /* SSI reg addr */
166 /* SSI reg addr */ 142 {0x0040, 0x8800}, /* SSI data to write */
167 /* 45085 1833 */ {0x0000, 0x8800}, 143 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
168 /* SSI data to write */ 144 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
169 /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 145 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
170 /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 146 {0x0008, 0x8802},
171 /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 147 {0x0013, 0x8801},
172 /* 45182 1837 */ {0x0008, 0x8802}, 148 {0x0000, 0x8800},
173 /* 375 Khz SSI clock */ 149 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
174 /* 45207 1838 */ {0x0011, 0x8801}, 150 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
175 /* SSI reg addr */ 151 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
176 /* 45232 1839 */ {0x0040, 0x8800}, 152 {0x0008, 0x8802},
177 /* SSI data to write */ 153 {0x0014, 0x8801},
178 /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 154 {0x0000, 0x8800},
179 /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 155 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
180 /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 156 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
181 /* 45329 1843 */ {0x0008, 0x8802}, 157 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
182 /* 45354 1844 */ {0x0013, 0x8801}, 158 {0x0008, 0x8802},
183 /* 45379 1845 */ {0x0000, 0x8800}, 159 {0x0015, 0x8801},
184 /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 160 {0x0001, 0x8800},
185 /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 161 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
186 /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 162 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
187 /* 45476 1849 */ {0x0008, 0x8802}, 163 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
188 /* 45501 1850 */ {0x0014, 0x8801}, 164 {0x0008, 0x8802},
189 /* 45526 1851 */ {0x0000, 0x8800}, 165 {0x0016, 0x8801},
190 /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 166 {0x0003, 0x8800},
191 /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 167 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
192 /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 168 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
193 /* 45623 1855 */ {0x0008, 0x8802}, 169 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
194 /* 45648 1856 */ {0x0015, 0x8801}, 170 {0x0008, 0x8802},
195 /* 45673 1857 */ {0x0001, 0x8800}, 171 {0x0017, 0x8801},
196 /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 172 {0x0036, 0x8800},
197 /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 173 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
198 /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 174 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
199 /* 45770 1861 */ {0x0008, 0x8802}, 175 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
200 /* 45795 1862 */ {0x0016, 0x8801}, 176 {0x0008, 0x8802},
201 /* 45820 1863 */ {0x0003, 0x8800}, 177 {0x0018, 0x8801},
202 /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 178 {0x00ec, 0x8800},
203 /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 179 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
204 /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 180 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
205 /* 45917 1867 */ {0x0008, 0x8802}, 181 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
206 /* 45942 1868 */ {0x0017, 0x8801}, 182 {0x0008, 0x8802},
207 /* 45967 1869 */ {0x0036, 0x8800}, 183 {0x001a, 0x8801},
208 /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 184 {0x0094, 0x8800},
209 /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 185 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
210 /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 186 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
211 /* 46064 1873 */ {0x0008, 0x8802}, 187 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
212 /* 46089 1874 */ {0x0018, 0x8801}, 188 {0x0008, 0x8802},
213 /* 46114 1875 */ {0x00ec, 0x8800}, 189 {0x001b, 0x8801},
214 /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 190 {0x0000, 0x8800},
215 /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 191 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
216 /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 192 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
217 /* 46211 1879 */ {0x0008, 0x8802}, 193 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
218 /* 46236 1880 */ {0x001a, 0x8801}, 194 {0x0008, 0x8802},
219 /* 46261 1881 */ {0x0094, 0x8800}, 195 {0x0027, 0x8801},
220 /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 196 {0x00a2, 0x8800},
221 /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 197 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
222 /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 198 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
223 /* 46358 1885 */ {0x0008, 0x8802}, 199 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
224 /* 46383 1886 */ {0x001b, 0x8801}, 200 {0x0008, 0x8802},
225 /* 46408 1887 */ {0x0000, 0x8800}, 201 {0x0028, 0x8801},
226 /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 202 {0x0040, 0x8800},
227 /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 203 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
228 /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 204 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
229 /* 46505 1891 */ {0x0008, 0x8802}, 205 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
230 /* 46530 1892 */ {0x0027, 0x8801}, 206 {0x0008, 0x8802},
231 /* 46555 1893 */ {0x00a2, 0x8800}, 207 {0x002a, 0x8801},
232 /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 208 {0x0084, 0x8800},
233 /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 209 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
234 /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 210 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
235 /* 46652 1897 */ {0x0008, 0x8802}, 211 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
236 /* 46677 1898 */ {0x0028, 0x8801}, 212 {0x0008, 0x8802},
237 /* 46702 1899 */ {0x0040, 0x8800}, 213 {0x002b, 0x8801},
238 /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 214 {0x00a8, 0x8800},
239 /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 215 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
240 /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 216 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
241 /* 46799 1903 */ {0x0008, 0x8802}, 217 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
242 /* 46824 1904 */ {0x002a, 0x8801}, 218 {0x0008, 0x8802},
243 /* 46849 1905 */ {0x0084, 0x8800}, 219 {0x002c, 0x8801},
244 /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 220 {0x00fe, 0x8800},
245 /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 221 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
246 /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 222 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
247 /* 46946 1909 */ {0x0008, 0x8802}, 223 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
248 /* 46971 1910 */ {0x002b, 0x8801}, 224 {0x0008, 0x8802},
249 /* 46996 1911 */ {0x00a8, 0x8800}, 225 {0x002d, 0x8801},
250 /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 226 {0x0003, 0x8800},
251 /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 227 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
252 /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 228 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
253 /* 47093 1915 */ {0x0008, 0x8802}, 229 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
254 /* 47118 1916 */ {0x002c, 0x8801}, 230 {0x0008, 0x8802},
255 /* 47143 1917 */ {0x00fe, 0x8800}, 231 {0x0038, 0x8801},
256 /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 232 {0x0083, 0x8800},
257 /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 233 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
258 /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 234 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
259 /* 47240 1921 */ {0x0008, 0x8802}, 235 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
260 /* 47265 1922 */ {0x002d, 0x8801}, 236 {0x0008, 0x8802},
261 /* 47290 1923 */ {0x0003, 0x8800}, 237 {0x0033, 0x8801},
262 /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 238 {0x0081, 0x8800},
263 /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 239 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
264 /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 240 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
265 /* 47387 1927 */ {0x0008, 0x8802}, 241 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
266 /* 47412 1928 */ {0x0038, 0x8801}, 242 {0x0008, 0x8802},
267 /* 47437 1929 */ {0x0083, 0x8800}, 243 {0x0034, 0x8801},
268 /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 244 {0x004a, 0x8800},
269 /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 245 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
270 /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 246 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
271 /* 47534 1933 */ {0x0008, 0x8802}, 247 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
272 /* 47559 1934 */ {0x0033, 0x8801}, 248 {0x0008, 0x8802},
273 /* 47584 1935 */ {0x0081, 0x8800}, 249 {0x0039, 0x8801},
274 /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 250 {0x0000, 0x8800},
275 /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 251 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
276 /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 252 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
277 /* 47681 1939 */ {0x0008, 0x8802}, 253 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
278 /* 47706 1940 */ {0x0034, 0x8801}, 254 {0x0008, 0x8802},
279 /* 47731 1941 */ {0x004a, 0x8800}, 255 {0x0010, 0x8801},
280 /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 256 {0x00a8, 0x8800},
281 /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 257 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
282 /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 258 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
283 /* 47828 1945 */ {0x0008, 0x8802}, 259 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
284 /* 47853 1946 */ {0x0039, 0x8801}, 260 {0x0008, 0x8802},
285 /* 47878 1947 */ {0x0000, 0x8800}, 261 {0x0006, 0x8801},
286 /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 262 {0x0058, 0x8800},
287 /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 263 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
288 /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 264 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
289 /* 47975 1951 */ {0x0008, 0x8802}, 265 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
290 /* 48000 1952 */ {0x0010, 0x8801}, 266 {0x0008, 0x8802},
291 /* 48025 1953 */ {0x00a8, 0x8800}, 267 {0x0000, 0x8801},
292 /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 268 {0x0004, 0x8800},
293 /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 269 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
294 /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 270 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
295 /* 48122 1957 */ {0x0008, 0x8802}, 271 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
296 /* 48147 1958 */ {0x0006, 0x8801}, 272 {0x0008, 0x8802},
297 /* 48172 1959 */ {0x0058, 0x8800}, 273 {0x0040, 0x8801},
298 /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 274 {0x0080, 0x8800},
299 /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 275 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
300 /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 276 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
301 /* 48269 1963 */ {0x0008, 0x8802}, 277 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
302 /* 48294 1964 */ {0x0000, 0x8801}, 278 {0x0008, 0x8802},
303 /* 48319 1965 */ {0x0004, 0x8800}, 279 {0x0041, 0x8801},
304 /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 280 {0x000c, 0x8800},
305 /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 281 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
306 /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 282 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
307 /* 48416 1969 */ {0x0008, 0x8802}, 283 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
308 /* 48441 1970 */ {0x0040, 0x8801}, 284 {0x0008, 0x8802},
309 /* 48466 1971 */ {0x0080, 0x8800}, 285 {0x0042, 0x8801},
310 /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 286 {0x000c, 0x8800},
311 /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 287 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
312 /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 288 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
313 /* 48563 1975 */ {0x0008, 0x8802}, 289 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
314 /* 48588 1976 */ {0x0041, 0x8801}, 290 {0x0008, 0x8802},
315 /* 48613 1977 */ {0x000c, 0x8800}, 291 {0x0043, 0x8801},
316 /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 292 {0x0028, 0x8800},
317 /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 293 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
318 /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 294 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
319 /* 48710 1981 */ {0x0008, 0x8802}, 295 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
320 /* 48735 1982 */ {0x0042, 0x8801}, 296 {0x0008, 0x8802},
321 /* 48760 1983 */ {0x000c, 0x8800}, 297 {0x0044, 0x8801},
322 /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 298 {0x0080, 0x8800},
323 /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 299 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
324 /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 300 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
325 /* 48857 1987 */ {0x0008, 0x8802}, 301 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
326 /* 48882 1988 */ {0x0043, 0x8801}, 302 {0x0008, 0x8802},
327 /* 48907 1989 */ {0x0028, 0x8800}, 303 {0x0045, 0x8801},
328 /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 304 {0x0020, 0x8800},
329 /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 305 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
330 /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 306 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
331 /* 49004 1993 */ {0x0008, 0x8802}, 307 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
332 /* 49029 1994 */ {0x0044, 0x8801}, 308 {0x0008, 0x8802},
333 /* 49054 1995 */ {0x0080, 0x8800}, 309 {0x0046, 0x8801},
334 /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 310 {0x0020, 0x8800},
335 /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 311 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
336 /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 312 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
337 /* 49151 1999 */ {0x0008, 0x8802}, 313 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
338 /* 49176 2000 */ {0x0045, 0x8801}, 314 {0x0008, 0x8802},
339 /* 49201 2001 */ {0x0020, 0x8800}, 315 {0x0047, 0x8801},
340 /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 316 {0x0080, 0x8800},
341 /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 317 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
342 /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 318 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
343 /* 49298 2005 */ {0x0008, 0x8802}, 319 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
344 /* 49323 2006 */ {0x0046, 0x8801}, 320 {0x0008, 0x8802},
345 /* 49348 2007 */ {0x0020, 0x8800}, 321 {0x0048, 0x8801},
346 /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 322 {0x004c, 0x8800},
347 /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 323 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
348 /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 324 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
349 /* 49445 2011 */ {0x0008, 0x8802}, 325 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
350 /* 49470 2012 */ {0x0047, 0x8801}, 326 {0x0008, 0x8802},
351 /* 49495 2013 */ {0x0080, 0x8800}, 327 {0x0049, 0x8801},
352 /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 328 {0x0084, 0x8800},
353 /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 329 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
354 /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 330 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
355 /* 49592 2017 */ {0x0008, 0x8802}, 331 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
356 /* 49617 2018 */ {0x0048, 0x8801}, 332 {0x0008, 0x8802},
357 /* 49642 2019 */ {0x004c, 0x8800}, 333 {0x004a, 0x8801},
358 /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 334 {0x0084, 0x8800},
359 /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 335 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
360 /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 336 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
361 /* 49739 2023 */ {0x0008, 0x8802}, 337 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
362 /* 49764 2024 */ {0x0049, 0x8801}, 338 {0x0008, 0x8802},
363 /* 49789 2025 */ {0x0084, 0x8800}, 339 {0x004b, 0x8801},
364 /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 340 {0x0084, 0x8800},
365 /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 341 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
366 /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
367 /* 49886 2029 */ {0x0008, 0x8802},
368 /* 49911 2030 */ {0x004a, 0x8801},
369 /* 49936 2031 */ {0x0084, 0x8800},
370 /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
371 /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
372 /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
373 /* 50033 2035 */ {0x0008, 0x8802},
374 /* 50058 2036 */ {0x004b, 0x8801},
375 /* 50083 2037 */ {0x0084, 0x8800},
376 /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
377 /* --------------------------------------- */ 342 /* --------------------------------------- */
378 /* 50132 2039 */ {0x0012, 0x8700}, 343 {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
379 /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ 344 {0x0000, 0x8701}, /* CKx1 clock delay adj */
380 /* 50157 2040 */ {0x0000, 0x8701}, 345 {0x0000, 0x8701}, /* CKx1 clock delay adj */
381 /* CKx1 clock delay adj */ 346 {0x0001, 0x870c}, /* CKOx2 output */
382 /* 50182 2041 */ {0x0000, 0x8701},
383 /* CKx1 clock delay adj */
384 /* 50207 2042 */ {0x0001, 0x870c},
385 /* CKOx2 output */
386 /* --------------------------------------- */ 347 /* --------------------------------------- */
387 /* 50232 2043 */ {0x0080, 0x8600}, 348 {0x0080, 0x8600}, /* Line memory read counter (L) */
388 /* Line memory read counter (L) */ 349 {0x0001, 0x8606}, /* reserved */
389 /* 50257 2044 */ {0x0001, 0x8606}, 350 {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */
390 /* reserved */ 351 {0x002a, 0x8601}, /* CDSP sharp interpolation mode,
391 /* 50282 2045 */ {0x0064, 0x8607},
392 /* Line memory read counter (H) 0x6480=25,728 */
393 /* 50307 2046 */ {0x002a, 0x8601},
394 /* CDSP sharp interpolation mode,
395 * line sel for color sep, edge enhance enab */ 352 * line sel for color sep, edge enhance enab */
396 /* 50332 2047 */ {0x0000, 0x8602}, 353 {0x0000, 0x8602}, /* optical black level for user settng = 0 */
397 /* optical black level for user settng = 0 */ 354 {0x0080, 0x8600}, /* Line memory read counter (L) */
398 /* 50357 2048 */ {0x0080, 0x8600}, 355 {0x000a, 0x8603}, /* optical black level calc mode:
399 /* Line memory read counter (L) */ 356 * auto; optical black offset = 10 */
400 /* 50382 2049 */ {0x000a, 0x8603}, 357 {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */
401 /* optical black level calc mode: auto; optical black offset = 10 */ 358 {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */
402 /* 50407 2050 */ {0x00df, 0x865b},
403 /* Horiz offset for valid pixels (L)=0xdf */
404 /* 50432 2051 */ {0x0012, 0x865c},
405 /* Vert offset for valid lines (L)=0x12 */
406 359
407/* The following two lines seem to be the "wrong" resolution. */ 360/* The following two lines seem to be the "wrong" resolution. */
408/* But perhaps these indicate the actual size of the sensor */ 361/* But perhaps these indicate the actual size of the sensor */
409/* rather than the size of the current video mode. */ 362/* rather than the size of the current video mode. */
410 /* 50457 2052 */ {0x0058, 0x865d}, 363 {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */
411 /* Horiz valid pixels (*4) (L) = 352 */ 364 {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */
412 /* 50482 2053 */ {0x0048, 0x865e}, 365
413 /* Vert valid lines (*4) (L) = 288 */ 366 {0x0015, 0x8608}, /* A11 Coef ... */
414 367 {0x0030, 0x8609},
415 /* 50507 2054 */ {0x0015, 0x8608}, 368 {0x00fb, 0x860a},
416 /* A11 Coef ... */ 369 {0x003e, 0x860b},
417 /* 50532 2055 */ {0x0030, 0x8609}, 370 {0x00ce, 0x860c},
418 /* 50557 2056 */ {0x00fb, 0x860a}, 371 {0x00f4, 0x860d},
419 /* 50582 2057 */ {0x003e, 0x860b}, 372 {0x00eb, 0x860e},
420 /* 50607 2058 */ {0x00ce, 0x860c}, 373 {0x00dc, 0x860f},
421 /* 50632 2059 */ {0x00f4, 0x860d}, 374 {0x0039, 0x8610},
422 /* 50657 2060 */ {0x00eb, 0x860e}, 375 {0x0001, 0x8611}, /* R offset for white balance ... */
423 /* 50682 2061 */ {0x00dc, 0x860f}, 376 {0x0000, 0x8612},
424 /* 50707 2062 */ {0x0039, 0x8610}, 377 {0x0001, 0x8613},
425 /* 50732 2063 */ {0x0001, 0x8611}, 378 {0x0000, 0x8614},
426 /* R offset for white balance ... */ 379 {0x005b, 0x8651}, /* R gain for white balance ... */
427 /* 50757 2064 */ {0x0000, 0x8612}, 380 {0x0040, 0x8652},
428 /* 50782 2065 */ {0x0001, 0x8613}, 381 {0x0060, 0x8653},
429 /* 50807 2066 */ {0x0000, 0x8614}, 382 {0x0040, 0x8654},
430 /* 50832 2067 */ {0x005b, 0x8651}, 383 {0x0000, 0x8655},
431 /* R gain for white balance ... */ 384 {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control,
432 /* 50857 2068 */ {0x0040, 0x8652}, 385 * lum filter disable, lum noise clip disable */
433 /* 50882 2069 */ {0x0060, 0x8653}, 386 {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64,
434 /* 50907 2070 */ {0x0040, 0x8654}, 387 * gamma look-up disable,
435 /* 50932 2071 */ {0x0000, 0x8655}, 388 * new edge enhancement enable */
436 /* 50957 2072 */ {0x0001, 0x863f}, 389 {0x0018, 0x8657}, /* Edge gain high thresh */
437 /* Fixed gamma correction enable, USB control, 390 {0x0020, 0x8658}, /* Edge gain low thresh */
438 * lum filter disable, lum noise clip disable */ 391 {0x000a, 0x8659}, /* Edge bandwidth high threshold */
439 /* 50982 2073 */ {0x00a1, 0x8656}, 392 {0x0005, 0x865a}, /* Edge bandwidth low threshold */
440 /* Window1 size 256x256, Windows2 size 64x64,
441 * gamma look-up disable, new edge enhancement enable */
442 /* 51007 2074 */ {0x0018, 0x8657},
443 /* Edge gain high thresh */
444 /* 51032 2075 */ {0x0020, 0x8658},
445 /* Edge gain low thresh */
446 /* 51057 2076 */ {0x000a, 0x8659},
447 /* Edge bandwidth high threshold */
448 /* 51082 2077 */ {0x0005, 0x865a},
449 /* Edge bandwidth low threshold */
450 /* -------------------------------- */ 393 /* -------------------------------- */
451 /* 51107 2078 */ {0x0030, 0x8112}, 394 {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */
452 /* Video drop enable, ISO streaming enable */ 395 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
453 /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 396 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
454 /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 397 {0xa908, 0x8802},
455 /* 51180 2081 */ {0xa908, 0x8802}, 398 {0x0034, 0x8801}, /* SSI reg addr */
456 /* 51205 2082 */ {0x0034, 0x8801}, 399 {0x00ca, 0x8800},
457 /* SSI reg addr */
458 /* 51230 2083 */ {0x00ca, 0x8800},
459 /* SSI data to write */ 400 /* SSI data to write */
460 /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 401 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
461 /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 402 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
462 /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 403 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
463 /* 51327 2087 */ {0x1f08, 0x8802}, 404 {0x1f08, 0x8802},
464 /* 51352 2088 */ {0x0006, 0x8801}, 405 {0x0006, 0x8801},
465 /* 51377 2089 */ {0x0080, 0x8800}, 406 {0x0080, 0x8800},
466 /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 407 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
467 408
468/* ----- Read back coefs we wrote earlier. */ 409/* ----- Read back coefs we wrote earlier. */
469 /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ 410 /* READ { 0x0000, 0x8608 } -> 0000: 15 */
470 /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ 411 /* READ { 0x0000, 0x8609 } -> 0000: 30 */
471 /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ 412 /* READ { 0x0000, 0x860a } -> 0000: fb */
472 /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ 413 /* READ { 0x0000, 0x860b } -> 0000: 3e */
473 /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ 414 /* READ { 0x0000, 0x860c } -> 0000: ce */
474 /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ 415 /* READ { 0x0000, 0x860d } -> 0000: f4 */
475 /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ 416 /* READ { 0x0000, 0x860e } -> 0000: eb */
476 /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ 417 /* READ { 0x0000, 0x860f } -> 0000: dc */
477 /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ 418 /* READ { 0x0000, 0x8610 } -> 0000: 39 */
478 /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 419 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
479 /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 420 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
480 /* 51690 2102 */ {0xb008, 0x8802}, 421 {0xb008, 0x8802},
481 /* 51715 2103 */ {0x0006, 0x8801}, 422 {0x0006, 0x8801},
482 /* 51740 2104 */ {0x007d, 0x8800}, 423 {0x007d, 0x8800},
483 /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 424 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
484 425
485 426
486 /* This chunk is seemingly redundant with */ 427 /* This chunk is seemingly redundant with */
487 /* earlier commands (A11 Coef...), but if I disable it, */ 428 /* earlier commands (A11 Coef...), but if I disable it, */
488 /* the image appears too dark. Maybe there was some kind of */ 429 /* the image appears too dark. Maybe there was some kind of */
489 /* reset since the earlier commands, so this is necessary again. */ 430 /* reset since the earlier commands, so this is necessary again. */
490 /* 51789 2106 */ {0x0015, 0x8608}, 431 {0x0015, 0x8608},
491 /* 51814 2107 */ {0x0030, 0x8609}, 432 {0x0030, 0x8609},
492 /* 51839 2108 */ {0xfffb, 0x860a}, 433 {0xfffb, 0x860a},
493 /* 51864 2109 */ {0x003e, 0x860b}, 434 {0x003e, 0x860b},
494 /* 51889 2110 */ {0xffce, 0x860c}, 435 {0xffce, 0x860c},
495 /* 51914 2111 */ {0xfff4, 0x860d}, 436 {0xfff4, 0x860d},
496 /* 51939 2112 */ {0xffeb, 0x860e}, 437 {0xffeb, 0x860e},
497 /* 51964 2113 */ {0xffdc, 0x860f}, 438 {0xffdc, 0x860f},
498 /* 51989 2114 */ {0x0039, 0x8610}, 439 {0x0039, 0x8610},
499 /* 52014 2115 */ {0x0018, 0x8657}, 440 {0x0018, 0x8657},
500 441
501 /* 52039 2116 */ {0x0000, 0x8508}, 442 {0x0000, 0x8508}, /* Disable compression. */
502 /* Disable compression. */
503 /* Previous line was: 443 /* Previous line was:
504 * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ 444 {0x0021, 0x8508}, * Enable compression. */
505 /* 52064 2117 */ {0x0032, 0x850b}, 445 {0x0032, 0x850b}, /* compression stuff */
506 /* compression stuff */ 446 {0x0003, 0x8509}, /* compression stuff */
507 /* 52089 2118 */ {0x0003, 0x8509}, 447 {0x0011, 0x850a}, /* compression stuff */
508 /* compression stuff */ 448 {0x0021, 0x850d}, /* compression stuff */
509 /* 52114 2119 */ {0x0011, 0x850a}, 449 {0x0010, 0x850c}, /* compression stuff */
510 /* compression stuff */ 450 {0x0003, 0x8500}, /* *** Video mode: 160x120 */
511 /* 52139 2120 */ {0x0021, 0x850d}, 451 {0x0001, 0x8501}, /* Hardware-dominated snap control */
512 /* compression stuff */ 452 {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128,
513 /* 52164 2121 */ {0x0010, 0x850c}, 453 * gamma look-up disable,
514 /* compression stuff */ 454 * new edge enhancement enable */
515 /* 52189 2122 */ {0x0003, 0x8500}, 455 {0x0018, 0x8617}, /* Window1 start X (*2) */
516 /* *** Video mode: 160x120 */ 456 {0x0008, 0x8618}, /* Window1 start Y (*2) */
517 /* 52214 2123 */ {0x0001, 0x8501}, 457 {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128,
518 /* Hardware-dominated snap control */ 458 * gamma look-up disable,
519 /* 52239 2124 */ {0x0061, 0x8656}, 459 * new edge enhancement enable */
520 /* Window1 size 128x128, Windows2 size 128x128, 460 {0x0058, 0x8619}, /* Window2 start X (*2) */
521 * gamma look-up disable, new edge enhancement enable */ 461 {0x0008, 0x861a}, /* Window2 start Y (*2) */
522 /* 52264 2125 */ {0x0018, 0x8617}, 462 {0x00ff, 0x8615}, /* High lum thresh for white balance */
523 /* Window1 start X (*2) */ 463 {0x0000, 0x8616}, /* Low lum thresh for white balance */
524 /* 52289 2126 */ {0x0008, 0x8618}, 464 {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
525 /* Window1 start Y (*2) */ 465 {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
526 /* 52314 2127 */ {0x0061, 0x8656}, 466 /* READ { 0x0000, 0x8656 } -> 0000: 61 */
527 /* Window1 size 128x128, Windows2 size 128x128, 467 {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
528 * gamma look-up disable, new edge enhancement enable */ 468 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
529 /* 52339 2128 */ {0x0058, 0x8619}, 469 /* READ { 0x0001, 0x8802 } -> 0000: 28 */
530 /* Window2 start X (*2) */ 470 {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
531 /* 52364 2129 */ {0x0008, 0x861a}, 471 {0x0010, 0x8801}, /* SSI reg addr */
532 /* Window2 start Y (*2) */ 472 {0x003e, 0x8800}, /* SSI data to write */
533 /* 52389 2130 */ {0x00ff, 0x8615}, 473 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
534 /* High lum thresh for white balance */ 474 {0x0028, 0x8802},
535 /* 52414 2131 */ {0x0000, 0x8616}, 475 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
536 /* Low lum thresh for white balance */ 476 /* READ { 0x0001, 0x8802 } -> 0000: 28 */
537 /* 52439 2132 */ {0x0012, 0x8700}, 477 {0x1f28, 0x8802},
538 /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ 478 {0x0000, 0x8801},
539 /* 52464 2133 */ {0x0012, 0x8700}, 479 {0x001f, 0x8800},
540 /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ 480 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
541 /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ 481 {0x0001, 0x8602}, /* optical black level for user settning = 1 */
542 /* 52513 2135 */ {0x0028, 0x8802},
543 /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
544 /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
545 /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
546 /* 52586 2138 */ {0x1f28, 0x8802},
547 /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
548 /* 52611 2139 */ {0x0010, 0x8801},
549 /* SSI reg addr */
550 /* 52636 2140 */ {0x003e, 0x8800},
551 /* SSI data to write */
552 /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
553 /* 52685 2142 */ {0x0028, 0x8802},
554 /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
555 /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
556 /* 52758 2145 */ {0x1f28, 0x8802},
557 /* 52783 2146 */ {0x0000, 0x8801},
558 /* 52808 2147 */ {0x001f, 0x8800},
559 /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
560 /* 52857 2149 */ {0x0001, 0x8602},
561 /* optical black level for user settning = 1 */
562 482
563 /* Original: */ 483 /* Original: */
564 /* 52882 2150 */ {0x0023, 0x8700}, 484 {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
565 /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ 485 {0x000f, 0x8602}, /* optical black level for user settning = 15 */
566 /* 52907 2151 */ {0x000f, 0x8602}, 486
567 /* optical black level for user settning = 15 */ 487 {0x0028, 0x8802},
568 488 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
569 /* 52932 2152 */ {0x0028, 0x8802}, 489 /* READ { 0x0001, 0x8802 } -> 0000: 28 */
570 /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 490 {0x1f28, 0x8802},
571 /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ 491 {0x0010, 0x8801},
572 /* 53005 2155 */ {0x1f28, 0x8802}, 492 {0x007b, 0x8800},
573 /* 53030 2156 */ {0x0010, 0x8801}, 493 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
574 /* 53055 2157 */ {0x007b, 0x8800}, 494 {0x002f, 0x8651}, /* R gain for white balance ... */
575 /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 495 {0x0080, 0x8653},
576 /* 53104 2159 */ {0x002f, 0x8651}, 496 /* READ { 0x0000, 0x8655 } -> 0000: 00 */
577 /* R gain for white balance ... */ 497 {0x0000, 0x8655},
578 /* 53129 2160 */ {0x0080, 0x8653}, 498
579 /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ 499 {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */
580 /* 53178 2162 */ {0x0000, 0x8655}, 500 {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
581 501 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
582 /* 53203 2163 */ {0x0030, 0x8112},
583 /* Video drop enable, ISO streaming enable */
584 /* 53228 2164 */ {0x0020, 0x8112},
585 /* Video drop enable, ISO streaming disable */
586 /* 53252 2165 */
587 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
588 {} 502 {}
589}; 503};
590 504
@@ -592,27 +506,27 @@ static const u16 spca508_init_data[][2] =
592 * Initialization data for Intel EasyPC Camera CS110 506 * Initialization data for Intel EasyPC Camera CS110
593 */ 507 */
594static const u16 spca508cs110_init_data[][2] = { 508static const u16 spca508cs110_init_data[][2] = {
595 {0x0000, 0x870b}, /* Reset CTL3 */ 509 {0x0000, 0x870b}, /* Reset CTL3 */
596 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ 510 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
597 {0x0000, 0x8111}, /* Normal operation on reset */ 511 {0x0000, 0x8111}, /* Normal operation on reset */
598 {0x0090, 0x8110}, 512 {0x0090, 0x8110},
599 /* External Clock 2x & Synchronous Serial Interface Output */ 513 /* External Clock 2x & Synchronous Serial Interface Output */
600 {0x0020, 0x8112}, /* Video Drop packet enable */ 514 {0x0020, 0x8112}, /* Video Drop packet enable */
601 {0x0000, 0x8114}, /* Software GPIO output data */ 515 {0x0000, 0x8114}, /* Software GPIO output data */
602 {0x0001, 0x8114}, 516 {0x0001, 0x8114},
603 {0x0001, 0x8114}, 517 {0x0001, 0x8114},
604 {0x0001, 0x8114}, 518 {0x0001, 0x8114},
605 {0x0003, 0x8114}, 519 {0x0003, 0x8114},
606 520
607 /* Initial sequence Synchronous Serial Interface */ 521 /* Initial sequence Synchronous Serial Interface */
608 {0x000f, 0x8402}, /* Memory bank Address */ 522 {0x000f, 0x8402}, /* Memory bank Address */
609 {0x0000, 0x8403}, /* Memory bank Address */ 523 {0x0000, 0x8403}, /* Memory bank Address */
610 {0x00ba, 0x8804}, /* SSI Slave address */ 524 {0x00ba, 0x8804}, /* SSI Slave address */
611 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ 525 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
612 {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ 526 {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */
613 527
614 {0x0001, 0x8801}, 528 {0x0001, 0x8801},
615 {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ 529 {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */
616 {0x0000, 0x8800}, 530 {0x0000, 0x8800},
617 {0x0010, 0x8802}, 531 {0x0010, 0x8802},
618 532
@@ -646,459 +560,459 @@ static const u16 spca508cs110_init_data[][2] = {
646 {0x0000, 0x8800}, 560 {0x0000, 0x8800},
647 {0x0010, 0x8802}, 561 {0x0010, 0x8802},
648 562
649 {0x0002, 0x8704}, /* External input CKIx1 */ 563 {0x0002, 0x8704}, /* External input CKIx1 */
650 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ 564 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
651 {0x009a, 0x8600}, /* Line memory Read Counter (L) */ 565 {0x009a, 0x8600}, /* Line memory Read Counter (L) */
652 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ 566 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
653 {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ 567 {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */
654 {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ 568 {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */
655 569
656 {0x0006, 0x8660}, /* Nibble data + input order */ 570 {0x0006, 0x8660}, /* Nibble data + input order */
657 571
658 {0x000a, 0x8602}, /* Optical black level set to 0x0a */ 572 {0x000a, 0x8602}, /* Optical black level set to 0x0a */
659/* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ 573 {0x0000, 0x8603}, /* Optical black level Offset */
660 574
661/* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ 575/* {0x0000, 0x8611}, * 0 R Offset for white Balance */
662/* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ 576/* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */
663/* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ 577/* {0x0000, 0x8613}, * 1f B Offset for white Balance */
664/* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ 578/* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */
665 579
666 {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ 580 {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */
667 {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ 581 {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */
668 {0x0035, 0x8653}, /* 26 RED gain for white balance */ 582 {0x0035, 0x8653}, /* 26 RED gain for white balance */
669 {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ 583 {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */
670 {0x0041, 0x863f}, 584 {0x0041, 0x863f},
671 /* Fixed Gamma correction enabled (makes colours look better) */ 585 /* Fixed Gamma correction enabled (makes colours look better) */
672 586
673/* 2422 */ {0x0000, 0x8655}, 587 {0x0000, 0x8655},
674 /* High bits for white balance*****brightness control*** */ 588 /* High bits for white balance*****brightness control*** */
675 {} 589 {}
676}; 590};
677 591
678static const u16 spca508_sightcam_init_data[][2] = { 592static const u16 spca508_sightcam_init_data[][2] = {
679/* This line seems to setup the frame/canvas */ 593/* This line seems to setup the frame/canvas */
680 /*368 */ {0x000f, 0x8402}, 594 {0x000f, 0x8402},
681 595
682/* Theese 6 lines are needed to startup the webcam */ 596/* Theese 6 lines are needed to startup the webcam */
683 /*398 */ {0x0090, 0x8110}, 597 {0x0090, 0x8110},
684 /*399 */ {0x0001, 0x8114}, 598 {0x0001, 0x8114},
685 /*400 */ {0x0001, 0x8114}, 599 {0x0001, 0x8114},
686 /*401 */ {0x0001, 0x8114}, 600 {0x0001, 0x8114},
687 /*402 */ {0x0003, 0x8114}, 601 {0x0003, 0x8114},
688 /*403 */ {0x0080, 0x8804}, 602 {0x0080, 0x8804},
689 603
690/* This part seems to make the pictures darker? (autobrightness?) */ 604/* This part seems to make the pictures darker? (autobrightness?) */
691 /*436 */ {0x0001, 0x8801}, 605 {0x0001, 0x8801},
692 /*437 */ {0x0004, 0x8800}, 606 {0x0004, 0x8800},
693 /*439 */ {0x0003, 0x8801}, 607 {0x0003, 0x8801},
694 /*440 */ {0x00e0, 0x8800}, 608 {0x00e0, 0x8800},
695 /*442 */ {0x0004, 0x8801}, 609 {0x0004, 0x8801},
696 /*443 */ {0x00b4, 0x8800}, 610 {0x00b4, 0x8800},
697 /*445 */ {0x0005, 0x8801}, 611 {0x0005, 0x8801},
698 /*446 */ {0x0000, 0x8800}, 612 {0x0000, 0x8800},
699 613
700 /*448 */ {0x0006, 0x8801}, 614 {0x0006, 0x8801},
701 /*449 */ {0x00e0, 0x8800}, 615 {0x00e0, 0x8800},
702 /*451 */ {0x0007, 0x8801}, 616 {0x0007, 0x8801},
703 /*452 */ {0x000c, 0x8800}, 617 {0x000c, 0x8800},
704 618
705/* This section is just needed, it probably 619/* This section is just needed, it probably
706 * does something like the previous section, 620 * does something like the previous section,
707 * but the cam won't start if it's not included. 621 * but the cam won't start if it's not included.
708 */ 622 */
709 /*484 */ {0x0014, 0x8801}, 623 {0x0014, 0x8801},
710 /*485 */ {0x0008, 0x8800}, 624 {0x0008, 0x8800},
711 /*487 */ {0x0015, 0x8801}, 625 {0x0015, 0x8801},
712 /*488 */ {0x0067, 0x8800}, 626 {0x0067, 0x8800},
713 /*490 */ {0x0016, 0x8801}, 627 {0x0016, 0x8801},
714 /*491 */ {0x0000, 0x8800}, 628 {0x0000, 0x8800},
715 /*493 */ {0x0017, 0x8801}, 629 {0x0017, 0x8801},
716 /*494 */ {0x0020, 0x8800}, 630 {0x0020, 0x8800},
717 /*496 */ {0x0018, 0x8801}, 631 {0x0018, 0x8801},
718 /*497 */ {0x0044, 0x8800}, 632 {0x0044, 0x8800},
719 633
720/* Makes the picture darker - and the 634/* Makes the picture darker - and the
721 * cam won't start if not included 635 * cam won't start if not included
722 */ 636 */
723 /*505 */ {0x001e, 0x8801}, 637 {0x001e, 0x8801},
724 /*506 */ {0x00ea, 0x8800}, 638 {0x00ea, 0x8800},
725 /*508 */ {0x001f, 0x8801}, 639 {0x001f, 0x8801},
726 /*509 */ {0x0001, 0x8800}, 640 {0x0001, 0x8800},
727 /*511 */ {0x0003, 0x8801}, 641 {0x0003, 0x8801},
728 /*512 */ {0x00e0, 0x8800}, 642 {0x00e0, 0x8800},
729 643
730/* seems to place the colors ontop of each other #1 */ 644/* seems to place the colors ontop of each other #1 */
731 /*517 */ {0x0006, 0x8704}, 645 {0x0006, 0x8704},
732 /*518 */ {0x0001, 0x870c}, 646 {0x0001, 0x870c},
733 /*519 */ {0x0016, 0x8600}, 647 {0x0016, 0x8600},
734 /*520 */ {0x0002, 0x8606}, 648 {0x0002, 0x8606},
735 649
736/* if not included the pictures becomes _very_ dark */ 650/* if not included the pictures becomes _very_ dark */
737 /*521 */ {0x0064, 0x8607}, 651 {0x0064, 0x8607},
738 /*522 */ {0x003a, 0x8601}, 652 {0x003a, 0x8601},
739 /*523 */ {0x0000, 0x8602}, 653 {0x0000, 0x8602},
740 654
741/* seems to place the colors ontop of each other #2 */ 655/* seems to place the colors ontop of each other #2 */
742 /*524 */ {0x0016, 0x8600}, 656 {0x0016, 0x8600},
743 /*525 */ {0x0018, 0x8617}, 657 {0x0018, 0x8617},
744 /*526 */ {0x0008, 0x8618}, 658 {0x0008, 0x8618},
745 /*527 */ {0x00a1, 0x8656}, 659 {0x00a1, 0x8656},
746 660
747/* webcam won't start if not included */ 661/* webcam won't start if not included */
748 /*528 */ {0x0007, 0x865b}, 662 {0x0007, 0x865b},
749 /*529 */ {0x0001, 0x865c}, 663 {0x0001, 0x865c},
750 /*530 */ {0x0058, 0x865d}, 664 {0x0058, 0x865d},
751 /*531 */ {0x0048, 0x865e}, 665 {0x0048, 0x865e},
752 666
753/* adjusts the colors */ 667/* adjusts the colors */
754 /*541 */ {0x0049, 0x8651}, 668 {0x0049, 0x8651},
755 /*542 */ {0x0040, 0x8652}, 669 {0x0040, 0x8652},
756 /*543 */ {0x004c, 0x8653}, 670 {0x004c, 0x8653},
757 /*544 */ {0x0040, 0x8654}, 671 {0x0040, 0x8654},
758 {} 672 {}
759}; 673};
760 674
761static const u16 spca508_sightcam2_init_data[][2] = { 675static const u16 spca508_sightcam2_init_data[][2] = {
762/* 35 */ {0x0020, 0x8112}, 676 {0x0020, 0x8112},
763 677
764/* 36 */ {0x000f, 0x8402}, 678 {0x000f, 0x8402},
765/* 37 */ {0x0000, 0x8403}, 679 {0x0000, 0x8403},
766 680
767/* 38 */ {0x0008, 0x8201}, 681 {0x0008, 0x8201},
768/* 39 */ {0x0008, 0x8200}, 682 {0x0008, 0x8200},
769/* 40 */ {0x0001, 0x8200}, 683 {0x0001, 0x8200},
770/* 43 */ {0x0009, 0x8201}, 684 {0x0009, 0x8201},
771/* 44 */ {0x0008, 0x8200}, 685 {0x0008, 0x8200},
772/* 45 */ {0x0001, 0x8200}, 686 {0x0001, 0x8200},
773/* 48 */ {0x000a, 0x8201}, 687 {0x000a, 0x8201},
774/* 49 */ {0x0008, 0x8200}, 688 {0x0008, 0x8200},
775/* 50 */ {0x0001, 0x8200}, 689 {0x0001, 0x8200},
776/* 53 */ {0x000b, 0x8201}, 690 {0x000b, 0x8201},
777/* 54 */ {0x0008, 0x8200}, 691 {0x0008, 0x8200},
778/* 55 */ {0x0001, 0x8200}, 692 {0x0001, 0x8200},
779/* 58 */ {0x000c, 0x8201}, 693 {0x000c, 0x8201},
780/* 59 */ {0x0008, 0x8200}, 694 {0x0008, 0x8200},
781/* 60 */ {0x0001, 0x8200}, 695 {0x0001, 0x8200},
782/* 63 */ {0x000d, 0x8201}, 696 {0x000d, 0x8201},
783/* 64 */ {0x0008, 0x8200}, 697 {0x0008, 0x8200},
784/* 65 */ {0x0001, 0x8200}, 698 {0x0001, 0x8200},
785/* 68 */ {0x000e, 0x8201}, 699 {0x000e, 0x8201},
786/* 69 */ {0x0008, 0x8200}, 700 {0x0008, 0x8200},
787/* 70 */ {0x0001, 0x8200}, 701 {0x0001, 0x8200},
788/* 73 */ {0x0007, 0x8201}, 702 {0x0007, 0x8201},
789/* 74 */ {0x0008, 0x8200}, 703 {0x0008, 0x8200},
790/* 75 */ {0x0001, 0x8200}, 704 {0x0001, 0x8200},
791/* 78 */ {0x000f, 0x8201}, 705 {0x000f, 0x8201},
792/* 79 */ {0x0008, 0x8200}, 706 {0x0008, 0x8200},
793/* 80 */ {0x0001, 0x8200}, 707 {0x0001, 0x8200},
794 708
795/* 84 */ {0x0018, 0x8660}, 709 {0x0018, 0x8660},
796/* 85 */ {0x0010, 0x8201}, 710 {0x0010, 0x8201},
797 711
798/* 86 */ {0x0008, 0x8200}, 712 {0x0008, 0x8200},
799/* 87 */ {0x0001, 0x8200}, 713 {0x0001, 0x8200},
800/* 90 */ {0x0011, 0x8201}, 714 {0x0011, 0x8201},
801/* 91 */ {0x0008, 0x8200}, 715 {0x0008, 0x8200},
802/* 92 */ {0x0001, 0x8200}, 716 {0x0001, 0x8200},
803 717
804/* 95 */ {0x0000, 0x86b0}, 718 {0x0000, 0x86b0},
805/* 96 */ {0x0034, 0x86b1}, 719 {0x0034, 0x86b1},
806/* 97 */ {0x0000, 0x86b2}, 720 {0x0000, 0x86b2},
807/* 98 */ {0x0049, 0x86b3}, 721 {0x0049, 0x86b3},
808/* 99 */ {0x0000, 0x86b4}, 722 {0x0000, 0x86b4},
809/* 100 */ {0x0000, 0x86b4}, 723 {0x0000, 0x86b4},
810 724
811/* 101 */ {0x0012, 0x8201}, 725 {0x0012, 0x8201},
812/* 102 */ {0x0008, 0x8200}, 726 {0x0008, 0x8200},
813/* 103 */ {0x0001, 0x8200}, 727 {0x0001, 0x8200},
814/* 106 */ {0x0013, 0x8201}, 728 {0x0013, 0x8201},
815/* 107 */ {0x0008, 0x8200}, 729 {0x0008, 0x8200},
816/* 108 */ {0x0001, 0x8200}, 730 {0x0001, 0x8200},
817 731
818/* 111 */ {0x0001, 0x86b0}, 732 {0x0001, 0x86b0},
819/* 112 */ {0x00aa, 0x86b1}, 733 {0x00aa, 0x86b1},
820/* 113 */ {0x0000, 0x86b2}, 734 {0x0000, 0x86b2},
821/* 114 */ {0x00e4, 0x86b3}, 735 {0x00e4, 0x86b3},
822/* 115 */ {0x0000, 0x86b4}, 736 {0x0000, 0x86b4},
823/* 116 */ {0x0000, 0x86b4}, 737 {0x0000, 0x86b4},
824 738
825/* 118 */ {0x0018, 0x8660}, 739 {0x0018, 0x8660},
826 740
827/* 119 */ {0x0090, 0x8110}, 741 {0x0090, 0x8110},
828/* 120 */ {0x0001, 0x8114}, 742 {0x0001, 0x8114},
829/* 121 */ {0x0001, 0x8114}, 743 {0x0001, 0x8114},
830/* 122 */ {0x0001, 0x8114}, 744 {0x0001, 0x8114},
831/* 123 */ {0x0003, 0x8114}, 745 {0x0003, 0x8114},
832 746
833/* 124 */ {0x0080, 0x8804}, 747 {0x0080, 0x8804},
834/* 157 */ {0x0003, 0x8801}, 748 {0x0003, 0x8801},
835/* 158 */ {0x0012, 0x8800}, 749 {0x0012, 0x8800},
836/* 160 */ {0x0004, 0x8801}, 750 {0x0004, 0x8801},
837/* 161 */ {0x0005, 0x8800}, 751 {0x0005, 0x8800},
838/* 163 */ {0x0005, 0x8801}, 752 {0x0005, 0x8801},
839/* 164 */ {0x0000, 0x8800}, 753 {0x0000, 0x8800},
840/* 166 */ {0x0006, 0x8801}, 754 {0x0006, 0x8801},
841/* 167 */ {0x0000, 0x8800}, 755 {0x0000, 0x8800},
842/* 169 */ {0x0007, 0x8801}, 756 {0x0007, 0x8801},
843/* 170 */ {0x0000, 0x8800}, 757 {0x0000, 0x8800},
844/* 172 */ {0x0008, 0x8801}, 758 {0x0008, 0x8801},
845/* 173 */ {0x0005, 0x8800}, 759 {0x0005, 0x8800},
846/* 175 */ {0x000a, 0x8700}, 760 {0x000a, 0x8700},
847/* 176 */ {0x000e, 0x8801}, 761 {0x000e, 0x8801},
848/* 177 */ {0x0004, 0x8800}, 762 {0x0004, 0x8800},
849/* 179 */ {0x0005, 0x8801}, 763 {0x0005, 0x8801},
850/* 180 */ {0x0047, 0x8800}, 764 {0x0047, 0x8800},
851/* 182 */ {0x0006, 0x8801}, 765 {0x0006, 0x8801},
852/* 183 */ {0x0000, 0x8800}, 766 {0x0000, 0x8800},
853/* 185 */ {0x0007, 0x8801}, 767 {0x0007, 0x8801},
854/* 186 */ {0x00c0, 0x8800}, 768 {0x00c0, 0x8800},
855/* 188 */ {0x0008, 0x8801}, 769 {0x0008, 0x8801},
856/* 189 */ {0x0003, 0x8800}, 770 {0x0003, 0x8800},
857/* 191 */ {0x0013, 0x8801}, 771 {0x0013, 0x8801},
858/* 192 */ {0x0001, 0x8800}, 772 {0x0001, 0x8800},
859/* 194 */ {0x0009, 0x8801}, 773 {0x0009, 0x8801},
860/* 195 */ {0x0000, 0x8800}, 774 {0x0000, 0x8800},
861/* 197 */ {0x000a, 0x8801}, 775 {0x000a, 0x8801},
862/* 198 */ {0x0000, 0x8800}, 776 {0x0000, 0x8800},
863/* 200 */ {0x000b, 0x8801}, 777 {0x000b, 0x8801},
864/* 201 */ {0x0000, 0x8800}, 778 {0x0000, 0x8800},
865/* 203 */ {0x000c, 0x8801}, 779 {0x000c, 0x8801},
866/* 204 */ {0x0000, 0x8800}, 780 {0x0000, 0x8800},
867/* 206 */ {0x000e, 0x8801}, 781 {0x000e, 0x8801},
868/* 207 */ {0x0004, 0x8800}, 782 {0x0004, 0x8800},
869/* 209 */ {0x000f, 0x8801}, 783 {0x000f, 0x8801},
870/* 210 */ {0x0000, 0x8800}, 784 {0x0000, 0x8800},
871/* 212 */ {0x0010, 0x8801}, 785 {0x0010, 0x8801},
872/* 213 */ {0x0006, 0x8800}, 786 {0x0006, 0x8800},
873/* 215 */ {0x0011, 0x8801}, 787 {0x0011, 0x8801},
874/* 216 */ {0x0006, 0x8800}, 788 {0x0006, 0x8800},
875/* 218 */ {0x0012, 0x8801}, 789 {0x0012, 0x8801},
876/* 219 */ {0x0000, 0x8800}, 790 {0x0000, 0x8800},
877/* 221 */ {0x0013, 0x8801}, 791 {0x0013, 0x8801},
878/* 222 */ {0x0001, 0x8800}, 792 {0x0001, 0x8800},
879 793
880/* 224 */ {0x000a, 0x8700}, 794 {0x000a, 0x8700},
881/* 225 */ {0x0000, 0x8702}, 795 {0x0000, 0x8702},
882/* 226 */ {0x0000, 0x8703}, 796 {0x0000, 0x8703},
883/* 227 */ {0x00c2, 0x8704}, 797 {0x00c2, 0x8704},
884/* 228 */ {0x0001, 0x870c}, 798 {0x0001, 0x870c},
885 799
886/* 229 */ {0x0044, 0x8600}, 800 {0x0044, 0x8600},
887/* 230 */ {0x0002, 0x8606}, 801 {0x0002, 0x8606},
888/* 231 */ {0x0064, 0x8607}, 802 {0x0064, 0x8607},
889/* 232 */ {0x003a, 0x8601}, 803 {0x003a, 0x8601},
890/* 233 */ {0x0008, 0x8602}, 804 {0x0008, 0x8602},
891/* 234 */ {0x0044, 0x8600}, 805 {0x0044, 0x8600},
892/* 235 */ {0x0018, 0x8617}, 806 {0x0018, 0x8617},
893/* 236 */ {0x0008, 0x8618}, 807 {0x0008, 0x8618},
894/* 237 */ {0x00a1, 0x8656}, 808 {0x00a1, 0x8656},
895/* 238 */ {0x0004, 0x865b}, 809 {0x0004, 0x865b},
896/* 239 */ {0x0002, 0x865c}, 810 {0x0002, 0x865c},
897/* 240 */ {0x0058, 0x865d}, 811 {0x0058, 0x865d},
898/* 241 */ {0x0048, 0x865e}, 812 {0x0048, 0x865e},
899/* 242 */ {0x0012, 0x8608}, 813 {0x0012, 0x8608},
900/* 243 */ {0x002c, 0x8609}, 814 {0x002c, 0x8609},
901/* 244 */ {0x0002, 0x860a}, 815 {0x0002, 0x860a},
902/* 245 */ {0x002c, 0x860b}, 816 {0x002c, 0x860b},
903/* 246 */ {0x00db, 0x860c}, 817 {0x00db, 0x860c},
904/* 247 */ {0x00f9, 0x860d}, 818 {0x00f9, 0x860d},
905/* 248 */ {0x00f1, 0x860e}, 819 {0x00f1, 0x860e},
906/* 249 */ {0x00e3, 0x860f}, 820 {0x00e3, 0x860f},
907/* 250 */ {0x002c, 0x8610}, 821 {0x002c, 0x8610},
908/* 251 */ {0x006c, 0x8651}, 822 {0x006c, 0x8651},
909/* 252 */ {0x0041, 0x8652}, 823 {0x0041, 0x8652},
910/* 253 */ {0x0059, 0x8653}, 824 {0x0059, 0x8653},
911/* 254 */ {0x0040, 0x8654}, 825 {0x0040, 0x8654},
912/* 255 */ {0x00fa, 0x8611}, 826 {0x00fa, 0x8611},
913/* 256 */ {0x00ff, 0x8612}, 827 {0x00ff, 0x8612},
914/* 257 */ {0x00f8, 0x8613}, 828 {0x00f8, 0x8613},
915/* 258 */ {0x0000, 0x8614}, 829 {0x0000, 0x8614},
916/* 259 */ {0x0001, 0x863f}, 830 {0x0001, 0x863f},
917/* 260 */ {0x0000, 0x8640}, 831 {0x0000, 0x8640},
918/* 261 */ {0x0026, 0x8641}, 832 {0x0026, 0x8641},
919/* 262 */ {0x0045, 0x8642}, 833 {0x0045, 0x8642},
920/* 263 */ {0x0060, 0x8643}, 834 {0x0060, 0x8643},
921/* 264 */ {0x0075, 0x8644}, 835 {0x0075, 0x8644},
922/* 265 */ {0x0088, 0x8645}, 836 {0x0088, 0x8645},
923/* 266 */ {0x009b, 0x8646}, 837 {0x009b, 0x8646},
924/* 267 */ {0x00b0, 0x8647}, 838 {0x00b0, 0x8647},
925/* 268 */ {0x00c5, 0x8648}, 839 {0x00c5, 0x8648},
926/* 269 */ {0x00d2, 0x8649}, 840 {0x00d2, 0x8649},
927/* 270 */ {0x00dc, 0x864a}, 841 {0x00dc, 0x864a},
928/* 271 */ {0x00e5, 0x864b}, 842 {0x00e5, 0x864b},
929/* 272 */ {0x00eb, 0x864c}, 843 {0x00eb, 0x864c},
930/* 273 */ {0x00f0, 0x864d}, 844 {0x00f0, 0x864d},
931/* 274 */ {0x00f6, 0x864e}, 845 {0x00f6, 0x864e},
932/* 275 */ {0x00fa, 0x864f}, 846 {0x00fa, 0x864f},
933/* 276 */ {0x00ff, 0x8650}, 847 {0x00ff, 0x8650},
934/* 277 */ {0x0060, 0x8657}, 848 {0x0060, 0x8657},
935/* 278 */ {0x0010, 0x8658}, 849 {0x0010, 0x8658},
936/* 279 */ {0x0018, 0x8659}, 850 {0x0018, 0x8659},
937/* 280 */ {0x0005, 0x865a}, 851 {0x0005, 0x865a},
938/* 281 */ {0x0018, 0x8660}, 852 {0x0018, 0x8660},
939/* 282 */ {0x0003, 0x8509}, 853 {0x0003, 0x8509},
940/* 283 */ {0x0011, 0x850a}, 854 {0x0011, 0x850a},
941/* 284 */ {0x0032, 0x850b}, 855 {0x0032, 0x850b},
942/* 285 */ {0x0010, 0x850c}, 856 {0x0010, 0x850c},
943/* 286 */ {0x0021, 0x850d}, 857 {0x0021, 0x850d},
944/* 287 */ {0x0001, 0x8500}, 858 {0x0001, 0x8500},
945/* 288 */ {0x0000, 0x8508}, 859 {0x0000, 0x8508},
946/* 289 */ {0x0012, 0x8608}, 860 {0x0012, 0x8608},
947/* 290 */ {0x002c, 0x8609}, 861 {0x002c, 0x8609},
948/* 291 */ {0x0002, 0x860a}, 862 {0x0002, 0x860a},
949/* 292 */ {0x0039, 0x860b}, 863 {0x0039, 0x860b},
950/* 293 */ {0x00d0, 0x860c}, 864 {0x00d0, 0x860c},
951/* 294 */ {0x00f7, 0x860d}, 865 {0x00f7, 0x860d},
952/* 295 */ {0x00ed, 0x860e}, 866 {0x00ed, 0x860e},
953/* 296 */ {0x00db, 0x860f}, 867 {0x00db, 0x860f},
954/* 297 */ {0x0039, 0x8610}, 868 {0x0039, 0x8610},
955/* 298 */ {0x0012, 0x8657}, 869 {0x0012, 0x8657},
956/* 299 */ {0x000c, 0x8619}, 870 {0x000c, 0x8619},
957/* 300 */ {0x0004, 0x861a}, 871 {0x0004, 0x861a},
958/* 301 */ {0x00a1, 0x8656}, 872 {0x00a1, 0x8656},
959/* 302 */ {0x00c8, 0x8615}, 873 {0x00c8, 0x8615},
960/* 303 */ {0x0032, 0x8616}, 874 {0x0032, 0x8616},
961 875
962/* 306 */ {0x0030, 0x8112}, 876 {0x0030, 0x8112},
963/* 313 */ {0x0020, 0x8112}, 877 {0x0020, 0x8112},
964/* 314 */ {0x0020, 0x8112}, 878 {0x0020, 0x8112},
965/* 315 */ {0x000f, 0x8402}, 879 {0x000f, 0x8402},
966/* 316 */ {0x0000, 0x8403}, 880 {0x0000, 0x8403},
967 881
968/* 317 */ {0x0090, 0x8110}, 882 {0x0090, 0x8110},
969/* 318 */ {0x0001, 0x8114}, 883 {0x0001, 0x8114},
970/* 319 */ {0x0001, 0x8114}, 884 {0x0001, 0x8114},
971/* 320 */ {0x0001, 0x8114}, 885 {0x0001, 0x8114},
972/* 321 */ {0x0003, 0x8114}, 886 {0x0003, 0x8114},
973/* 322 */ {0x0080, 0x8804}, 887 {0x0080, 0x8804},
974 888
975/* 355 */ {0x0003, 0x8801}, 889 {0x0003, 0x8801},
976/* 356 */ {0x0012, 0x8800}, 890 {0x0012, 0x8800},
977/* 358 */ {0x0004, 0x8801}, 891 {0x0004, 0x8801},
978/* 359 */ {0x0005, 0x8800}, 892 {0x0005, 0x8800},
979/* 361 */ {0x0005, 0x8801}, 893 {0x0005, 0x8801},
980/* 362 */ {0x0047, 0x8800}, 894 {0x0047, 0x8800},
981/* 364 */ {0x0006, 0x8801}, 895 {0x0006, 0x8801},
982/* 365 */ {0x0000, 0x8800}, 896 {0x0000, 0x8800},
983/* 367 */ {0x0007, 0x8801}, 897 {0x0007, 0x8801},
984/* 368 */ {0x00c0, 0x8800}, 898 {0x00c0, 0x8800},
985/* 370 */ {0x0008, 0x8801}, 899 {0x0008, 0x8801},
986/* 371 */ {0x0003, 0x8800}, 900 {0x0003, 0x8800},
987/* 373 */ {0x000a, 0x8700}, 901 {0x000a, 0x8700},
988/* 374 */ {0x000e, 0x8801}, 902 {0x000e, 0x8801},
989/* 375 */ {0x0004, 0x8800}, 903 {0x0004, 0x8800},
990/* 377 */ {0x0005, 0x8801}, 904 {0x0005, 0x8801},
991/* 378 */ {0x0047, 0x8800}, 905 {0x0047, 0x8800},
992/* 380 */ {0x0006, 0x8801}, 906 {0x0006, 0x8801},
993/* 381 */ {0x0000, 0x8800}, 907 {0x0000, 0x8800},
994/* 383 */ {0x0007, 0x8801}, 908 {0x0007, 0x8801},
995/* 384 */ {0x00c0, 0x8800}, 909 {0x00c0, 0x8800},
996/* 386 */ {0x0008, 0x8801}, 910 {0x0008, 0x8801},
997/* 387 */ {0x0003, 0x8800}, 911 {0x0003, 0x8800},
998/* 389 */ {0x0013, 0x8801}, 912 {0x0013, 0x8801},
999/* 390 */ {0x0001, 0x8800}, 913 {0x0001, 0x8800},
1000/* 392 */ {0x0009, 0x8801}, 914 {0x0009, 0x8801},
1001/* 393 */ {0x0000, 0x8800}, 915 {0x0000, 0x8800},
1002/* 395 */ {0x000a, 0x8801}, 916 {0x000a, 0x8801},
1003/* 396 */ {0x0000, 0x8800}, 917 {0x0000, 0x8800},
1004/* 398 */ {0x000b, 0x8801}, 918 {0x000b, 0x8801},
1005/* 399 */ {0x0000, 0x8800}, 919 {0x0000, 0x8800},
1006/* 401 */ {0x000c, 0x8801}, 920 {0x000c, 0x8801},
1007/* 402 */ {0x0000, 0x8800}, 921 {0x0000, 0x8800},
1008/* 404 */ {0x000e, 0x8801}, 922 {0x000e, 0x8801},
1009/* 405 */ {0x0004, 0x8800}, 923 {0x0004, 0x8800},
1010/* 407 */ {0x000f, 0x8801}, 924 {0x000f, 0x8801},
1011/* 408 */ {0x0000, 0x8800}, 925 {0x0000, 0x8800},
1012/* 410 */ {0x0010, 0x8801}, 926 {0x0010, 0x8801},
1013/* 411 */ {0x0006, 0x8800}, 927 {0x0006, 0x8800},
1014/* 413 */ {0x0011, 0x8801}, 928 {0x0011, 0x8801},
1015/* 414 */ {0x0006, 0x8800}, 929 {0x0006, 0x8800},
1016/* 416 */ {0x0012, 0x8801}, 930 {0x0012, 0x8801},
1017/* 417 */ {0x0000, 0x8800}, 931 {0x0000, 0x8800},
1018/* 419 */ {0x0013, 0x8801}, 932 {0x0013, 0x8801},
1019/* 420 */ {0x0001, 0x8800}, 933 {0x0001, 0x8800},
1020/* 422 */ {0x000a, 0x8700}, 934 {0x000a, 0x8700},
1021/* 423 */ {0x0000, 0x8702}, 935 {0x0000, 0x8702},
1022/* 424 */ {0x0000, 0x8703}, 936 {0x0000, 0x8703},
1023/* 425 */ {0x00c2, 0x8704}, 937 {0x00c2, 0x8704},
1024/* 426 */ {0x0001, 0x870c}, 938 {0x0001, 0x870c},
1025/* 427 */ {0x0044, 0x8600}, 939 {0x0044, 0x8600},
1026/* 428 */ {0x0002, 0x8606}, 940 {0x0002, 0x8606},
1027/* 429 */ {0x0064, 0x8607}, 941 {0x0064, 0x8607},
1028/* 430 */ {0x003a, 0x8601}, 942 {0x003a, 0x8601},
1029/* 431 */ {0x0008, 0x8602}, 943 {0x0008, 0x8602},
1030/* 432 */ {0x0044, 0x8600}, 944 {0x0044, 0x8600},
1031/* 433 */ {0x0018, 0x8617}, 945 {0x0018, 0x8617},
1032/* 434 */ {0x0008, 0x8618}, 946 {0x0008, 0x8618},
1033/* 435 */ {0x00a1, 0x8656}, 947 {0x00a1, 0x8656},
1034/* 436 */ {0x0004, 0x865b}, 948 {0x0004, 0x865b},
1035/* 437 */ {0x0002, 0x865c}, 949 {0x0002, 0x865c},
1036/* 438 */ {0x0058, 0x865d}, 950 {0x0058, 0x865d},
1037/* 439 */ {0x0048, 0x865e}, 951 {0x0048, 0x865e},
1038/* 440 */ {0x0012, 0x8608}, 952 {0x0012, 0x8608},
1039/* 441 */ {0x002c, 0x8609}, 953 {0x002c, 0x8609},
1040/* 442 */ {0x0002, 0x860a}, 954 {0x0002, 0x860a},
1041/* 443 */ {0x002c, 0x860b}, 955 {0x002c, 0x860b},
1042/* 444 */ {0x00db, 0x860c}, 956 {0x00db, 0x860c},
1043/* 445 */ {0x00f9, 0x860d}, 957 {0x00f9, 0x860d},
1044/* 446 */ {0x00f1, 0x860e}, 958 {0x00f1, 0x860e},
1045/* 447 */ {0x00e3, 0x860f}, 959 {0x00e3, 0x860f},
1046/* 448 */ {0x002c, 0x8610}, 960 {0x002c, 0x8610},
1047/* 449 */ {0x006c, 0x8651}, 961 {0x006c, 0x8651},
1048/* 450 */ {0x0041, 0x8652}, 962 {0x0041, 0x8652},
1049/* 451 */ {0x0059, 0x8653}, 963 {0x0059, 0x8653},
1050/* 452 */ {0x0040, 0x8654}, 964 {0x0040, 0x8654},
1051/* 453 */ {0x00fa, 0x8611}, 965 {0x00fa, 0x8611},
1052/* 454 */ {0x00ff, 0x8612}, 966 {0x00ff, 0x8612},
1053/* 455 */ {0x00f8, 0x8613}, 967 {0x00f8, 0x8613},
1054/* 456 */ {0x0000, 0x8614}, 968 {0x0000, 0x8614},
1055/* 457 */ {0x0001, 0x863f}, 969 {0x0001, 0x863f},
1056/* 458 */ {0x0000, 0x8640}, 970 {0x0000, 0x8640},
1057/* 459 */ {0x0026, 0x8641}, 971 {0x0026, 0x8641},
1058/* 460 */ {0x0045, 0x8642}, 972 {0x0045, 0x8642},
1059/* 461 */ {0x0060, 0x8643}, 973 {0x0060, 0x8643},
1060/* 462 */ {0x0075, 0x8644}, 974 {0x0075, 0x8644},
1061/* 463 */ {0x0088, 0x8645}, 975 {0x0088, 0x8645},
1062/* 464 */ {0x009b, 0x8646}, 976 {0x009b, 0x8646},
1063/* 465 */ {0x00b0, 0x8647}, 977 {0x00b0, 0x8647},
1064/* 466 */ {0x00c5, 0x8648}, 978 {0x00c5, 0x8648},
1065/* 467 */ {0x00d2, 0x8649}, 979 {0x00d2, 0x8649},
1066/* 468 */ {0x00dc, 0x864a}, 980 {0x00dc, 0x864a},
1067/* 469 */ {0x00e5, 0x864b}, 981 {0x00e5, 0x864b},
1068/* 470 */ {0x00eb, 0x864c}, 982 {0x00eb, 0x864c},
1069/* 471 */ {0x00f0, 0x864d}, 983 {0x00f0, 0x864d},
1070/* 472 */ {0x00f6, 0x864e}, 984 {0x00f6, 0x864e},
1071/* 473 */ {0x00fa, 0x864f}, 985 {0x00fa, 0x864f},
1072/* 474 */ {0x00ff, 0x8650}, 986 {0x00ff, 0x8650},
1073/* 475 */ {0x0060, 0x8657}, 987 {0x0060, 0x8657},
1074/* 476 */ {0x0010, 0x8658}, 988 {0x0010, 0x8658},
1075/* 477 */ {0x0018, 0x8659}, 989 {0x0018, 0x8659},
1076/* 478 */ {0x0005, 0x865a}, 990 {0x0005, 0x865a},
1077/* 479 */ {0x0018, 0x8660}, 991 {0x0018, 0x8660},
1078/* 480 */ {0x0003, 0x8509}, 992 {0x0003, 0x8509},
1079/* 481 */ {0x0011, 0x850a}, 993 {0x0011, 0x850a},
1080/* 482 */ {0x0032, 0x850b}, 994 {0x0032, 0x850b},
1081/* 483 */ {0x0010, 0x850c}, 995 {0x0010, 0x850c},
1082/* 484 */ {0x0021, 0x850d}, 996 {0x0021, 0x850d},
1083/* 485 */ {0x0001, 0x8500}, 997 {0x0001, 0x8500},
1084/* 486 */ {0x0000, 0x8508}, 998 {0x0000, 0x8508},
1085 999
1086/* 487 */ {0x0012, 0x8608}, 1000 {0x0012, 0x8608},
1087/* 488 */ {0x002c, 0x8609}, 1001 {0x002c, 0x8609},
1088/* 489 */ {0x0002, 0x860a}, 1002 {0x0002, 0x860a},
1089/* 490 */ {0x0039, 0x860b}, 1003 {0x0039, 0x860b},
1090/* 491 */ {0x00d0, 0x860c}, 1004 {0x00d0, 0x860c},
1091/* 492 */ {0x00f7, 0x860d}, 1005 {0x00f7, 0x860d},
1092/* 493 */ {0x00ed, 0x860e}, 1006 {0x00ed, 0x860e},
1093/* 494 */ {0x00db, 0x860f}, 1007 {0x00db, 0x860f},
1094/* 495 */ {0x0039, 0x8610}, 1008 {0x0039, 0x8610},
1095/* 496 */ {0x0012, 0x8657}, 1009 {0x0012, 0x8657},
1096/* 497 */ {0x0064, 0x8619}, 1010 {0x0064, 0x8619},
1097 1011
1098/* This line starts it all, it is not needed here */ 1012/* This line starts it all, it is not needed here */
1099/* since it has been build into the driver */ 1013/* since it has been build into the driver */
1100/* jfm: don't start now */ 1014/* jfm: don't start now */
1101/* 590 * {0x0030, 0x8112}, */ 1015/* {0x0030, 0x8112}, */
1102 {} 1016 {}
1103}; 1017};
1104 1018
@@ -1109,14 +1023,14 @@ static const u16 spca508_vista_init_data[][2] = {
1109 {0x0008, 0x8200}, /* Clear register */ 1023 {0x0008, 0x8200}, /* Clear register */
1110 {0x0000, 0x870b}, /* Reset CTL3 */ 1024 {0x0000, 0x870b}, /* Reset CTL3 */
1111 {0x0020, 0x8112}, /* Video Drop packet enable */ 1025 {0x0020, 0x8112}, /* Video Drop packet enable */
1112 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ 1026 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
1113 {0x0000, 0x8110}, /* Disable everything */ 1027 {0x0000, 0x8110}, /* Disable everything */
1114 {0x0000, 0x8114}, /* Software GPIO output data */ 1028 {0x0000, 0x8114}, /* Software GPIO output data */
1115 {0x0000, 0x8114}, 1029 {0x0000, 0x8114},
1116 1030
1117 {0x0003, 0x8111}, 1031 {0x0003, 0x8111},
1118 {0x0000, 0x8111}, 1032 {0x0000, 0x8111},
1119 {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ 1033 {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */
1120 {0x0020, 0x8112}, 1034 {0x0020, 0x8112},
1121 {0x0000, 0x8114}, 1035 {0x0000, 0x8114},
1122 {0x0001, 0x8114}, 1036 {0x0001, 0x8114},
@@ -1129,191 +1043,143 @@ static const u16 spca508_vista_init_data[][2] = {
1129 {0x00ba, 0x8804}, /* SSI Slave address */ 1043 {0x00ba, 0x8804}, /* SSI Slave address */
1130 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ 1044 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
1131 1045
1132 /* READ { 0, 0x0001, 0x8803 } -> 1046 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1133 0000: 00 */ 1047 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1134 /* READ { 0, 0x0001, 0x8802 } ->
1135 0000: 10 */
1136 {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ 1048 {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */
1137 {0x0020, 0x8801}, /* Register address for SSI read/write */ 1049 {0x0020, 0x8801}, /* Register address for SSI read/write */
1138 {0x0044, 0x8805}, /* DATA2 */ 1050 {0x0044, 0x8805}, /* DATA2 */
1139 {0x0004, 0x8800}, /* DATA1 -> write triggered */ 1051 {0x0004, 0x8800}, /* DATA1 -> write triggered */
1140 /* READ { 0, 0x0001, 0x8803 } -> 1052 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1141 0000: 00 */
1142 1053
1143 /* READ { 0, 0x0001, 0x8803 } -> 1054 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1144 0000: 00 */ 1055 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1145 /* READ { 0, 0x0001, 0x8802 } ->
1146 0000: 10 */
1147 {0x0010, 0x8802}, 1056 {0x0010, 0x8802},
1148 {0x0009, 0x8801}, 1057 {0x0009, 0x8801},
1149 {0x0042, 0x8805}, 1058 {0x0042, 0x8805},
1150 {0x0001, 0x8800}, 1059 {0x0001, 0x8800},
1151 /* READ { 0, 0x0001, 0x8803 } -> 1060 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1152 0000: 00 */
1153 1061
1154 /* READ { 0, 0x0001, 0x8803 } -> 1062 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1155 0000: 00 */ 1063 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1156 /* READ { 0, 0x0001, 0x8802 } ->
1157 0000: 10 */
1158 {0x0010, 0x8802}, 1064 {0x0010, 0x8802},
1159 {0x003c, 0x8801}, 1065 {0x003c, 0x8801},
1160 {0x0001, 0x8805}, 1066 {0x0001, 0x8805},
1161 {0x0000, 0x8800}, 1067 {0x0000, 0x8800},
1162 /* READ { 0, 0x0001, 0x8803 } -> 1068 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1163 0000: 00 */
1164 1069
1165 /* READ { 0, 0x0001, 0x8803 } -> 1070 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1166 0000: 00 */ 1071 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1167 /* READ { 0, 0x0001, 0x8802 } ->
1168 0000: 10 */
1169 {0x0010, 0x8802}, 1072 {0x0010, 0x8802},
1170 {0x0001, 0x8801}, 1073 {0x0001, 0x8801},
1171 {0x000a, 0x8805}, 1074 {0x000a, 0x8805},
1172 {0x0000, 0x8800}, 1075 {0x0000, 0x8800},
1173 /* READ { 0, 0x0001, 0x8803 } -> 1076 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1174 0000: 00 */
1175 1077
1176 /* READ { 0, 0x0001, 0x8803 } -> 1078 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1177 0000: 00 */ 1079 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1178 /* READ { 0, 0x0001, 0x8802 } ->
1179 0000: 10 */
1180 {0x0010, 0x8802}, 1080 {0x0010, 0x8802},
1181 {0x0002, 0x8801}, 1081 {0x0002, 0x8801},
1182 {0x0000, 0x8805}, 1082 {0x0000, 0x8805},
1183 {0x0000, 0x8800}, 1083 {0x0000, 0x8800},
1184 /* READ { 0, 0x0001, 0x8803 } -> 1084 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1185 0000: 00 */
1186 1085
1187 /* READ { 0, 0x0001, 0x8803 } -> 1086 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1188 0000: 00 */ 1087 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1189 /* READ { 0, 0x0001, 0x8802 } ->
1190 0000: 10 */
1191 {0x0010, 0x8802}, 1088 {0x0010, 0x8802},
1192 {0x0003, 0x8801}, 1089 {0x0003, 0x8801},
1193 {0x0027, 0x8805}, 1090 {0x0027, 0x8805},
1194 {0x0001, 0x8800}, 1091 {0x0001, 0x8800},
1195 /* READ { 0, 0x0001, 0x8803 } -> 1092 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1196 0000: 00 */
1197 1093
1198 /* READ { 0, 0x0001, 0x8803 } -> 1094 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1199 0000: 00 */ 1095 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1200 /* READ { 0, 0x0001, 0x8802 } ->
1201 0000: 10 */
1202 {0x0010, 0x8802}, 1096 {0x0010, 0x8802},
1203 {0x0004, 0x8801}, 1097 {0x0004, 0x8801},
1204 {0x0065, 0x8805}, 1098 {0x0065, 0x8805},
1205 {0x0001, 0x8800}, 1099 {0x0001, 0x8800},
1206 /* READ { 0, 0x0001, 0x8803 } -> 1100 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1207 0000: 00 */
1208 1101
1209 /* READ { 0, 0x0001, 0x8803 } -> 1102 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1210 0000: 00 */ 1103 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1211 /* READ { 0, 0x0001, 0x8802 } ->
1212 0000: 10 */
1213 {0x0010, 0x8802}, 1104 {0x0010, 0x8802},
1214 {0x0005, 0x8801}, 1105 {0x0005, 0x8801},
1215 {0x0003, 0x8805}, 1106 {0x0003, 0x8805},
1216 {0x0000, 0x8800}, 1107 {0x0000, 0x8800},
1217 /* READ { 0, 0x0001, 0x8803 } -> 1108 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1218 0000: 00 */
1219 1109
1220 /* READ { 0, 0x0001, 0x8803 } -> 1110 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1221 0000: 00 */ 1111 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1222 /* READ { 0, 0x0001, 0x8802 } ->
1223 0000: 10 */
1224 {0x0010, 0x8802}, 1112 {0x0010, 0x8802},
1225 {0x0006, 0x8801}, 1113 {0x0006, 0x8801},
1226 {0x001c, 0x8805}, 1114 {0x001c, 0x8805},
1227 {0x0000, 0x8800}, 1115 {0x0000, 0x8800},
1228 /* READ { 0, 0x0001, 0x8803 } -> 1116 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1229 0000: 00 */
1230 1117
1231 /* READ { 0, 0x0001, 0x8803 } -> 1118 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1232 0000: 00 */ 1119 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1233 /* READ { 0, 0x0001, 0x8802 } ->
1234 0000: 10 */
1235 {0x0010, 0x8802}, 1120 {0x0010, 0x8802},
1236 {0x0007, 0x8801}, 1121 {0x0007, 0x8801},
1237 {0x002a, 0x8805}, 1122 {0x002a, 0x8805},
1238 {0x0000, 0x8800}, 1123 {0x0000, 0x8800},
1239 /* READ { 0, 0x0001, 0x8803 } -> 1124 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1240 0000: 00 */
1241 1125
1242 /* READ { 0, 0x0001, 0x8803 } -> 1126 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1243 0000: 00 */ 1127 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1244 /* READ { 0, 0x0001, 0x8802 } ->
1245 0000: 10 */
1246 {0x0010, 0x8802}, 1128 {0x0010, 0x8802},
1247 {0x000e, 0x8801}, 1129 {0x000e, 0x8801},
1248 {0x0000, 0x8805}, 1130 {0x0000, 0x8805},
1249 {0x0000, 0x8800}, 1131 {0x0000, 0x8800},
1250 /* READ { 0, 0x0001, 0x8803 } -> 1132 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1251 0000: 00 */
1252 1133
1253 /* READ { 0, 0x0001, 0x8803 } -> 1134 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1254 0000: 00 */ 1135 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1255 /* READ { 0, 0x0001, 0x8802 } ->
1256 0000: 10 */
1257 {0x0010, 0x8802}, 1136 {0x0010, 0x8802},
1258 {0x0028, 0x8801}, 1137 {0x0028, 0x8801},
1259 {0x002e, 0x8805}, 1138 {0x002e, 0x8805},
1260 {0x0000, 0x8800}, 1139 {0x0000, 0x8800},
1261 /* READ { 0, 0x0001, 0x8803 } -> 1140 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1262 0000: 00 */
1263 1141
1264 /* READ { 0, 0x0001, 0x8803 } -> 1142 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1265 0000: 00 */ 1143 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1266 /* READ { 0, 0x0001, 0x8802 } ->
1267 0000: 10 */
1268 {0x0010, 0x8802}, 1144 {0x0010, 0x8802},
1269 {0x0039, 0x8801}, 1145 {0x0039, 0x8801},
1270 {0x0013, 0x8805}, 1146 {0x0013, 0x8805},
1271 {0x0000, 0x8800}, 1147 {0x0000, 0x8800},
1272 /* READ { 0, 0x0001, 0x8803 } -> 1148 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1273 0000: 00 */
1274 1149
1275 /* READ { 0, 0x0001, 0x8803 } -> 1150 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1276 0000: 00 */ 1151 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1277 /* READ { 0, 0x0001, 0x8802 } ->
1278 0000: 10 */
1279 {0x0010, 0x8802}, 1152 {0x0010, 0x8802},
1280 {0x003b, 0x8801}, 1153 {0x003b, 0x8801},
1281 {0x000c, 0x8805}, 1154 {0x000c, 0x8805},
1282 {0x0000, 0x8800}, 1155 {0x0000, 0x8800},
1283 /* READ { 0, 0x0001, 0x8803 } -> 1156 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1284 0000: 00 */
1285 1157
1286 /* READ { 0, 0x0001, 0x8803 } -> 1158 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1287 0000: 00 */ 1159 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1288 /* READ { 0, 0x0001, 0x8802 } ->
1289 0000: 10 */
1290 {0x0010, 0x8802}, 1160 {0x0010, 0x8802},
1291 {0x0035, 0x8801}, 1161 {0x0035, 0x8801},
1292 {0x0028, 0x8805}, 1162 {0x0028, 0x8805},
1293 {0x0000, 0x8800}, 1163 {0x0000, 0x8800},
1294 /* READ { 0, 0x0001, 0x8803 } -> 1164 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1295 0000: 00 */
1296 1165
1297 /* READ { 0, 0x0001, 0x8803 } -> 1166 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1298 0000: 00 */ 1167 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1299 /* READ { 0, 0x0001, 0x8802 } ->
1300 0000: 10 */
1301 {0x0010, 0x8802}, 1168 {0x0010, 0x8802},
1302 {0x0009, 0x8801}, 1169 {0x0009, 0x8801},
1303 {0x0042, 0x8805}, 1170 {0x0042, 0x8805},
1304 {0x0001, 0x8800}, 1171 {0x0001, 0x8800},
1305 /* READ { 0, 0x0001, 0x8803 } -> 1172 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1306 0000: 00 */
1307 1173
1308 {0x0050, 0x8703}, 1174 {0x0050, 0x8703},
1309 {0x0002, 0x8704}, /* External input CKIx1 */ 1175 {0x0002, 0x8704}, /* External input CKIx1 */
1310 {0x0001, 0x870c}, /* Select CKOx2 output */ 1176 {0x0001, 0x870c}, /* Select CKOx2 output */
1311 {0x009a, 0x8600}, /* Line memory Read Counter (L) */ 1177 {0x009a, 0x8600}, /* Line memory Read Counter (L) */
1312 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ 1178 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
1313 {0x0023, 0x8601}, 1179 {0x0023, 0x8601},
1314 {0x0010, 0x8602}, 1180 {0x0010, 0x8602},
1315 {0x000a, 0x8603}, 1181 {0x000a, 0x8603},
1316 {0x009A, 0x8600}, 1182 {0x009a, 0x8600},
1317 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ 1183 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
1318 {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ 1184 {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
1319 {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ 1185 {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
@@ -1329,7 +1195,7 @@ static const u16 spca508_vista_init_data[][2] = {
1329 {0x0005, 0x860a}, /* ... */ 1195 {0x0005, 0x860a}, /* ... */
1330 {0x0025, 0x860b}, 1196 {0x0025, 0x860b},
1331 {0x00e1, 0x860c}, 1197 {0x00e1, 0x860c},
1332 {0x00fa, 0x860D}, 1198 {0x00fa, 0x860d},
1333 {0x00f4, 0x860e}, 1199 {0x00f4, 0x860e},
1334 {0x00e8, 0x860f}, 1200 {0x00e8, 0x860f},
1335 {0x0025, 0x8610}, /* A33 Coef. */ 1201 {0x0025, 0x8610}, /* A33 Coef. */
@@ -1344,11 +1210,12 @@ static const u16 spca508_vista_init_data[][2] = {
1344 {0x0040, 0x8654}, /* Gb gain for white balance (L) */ 1210 {0x0040, 0x8654}, /* Gb gain for white balance (L) */
1345 {0x0001, 0x863f}, /* Enable fixed gamma correction */ 1211 {0x0001, 0x863f}, /* Enable fixed gamma correction */
1346 1212
1347 {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ 1213 {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128,
1348 /* UV division: UV no change, Enable New edge enhancement */ 1214 * UV division: UV no change,
1215 * Enable New edge enhancement */
1349 {0x0018, 0x8657}, /* Edge gain high threshold */ 1216 {0x0018, 0x8657}, /* Edge gain high threshold */
1350 {0x0020, 0x8658}, /* Edge gain low threshold */ 1217 {0x0020, 0x8658}, /* Edge gain low threshold */
1351 {0x000A, 0x8659}, /* Edge bandwidth high threshold */ 1218 {0x000a, 0x8659}, /* Edge bandwidth high threshold */
1352 {0x0005, 0x865a}, /* Edge bandwidth low threshold */ 1219 {0x0005, 0x865a}, /* Edge bandwidth low threshold */
1353 {0x0064, 0x8607}, /* UV filter enable */ 1220 {0x0064, 0x8607}, /* UV filter enable */
1354 1221
@@ -1384,29 +1251,20 @@ static const u16 spca508_vista_init_data[][2] = {
1384 {0x0000, 0x86b4}, 1251 {0x0000, 0x86b4},
1385 {0x001e, 0x8660}, 1252 {0x001e, 0x8660},
1386 1253
1387 /* READ { 0, 0x0000, 0x8608 } -> 1254 /* READ { 0x0000, 0x8608 } -> 0000: 13 */
1388 0000: 13 */ 1255 /* READ { 0x0000, 0x8609 } -> 0000: 28 */
1389 /* READ { 0, 0x0000, 0x8609 } -> 1256 /* READ { 0x0000, 0x8610 } -> 0000: 05 */
1390 0000: 28 */ 1257 /* READ { 0x0000, 0x8611 } -> 0000: 25 */
1391 /* READ { 0, 0x0000, 0x8610 } -> 1258 /* READ { 0x0000, 0x8612 } -> 0000: e1 */
1392 0000: 05 */ 1259 /* READ { 0x0000, 0x8613 } -> 0000: fa */
1393 /* READ { 0, 0x0000, 0x8611 } -> 1260 /* READ { 0x0000, 0x8614 } -> 0000: f4 */
1394 0000: 25 */ 1261 /* READ { 0x0000, 0x8615 } -> 0000: e8 */
1395 /* READ { 0, 0x0000, 0x8612 } -> 1262 /* READ { 0x0000, 0x8616 } -> 0000: 25 */
1396 0000: e1 */
1397 /* READ { 0, 0x0000, 0x8613 } ->
1398 0000: fa */
1399 /* READ { 0, 0x0000, 0x8614 } ->
1400 0000: f4 */
1401 /* READ { 0, 0x0000, 0x8615 } ->
1402 0000: e8 */
1403 /* READ { 0, 0x0000, 0x8616 } ->
1404 0000: 25 */
1405 {} 1263 {}
1406}; 1264};
1407 1265
1408static int reg_write(struct usb_device *dev, 1266static int reg_write(struct usb_device *dev,
1409 __u16 index, __u16 value) 1267 u16 index, u16 value)
1410{ 1268{
1411 int ret; 1269 int ret;
1412 1270
@@ -1425,7 +1283,7 @@ static int reg_write(struct usb_device *dev,
1425/* read 1 byte */ 1283/* read 1 byte */
1426/* returns: negative is error, pos or zero is data */ 1284/* returns: negative is error, pos or zero is data */
1427static int reg_read(struct gspca_dev *gspca_dev, 1285static int reg_read(struct gspca_dev *gspca_dev,
1428 __u16 index) /* wIndex */ 1286 u16 index) /* wIndex */
1429{ 1287{
1430 int ret; 1288 int ret;
1431 1289
@@ -1447,16 +1305,16 @@ static int reg_read(struct gspca_dev *gspca_dev,
1447} 1305}
1448 1306
1449static int write_vector(struct gspca_dev *gspca_dev, 1307static int write_vector(struct gspca_dev *gspca_dev,
1450 const u16 data[][2]) 1308 const u16 (*data)[2])
1451{ 1309{
1452 struct usb_device *dev = gspca_dev->dev; 1310 struct usb_device *dev = gspca_dev->dev;
1453 int ret, i = 0; 1311 int ret;
1454 1312
1455 while (data[i][1] != 0) { 1313 while ((*data)[1] != 0) {
1456 ret = reg_write(dev, data[i][1], data[i][0]); 1314 ret = reg_write(dev, (*data)[1], (*data)[0]);
1457 if (ret < 0) 1315 if (ret < 0)
1458 return ret; 1316 return ret;
1459 i++; 1317 data++;
1460 } 1318 }
1461 return 0; 1319 return 0;
1462} 1320}
@@ -1468,6 +1326,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
1468 struct sd *sd = (struct sd *) gspca_dev; 1326 struct sd *sd = (struct sd *) gspca_dev;
1469 struct cam *cam; 1327 struct cam *cam;
1470 int data1, data2; 1328 int data1, data2;
1329 const u16 (*init_data)[2];
1330 static const u16 (*(init_data_tb[]))[2] = {
1331 spca508_vista_init_data, /* CreativeVista 0 */
1332 spca508_sightcam_init_data, /* HamaUSBSightcam 1 */
1333 spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */
1334 spca508cs110_init_data, /* IntelEasyPCCamera 3 */
1335 spca508cs110_init_data, /* MicroInnovationIC200 4 */
1336 spca508_init_data, /* ViewQuestVQ110 5 */
1337 };
1471 1338
1472 /* Read from global register the USB product and vendor IDs, just to 1339 /* Read from global register the USB product and vendor IDs, just to
1473 * prove that we can communicate with the device. This works, which 1340 * prove that we can communicate with the device. This works, which
@@ -1491,37 +1358,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
1491 sd->subtype = id->driver_info; 1358 sd->subtype = id->driver_info;
1492 sd->brightness = BRIGHTNESS_DEF; 1359 sd->brightness = BRIGHTNESS_DEF;
1493 1360
1494 switch (sd->subtype) { 1361 init_data = init_data_tb[sd->subtype];
1495 case ViewQuestVQ110: 1362 return write_vector(gspca_dev, init_data);
1496 if (write_vector(gspca_dev, spca508_init_data))
1497 return -1;
1498 break;
1499 default:
1500/* case MicroInnovationIC200: */
1501/* case IntelEasyPCCamera: */
1502 if (write_vector(gspca_dev, spca508cs110_init_data))
1503 return -1;
1504 break;
1505 case HamaUSBSightcam:
1506 if (write_vector(gspca_dev, spca508_sightcam_init_data))
1507 return -1;
1508 break;
1509 case HamaUSBSightcam2:
1510 if (write_vector(gspca_dev, spca508_sightcam2_init_data))
1511 return -1;
1512 break;
1513 case CreativeVista:
1514 if (write_vector(gspca_dev, spca508_vista_init_data))
1515 return -1;
1516 break;
1517 }
1518 return 0; /* success */
1519} 1363}
1520 1364
1521/* this function is called at probe and resume time */ 1365/* this function is called at probe and resume time */
1522static int sd_init(struct gspca_dev *gspca_dev) 1366static int sd_init(struct gspca_dev *gspca_dev)
1523{ 1367{
1524/* write_vector(gspca_dev, spca508_open_data); */
1525 return 0; 1368 return 0;
1526} 1369}
1527 1370
@@ -1529,7 +1372,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1529{ 1372{
1530 int mode; 1373 int mode;
1531 1374
1532 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1375 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1533 reg_write(gspca_dev->dev, 0x8500, mode); 1376 reg_write(gspca_dev->dev, 0x8500, mode);
1534 switch (mode) { 1377 switch (mode) {
1535 case 0: 1378 case 0:
@@ -1554,7 +1397,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1554 1397
1555static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1398static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1556 struct gspca_frame *frame, /* target */ 1399 struct gspca_frame *frame, /* target */
1557 __u8 *data, /* isoc packet */ 1400 u8 *data, /* isoc packet */
1558 int len) /* iso packet length */ 1401 int len) /* iso packet length */
1559{ 1402{
1560 switch (data[0]) { 1403 switch (data[0]) {
@@ -1567,7 +1410,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1567 data, len); 1410 data, len);
1568 break; 1411 break;
1569 case 0xff: /* drop */ 1412 case 0xff: /* drop */
1570/* gspca_dev->last_packet_type = DISCARD_PACKET; */
1571 break; 1413 break;
1572 default: 1414 default:
1573 data += 1; 1415 data += 1;
@@ -1581,7 +1423,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1581static void setbrightness(struct gspca_dev *gspca_dev) 1423static void setbrightness(struct gspca_dev *gspca_dev)
1582{ 1424{
1583 struct sd *sd = (struct sd *) gspca_dev; 1425 struct sd *sd = (struct sd *) gspca_dev;
1584 __u8 brightness = sd->brightness; 1426 u8 brightness = sd->brightness;
1585 1427
1586 /* MX seem contrast */ 1428 /* MX seem contrast */
1587 reg_write(gspca_dev->dev, 0x8651, brightness); 1429 reg_write(gspca_dev->dev, 0x8651, brightness);
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index c99c5e34e211..27e82b35f3e7 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -34,8 +34,8 @@ struct sd {
34 34
35 __u16 exposure; /* rev12a only */ 35 __u16 exposure; /* rev12a only */
36#define EXPOSURE_MIN 1 36#define EXPOSURE_MIN 1
37#define EXPOSURE_DEF 200 37#define EXPOSURE_DEF 700 /* == 10 fps */
38#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ 38#define EXPOSURE_MAX (2047 + 325) /* see setexposure */
39 39
40 __u8 contrast; /* rev72a only */ 40 __u8 contrast; /* rev72a only */
41#define CONTRAST_MIN 0x00 41#define CONTRAST_MIN 0x00
@@ -48,9 +48,9 @@ struct sd {
48#define BRIGHTNESS_MAX 0x3f 48#define BRIGHTNESS_MAX 0x3f
49 49
50 __u8 white; 50 __u8 white;
51#define WHITE_MIN 1 51#define HUE_MIN 1
52#define WHITE_DEF 0x40 52#define HUE_DEF 0x40
53#define WHITE_MAX 0x7f 53#define HUE_MAX 0x7f
54 54
55 __u8 autogain; 55 __u8 autogain;
56#define AUTOGAIN_MIN 0 56#define AUTOGAIN_MIN 0
@@ -58,9 +58,9 @@ struct sd {
58#define AUTOGAIN_MAX 1 58#define AUTOGAIN_MAX 1
59 59
60 __u8 gain; /* rev12a only */ 60 __u8 gain; /* rev12a only */
61#define GAIN_MIN 0x0 61#define GAIN_MIN 0
62#define GAIN_DEF 0x24 62#define GAIN_DEF 63
63#define GAIN_MAX 0x24 63#define GAIN_MAX 255
64 64
65#define EXPO12A_DEF 3 65#define EXPO12A_DEF 3
66 __u8 expo12a; /* expo/gain? for rev 12a */ 66 __u8 expo12a; /* expo/gain? for rev 12a */
@@ -461,7 +461,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
461 } 461 }
462 sd->brightness = BRIGHTNESS_DEF; 462 sd->brightness = BRIGHTNESS_DEF;
463 sd->contrast = CONTRAST_DEF; 463 sd->contrast = CONTRAST_DEF;
464 sd->white = WHITE_DEF; 464 sd->white = HUE_DEF;
465 sd->exposure = EXPOSURE_DEF; 465 sd->exposure = EXPOSURE_DEF;
466 sd->autogain = AUTOGAIN_DEF; 466 sd->autogain = AUTOGAIN_DEF;
467 sd->gain = GAIN_DEF; 467 sd->gain = GAIN_DEF;
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
549static void setexposure(struct gspca_dev *gspca_dev) 549static void setexposure(struct gspca_dev *gspca_dev)
550{ 550{
551 struct sd *sd = (struct sd *) gspca_dev; 551 struct sd *sd = (struct sd *) gspca_dev;
552 int expo; 552 int i, expo = 0;
553 int clock_divider;
554 553
555 /* Register 0x8309 controls exposure for the spca561, 554 /* Register 0x8309 controls exposure for the spca561,
556 the basic exposure setting goes from 1-2047, where 1 is completely 555 the basic exposure setting goes from 1-2047, where 1 is completely
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev)
564 configure a divider for the base framerate which us used at the 563 configure a divider for the base framerate which us used at the
565 exposure setting of 1-300. These bits configure the base framerate 564 exposure setting of 1-300. These bits configure the base framerate
566 according to the following formula: fps = 60 / (value + 2) */ 565 according to the following formula: fps = 60 / (value + 2) */
567 if (sd->exposure < 2048) { 566
568 expo = sd->exposure; 567 /* We choose to use the high bits setting the fixed framerate divisor
569 clock_divider = 0; 568 asap, as setting high basic exposure setting without the fixed
570 } else { 569 divider in combination with high gains makes the cam stop */
571 /* Add 900 to make the 0 setting of the second part of the 570 int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
572 exposure equal to the 2047 setting of the first part. */ 571
573 expo = (sd->exposure - 2048) + 900; 572 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
574 clock_divider = 3; 573 if (sd->exposure <= table[i + 1]) {
574 expo = sd->exposure - table[i];
575 if (i)
576 expo += 300;
577 expo |= i << 11;
578 break;
579 }
575 } 580 }
576 expo |= clock_divider << 11; 581
577 gspca_dev->usb_buf[0] = expo; 582 gspca_dev->usb_buf[0] = expo;
578 gspca_dev->usb_buf[1] = expo >> 8; 583 gspca_dev->usb_buf[1] = expo >> 8;
579 reg_w_buf(gspca_dev, 0x8309, 2); 584 reg_w_buf(gspca_dev, 0x8309, 2);
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev)
584{ 589{
585 struct sd *sd = (struct sd *) gspca_dev; 590 struct sd *sd = (struct sd *) gspca_dev;
586 591
587 gspca_dev->usb_buf[0] = sd->gain; 592 /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
593 sensitivity when set, so 31 + one of them set == 63, and 15
594 with both of them set == 63 */
595 if (sd->gain < 64)
596 gspca_dev->usb_buf[0] = sd->gain;
597 else if (sd->gain < 128)
598 gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
599 else
600 gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
601
588 gspca_dev->usb_buf[1] = 0; 602 gspca_dev->usb_buf[1] = 0;
589 reg_w_buf(gspca_dev, 0x8335, 2); 603 reg_w_buf(gspca_dev, 0x8335, 2);
590} 604}
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
629 reg_w_buf(gspca_dev, 0x8391, 8); 643 reg_w_buf(gspca_dev, 0x8391, 8);
630 reg_w_buf(gspca_dev, 0x8390, 8); 644 reg_w_buf(gspca_dev, 0x8390, 8);
631 setwhite(gspca_dev); 645 setwhite(gspca_dev);
632 setautogain(gspca_dev); 646 setgain(gspca_dev);
633/* setgain(gspca_dev); */
634 setexposure(gspca_dev); 647 setexposure(gspca_dev);
635 return 0; 648 return 0;
636} 649}
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
762 i2c_write(gspca_dev, expotimes | pixelclk, 0x09); 775 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
763 } 776 }
764 break; 777 break;
765 case Rev012A:
766 reg_r(gspca_dev, 0x8330, 2);
767 if (gspca_dev->usb_buf[1] > 0x08) {
768 gspca_dev->usb_buf[0] = ++sd->expo12a;
769 gspca_dev->usb_buf[1] = 0;
770 reg_w_buf(gspca_dev, 0x8339, 2);
771 } else if (gspca_dev->usb_buf[1] < 0x02) {
772 gspca_dev->usb_buf[0] = --sd->expo12a;
773 gspca_dev->usb_buf[1] = 0;
774 reg_w_buf(gspca_dev, 0x8339, 2);
775 }
776 break;
777 } 778 }
778} 779}
779 780
@@ -928,13 +929,13 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
928static struct ctrl sd_ctrls_12a[] = { 929static struct ctrl sd_ctrls_12a[] = {
929 { 930 {
930 { 931 {
931 .id = V4L2_CID_DO_WHITE_BALANCE, 932 .id = V4L2_CID_HUE,
932 .type = V4L2_CTRL_TYPE_INTEGER, 933 .type = V4L2_CTRL_TYPE_INTEGER,
933 .name = "White Balance", 934 .name = "Hue",
934 .minimum = WHITE_MIN, 935 .minimum = HUE_MIN,
935 .maximum = WHITE_MAX, 936 .maximum = HUE_MAX,
936 .step = 1, 937 .step = 1,
937 .default_value = WHITE_DEF, 938 .default_value = HUE_DEF,
938 }, 939 },
939 .set = sd_setwhite, 940 .set = sd_setwhite,
940 .get = sd_getwhite, 941 .get = sd_getwhite,
@@ -954,19 +955,6 @@ static struct ctrl sd_ctrls_12a[] = {
954 }, 955 },
955 { 956 {
956 { 957 {
957 .id = V4L2_CID_AUTOGAIN,
958 .type = V4L2_CTRL_TYPE_BOOLEAN,
959 .name = "Auto Gain",
960 .minimum = AUTOGAIN_MIN,
961 .maximum = AUTOGAIN_MAX,
962 .step = 1,
963 .default_value = AUTOGAIN_DEF,
964 },
965 .set = sd_setautogain,
966 .get = sd_getautogain,
967 },
968 {
969 {
970 .id = V4L2_CID_GAIN, 958 .id = V4L2_CID_GAIN,
971 .type = V4L2_CTRL_TYPE_INTEGER, 959 .type = V4L2_CTRL_TYPE_INTEGER,
972 .name = "Gain", 960 .name = "Gain",
@@ -983,13 +971,13 @@ static struct ctrl sd_ctrls_12a[] = {
983static struct ctrl sd_ctrls_72a[] = { 971static struct ctrl sd_ctrls_72a[] = {
984 { 972 {
985 { 973 {
986 .id = V4L2_CID_DO_WHITE_BALANCE, 974 .id = V4L2_CID_HUE,
987 .type = V4L2_CTRL_TYPE_INTEGER, 975 .type = V4L2_CTRL_TYPE_INTEGER,
988 .name = "White Balance", 976 .name = "Hue",
989 .minimum = WHITE_MIN, 977 .minimum = HUE_MIN,
990 .maximum = WHITE_MAX, 978 .maximum = HUE_MAX,
991 .step = 1, 979 .step = 1,
992 .default_value = WHITE_DEF, 980 .default_value = HUE_DEF,
993 }, 981 },
994 .set = sd_setwhite, 982 .set = sd_setwhite,
995 .get = sd_getwhite, 983 .get = sd_getwhite,
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = {
1046 .stopN = sd_stopN, 1034 .stopN = sd_stopN,
1047 .stop0 = sd_stop0, 1035 .stop0 = sd_stop0,
1048 .pkt_scan = sd_pkt_scan, 1036 .pkt_scan = sd_pkt_scan,
1049/* .dq_callback = do_autogain, * fixme */
1050}; 1037};
1051static const struct sd_desc sd_desc_72a = { 1038static const struct sd_desc sd_desc_72a = {
1052 .name = MODULE_NAME, 1039 .name = MODULE_NAME,
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 2e1cdf068fda..715a68f0156e 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
309 struct sd *dev = (struct sd *) gspca_dev; 309 struct sd *dev = (struct sd *) gspca_dev;
310 310
311 /* We don't use the buffer gspca allocates so make it small. */ 311 /* We don't use the buffer gspca allocates so make it small. */
312 cam->bulk = 1;
312 cam->bulk_size = 64; 313 cam->bulk_size = 64;
313 314
314 INIT_WORK(&dev->work_struct, sq905_dostream); 315 INIT_WORK(&dev->work_struct, sq905_dostream);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 0bcb74a1b143..916892505432 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
206 cam->nmodes = 1; 206 cam->nmodes = 1;
207 /* We don't use the buffer gspca allocates so make it small. */ 207 /* We don't use the buffer gspca allocates so make it small. */
208 cam->bulk_size = 32; 208 cam->bulk_size = 32;
209 cam->bulk = 1;
209 INIT_WORK(&dev->work_struct, sq905c_dostream); 210 INIT_WORK(&dev->work_struct, sq905c_dostream);
210 return 0; 211 return 0;
211} 212}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 9dff2e65b116..e573c3406324 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -293,8 +293,6 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev)
293 goto out; 293 goto out;
294 294
295 err = sd->sensor->stop(sd); 295 err = sd->sensor->stop(sd);
296 if (err < 0)
297 goto out;
298 296
299out: 297out:
300 if (err < 0) 298 if (err < 0)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 69c77c932fc0..11a0c002f5dc 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -80,12 +80,26 @@ static const struct ctrl vv6410_ctrl[] = {
80 .minimum = 0, 80 .minimum = 0,
81 .maximum = 15, 81 .maximum = 15,
82 .step = 1, 82 .step = 1,
83 .default_value = 0 83 .default_value = 10
84 }, 84 },
85 .set = vv6410_set_analog_gain, 85 .set = vv6410_set_analog_gain,
86 .get = vv6410_get_analog_gain 86 .get = vv6410_get_analog_gain
87 },
88#define EXPOSURE_IDX 3
89 {
90 {
91 .id = V4L2_CID_EXPOSURE,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "exposure",
94 .minimum = 0,
95 .maximum = 32768,
96 .step = 1,
97 .default_value = 20000
98 },
99 .set = vv6410_set_exposure,
100 .get = vv6410_get_exposure
87 } 101 }
88}; 102 };
89 103
90static int vv6410_probe(struct sd *sd) 104static int vv6410_probe(struct sd *sd)
91{ 105{
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd)
121static int vv6410_init(struct sd *sd) 135static int vv6410_init(struct sd *sd)
122{ 136{
123 int err = 0, i; 137 int err = 0, i;
138 s32 *sensor_settings = sd->sensor_priv;
124 139
125 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { 140 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
126 /* if NULL then len contains single value */ 141 /* if NULL then len contains single value */
@@ -142,6 +157,16 @@ static int vv6410_init(struct sd *sd)
142 157
143 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, 158 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
144 ARRAY_SIZE(vv6410_sensor_init)); 159 ARRAY_SIZE(vv6410_sensor_init));
160 if (err < 0)
161 return err;
162
163 err = vv6410_set_exposure(&sd->gspca_dev,
164 sensor_settings[EXPOSURE_IDX]);
165 if (err < 0)
166 return err;
167
168 err = vv6410_set_analog_gain(&sd->gspca_dev,
169 sensor_settings[GAIN_IDX]);
145 170
146 return (err < 0) ? err : 0; 171 return (err < 0) ? err : 0;
147} 172}
@@ -318,3 +343,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
318 343
319 return (err < 0) ? err : 0; 344 return (err < 0) ? err : 0;
320} 345}
346
347static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
348{
349 struct sd *sd = (struct sd *) gspca_dev;
350 s32 *sensor_settings = sd->sensor_priv;
351
352 *val = sensor_settings[EXPOSURE_IDX];
353
354 PDEBUG(D_V4L2, "Read exposure %d", *val);
355
356 return 0;
357}
358
359static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
360{
361 int err;
362 struct sd *sd = (struct sd *) gspca_dev;
363 s32 *sensor_settings = sd->sensor_priv;
364 unsigned int fine, coarse;
365
366 sensor_settings[EXPOSURE_IDX] = val;
367
368 val = (val * val >> 14) + val / 4;
369
370 fine = val % VV6410_CIF_LINELENGTH;
371 coarse = min(512, val / VV6410_CIF_LINELENGTH);
372
373 PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d",
374 coarse, fine);
375
376 err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
377 if (err < 0)
378 goto out;
379
380 err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff);
381 if (err < 0)
382 goto out;
383
384 err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8);
385 if (err < 0)
386 goto out;
387
388 err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff);
389
390out:
391 return err;
392}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 95ac55891bd4..487d40555343 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -173,6 +173,8 @@
173#define VV6410_SUBSAMPLE 0x01 173#define VV6410_SUBSAMPLE 0x01
174#define VV6410_CROP_TO_QVGA 0x02 174#define VV6410_CROP_TO_QVGA 0x02
175 175
176#define VV6410_CIF_LINELENGTH 415
177
176static int vv6410_probe(struct sd *sd); 178static int vv6410_probe(struct sd *sd);
177static int vv6410_start(struct sd *sd); 179static int vv6410_start(struct sd *sd);
178static int vv6410_init(struct sd *sd); 180static int vv6410_init(struct sd *sd);
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
187static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 189static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
188static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); 190static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
189static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); 191static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
192static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
193static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
190 194
191const struct stv06xx_sensor stv06xx_sensor_vv6410 = { 195const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
192 .name = "ST VV6410", 196 .name = "ST VV6410",
@@ -242,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = {
242 /* Pre-clock generator divide off */ 246 /* Pre-clock generator divide off */
243 {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, 247 {VV6410_DATAFORMAT, BIT(7) | BIT(0)},
244 248
245 /* Exposure registers */
246 {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8},
247 {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff},
248 {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8},
249 {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff},
250 {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN},
251 {VV6410_CLKDIV, VV6410_CLK_DIV_2}, 249 {VV6410_CLKDIV, VV6410_CLK_DIV_2},
252 250
253 /* System registers */ 251 /* System registers */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index c2b8c10c075a..9623f294bdac 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 __u8 packet[ISO_MAX_SIZE + 128];
36 /* !! no more than 128 ff in an ISO packet */
37
38 unsigned char brightness; 35 unsigned char brightness;
39 unsigned char contrast; 36 unsigned char contrast;
40 unsigned char colors; 37 unsigned char colors;
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1103{ 1100{
1104 struct sd *sd = (struct sd *) gspca_dev; 1101 struct sd *sd = (struct sd *) gspca_dev;
1105 int i, sof = 0; 1102 int i, sof = 0;
1106 unsigned char *s, *d;
1107 static unsigned char ffd9[] = {0xff, 0xd9}; 1103 static unsigned char ffd9[] = {0xff, 0xd9};
1108 1104
1109/* frames are jpeg 4.1.1 without 0xff escape */ 1105/* frames are jpeg 4.1.1 without 0xff escape */
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1177 } 1173 }
1178 1174
1179 /* add 0x00 after 0xff */ 1175 /* add 0x00 after 0xff */
1180 for (i = len; --i >= 0; ) 1176 i = 0;
1181 if (data[i] == 0xff) 1177 do {
1182 break; 1178 if (data[i] == 0xff) {
1183 if (i < 0) { /* no 0xff */ 1179 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1184 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1180 data, i + 1);
1185 return; 1181 len -= i;
1186 } 1182 data += i;
1187 s = data; 1183 *data = 0x00;
1188 d = sd->packet; 1184 i = 0;
1189 for (i = 0; i < len; i++) { 1185 }
1190 *d++ = *s++; 1186 i++;
1191 if (s[-1] == 0xff) 1187 } while (i < len);
1192 *d++ = 0x00; 1188 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1193 }
1194 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1195 sd->packet, d - sd->packet);
1196} 1189}
1197 1190
1198static void setbrightness(struct gspca_dev *gspca_dev) 1191static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index f63e37e2e4fd..404214b8cd2b 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
697 return -EINVAL; 697 return -EINVAL;
698 } 698 }
699 699
700 if (sd->sensor != SENSOR_OTHER) { 700 if (sd->sensor == SENSOR_OM6802) {
701 reg_w_buf(gspca_dev, n1, sizeof n1); 701 reg_w_buf(gspca_dev, n1, sizeof n1);
702 i = 5; 702 i = 5;
703 while (--i >= 0) { 703 while (--i >= 0) {
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index e4e933c400bc..26dd155efcc3 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -42,7 +42,7 @@ struct sd {
42 char bridge; 42 char bridge;
43#define BRIDGE_VC0321 0 43#define BRIDGE_VC0321 0
44#define BRIDGE_VC0323 1 44#define BRIDGE_VC0323 1
45 char sensor; 45 u8 sensor;
46#define SENSOR_HV7131R 0 46#define SENSOR_HV7131R 0
47#define SENSOR_MI0360 1 47#define SENSOR_MI0360 1
48#define SENSOR_MI1310_SOC 2 48#define SENSOR_MI1310_SOC 2
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = {
159 .priv = 2}, 159 .priv = 2},
160}; 160};
161static const struct v4l2_pix_format bi_mode[] = { 161static const struct v4l2_pix_format bi_mode[] = {
162 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 162 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
163 .bytesperline = 320, 163 .bytesperline = 320,
164 .sizeimage = 320 * 240 * 2, 164 .sizeimage = 320 * 240 * 2,
165 .colorspace = V4L2_COLORSPACE_SRGB, 165 .colorspace = V4L2_COLORSPACE_SRGB,
166 .priv = 2}, 166 .priv = 2},
167 {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 167 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
168 .bytesperline = 640, 168 .bytesperline = 640,
169 .sizeimage = 640 * 480 * 2, 169 .sizeimage = 640 * 480 * 2,
170 .colorspace = V4L2_COLORSPACE_SRGB, 170 .colorspace = V4L2_COLORSPACE_SRGB,
171 .priv = 1}, 171 .priv = 1},
172 {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 172 {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
173 .bytesperline = 1280, 173 .bytesperline = 1280,
174 .sizeimage = 1280 * 1024 * 2, 174 .sizeimage = 1280 * 1024 * 2,
175 .colorspace = V4L2_COLORSPACE_SRGB, 175 .colorspace = V4L2_COLORSPACE_SRGB,
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
2453 struct usb_device *dev = gspca_dev->dev; 2453 struct usb_device *dev = gspca_dev->dev;
2454 struct cam *cam; 2454 struct cam *cam;
2455 int sensor; 2455 int sensor;
2456 static u8 npkt[] = { /* number of packets per ISOC message */
2457 64, /* HV7131R 0 */
2458 32, /* MI0360 1 */
2459 32, /* MI1310_SOC 2 */
2460 64, /* MI1320 3 */
2461 128, /* MI1320_SOC 4 */
2462 32, /* OV7660 5 */
2463 64, /* OV7670 6 */
2464 128, /* PO1200 7 */
2465 128, /* PO3130NC 8 */
2466 };
2456 2467
2457 cam = &gspca_dev->cam; 2468 cam = &gspca_dev->cam;
2458 sd->bridge = id->driver_info; 2469 sd->bridge = id->driver_info;
@@ -2508,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
2508 case SENSOR_MI1320_SOC: 2519 case SENSOR_MI1320_SOC:
2509 cam->cam_mode = bi_mode; 2520 cam->cam_mode = bi_mode;
2510 cam->nmodes = ARRAY_SIZE(bi_mode); 2521 cam->nmodes = ARRAY_SIZE(bi_mode);
2522 cam->input_flags = V4L2_IN_ST_VFLIP |
2523 V4L2_IN_ST_HFLIP;
2511 break; 2524 break;
2512 default: 2525 default:
2513 cam->cam_mode = vc0323_mode; 2526 cam->cam_mode = vc0323_mode;
@@ -2515,6 +2528,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2515 break; 2528 break;
2516 } 2529 }
2517 } 2530 }
2531 cam->npkt = npkt[sd->sensor];
2518 2532
2519 sd->hflip = HFLIP_DEF; 2533 sd->hflip = HFLIP_DEF;
2520 sd->vflip = VFLIP_DEF; 2534 sd->vflip = VFLIP_DEF;
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 4fe01d8b6c87..08422d315e68 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
6308 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 6308 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
6309 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 6309 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */
6310 PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", 6310 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
6311 reg, retval, retbyte); 6311 reg, retval, retbyte);
6312 return retval; 6312 return retval;
6313} 6313}
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6868 {0x8001, 0x13}, 6868 {0x8001, 0x13},
6869 {0x8000, 0x14}, /* CS2102K */ 6869 {0x8000, 0x14}, /* CS2102K */
6870 {0x8400, 0x15}, /* TAS5130K */ 6870 {0x8400, 0x15}, /* TAS5130K */
6871 {0x4001, 0x16}, /* ADCM2700 */
6872}; 6871};
6873 6872
6874static int vga_3wr_probe(struct gspca_dev *gspca_dev) 6873static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6904 retword |= reg_r(gspca_dev, 0x000a); 6903 retword |= reg_r(gspca_dev, 0x000a);
6905 PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); 6904 PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
6906 reg_r(gspca_dev, 0x0010); 6905 reg_r(gspca_dev, 0x0010);
6907 /* this is tested only once anyway */ 6906 /* value 0x4001 is meaningless */
6908 for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { 6907 if (retword != 0x4001) {
6909 if (chipset_revision_sensor[i].revision == retword) { 6908 for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
6910 sd->chip_revision = retword; 6909 if (chipset_revision_sensor[i].revision == retword) {
6911 send_unknown(dev, SENSOR_PB0330); 6910 sd->chip_revision = retword;
6912 return chipset_revision_sensor[i].internal_sensor_id; 6911 send_unknown(dev, SENSOR_PB0330);
6912 return chipset_revision_sensor[i]
6913 .internal_sensor_id;
6914 }
6913 } 6915 }
6914 } 6916 }
6915 6917
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6980 reg_w(dev, 0x01, 0x0001); 6982 reg_w(dev, 0x01, 0x0001);
6981 reg_w(dev, 0x03, 0x0012); 6983 reg_w(dev, 0x03, 0x0012);
6982 reg_w(dev, 0x01, 0x0012); 6984 reg_w(dev, 0x01, 0x0012);
6983 reg_w(dev, 0x05, 0x0001); 6985 reg_w(dev, 0x05, 0x0012);
6984 reg_w(dev, 0xd3, 0x008b); 6986 reg_w(dev, 0xd3, 0x008b);
6985 retword = i2c_read(gspca_dev, 0x01); 6987 retword = i2c_read(gspca_dev, 0x01);
6986 if (retword != 0) { 6988 if (retword != 0) {
6987 PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); 6989 PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
6988 return retword; 6990 return 0x16; /* adcm2700 (6100/6200) */
6989 } 6991 }
6990 return -1; 6992 return -1;
6991} 6993}