aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/conex.c24
-rw-r--r--drivers/media/video/gspca/etoms.c30
-rw-r--r--drivers/media/video/gspca/gspca.c119
-rw-r--r--drivers/media/video/gspca/gspca.h21
-rw-r--r--drivers/media/video/gspca/mars.c41
-rw-r--r--drivers/media/video/gspca/ov519.c1167
-rw-r--r--drivers/media/video/gspca/pac207.c87
-rw-r--r--drivers/media/video/gspca/pac7311.c1110
-rw-r--r--drivers/media/video/gspca/pac_common.h60
-rw-r--r--drivers/media/video/gspca/sonixb.c594
-rw-r--r--drivers/media/video/gspca/sonixj.c539
-rw-r--r--drivers/media/video/gspca/spca500.c20
-rw-r--r--drivers/media/video/gspca/spca501.c16
-rw-r--r--drivers/media/video/gspca/spca505.c16
-rw-r--r--drivers/media/video/gspca/spca506.c20
-rw-r--r--drivers/media/video/gspca/spca508.c21
-rw-r--r--drivers/media/video/gspca/spca561.c723
-rw-r--r--drivers/media/video/gspca/stk014.c20
-rw-r--r--drivers/media/video/gspca/sunplus.c167
-rw-r--r--drivers/media/video/gspca/t613.c41
-rw-r--r--drivers/media/video/gspca/tv8532.c20
-rw-r--r--drivers/media/video/gspca/vc032x.c31
-rw-r--r--drivers/media/video/gspca/zc3xx.c85
23 files changed, 2882 insertions, 2090 deletions
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index cd3a3f5829b2..8c91ffde9536 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -124,7 +124,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
124 struct usb_device *dev = gspca_dev->dev; 124 struct usb_device *dev = gspca_dev->dev;
125 125
126#ifdef GSPCA_DEBUG 126#ifdef GSPCA_DEBUG
127 if (len > sizeof gspca_dev->usb_buf) { 127 if (len > USB_BUF_SZ) {
128 err("reg_r: buffer overflow"); 128 err("reg_r: buffer overflow");
129 return; 129 return;
130 } 130 }
@@ -164,7 +164,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
164 struct usb_device *dev = gspca_dev->dev; 164 struct usb_device *dev = gspca_dev->dev;
165 165
166#ifdef GSPCA_DEBUG 166#ifdef GSPCA_DEBUG
167 if (len > sizeof gspca_dev->usb_buf) { 167 if (len > USB_BUF_SZ) {
168 err("reg_w: buffer overflow"); 168 err("reg_w: buffer overflow");
169 return; 169 return;
170 } 170 }
@@ -826,8 +826,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
826 return 0; 826 return 0;
827} 827}
828 828
829/* this function is called at open time */ 829/* this function is called at probe and resume time */
830static int sd_open(struct gspca_dev *gspca_dev) 830static int sd_init(struct gspca_dev *gspca_dev)
831{ 831{
832 cx11646_init1(gspca_dev); 832 cx11646_init1(gspca_dev);
833 cx11646_initsize(gspca_dev); 833 cx11646_initsize(gspca_dev);
@@ -845,10 +845,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
845 cx11646_jpeg(gspca_dev); 845 cx11646_jpeg(gspca_dev);
846} 846}
847 847
848static void sd_stopN(struct gspca_dev *gspca_dev)
849{
850}
851
852static void sd_stop0(struct gspca_dev *gspca_dev) 848static void sd_stop0(struct gspca_dev *gspca_dev)
853{ 849{
854 int retry = 50; 850 int retry = 50;
@@ -871,10 +867,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
871 reg_w_val(gspca_dev, 0x00fc, 0xe0); 867 reg_w_val(gspca_dev, 0x00fc, 0xe0);
872} 868}
873 869
874static void sd_close(struct gspca_dev *gspca_dev)
875{
876}
877
878static void sd_pkt_scan(struct gspca_dev *gspca_dev, 870static void sd_pkt_scan(struct gspca_dev *gspca_dev,
879 struct gspca_frame *frame, /* target */ 871 struct gspca_frame *frame, /* target */
880 __u8 *data, /* isoc packet */ 872 __u8 *data, /* isoc packet */
@@ -998,11 +990,9 @@ static struct sd_desc sd_desc = {
998 .ctrls = sd_ctrls, 990 .ctrls = sd_ctrls,
999 .nctrls = ARRAY_SIZE(sd_ctrls), 991 .nctrls = ARRAY_SIZE(sd_ctrls),
1000 .config = sd_config, 992 .config = sd_config,
1001 .open = sd_open, 993 .init = sd_init,
1002 .start = sd_start, 994 .start = sd_start,
1003 .stopN = sd_stopN,
1004 .stop0 = sd_stop0, 995 .stop0 = sd_stop0,
1005 .close = sd_close,
1006 .pkt_scan = sd_pkt_scan, 996 .pkt_scan = sd_pkt_scan,
1007}; 997};
1008 998
@@ -1026,6 +1016,10 @@ static struct usb_driver sd_driver = {
1026 .id_table = device_table, 1016 .id_table = device_table,
1027 .probe = sd_probe, 1017 .probe = sd_probe,
1028 .disconnect = gspca_disconnect, 1018 .disconnect = gspca_disconnect,
1019#ifdef CONFIG_PM
1020 .suspend = gspca_suspend,
1021 .resume = gspca_resume,
1022#endif
1029}; 1023};
1030 1024
1031/* -- module insert / remove -- */ 1025/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 1dbe92d01e6a..4ff0e386914b 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -81,6 +81,7 @@ static struct ctrl sd_ctrls[] = {
81 .set = sd_setcontrast, 81 .set = sd_setcontrast,
82 .get = sd_getcontrast, 82 .get = sd_getcontrast,
83 }, 83 },
84#define COLOR_IDX 2
84 { 85 {
85 { 86 {
86 .id = V4L2_CID_SATURATION, 87 .id = V4L2_CID_SATURATION,
@@ -234,7 +235,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
234 struct usb_device *dev = gspca_dev->dev; 235 struct usb_device *dev = gspca_dev->dev;
235 236
236#ifdef GSPCA_DEBUG 237#ifdef GSPCA_DEBUG
237 if (len > sizeof gspca_dev->usb_buf) { 238 if (len > USB_BUF_SZ) {
238 err("reg_r: buffer overflow"); 239 err("reg_r: buffer overflow");
239 return; 240 return;
240 } 241 }
@@ -272,7 +273,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
272 struct usb_device *dev = gspca_dev->dev; 273 struct usb_device *dev = gspca_dev->dev;
273 274
274#ifdef GSPCA_DEBUG 275#ifdef GSPCA_DEBUG
275 if (len > sizeof gspca_dev->usb_buf) { 276 if (len > USB_BUF_SZ) {
276 err("reg_w: buffer overflow"); 277 err("reg_w: buffer overflow");
277 return; 278 return;
278 } 279 }
@@ -665,6 +666,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
665 } else { 666 } else {
666 cam->cam_mode = vga_mode; 667 cam->cam_mode = vga_mode;
667 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 668 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
669 gspca_dev->ctrl_dis = (1 << COLOR_IDX);
668 } 670 }
669 sd->brightness = BRIGHTNESS_DEF; 671 sd->brightness = BRIGHTNESS_DEF;
670 sd->contrast = CONTRAST_DEF; 672 sd->contrast = CONTRAST_DEF;
@@ -674,8 +676,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
674 return 0; 676 return 0;
675} 677}
676 678
677/* this function is called at open time */ 679/* this function is called at probe and resume time */
678static int sd_open(struct gspca_dev *gspca_dev) 680static int sd_init(struct gspca_dev *gspca_dev)
679{ 681{
680 struct sd *sd = (struct sd *) gspca_dev; 682 struct sd *sd = (struct sd *) gspca_dev;
681 683
@@ -709,14 +711,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
709 et_video(gspca_dev, 0); /* video off */ 711 et_video(gspca_dev, 0); /* video off */
710} 712}
711 713
712static void sd_stop0(struct gspca_dev *gspca_dev)
713{
714}
715
716static void sd_close(struct gspca_dev *gspca_dev)
717{
718}
719
720static __u8 Et_getgainG(struct gspca_dev *gspca_dev) 714static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
721{ 715{
722 struct sd *sd = (struct sd *) gspca_dev; 716 struct sd *sd = (struct sd *) gspca_dev;
@@ -893,21 +887,19 @@ static struct sd_desc sd_desc = {
893 .ctrls = sd_ctrls, 887 .ctrls = sd_ctrls,
894 .nctrls = ARRAY_SIZE(sd_ctrls), 888 .nctrls = ARRAY_SIZE(sd_ctrls),
895 .config = sd_config, 889 .config = sd_config,
896 .open = sd_open, 890 .init = sd_init,
897 .start = sd_start, 891 .start = sd_start,
898 .stopN = sd_stopN, 892 .stopN = sd_stopN,
899 .stop0 = sd_stop0,
900 .close = sd_close,
901 .pkt_scan = sd_pkt_scan, 893 .pkt_scan = sd_pkt_scan,
902 .dq_callback = do_autogain, 894 .dq_callback = do_autogain,
903}; 895};
904 896
905/* -- module initialisation -- */ 897/* -- module initialisation -- */
906static __devinitdata struct usb_device_id device_table[] = { 898static __devinitdata struct usb_device_id device_table[] = {
907#ifndef CONFIG_USB_ET61X251
908 {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, 899 {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
909#endif 900#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
910 {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, 901 {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
902#endif
911 {} 903 {}
912}; 904};
913 905
@@ -926,6 +918,10 @@ static struct usb_driver sd_driver = {
926 .id_table = device_table, 918 .id_table = device_table,
927 .probe = sd_probe, 919 .probe = sd_probe,
928 .disconnect = gspca_disconnect, 920 .disconnect = gspca_disconnect,
921#ifdef CONFIG_PM
922 .suspend = gspca_suspend,
923 .resume = gspca_resume,
924#endif
929}; 925};
930 926
931/* -- module insert / remove -- */ 927/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 15d302b28b79..7be69284da03 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -114,7 +114,10 @@ static void fill_frame(struct gspca_dev *gspca_dev,
114 cam_pkt_op pkt_scan; 114 cam_pkt_op pkt_scan;
115 115
116 if (urb->status != 0) { 116 if (urb->status != 0) {
117 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); 117#ifdef CONFIG_PM
118 if (!gspca_dev->frozen)
119#endif
120 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
118 return; /* disconnection ? */ 121 return; /* disconnection ? */
119 } 122 }
120 pkt_scan = gspca_dev->sd_desc->pkt_scan; 123 pkt_scan = gspca_dev->sd_desc->pkt_scan;
@@ -555,10 +558,12 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
555 gspca_dev->streaming = 0; 558 gspca_dev->streaming = 0;
556 atomic_set(&gspca_dev->nevent, 0); 559 atomic_set(&gspca_dev->nevent, 0);
557 if (gspca_dev->present) { 560 if (gspca_dev->present) {
558 gspca_dev->sd_desc->stopN(gspca_dev); 561 if (gspca_dev->sd_desc->stopN)
562 gspca_dev->sd_desc->stopN(gspca_dev);
559 destroy_urbs(gspca_dev); 563 destroy_urbs(gspca_dev);
560 gspca_set_alt0(gspca_dev); 564 gspca_set_alt0(gspca_dev);
561 gspca_dev->sd_desc->stop0(gspca_dev); 565 if (gspca_dev->sd_desc->stop0)
566 gspca_dev->sd_desc->stop0(gspca_dev);
562 PDEBUG(D_STREAM, "stream off OK"); 567 PDEBUG(D_STREAM, "stream off OK");
563 } 568 }
564} 569}
@@ -767,19 +772,7 @@ static int dev_open(struct inode *inode, struct file *file)
767 goto out; 772 goto out;
768 } 773 }
769 774
770 /* if not done yet, initialize the sensor */ 775 if (gspca_dev->users > 4) { /* (arbitrary value) */
771 if (gspca_dev->users == 0) {
772 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
773 ret = -ERESTARTSYS;
774 goto out;
775 }
776 ret = gspca_dev->sd_desc->open(gspca_dev);
777 mutex_unlock(&gspca_dev->usb_lock);
778 if (ret != 0) {
779 PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
780 goto out;
781 }
782 } else if (gspca_dev->users > 4) { /* (arbitrary value) */
783 ret = -EBUSY; 776 ret = -EBUSY;
784 goto out; 777 goto out;
785 } 778 }
@@ -792,6 +785,7 @@ static int dev_open(struct inode *inode, struct file *file)
792 else 785 else
793 gspca_dev->vdev.debug &= ~3; 786 gspca_dev->vdev.debug &= ~3;
794#endif 787#endif
788 ret = 0;
795out: 789out:
796 mutex_unlock(&gspca_dev->queue_lock); 790 mutex_unlock(&gspca_dev->queue_lock);
797 if (ret != 0) 791 if (ret != 0)
@@ -812,11 +806,11 @@ static int dev_close(struct inode *inode, struct file *file)
812 806
813 /* if the file did the capture, free the streaming resources */ 807 /* if the file did the capture, free the streaming resources */
814 if (gspca_dev->capt_file == file) { 808 if (gspca_dev->capt_file == file) {
815 mutex_lock(&gspca_dev->usb_lock); 809 if (gspca_dev->streaming) {
816 if (gspca_dev->streaming) 810 mutex_lock(&gspca_dev->usb_lock);
817 gspca_stream_off(gspca_dev); 811 gspca_stream_off(gspca_dev);
818 gspca_dev->sd_desc->close(gspca_dev); 812 mutex_unlock(&gspca_dev->usb_lock);
819 mutex_unlock(&gspca_dev->usb_lock); 813 }
820 frame_free(gspca_dev); 814 frame_free(gspca_dev);
821 gspca_dev->capt_file = NULL; 815 gspca_dev->capt_file = NULL;
822 gspca_dev->memory = GSPCA_MEMORY_NO; 816 gspca_dev->memory = GSPCA_MEMORY_NO;
@@ -853,42 +847,44 @@ static int vidioc_querycap(struct file *file, void *priv,
853 return 0; 847 return 0;
854} 848}
855 849
856/* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */
857static int vidioc_queryctrl(struct file *file, void *priv, 850static int vidioc_queryctrl(struct file *file, void *priv,
858 struct v4l2_queryctrl *q_ctrl) 851 struct v4l2_queryctrl *q_ctrl)
859{ 852{
860 struct gspca_dev *gspca_dev = priv; 853 struct gspca_dev *gspca_dev = priv;
861 int i; 854 int i, ix;
862 u32 id; 855 u32 id;
863 856
857 ix = -1;
864 id = q_ctrl->id; 858 id = q_ctrl->id;
865 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { 859 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
866 id &= V4L2_CTRL_ID_MASK; 860 id &= V4L2_CTRL_ID_MASK;
867 id++; 861 id++;
868 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 862 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
869 if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { 863 if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
870 memcpy(q_ctrl, 864 continue;
871 &gspca_dev->sd_desc->ctrls[i].qctrl, 865 if (ix < 0) {
872 sizeof *q_ctrl); 866 ix = i;
873 return 0; 867 continue;
874 } 868 }
869 if (gspca_dev->sd_desc->ctrls[i].qctrl.id
870 > gspca_dev->sd_desc->ctrls[ix].qctrl.id)
871 continue;
872 ix = i;
875 } 873 }
876 return -EINVAL;
877 } 874 }
878 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 875 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
879 if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { 876 if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
880 memcpy(q_ctrl, 877 ix = i;
881 &gspca_dev->sd_desc->ctrls[i].qctrl, 878 break;
882 sizeof *q_ctrl);
883 return 0;
884 } 879 }
885 } 880 }
886 if (id >= V4L2_CID_BASE 881 if (ix < 0)
887 && id <= V4L2_CID_LASTP1) { 882 return -EINVAL;
883 memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl,
884 sizeof *q_ctrl);
885 if (gspca_dev->ctrl_dis & (1 << ix))
888 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; 886 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
889 return 0; 887 return 0;
890 }
891 return -EINVAL;
892} 888}
893 889
894static int vidioc_s_ctrl(struct file *file, void *priv, 890static int vidioc_s_ctrl(struct file *file, void *priv,
@@ -903,6 +899,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
903 i++, ctrls++) { 899 i++, ctrls++) {
904 if (ctrl->id != ctrls->qctrl.id) 900 if (ctrl->id != ctrls->qctrl.id)
905 continue; 901 continue;
902 if (gspca_dev->ctrl_dis & (1 << i))
903 return -EINVAL;
906 if (ctrl->value < ctrls->qctrl.minimum 904 if (ctrl->value < ctrls->qctrl.minimum
907 || ctrl->value > ctrls->qctrl.maximum) 905 || ctrl->value > ctrls->qctrl.maximum)
908 return -ERANGE; 906 return -ERANGE;
@@ -929,6 +927,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
929 i++, ctrls++) { 927 i++, ctrls++) {
930 if (ctrl->id != ctrls->qctrl.id) 928 if (ctrl->id != ctrls->qctrl.id)
931 continue; 929 continue;
930 if (gspca_dev->ctrl_dis & (1 << i))
931 return -EINVAL;
932 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 932 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
933 return -ERESTARTSYS; 933 return -ERESTARTSYS;
934 ret = ctrls->get(gspca_dev, &ctrl->value); 934 ret = ctrls->get(gspca_dev, &ctrl->value);
@@ -1403,7 +1403,7 @@ static int vidioc_dqbuf(struct file *file, void *priv,
1403 i = ret; /* frame index */ 1403 i = ret; /* frame index */
1404 frame = &gspca_dev->frame[i]; 1404 frame = &gspca_dev->frame[i];
1405 if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { 1405 if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
1406 if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr, 1406 if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
1407 frame->data, 1407 frame->data,
1408 frame->v4l2_buf.bytesused)) { 1408 frame->v4l2_buf.bytesused)) {
1409 PDEBUG(D_ERR|D_STREAM, 1409 PDEBUG(D_ERR|D_STREAM,
@@ -1731,6 +1731,12 @@ int gspca_dev_probe(struct usb_interface *intf,
1731 err("couldn't kzalloc gspca struct"); 1731 err("couldn't kzalloc gspca struct");
1732 return -EIO; 1732 return -EIO;
1733 } 1733 }
1734 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
1735 if (!gspca_dev->usb_buf) {
1736 err("out of memory");
1737 ret = -EIO;
1738 goto out;
1739 }
1734 gspca_dev->dev = dev; 1740 gspca_dev->dev = dev;
1735 gspca_dev->iface = interface->bInterfaceNumber; 1741 gspca_dev->iface = interface->bInterfaceNumber;
1736 gspca_dev->nbalt = intf->num_altsetting; 1742 gspca_dev->nbalt = intf->num_altsetting;
@@ -1738,10 +1744,13 @@ int gspca_dev_probe(struct usb_interface *intf,
1738/* gspca_dev->users = 0; (done by kzalloc) */ 1744/* gspca_dev->users = 0; (done by kzalloc) */
1739 gspca_dev->nbufread = 2; 1745 gspca_dev->nbufread = 2;
1740 1746
1741 /* configure the subdriver */ 1747 /* configure the subdriver and initialize the USB device */
1742 ret = gspca_dev->sd_desc->config(gspca_dev, id); 1748 ret = gspca_dev->sd_desc->config(gspca_dev, id);
1743 if (ret < 0) 1749 if (ret < 0)
1744 goto out; 1750 goto out;
1751 ret = gspca_dev->sd_desc->init(gspca_dev);
1752 if (ret < 0)
1753 goto out;
1745 ret = gspca_set_alt0(gspca_dev); 1754 ret = gspca_set_alt0(gspca_dev);
1746 if (ret < 0) 1755 if (ret < 0)
1747 goto out; 1756 goto out;
@@ -1771,6 +1780,7 @@ int gspca_dev_probe(struct usb_interface *intf,
1771 PDEBUG(D_PROBE, "probe ok"); 1780 PDEBUG(D_PROBE, "probe ok");
1772 return 0; 1781 return 0;
1773out: 1782out:
1783 kfree(gspca_dev->usb_buf);
1774 kfree(gspca_dev); 1784 kfree(gspca_dev);
1775 return ret; 1785 return ret;
1776} 1786}
@@ -1803,11 +1813,42 @@ void gspca_disconnect(struct usb_interface *intf)
1803/* We don't want people trying to open up the device */ 1813/* We don't want people trying to open up the device */
1804 video_unregister_device(&gspca_dev->vdev); 1814 video_unregister_device(&gspca_dev->vdev);
1805/* Free the memory */ 1815/* Free the memory */
1816 kfree(gspca_dev->usb_buf);
1806 kfree(gspca_dev); 1817 kfree(gspca_dev);
1807 PDEBUG(D_PROBE, "disconnect complete"); 1818 PDEBUG(D_PROBE, "disconnect complete");
1808} 1819}
1809EXPORT_SYMBOL(gspca_disconnect); 1820EXPORT_SYMBOL(gspca_disconnect);
1810 1821
1822#ifdef CONFIG_PM
1823int gspca_suspend(struct usb_interface *intf, pm_message_t message)
1824{
1825 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1826
1827 if (!gspca_dev->streaming)
1828 return 0;
1829 gspca_dev->frozen = 1; /* avoid urb error messages */
1830 if (gspca_dev->sd_desc->stopN)
1831 gspca_dev->sd_desc->stopN(gspca_dev);
1832 destroy_urbs(gspca_dev);
1833 gspca_set_alt0(gspca_dev);
1834 if (gspca_dev->sd_desc->stop0)
1835 gspca_dev->sd_desc->stop0(gspca_dev);
1836 return 0;
1837}
1838EXPORT_SYMBOL(gspca_suspend);
1839
1840int gspca_resume(struct usb_interface *intf)
1841{
1842 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1843
1844 gspca_dev->frozen = 0;
1845 gspca_dev->sd_desc->init(gspca_dev);
1846 if (gspca_dev->streaming)
1847 return gspca_init_transfer(gspca_dev);
1848 return 0;
1849}
1850EXPORT_SYMBOL(gspca_resume);
1851#endif
1811/* -- cam driver utility functions -- */ 1852/* -- cam driver utility functions -- */
1812 1853
1813/* auto gain and exposure algorithm based on the knee algorithm described here: 1854/* auto gain and exposure algorithm based on the knee algorithm described here:
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 67e448940eaa..c17625cff9ba 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,7 +56,6 @@ extern int gspca_debug;
56 56
57/* device information - set at probe time */ 57/* device information - set at probe time */
58struct cam { 58struct cam {
59 char *dev_name;
60 struct v4l2_pix_format *cam_mode; /* size nmodes */ 59 struct v4l2_pix_format *cam_mode; /* size nmodes */
61 char nmodes; 60 char nmodes;
62 __u8 epaddr; 61 __u8 epaddr;
@@ -91,15 +90,14 @@ struct sd_desc {
91/* controls */ 90/* controls */
92 const struct ctrl *ctrls; 91 const struct ctrl *ctrls;
93 int nctrls; 92 int nctrls;
94/* operations */ 93/* mandatory operations */
95 cam_cf_op config; /* called on probe */ 94 cam_cf_op config; /* called on probe */
96 cam_op open; /* called on open */ 95 cam_op init; /* called on probe and resume */
97 cam_v_op start; /* called on stream on */ 96 cam_v_op start; /* called on stream on */
98 cam_v_op stopN; /* called on stream off - main alt */
99 cam_v_op stop0; /* called on stream off - alt 0 */
100 cam_v_op close; /* called on close */
101 cam_pkt_op pkt_scan; 97 cam_pkt_op pkt_scan;
102/* optional operations */ 98/* optional operations */
99 cam_v_op stopN; /* called on stream off - main alt */
100 cam_v_op stop0; /* called on stream off - alt 0 */
103 cam_v_op dq_callback; /* called when a frame has been dequeued */ 101 cam_v_op dq_callback; /* called when a frame has been dequeued */
104 cam_jpg_op get_jcomp; 102 cam_jpg_op get_jcomp;
105 cam_jpg_op set_jcomp; 103 cam_jpg_op set_jcomp;
@@ -127,8 +125,10 @@ struct gspca_dev {
127 125
128 struct cam cam; /* device information */ 126 struct cam cam; /* device information */
129 const struct sd_desc *sd_desc; /* subdriver description */ 127 const struct sd_desc *sd_desc; /* subdriver description */
128 unsigned ctrl_dis; /* disabled controls (bit map) */
130 129
131 __u8 usb_buf[8]; /* buffer for USB exchanges */ 130#define USB_BUF_SZ 64
131 __u8 *usb_buf; /* buffer for USB exchanges */
132 struct urb *urb[MAX_NURBS]; 132 struct urb *urb[MAX_NURBS];
133 133
134 __u8 *frbuf; /* buffer for nframes */ 134 __u8 *frbuf; /* buffer for nframes */
@@ -155,6 +155,9 @@ struct gspca_dev {
155 struct mutex queue_lock; /* ISOC queue protection */ 155 struct mutex queue_lock; /* ISOC queue protection */
156 __u32 sequence; /* frame sequence number */ 156 __u32 sequence; /* frame sequence number */
157 char streaming; 157 char streaming;
158#ifdef CONFIG_PM
159 char frozen; /* suspend - resume */
160#endif
158 char users; /* number of opens */ 161 char users; /* number of opens */
159 char present; /* device connected */ 162 char present; /* device connected */
160 char nbufread; /* number of buffers for read() */ 163 char nbufread; /* number of buffers for read() */
@@ -174,6 +177,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
174 struct gspca_frame *frame, 177 struct gspca_frame *frame,
175 const __u8 *data, 178 const __u8 *data,
176 int len); 179 int len);
180#ifdef CONFIG_PM
181int gspca_suspend(struct usb_interface *intf, pm_message_t message);
182int gspca_resume(struct usb_interface *intf);
183#endif
177int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, 184int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
178 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); 185 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
179#endif /* GSPCAV2_H */ 186#endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 21c4ee56a10a..4d5db47ba8cb 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -100,22 +100,6 @@ static int reg_w(struct gspca_dev *gspca_dev,
100 return rc; 100 return rc;
101} 101}
102 102
103static int reg_w_buf(struct gspca_dev *gspca_dev,
104 __u16 index, __u8 *buf, int len)
105{
106 int rc;
107
108 rc = usb_control_msg(gspca_dev->dev,
109 usb_sndbulkpipe(gspca_dev->dev, 4),
110 0x12,
111 0xc8, /* ?? */
112 0, /* value */
113 index, buf, len, 500);
114 if (rc < 0)
115 PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
116 return rc;
117}
118
119static void bulk_w(struct gspca_dev *gspca_dev, 103static void bulk_w(struct gspca_dev *gspca_dev,
120 __u16 *pch, 104 __u16 *pch,
121 __u16 Address) 105 __u16 Address)
@@ -144,8 +128,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
144 return 0; 128 return 0;
145} 129}
146 130
147/* this function is called at open time */ 131/* this function is called at probe and resume time */
148static int sd_open(struct gspca_dev *gspca_dev) 132static int sd_init(struct gspca_dev *gspca_dev)
149{ 133{
150 return 0; 134 return 0;
151} 135}
@@ -175,7 +159,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
175 /* 159 /*
176 Initialize the MR97113 chip register 160 Initialize the MR97113 chip register
177 */ 161 */
178 data = kmalloc(16, GFP_KERNEL);
179 data[0] = 0x00; /* address */ 162 data[0] = 0x00; /* address */
180 data[1] = 0x0c | 0x01; /* reg 0 */ 163 data[1] = 0x0c | 0x01; /* reg 0 */
181 data[2] = 0x01; /* reg 1 */ 164 data[2] = 0x01; /* reg 1 */
@@ -195,12 +178,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
195 data[10] = 0x5d; /* reg 9, I2C device address 178 data[10] = 0x5d; /* reg 9, I2C device address
196 * [for PAS5101 (0x40)] [for MI (0x5d)] */ 179 * [for PAS5101 (0x40)] [for MI (0x5d)] */
197 180
198 err_code = reg_w_buf(gspca_dev, data[0], data, 11); 181 err_code = reg_w(gspca_dev, data[0], 11);
199 kfree(data);
200 if (err_code < 0) 182 if (err_code < 0)
201 return; 183 return;
202 184
203 data = gspca_dev->usb_buf;
204 data[0] = 0x23; /* address */ 185 data[0] = 0x23; /* address */
205 data[1] = 0x09; /* reg 35, append frame header */ 186 data[1] = 0x09; /* reg 35, append frame header */
206 187
@@ -358,14 +339,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
358 PDEBUG(D_ERR, "Camera Stop failed"); 339 PDEBUG(D_ERR, "Camera Stop failed");
359} 340}
360 341
361static void sd_stop0(struct gspca_dev *gspca_dev)
362{
363}
364
365static void sd_close(struct gspca_dev *gspca_dev)
366{
367}
368
369static void sd_pkt_scan(struct gspca_dev *gspca_dev, 342static void sd_pkt_scan(struct gspca_dev *gspca_dev,
370 struct gspca_frame *frame, /* target */ 343 struct gspca_frame *frame, /* target */
371 __u8 *data, /* isoc packet */ 344 __u8 *data, /* isoc packet */
@@ -411,11 +384,9 @@ static const struct sd_desc sd_desc = {
411 .ctrls = sd_ctrls, 384 .ctrls = sd_ctrls,
412 .nctrls = ARRAY_SIZE(sd_ctrls), 385 .nctrls = ARRAY_SIZE(sd_ctrls),
413 .config = sd_config, 386 .config = sd_config,
414 .open = sd_open, 387 .init = sd_init,
415 .start = sd_start, 388 .start = sd_start,
416 .stopN = sd_stopN, 389 .stopN = sd_stopN,
417 .stop0 = sd_stop0,
418 .close = sd_close,
419 .pkt_scan = sd_pkt_scan, 390 .pkt_scan = sd_pkt_scan,
420}; 391};
421 392
@@ -439,6 +410,10 @@ static struct usb_driver sd_driver = {
439 .id_table = device_table, 410 .id_table = device_table,
440 .probe = sd_probe, 411 .probe = sd_probe,
441 .disconnect = gspca_disconnect, 412 .disconnect = gspca_disconnect,
413#ifdef CONFIG_PM
414 .suspend = gspca_suspend,
415 .resume = gspca_resume,
416#endif
442}; 417};
443 418
444/* -- module insert / remove -- */ 419/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index b4f00ec0885c..4df4eec9f7e7 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -63,11 +63,10 @@ struct sd {
63#define SEN_OV6630 2 63#define SEN_OV6630 2
64#define SEN_OV7610 3 64#define SEN_OV7610 3
65#define SEN_OV7620 4 65#define SEN_OV7620 4
66#define SEN_OV7630 5 66#define SEN_OV7640 5
67#define SEN_OV7640 6 67#define SEN_OV7670 6
68#define SEN_OV7670 7 68#define SEN_OV76BE 7
69#define SEN_OV76BE 8 69#define SEN_OV8610 8
70#define SEN_OV8610 9
71 70
72}; 71};
73 72
@@ -127,6 +126,7 @@ static struct ctrl sd_ctrls[] = {
127 .get = sd_getcolors, 126 .get = sd_getcolors,
128 }, 127 },
129/* next controls work with ov7670 only */ 128/* next controls work with ov7670 only */
129#define HFLIP_IDX 3
130 { 130 {
131 { 131 {
132 .id = V4L2_CID_HFLIP, 132 .id = V4L2_CID_HFLIP,
@@ -141,6 +141,7 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_sethflip, 141 .set = sd_sethflip,
142 .get = sd_gethflip, 142 .get = sd_gethflip,
143 }, 143 },
144#define VFLIP_IDX 4
144 { 145 {
145 { 146 {
146 .id = V4L2_CID_VFLIP, 147 .id = V4L2_CID_VFLIP,
@@ -293,6 +294,541 @@ static struct v4l2_pix_format sif_mode[] = {
293#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ 294#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
294#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ 295#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
295 296
297struct ov_regvals {
298 __u8 reg;
299 __u8 val;
300};
301struct ov_i2c_regvals {
302 __u8 reg;
303 __u8 val;
304};
305
306static const struct ov_i2c_regvals norm_6x20[] = {
307 { 0x12, 0x80 }, /* reset */
308 { 0x11, 0x01 },
309 { 0x03, 0x60 },
310 { 0x05, 0x7f }, /* For when autoadjust is off */
311 { 0x07, 0xa8 },
312 /* The ratio of 0x0c and 0x0d controls the white point */
313 { 0x0c, 0x24 },
314 { 0x0d, 0x24 },
315 { 0x0f, 0x15 }, /* COMS */
316 { 0x10, 0x75 }, /* AEC Exposure time */
317 { 0x12, 0x24 }, /* Enable AGC */
318 { 0x14, 0x04 },
319 /* 0x16: 0x06 helps frame stability with moving objects */
320 { 0x16, 0x06 },
321/* { 0x20, 0x30 }, * Aperture correction enable */
322 { 0x26, 0xb2 }, /* BLC enable */
323 /* 0x28: 0x05 Selects RGB format if RGB on */
324 { 0x28, 0x05 },
325 { 0x2a, 0x04 }, /* Disable framerate adjust */
326/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
327 { 0x2d, 0x99 },
328 { 0x33, 0xa0 }, /* Color Processing Parameter */
329 { 0x34, 0xd2 }, /* Max A/D range */
330 { 0x38, 0x8b },
331 { 0x39, 0x40 },
332
333 { 0x3c, 0x39 }, /* Enable AEC mode changing */
334 { 0x3c, 0x3c }, /* Change AEC mode */
335 { 0x3c, 0x24 }, /* Disable AEC mode changing */
336
337 { 0x3d, 0x80 },
338 /* These next two registers (0x4a, 0x4b) are undocumented.
339 * They control the color balance */
340 { 0x4a, 0x80 },
341 { 0x4b, 0x80 },
342 { 0x4d, 0xd2 }, /* This reduces noise a bit */
343 { 0x4e, 0xc1 },
344 { 0x4f, 0x04 },
345/* Do 50-53 have any effect? */
346/* Toggle 0x12[2] off and on here? */
347};
348
349static const struct ov_i2c_regvals norm_6x30[] = {
350 { 0x12, 0x80 }, /* Reset */
351 { 0x00, 0x1f }, /* Gain */
352 { 0x01, 0x99 }, /* Blue gain */
353 { 0x02, 0x7c }, /* Red gain */
354 { 0x03, 0xc0 }, /* Saturation */
355 { 0x05, 0x0a }, /* Contrast */
356 { 0x06, 0x95 }, /* Brightness */
357 { 0x07, 0x2d }, /* Sharpness */
358 { 0x0c, 0x20 },
359 { 0x0d, 0x20 },
360 { 0x0e, 0x20 },
361 { 0x0f, 0x05 },
362 { 0x10, 0x9a },
363 { 0x11, 0x00 }, /* Pixel clock = fastest */
364 { 0x12, 0x24 }, /* Enable AGC and AWB */
365 { 0x13, 0x21 },
366 { 0x14, 0x80 },
367 { 0x15, 0x01 },
368 { 0x16, 0x03 },
369 { 0x17, 0x38 },
370 { 0x18, 0xea },
371 { 0x19, 0x04 },
372 { 0x1a, 0x93 },
373 { 0x1b, 0x00 },
374 { 0x1e, 0xc4 },
375 { 0x1f, 0x04 },
376 { 0x20, 0x20 },
377 { 0x21, 0x10 },
378 { 0x22, 0x88 },
379 { 0x23, 0xc0 }, /* Crystal circuit power level */
380 { 0x25, 0x9a }, /* Increase AEC black ratio */
381 { 0x26, 0xb2 }, /* BLC enable */
382 { 0x27, 0xa2 },
383 { 0x28, 0x00 },
384 { 0x29, 0x00 },
385 { 0x2a, 0x84 }, /* 60 Hz power */
386 { 0x2b, 0xa8 }, /* 60 Hz power */
387 { 0x2c, 0xa0 },
388 { 0x2d, 0x95 }, /* Enable auto-brightness */
389 { 0x2e, 0x88 },
390 { 0x33, 0x26 },
391 { 0x34, 0x03 },
392 { 0x36, 0x8f },
393 { 0x37, 0x80 },
394 { 0x38, 0x83 },
395 { 0x39, 0x80 },
396 { 0x3a, 0x0f },
397 { 0x3b, 0x3c },
398 { 0x3c, 0x1a },
399 { 0x3d, 0x80 },
400 { 0x3e, 0x80 },
401 { 0x3f, 0x0e },
402 { 0x40, 0x00 }, /* White bal */
403 { 0x41, 0x00 }, /* White bal */
404 { 0x42, 0x80 },
405 { 0x43, 0x3f }, /* White bal */
406 { 0x44, 0x80 },
407 { 0x45, 0x20 },
408 { 0x46, 0x20 },
409 { 0x47, 0x80 },
410 { 0x48, 0x7f },
411 { 0x49, 0x00 },
412 { 0x4a, 0x00 },
413 { 0x4b, 0x80 },
414 { 0x4c, 0xd0 },
415 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
416 { 0x4e, 0x40 },
417 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
418 { 0x50, 0xff },
419 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
420 { 0x55, 0xff },
421 { 0x56, 0x12 },
422 { 0x57, 0x81 },
423 { 0x58, 0x75 },
424 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
425 { 0x5a, 0x2c },
426 { 0x5b, 0x0f }, /* AWB chrominance levels */
427 { 0x5c, 0x10 },
428 { 0x3d, 0x80 },
429 { 0x27, 0xa6 },
430 { 0x12, 0x20 }, /* Toggle AWB */
431 { 0x12, 0x24 },
432};
433
434/* Lawrence Glaister <lg@jfm.bc.ca> reports:
435 *
436 * Register 0x0f in the 7610 has the following effects:
437 *
438 * 0x85 (AEC method 1): Best overall, good contrast range
439 * 0x45 (AEC method 2): Very overexposed
440 * 0xa5 (spec sheet default): Ok, but the black level is
441 * shifted resulting in loss of contrast
442 * 0x05 (old driver setting): very overexposed, too much
443 * contrast
444 */
445static const struct ov_i2c_regvals norm_7610[] = {
446 { 0x10, 0xff },
447 { 0x16, 0x06 },
448 { 0x28, 0x24 },
449 { 0x2b, 0xac },
450 { 0x12, 0x00 },
451 { 0x38, 0x81 },
452 { 0x28, 0x24 }, /* 0c */
453 { 0x0f, 0x85 }, /* lg's setting */
454 { 0x15, 0x01 },
455 { 0x20, 0x1c },
456 { 0x23, 0x2a },
457 { 0x24, 0x10 },
458 { 0x25, 0x8a },
459 { 0x26, 0xa2 },
460 { 0x27, 0xc2 },
461 { 0x2a, 0x04 },
462 { 0x2c, 0xfe },
463 { 0x2d, 0x93 },
464 { 0x30, 0x71 },
465 { 0x31, 0x60 },
466 { 0x32, 0x26 },
467 { 0x33, 0x20 },
468 { 0x34, 0x48 },
469 { 0x12, 0x24 },
470 { 0x11, 0x01 },
471 { 0x0c, 0x24 },
472 { 0x0d, 0x24 },
473};
474
475static const struct ov_i2c_regvals norm_7620[] = {
476 { 0x00, 0x00 }, /* gain */
477 { 0x01, 0x80 }, /* blue gain */
478 { 0x02, 0x80 }, /* red gain */
479 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
480 { 0x06, 0x60 },
481 { 0x07, 0x00 },
482 { 0x0c, 0x24 },
483 { 0x0c, 0x24 },
484 { 0x0d, 0x24 },
485 { 0x11, 0x01 },
486 { 0x12, 0x24 },
487 { 0x13, 0x01 },
488 { 0x14, 0x84 },
489 { 0x15, 0x01 },
490 { 0x16, 0x03 },
491 { 0x17, 0x2f },
492 { 0x18, 0xcf },
493 { 0x19, 0x06 },
494 { 0x1a, 0xf5 },
495 { 0x1b, 0x00 },
496 { 0x20, 0x18 },
497 { 0x21, 0x80 },
498 { 0x22, 0x80 },
499 { 0x23, 0x00 },
500 { 0x26, 0xa2 },
501 { 0x27, 0xea },
502 { 0x28, 0x20 },
503 { 0x29, 0x00 },
504 { 0x2a, 0x10 },
505 { 0x2b, 0x00 },
506 { 0x2c, 0x88 },
507 { 0x2d, 0x91 },
508 { 0x2e, 0x80 },
509 { 0x2f, 0x44 },
510 { 0x60, 0x27 },
511 { 0x61, 0x02 },
512 { 0x62, 0x5f },
513 { 0x63, 0xd5 },
514 { 0x64, 0x57 },
515 { 0x65, 0x83 },
516 { 0x66, 0x55 },
517 { 0x67, 0x92 },
518 { 0x68, 0xcf },
519 { 0x69, 0x76 },
520 { 0x6a, 0x22 },
521 { 0x6b, 0x00 },
522 { 0x6c, 0x02 },
523 { 0x6d, 0x44 },
524 { 0x6e, 0x80 },
525 { 0x6f, 0x1d },
526 { 0x70, 0x8b },
527 { 0x71, 0x00 },
528 { 0x72, 0x14 },
529 { 0x73, 0x54 },
530 { 0x74, 0x00 },
531 { 0x75, 0x8e },
532 { 0x76, 0x00 },
533 { 0x77, 0xff },
534 { 0x78, 0x80 },
535 { 0x79, 0x80 },
536 { 0x7a, 0x80 },
537 { 0x7b, 0xe2 },
538 { 0x7c, 0x00 },
539};
540
541/* 7640 and 7648. The defaults should be OK for most registers. */
542static const struct ov_i2c_regvals norm_7640[] = {
543 { 0x12, 0x80 },
544 { 0x12, 0x14 },
545};
546
547/* 7670. Defaults taken from OmniVision provided data,
548* as provided by Jonathan Corbet of OLPC */
549static const struct ov_i2c_regvals norm_7670[] = {
550 { OV7670_REG_COM7, OV7670_COM7_RESET },
551 { OV7670_REG_TSLB, 0x04 }, /* OV */
552 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
553 { OV7670_REG_CLKRC, 0x01 },
554/*
555 * Set the hardware window. These values from OV don't entirely
556 * make sense - hstop is less than hstart. But they work...
557 */
558 { OV7670_REG_HSTART, 0x13 },
559 { OV7670_REG_HSTOP, 0x01 },
560 { OV7670_REG_HREF, 0xb6 },
561 { OV7670_REG_VSTART, 0x02 },
562 { OV7670_REG_VSTOP, 0x7a },
563 { OV7670_REG_VREF, 0x0a },
564
565 { OV7670_REG_COM3, 0 },
566 { OV7670_REG_COM14, 0 },
567/* Mystery scaling numbers */
568 { 0x70, 0x3a },
569 { 0x71, 0x35 },
570 { 0x72, 0x11 },
571 { 0x73, 0xf0 },
572 { 0xa2, 0x02 },
573/* { OV7670_REG_COM10, 0x0 }, */
574
575/* Gamma curve values */
576 { 0x7a, 0x20 },
577 { 0x7b, 0x10 },
578 { 0x7c, 0x1e },
579 { 0x7d, 0x35 },
580 { 0x7e, 0x5a },
581 { 0x7f, 0x69 },
582 { 0x80, 0x76 },
583 { 0x81, 0x80 },
584 { 0x82, 0x88 },
585 { 0x83, 0x8f },
586 { 0x84, 0x96 },
587 { 0x85, 0xa3 },
588 { 0x86, 0xaf },
589 { 0x87, 0xc4 },
590 { 0x88, 0xd7 },
591 { 0x89, 0xe8 },
592
593/* AGC and AEC parameters. Note we start by disabling those features,
594 then turn them only after tweaking the values. */
595 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
596 | OV7670_COM8_AECSTEP
597 | OV7670_COM8_BFILT },
598 { OV7670_REG_GAIN, 0 },
599 { OV7670_REG_AECH, 0 },
600 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
601 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
602 { OV7670_REG_BD50MAX, 0x05 },
603 { OV7670_REG_BD60MAX, 0x07 },
604 { OV7670_REG_AEW, 0x95 },
605 { OV7670_REG_AEB, 0x33 },
606 { OV7670_REG_VPT, 0xe3 },
607 { OV7670_REG_HAECC1, 0x78 },
608 { OV7670_REG_HAECC2, 0x68 },
609 { 0xa1, 0x03 }, /* magic */
610 { OV7670_REG_HAECC3, 0xd8 },
611 { OV7670_REG_HAECC4, 0xd8 },
612 { OV7670_REG_HAECC5, 0xf0 },
613 { OV7670_REG_HAECC6, 0x90 },
614 { OV7670_REG_HAECC7, 0x94 },
615 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
616 | OV7670_COM8_AECSTEP
617 | OV7670_COM8_BFILT
618 | OV7670_COM8_AGC
619 | OV7670_COM8_AEC },
620
621/* Almost all of these are magic "reserved" values. */
622 { OV7670_REG_COM5, 0x61 },
623 { OV7670_REG_COM6, 0x4b },
624 { 0x16, 0x02 },
625 { OV7670_REG_MVFP, 0x07 },
626 { 0x21, 0x02 },
627 { 0x22, 0x91 },
628 { 0x29, 0x07 },
629 { 0x33, 0x0b },
630 { 0x35, 0x0b },
631 { 0x37, 0x1d },
632 { 0x38, 0x71 },
633 { 0x39, 0x2a },
634 { OV7670_REG_COM12, 0x78 },
635 { 0x4d, 0x40 },
636 { 0x4e, 0x20 },
637 { OV7670_REG_GFIX, 0 },
638 { 0x6b, 0x4a },
639 { 0x74, 0x10 },
640 { 0x8d, 0x4f },
641 { 0x8e, 0 },
642 { 0x8f, 0 },
643 { 0x90, 0 },
644 { 0x91, 0 },
645 { 0x96, 0 },
646 { 0x9a, 0 },
647 { 0xb0, 0x84 },
648 { 0xb1, 0x0c },
649 { 0xb2, 0x0e },
650 { 0xb3, 0x82 },
651 { 0xb8, 0x0a },
652
653/* More reserved magic, some of which tweaks white balance */
654 { 0x43, 0x0a },
655 { 0x44, 0xf0 },
656 { 0x45, 0x34 },
657 { 0x46, 0x58 },
658 { 0x47, 0x28 },
659 { 0x48, 0x3a },
660 { 0x59, 0x88 },
661 { 0x5a, 0x88 },
662 { 0x5b, 0x44 },
663 { 0x5c, 0x67 },
664 { 0x5d, 0x49 },
665 { 0x5e, 0x0e },
666 { 0x6c, 0x0a },
667 { 0x6d, 0x55 },
668 { 0x6e, 0x11 },
669 { 0x6f, 0x9f },
670 /* "9e for advance AWB" */
671 { 0x6a, 0x40 },
672 { OV7670_REG_BLUE, 0x40 },
673 { OV7670_REG_RED, 0x60 },
674 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
675 | OV7670_COM8_AECSTEP
676 | OV7670_COM8_BFILT
677 | OV7670_COM8_AGC
678 | OV7670_COM8_AEC
679 | OV7670_COM8_AWB },
680
681/* Matrix coefficients */
682 { 0x4f, 0x80 },
683 { 0x50, 0x80 },
684 { 0x51, 0 },
685 { 0x52, 0x22 },
686 { 0x53, 0x5e },
687 { 0x54, 0x80 },
688 { 0x58, 0x9e },
689
690 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
691 { OV7670_REG_EDGE, 0 },
692 { 0x75, 0x05 },
693 { 0x76, 0xe1 },
694 { 0x4c, 0 },
695 { 0x77, 0x01 },
696 { OV7670_REG_COM13, OV7670_COM13_GAMMA
697 | OV7670_COM13_UVSAT
698 | 2}, /* was 3 */
699 { 0x4b, 0x09 },
700 { 0xc9, 0x60 },
701 { OV7670_REG_COM16, 0x38 },
702 { 0x56, 0x40 },
703
704 { 0x34, 0x11 },
705 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
706 { 0xa4, 0x88 },
707 { 0x96, 0 },
708 { 0x97, 0x30 },
709 { 0x98, 0x20 },
710 { 0x99, 0x30 },
711 { 0x9a, 0x84 },
712 { 0x9b, 0x29 },
713 { 0x9c, 0x03 },
714 { 0x9d, 0x4c },
715 { 0x9e, 0x3f },
716 { 0x78, 0x04 },
717
718/* Extra-weird stuff. Some sort of multiplexor register */
719 { 0x79, 0x01 },
720 { 0xc8, 0xf0 },
721 { 0x79, 0x0f },
722 { 0xc8, 0x00 },
723 { 0x79, 0x10 },
724 { 0xc8, 0x7e },
725 { 0x79, 0x0a },
726 { 0xc8, 0x80 },
727 { 0x79, 0x0b },
728 { 0xc8, 0x01 },
729 { 0x79, 0x0c },
730 { 0xc8, 0x0f },
731 { 0x79, 0x0d },
732 { 0xc8, 0x20 },
733 { 0x79, 0x09 },
734 { 0xc8, 0x80 },
735 { 0x79, 0x02 },
736 { 0xc8, 0xc0 },
737 { 0x79, 0x03 },
738 { 0xc8, 0x40 },
739 { 0x79, 0x05 },
740 { 0xc8, 0x30 },
741 { 0x79, 0x26 },
742};
743
744static const struct ov_i2c_regvals norm_8610[] = {
745 { 0x12, 0x80 },
746 { 0x00, 0x00 },
747 { 0x01, 0x80 },
748 { 0x02, 0x80 },
749 { 0x03, 0xc0 },
750 { 0x04, 0x30 },
751 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
752 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
753 { 0x0a, 0x86 },
754 { 0x0b, 0xb0 },
755 { 0x0c, 0x20 },
756 { 0x0d, 0x20 },
757 { 0x11, 0x01 },
758 { 0x12, 0x25 },
759 { 0x13, 0x01 },
760 { 0x14, 0x04 },
761 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
762 { 0x16, 0x03 },
763 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
764 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
765 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
766 { 0x1a, 0xf5 },
767 { 0x1b, 0x00 },
768 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
769 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
770 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
771 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
772 { 0x26, 0xa2 },
773 { 0x27, 0xea },
774 { 0x28, 0x00 },
775 { 0x29, 0x00 },
776 { 0x2a, 0x80 },
777 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
778 { 0x2c, 0xac },
779 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
780 { 0x2e, 0x80 },
781 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
782 { 0x4c, 0x00 },
783 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
784 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
785 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
786 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
787 { 0x63, 0xff },
788 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
789 * maybe thats wrong */
790 { 0x65, 0x00 },
791 { 0x66, 0x55 },
792 { 0x67, 0xb0 },
793 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
794 { 0x69, 0x02 },
795 { 0x6a, 0x22 },
796 { 0x6b, 0x00 },
797 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
798 * deleting bit7 colors the first images red */
799 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
800 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
801 { 0x6f, 0x01 },
802 { 0x70, 0x8b },
803 { 0x71, 0x00 },
804 { 0x72, 0x14 },
805 { 0x73, 0x54 },
806 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
807 { 0x75, 0x0e },
808 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
809 { 0x77, 0xff },
810 { 0x78, 0x80 },
811 { 0x79, 0x80 },
812 { 0x7a, 0x80 },
813 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
814 { 0x7c, 0x00 },
815 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
816 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
817 { 0x7f, 0xfb },
818 { 0x80, 0x28 },
819 { 0x81, 0x00 },
820 { 0x82, 0x23 },
821 { 0x83, 0x0b },
822 { 0x84, 0x00 },
823 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
824 { 0x86, 0xc9 },
825 { 0x87, 0x00 },
826 { 0x88, 0x00 },
827 { 0x89, 0x01 },
828 { 0x12, 0x20 },
829 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
830};
831
296static unsigned char ov7670_abs_to_sm(unsigned char v) 832static unsigned char ov7670_abs_to_sm(unsigned char v)
297{ 833{
298 if (v > 127) 834 if (v > 127)
@@ -537,18 +1073,10 @@ static int ov51x_set_slave_ids(struct sd *sd,
537 rc = reg_w(sd, R51x_I2C_W_SID, slave); 1073 rc = reg_w(sd, R51x_I2C_W_SID, slave);
538 if (rc < 0) 1074 if (rc < 0)
539 return rc; 1075 return rc;
1076 sd->primary_i2c_slave = slave;
540 return reg_w(sd, R51x_I2C_R_SID, slave + 1); 1077 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
541} 1078}
542 1079
543struct ov_regvals {
544 __u8 reg;
545 __u8 val;
546};
547struct ov_i2c_regvals {
548 __u8 reg;
549 __u8 val;
550};
551
552static int write_regvals(struct sd *sd, 1080static int write_regvals(struct sd *sd,
553 const struct ov_regvals *regvals, 1081 const struct ov_regvals *regvals,
554 int n) 1082 int n)
@@ -591,101 +1119,9 @@ static int write_i2c_regvals(struct sd *sd,
591static int ov8xx0_configure(struct sd *sd) 1119static int ov8xx0_configure(struct sd *sd)
592{ 1120{
593 int rc; 1121 int rc;
594 static const struct ov_i2c_regvals norm_8610[] = {
595 { 0x12, 0x80 },
596 { 0x00, 0x00 },
597 { 0x01, 0x80 },
598 { 0x02, 0x80 },
599 { 0x03, 0xc0 },
600 { 0x04, 0x30 },
601 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
602 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
603 { 0x0a, 0x86 },
604 { 0x0b, 0xb0 },
605 { 0x0c, 0x20 },
606 { 0x0d, 0x20 },
607 { 0x11, 0x01 },
608 { 0x12, 0x25 },
609 { 0x13, 0x01 },
610 { 0x14, 0x04 },
611 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
612 { 0x16, 0x03 },
613 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
614 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
615 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
616 { 0x1a, 0xf5 },
617 { 0x1b, 0x00 },
618 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
619 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
620 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
621 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
622 { 0x26, 0xa2 },
623 { 0x27, 0xea },
624 { 0x28, 0x00 },
625 { 0x29, 0x00 },
626 { 0x2a, 0x80 },
627 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
628 { 0x2c, 0xac },
629 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
630 { 0x2e, 0x80 },
631 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
632 { 0x4c, 0x00 },
633 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
634 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
635 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
636 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
637 { 0x63, 0xff },
638 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
639 * maybe thats wrong */
640 { 0x65, 0x00 },
641 { 0x66, 0x55 },
642 { 0x67, 0xb0 },
643 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
644 { 0x69, 0x02 },
645 { 0x6a, 0x22 },
646 { 0x6b, 0x00 },
647 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
648 deleting bit7 colors the first images red */
649 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
650 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
651 { 0x6f, 0x01 },
652 { 0x70, 0x8b },
653 { 0x71, 0x00 },
654 { 0x72, 0x14 },
655 { 0x73, 0x54 },
656 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
657 { 0x75, 0x0e },
658 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
659 { 0x77, 0xff },
660 { 0x78, 0x80 },
661 { 0x79, 0x80 },
662 { 0x7a, 0x80 },
663 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
664 { 0x7c, 0x00 },
665 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
666 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
667 { 0x7f, 0xfb },
668 { 0x80, 0x28 },
669 { 0x81, 0x00 },
670 { 0x82, 0x23 },
671 { 0x83, 0x0b },
672 { 0x84, 0x00 },
673 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
674 { 0x86, 0xc9 },
675 { 0x87, 0x00 },
676 { 0x88, 0x00 },
677 { 0x89, 0x01 },
678 { 0x12, 0x20 },
679 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
680 };
681 1122
682 PDEBUG(D_PROBE, "starting ov8xx0 configuration"); 1123 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
683 1124
684 if (init_ov_sensor(sd) < 0)
685 PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID");
686 else
687 PDEBUG(D_PROBE, "OV86x0 initialized");
688
689 /* Detect sensor (sub)type */ 1125 /* Detect sensor (sub)type */
690 rc = i2c_r(sd, OV7610_REG_COM_I); 1126 rc = i2c_r(sd, OV7610_REG_COM_I);
691 if (rc < 0) { 1127 if (rc < 0) {
@@ -698,9 +1134,6 @@ static int ov8xx0_configure(struct sd *sd)
698 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); 1134 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
699 return -1; 1135 return -1;
700 } 1136 }
701 PDEBUG(D_PROBE, "Writing 8610 registers");
702 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
703 return -1;
704 1137
705 /* Set sensor-specific vars */ 1138 /* Set sensor-specific vars */
706/* sd->sif = 0; already done */ 1139/* sd->sif = 0; already done */
@@ -714,252 +1147,6 @@ static int ov7xx0_configure(struct sd *sd)
714{ 1147{
715 int rc, high, low; 1148 int rc, high, low;
716 1149
717 /* Lawrence Glaister <lg@jfm.bc.ca> reports:
718 *
719 * Register 0x0f in the 7610 has the following effects:
720 *
721 * 0x85 (AEC method 1): Best overall, good contrast range
722 * 0x45 (AEC method 2): Very overexposed
723 * 0xa5 (spec sheet default): Ok, but the black level is
724 * shifted resulting in loss of contrast
725 * 0x05 (old driver setting): very overexposed, too much
726 * contrast
727 */
728 static const struct ov_i2c_regvals norm_7610[] = {
729 { 0x10, 0xff },
730 { 0x16, 0x06 },
731 { 0x28, 0x24 },
732 { 0x2b, 0xac },
733 { 0x12, 0x00 },
734 { 0x38, 0x81 },
735 { 0x28, 0x24 }, /* 0c */
736 { 0x0f, 0x85 }, /* lg's setting */
737 { 0x15, 0x01 },
738 { 0x20, 0x1c },
739 { 0x23, 0x2a },
740 { 0x24, 0x10 },
741 { 0x25, 0x8a },
742 { 0x26, 0xa2 },
743 { 0x27, 0xc2 },
744 { 0x2a, 0x04 },
745 { 0x2c, 0xfe },
746 { 0x2d, 0x93 },
747 { 0x30, 0x71 },
748 { 0x31, 0x60 },
749 { 0x32, 0x26 },
750 { 0x33, 0x20 },
751 { 0x34, 0x48 },
752 { 0x12, 0x24 },
753 { 0x11, 0x01 },
754 { 0x0c, 0x24 },
755 { 0x0d, 0x24 },
756 };
757
758 static const struct ov_i2c_regvals norm_7620[] = {
759 { 0x00, 0x00 }, /* gain */
760 { 0x01, 0x80 }, /* blue gain */
761 { 0x02, 0x80 }, /* red gain */
762 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
763 { 0x06, 0x60 },
764 { 0x07, 0x00 },
765 { 0x0c, 0x24 },
766 { 0x0c, 0x24 },
767 { 0x0d, 0x24 },
768 { 0x11, 0x01 },
769 { 0x12, 0x24 },
770 { 0x13, 0x01 },
771 { 0x14, 0x84 },
772 { 0x15, 0x01 },
773 { 0x16, 0x03 },
774 { 0x17, 0x2f },
775 { 0x18, 0xcf },
776 { 0x19, 0x06 },
777 { 0x1a, 0xf5 },
778 { 0x1b, 0x00 },
779 { 0x20, 0x18 },
780 { 0x21, 0x80 },
781 { 0x22, 0x80 },
782 { 0x23, 0x00 },
783 { 0x26, 0xa2 },
784 { 0x27, 0xea },
785 { 0x28, 0x20 },
786 { 0x29, 0x00 },
787 { 0x2a, 0x10 },
788 { 0x2b, 0x00 },
789 { 0x2c, 0x88 },
790 { 0x2d, 0x91 },
791 { 0x2e, 0x80 },
792 { 0x2f, 0x44 },
793 { 0x60, 0x27 },
794 { 0x61, 0x02 },
795 { 0x62, 0x5f },
796 { 0x63, 0xd5 },
797 { 0x64, 0x57 },
798 { 0x65, 0x83 },
799 { 0x66, 0x55 },
800 { 0x67, 0x92 },
801 { 0x68, 0xcf },
802 { 0x69, 0x76 },
803 { 0x6a, 0x22 },
804 { 0x6b, 0x00 },
805 { 0x6c, 0x02 },
806 { 0x6d, 0x44 },
807 { 0x6e, 0x80 },
808 { 0x6f, 0x1d },
809 { 0x70, 0x8b },
810 { 0x71, 0x00 },
811 { 0x72, 0x14 },
812 { 0x73, 0x54 },
813 { 0x74, 0x00 },
814 { 0x75, 0x8e },
815 { 0x76, 0x00 },
816 { 0x77, 0xff },
817 { 0x78, 0x80 },
818 { 0x79, 0x80 },
819 { 0x7a, 0x80 },
820 { 0x7b, 0xe2 },
821 { 0x7c, 0x00 },
822 };
823
824 /* 7640 and 7648. The defaults should be OK for most registers. */
825 static const struct ov_i2c_regvals norm_7640[] = {
826 { 0x12, 0x80 },
827 { 0x12, 0x14 },
828 };
829
830 /* 7670. Defaults taken from OmniVision provided data,
831 * as provided by Jonathan Corbet of OLPC */
832 static const struct ov_i2c_regvals norm_7670[] = {
833 { OV7670_REG_COM7, OV7670_COM7_RESET },
834 { OV7670_REG_TSLB, 0x04 }, /* OV */
835 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
836 { OV7670_REG_CLKRC, 0x01 },
837 /*
838 * Set the hardware window. These values from OV don't entirely
839 * make sense - hstop is less than hstart. But they work...
840 */
841 { OV7670_REG_HSTART, 0x13 }, { OV7670_REG_HSTOP, 0x01 },
842 { OV7670_REG_HREF, 0xb6 }, { OV7670_REG_VSTART, 0x02 },
843 { OV7670_REG_VSTOP, 0x7a }, { OV7670_REG_VREF, 0x0a },
844
845 { OV7670_REG_COM3, 0 }, { OV7670_REG_COM14, 0 },
846 /* Mystery scaling numbers */
847 { 0x70, 0x3a }, { 0x71, 0x35 },
848 { 0x72, 0x11 }, { 0x73, 0xf0 },
849 { 0xa2, 0x02 },
850/* { OV7670_REG_COM10, 0x0 }, */
851
852 /* Gamma curve values */
853 { 0x7a, 0x20 },
854 { 0x7b, 0x10 },
855 { 0x7c, 0x1e },
856 { 0x7d, 0x35 },
857 { 0x7e, 0x5a }, { 0x7f, 0x69 },
858 { 0x80, 0x76 }, { 0x81, 0x80 },
859 { 0x82, 0x88 }, { 0x83, 0x8f },
860 { 0x84, 0x96 }, { 0x85, 0xa3 },
861 { 0x86, 0xaf }, { 0x87, 0xc4 },
862 { 0x88, 0xd7 }, { 0x89, 0xe8 },
863
864 /* AGC and AEC parameters. Note we start by disabling those features,
865 then turn them only after tweaking the values. */
866 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
867 | OV7670_COM8_AECSTEP
868 | OV7670_COM8_BFILT },
869 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
870 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
871 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
872 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
873 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
874 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
875 { OV7670_REG_HAECC2, 0x68 },
876 { 0xa1, 0x03 }, /* magic */
877 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
878 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
879 { OV7670_REG_HAECC7, 0x94 },
880 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
881 | OV7670_COM8_AECSTEP
882 | OV7670_COM8_BFILT
883 | OV7670_COM8_AGC
884 | OV7670_COM8_AEC },
885
886 /* Almost all of these are magic "reserved" values. */
887 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
888 { 0x16, 0x02 },
889 { OV7670_REG_MVFP, 0x07 },
890 { 0x21, 0x02 }, { 0x22, 0x91 },
891 { 0x29, 0x07 }, { 0x33, 0x0b },
892 { 0x35, 0x0b }, { 0x37, 0x1d },
893 { 0x38, 0x71 }, { 0x39, 0x2a },
894 { OV7670_REG_COM12, 0x78 }, { 0x4d, 0x40 },
895 { 0x4e, 0x20 }, { OV7670_REG_GFIX, 0 },
896 { 0x6b, 0x4a }, { 0x74, 0x10 },
897 { 0x8d, 0x4f }, { 0x8e, 0 },
898 { 0x8f, 0 }, { 0x90, 0 },
899 { 0x91, 0 }, { 0x96, 0 },
900 { 0x9a, 0 }, { 0xb0, 0x84 },
901 { 0xb1, 0x0c }, { 0xb2, 0x0e },
902 { 0xb3, 0x82 }, { 0xb8, 0x0a },
903
904 /* More reserved magic, some of which tweaks white balance */
905 { 0x43, 0x0a }, { 0x44, 0xf0 },
906 { 0x45, 0x34 }, { 0x46, 0x58 },
907 { 0x47, 0x28 }, { 0x48, 0x3a },
908 { 0x59, 0x88 }, { 0x5a, 0x88 },
909 { 0x5b, 0x44 }, { 0x5c, 0x67 },
910 { 0x5d, 0x49 }, { 0x5e, 0x0e },
911 { 0x6c, 0x0a }, { 0x6d, 0x55 },
912 { 0x6e, 0x11 }, { 0x6f, 0x9f },
913 /* "9e for advance AWB" */
914 { 0x6a, 0x40 }, { OV7670_REG_BLUE, 0x40 },
915 { OV7670_REG_RED, 0x60 },
916 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
917 | OV7670_COM8_AECSTEP
918 | OV7670_COM8_BFILT
919 | OV7670_COM8_AGC
920 | OV7670_COM8_AEC
921 | OV7670_COM8_AWB },
922
923 /* Matrix coefficients */
924 { 0x4f, 0x80 }, { 0x50, 0x80 },
925 { 0x51, 0 }, { 0x52, 0x22 },
926 { 0x53, 0x5e }, { 0x54, 0x80 },
927 { 0x58, 0x9e },
928
929 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
930 { OV7670_REG_EDGE, 0 },
931 { 0x75, 0x05 }, { 0x76, 0xe1 },
932 { 0x4c, 0 }, { 0x77, 0x01 },
933 { OV7670_REG_COM13, OV7670_COM13_GAMMA
934 | OV7670_COM13_UVSAT
935 | 2}, /* was 3 */
936 { 0x4b, 0x09 },
937 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
938 { 0x56, 0x40 },
939
940 { 0x34, 0x11 },
941 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
942 { 0xa4, 0x88 }, { 0x96, 0 },
943 { 0x97, 0x30 }, { 0x98, 0x20 },
944 { 0x99, 0x30 }, { 0x9a, 0x84 },
945 { 0x9b, 0x29 }, { 0x9c, 0x03 },
946 { 0x9d, 0x4c }, { 0x9e, 0x3f },
947 { 0x78, 0x04 },
948
949 /* Extra-weird stuff. Some sort of multiplexor register */
950 { 0x79, 0x01 }, { 0xc8, 0xf0 },
951 { 0x79, 0x0f }, { 0xc8, 0x00 },
952 { 0x79, 0x10 }, { 0xc8, 0x7e },
953 { 0x79, 0x0a }, { 0xc8, 0x80 },
954 { 0x79, 0x0b }, { 0xc8, 0x01 },
955 { 0x79, 0x0c }, { 0xc8, 0x0f },
956 { 0x79, 0x0d }, { 0xc8, 0x20 },
957 { 0x79, 0x09 }, { 0xc8, 0x80 },
958 { 0x79, 0x02 }, { 0xc8, 0xc0 },
959 { 0x79, 0x03 }, { 0xc8, 0x40 },
960 { 0x79, 0x05 }, { 0xc8, 0x30 },
961 { 0x79, 0x26 },
962 };
963 1150
964 PDEBUG(D_PROBE, "starting OV7xx0 configuration"); 1151 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
965 1152
@@ -1011,8 +1198,9 @@ static int ov7xx0_configure(struct sd *sd)
1011 switch (low) { 1198 switch (low) {
1012 case 0x30: 1199 case 0x30:
1013 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); 1200 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
1014 sd->sensor = SEN_OV7630; 1201 PDEBUG(D_ERR,
1015 break; 1202 "7630 is not supported by this driver");
1203 return -1;
1016 case 0x40: 1204 case 0x40:
1017 PDEBUG(D_PROBE, "Sensor is an OV7645"); 1205 PDEBUG(D_PROBE, "Sensor is an OV7645");
1018 sd->sensor = SEN_OV7640; /* FIXME */ 1206 sd->sensor = SEN_OV7640; /* FIXME */
@@ -1038,32 +1226,6 @@ static int ov7xx0_configure(struct sd *sd)
1038 return -1; 1226 return -1;
1039 } 1227 }
1040 1228
1041 switch (sd->sensor) {
1042 case SEN_OV7620:
1043 PDEBUG(D_PROBE, "Writing 7620 registers");
1044 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1045 return -1;
1046 break;
1047 case SEN_OV7630:
1048 PDEBUG(D_ERR, "7630 is not supported by this driver version");
1049 return -1;
1050 case SEN_OV7640:
1051 PDEBUG(D_PROBE, "Writing 7640 registers");
1052 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1053 return -1;
1054 break;
1055 case SEN_OV7670:
1056 PDEBUG(D_PROBE, "Writing 7670 registers");
1057 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1058 return -1;
1059 break;
1060 default:
1061 PDEBUG(D_PROBE, "Writing 7610 registers");
1062 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1063 return -1;
1064 break;
1065 }
1066
1067 /* Set sensor-specific vars */ 1229 /* Set sensor-specific vars */
1068/* sd->sif = 0; already done */ 1230/* sd->sif = 0; already done */
1069 return 0; 1231 return 0;
@@ -1073,141 +1235,7 @@ static int ov7xx0_configure(struct sd *sd)
1073static int ov6xx0_configure(struct sd *sd) 1235static int ov6xx0_configure(struct sd *sd)
1074{ 1236{
1075 int rc; 1237 int rc;
1076 static const struct ov_i2c_regvals norm_6x20[] = { 1238 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
1077 { 0x12, 0x80 }, /* reset */
1078 { 0x11, 0x01 },
1079 { 0x03, 0x60 },
1080 { 0x05, 0x7f }, /* For when autoadjust is off */
1081 { 0x07, 0xa8 },
1082 /* The ratio of 0x0c and 0x0d controls the white point */
1083 { 0x0c, 0x24 },
1084 { 0x0d, 0x24 },
1085 { 0x0f, 0x15 }, /* COMS */
1086 { 0x10, 0x75 }, /* AEC Exposure time */
1087 { 0x12, 0x24 }, /* Enable AGC */
1088 { 0x14, 0x04 },
1089 /* 0x16: 0x06 helps frame stability with moving objects */
1090 { 0x16, 0x06 },
1091/* { 0x20, 0x30 }, * Aperture correction enable */
1092 { 0x26, 0xb2 }, /* BLC enable */
1093 /* 0x28: 0x05 Selects RGB format if RGB on */
1094 { 0x28, 0x05 },
1095 { 0x2a, 0x04 }, /* Disable framerate adjust */
1096/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
1097 { 0x2d, 0x99 },
1098 { 0x33, 0xa0 }, /* Color Processing Parameter */
1099 { 0x34, 0xd2 }, /* Max A/D range */
1100 { 0x38, 0x8b },
1101 { 0x39, 0x40 },
1102
1103 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1104 { 0x3c, 0x3c }, /* Change AEC mode */
1105 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1106
1107 { 0x3d, 0x80 },
1108 /* These next two registers (0x4a, 0x4b) are undocumented.
1109 * They control the color balance */
1110 { 0x4a, 0x80 },
1111 { 0x4b, 0x80 },
1112 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1113 { 0x4e, 0xc1 },
1114 { 0x4f, 0x04 },
1115/* Do 50-53 have any effect? */
1116/* Toggle 0x12[2] off and on here? */
1117 };
1118
1119 static const struct ov_i2c_regvals norm_6x30[] = {
1120 { 0x12, 0x80 }, /* Reset */
1121 { 0x00, 0x1f }, /* Gain */
1122 { 0x01, 0x99 }, /* Blue gain */
1123 { 0x02, 0x7c }, /* Red gain */
1124 { 0x03, 0xc0 }, /* Saturation */
1125 { 0x05, 0x0a }, /* Contrast */
1126 { 0x06, 0x95 }, /* Brightness */
1127 { 0x07, 0x2d }, /* Sharpness */
1128 { 0x0c, 0x20 },
1129 { 0x0d, 0x20 },
1130 { 0x0e, 0x20 },
1131 { 0x0f, 0x05 },
1132 { 0x10, 0x9a },
1133 { 0x11, 0x00 }, /* Pixel clock = fastest */
1134 { 0x12, 0x24 }, /* Enable AGC and AWB */
1135 { 0x13, 0x21 },
1136 { 0x14, 0x80 },
1137 { 0x15, 0x01 },
1138 { 0x16, 0x03 },
1139 { 0x17, 0x38 },
1140 { 0x18, 0xea },
1141 { 0x19, 0x04 },
1142 { 0x1a, 0x93 },
1143 { 0x1b, 0x00 },
1144 { 0x1e, 0xc4 },
1145 { 0x1f, 0x04 },
1146 { 0x20, 0x20 },
1147 { 0x21, 0x10 },
1148 { 0x22, 0x88 },
1149 { 0x23, 0xc0 }, /* Crystal circuit power level */
1150 { 0x25, 0x9a }, /* Increase AEC black ratio */
1151 { 0x26, 0xb2 }, /* BLC enable */
1152 { 0x27, 0xa2 },
1153 { 0x28, 0x00 },
1154 { 0x29, 0x00 },
1155 { 0x2a, 0x84 }, /* 60 Hz power */
1156 { 0x2b, 0xa8 }, /* 60 Hz power */
1157 { 0x2c, 0xa0 },
1158 { 0x2d, 0x95 }, /* Enable auto-brightness */
1159 { 0x2e, 0x88 },
1160 { 0x33, 0x26 },
1161 { 0x34, 0x03 },
1162 { 0x36, 0x8f },
1163 { 0x37, 0x80 },
1164 { 0x38, 0x83 },
1165 { 0x39, 0x80 },
1166 { 0x3a, 0x0f },
1167 { 0x3b, 0x3c },
1168 { 0x3c, 0x1a },
1169 { 0x3d, 0x80 },
1170 { 0x3e, 0x80 },
1171 { 0x3f, 0x0e },
1172 { 0x40, 0x00 }, /* White bal */
1173 { 0x41, 0x00 }, /* White bal */
1174 { 0x42, 0x80 },
1175 { 0x43, 0x3f }, /* White bal */
1176 { 0x44, 0x80 },
1177 { 0x45, 0x20 },
1178 { 0x46, 0x20 },
1179 { 0x47, 0x80 },
1180 { 0x48, 0x7f },
1181 { 0x49, 0x00 },
1182 { 0x4a, 0x00 },
1183 { 0x4b, 0x80 },
1184 { 0x4c, 0xd0 },
1185 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1186 { 0x4e, 0x40 },
1187 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1188 { 0x50, 0xff },
1189 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1190 { 0x55, 0xff },
1191 { 0x56, 0x12 },
1192 { 0x57, 0x81 },
1193 { 0x58, 0x75 },
1194 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1195 { 0x5a, 0x2c },
1196 { 0x5b, 0x0f }, /* AWB chrominance levels */
1197 { 0x5c, 0x10 },
1198 { 0x3d, 0x80 },
1199 { 0x27, 0xa6 },
1200 { 0x12, 0x20 }, /* Toggle AWB */
1201 { 0x12, 0x24 },
1202 };
1203
1204 PDEBUG(D_PROBE, "starting sensor configuration");
1205
1206 if (init_ov_sensor(sd) < 0) {
1207 PDEBUG(D_ERR, "Failed to read sensor ID.");
1208 return -1;
1209 }
1210 PDEBUG(D_PROBE, "OV6xx0 sensor detected");
1211 1239
1212 /* Detect sensor (sub)type */ 1240 /* Detect sensor (sub)type */
1213 rc = i2c_r(sd, OV7610_REG_COM_I); 1241 rc = i2c_r(sd, OV7610_REG_COM_I);
@@ -1251,15 +1279,6 @@ static int ov6xx0_configure(struct sd *sd)
1251 /* Set sensor-specific vars */ 1279 /* Set sensor-specific vars */
1252 sd->sif = 1; 1280 sd->sif = 1;
1253 1281
1254 if (sd->sensor == SEN_OV6620) {
1255 PDEBUG(D_PROBE, "Writing 6x20 registers");
1256 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1257 return -1;
1258 } else {
1259 PDEBUG(D_PROBE, "Writing 6x30 registers");
1260 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1261 return -1;
1262 }
1263 return 0; 1282 return 0;
1264} 1283}
1265 1284
@@ -1298,22 +1317,31 @@ static int sd_config(struct gspca_dev *gspca_dev,
1298 ov51x_led_control(sd, 0); /* turn LED off */ 1317 ov51x_led_control(sd, 0); /* turn LED off */
1299 1318
1300 /* Test for 76xx */ 1319 /* Test for 76xx */
1301 sd->primary_i2c_slave = OV7xx0_SID;
1302 if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) 1320 if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
1303 goto error; 1321 goto error;
1304 1322
1305 /* The OV519 must be more aggressive about sensor detection since 1323 /* The OV519 must be more aggressive about sensor detection since
1306 * I2C write will never fail if the sensor is not present. We have 1324 * I2C write will never fail if the sensor is not present. We have
1307 * to try to initialize the sensor to detect its presence */ 1325 * to try to initialize the sensor to detect its presence */
1308 if (init_ov_sensor(sd) < 0) { 1326 if (init_ov_sensor(sd) >= 0) {
1327 if (ov7xx0_configure(sd) < 0) {
1328 PDEBUG(D_ERR, "Failed to configure OV7xx0");
1329 goto error;
1330 }
1331 } else {
1332
1309 /* Test for 6xx0 */ 1333 /* Test for 6xx0 */
1310 sd->primary_i2c_slave = OV6xx0_SID;
1311 if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) 1334 if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0)
1312 goto error; 1335 goto error;
1313 1336
1314 if (init_ov_sensor(sd) < 0) { 1337 if (init_ov_sensor(sd) >= 0) {
1338 if (ov6xx0_configure(sd) < 0) {
1339 PDEBUG(D_ERR, "Failed to configure OV6xx0");
1340 goto error;
1341 }
1342 } else {
1343
1315 /* Test for 8xx0 */ 1344 /* Test for 8xx0 */
1316 sd->primary_i2c_slave = OV8xx0_SID;
1317 if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) 1345 if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
1318 goto error; 1346 goto error;
1319 1347
@@ -1321,24 +1349,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
1321 PDEBUG(D_ERR, 1349 PDEBUG(D_ERR,
1322 "Can't determine sensor slave IDs"); 1350 "Can't determine sensor slave IDs");
1323 goto error; 1351 goto error;
1324 } else {
1325 if (ov8xx0_configure(sd) < 0) {
1326 PDEBUG(D_ERR,
1327 "Failed to configure OV8xx0 sensor");
1328 goto error;
1329 }
1330 } 1352 }
1331 } else { 1353 if (ov8xx0_configure(sd) < 0) {
1332 if (ov6xx0_configure(sd) < 0) { 1354 PDEBUG(D_ERR,
1333 PDEBUG(D_ERR, "Failed to configure OV6xx0"); 1355 "Failed to configure OV8xx0 sensor");
1334 goto error; 1356 goto error;
1335 } 1357 }
1336 } 1358 }
1337 } else {
1338 if (ov7xx0_configure(sd) < 0) {
1339 PDEBUG(D_ERR, "Failed to configure OV7xx0");
1340 goto error;
1341 }
1342 } 1359 }
1343 1360
1344 cam = &gspca_dev->cam; 1361 cam = &gspca_dev->cam;
@@ -1355,15 +1372,53 @@ static int sd_config(struct gspca_dev *gspca_dev,
1355 sd->colors = COLOR_DEF; 1372 sd->colors = COLOR_DEF;
1356 sd->hflip = HFLIP_DEF; 1373 sd->hflip = HFLIP_DEF;
1357 sd->vflip = VFLIP_DEF; 1374 sd->vflip = VFLIP_DEF;
1375 if (sd->sensor != SEN_OV7670)
1376 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
1377 | (1 << VFLIP_IDX);
1358 return 0; 1378 return 0;
1359error: 1379error:
1360 PDEBUG(D_ERR, "OV519 Config failed"); 1380 PDEBUG(D_ERR, "OV519 Config failed");
1361 return -EBUSY; 1381 return -EBUSY;
1362} 1382}
1363 1383
1364/* this function is called at open time */ 1384/* this function is called at probe and resume time */
1365static int sd_open(struct gspca_dev *gspca_dev) 1385static int sd_init(struct gspca_dev *gspca_dev)
1366{ 1386{
1387 struct sd *sd = (struct sd *) gspca_dev;
1388
1389 /* initialize the sensor */
1390 switch (sd->sensor) {
1391 case SEN_OV6620:
1392 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1393 return -EIO;
1394 break;
1395 case SEN_OV6630:
1396 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1397 return -EIO;
1398 break;
1399 default:
1400/* case SEN_OV7610: */
1401/* case SEN_OV76BE: */
1402 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1403 return -EIO;
1404 break;
1405 case SEN_OV7620:
1406 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1407 return -EIO;
1408 break;
1409 case SEN_OV7640:
1410 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1411 return -EIO;
1412 break;
1413 case SEN_OV7670:
1414 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1415 return -EIO;
1416 break;
1417 case SEN_OV8610:
1418 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
1419 return -EIO;
1420 break;
1421 }
1367 return 0; 1422 return 0;
1368} 1423}
1369 1424
@@ -1827,14 +1882,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1827 ov51x_led_control((struct sd *) gspca_dev, 0); 1882 ov51x_led_control((struct sd *) gspca_dev, 0);
1828} 1883}
1829 1884
1830static void sd_stop0(struct gspca_dev *gspca_dev)
1831{
1832}
1833
1834static void sd_close(struct gspca_dev *gspca_dev)
1835{
1836}
1837
1838static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1885static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1839 struct gspca_frame *frame, /* target */ 1886 struct gspca_frame *frame, /* target */
1840 __u8 *data, /* isoc packet */ 1887 __u8 *data, /* isoc packet */
@@ -2091,11 +2138,9 @@ static const struct sd_desc sd_desc = {
2091 .ctrls = sd_ctrls, 2138 .ctrls = sd_ctrls,
2092 .nctrls = ARRAY_SIZE(sd_ctrls), 2139 .nctrls = ARRAY_SIZE(sd_ctrls),
2093 .config = sd_config, 2140 .config = sd_config,
2094 .open = sd_open, 2141 .init = sd_init,
2095 .start = sd_start, 2142 .start = sd_start,
2096 .stopN = sd_stopN, 2143 .stopN = sd_stopN,
2097 .stop0 = sd_stop0,
2098 .close = sd_close,
2099 .pkt_scan = sd_pkt_scan, 2144 .pkt_scan = sd_pkt_scan,
2100}; 2145};
2101 2146
@@ -2132,6 +2177,10 @@ static struct usb_driver sd_driver = {
2132 .id_table = device_table, 2177 .id_table = device_table,
2133 .probe = sd_probe, 2178 .probe = sd_probe,
2134 .disconnect = gspca_disconnect, 2179 .disconnect = gspca_disconnect,
2180#ifdef CONFIG_PM
2181 .suspend = gspca_suspend,
2182 .resume = gspca_resume,
2183#endif
2135}; 2184};
2136 2185
2137/* -- module insert / remove -- */ 2186/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 7ef18d578811..83b5f740c947 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -56,12 +56,6 @@ MODULE_LICENSE("GPL");
56#define PAC207_GAIN_KNEE 20 56#define PAC207_GAIN_KNEE 20
57 57
58#define PAC207_AUTOGAIN_DEADZONE 30 58#define PAC207_AUTOGAIN_DEADZONE 30
59/* We calculating the autogain at the end of the transfer of a frame, at this
60 moment a frame with the old settings is being transmitted, and a frame is
61 being captured with the old settings. So if we adjust the autogain we must
62 ignore atleast the 2 next frames for the new settings to come into effect
63 before doing any other adjustments */
64#define PAC207_AUTOGAIN_IGNORE_FRAMES 3
65 59
66/* specific webcam descriptor */ 60/* specific webcam descriptor */
67struct sd { 61struct sd {
@@ -131,7 +125,8 @@ static struct ctrl sd_ctrls[] = {
131 .minimum = 0, 125 .minimum = 0,
132 .maximum = 1, 126 .maximum = 1,
133 .step = 1, 127 .step = 1,
134 .default_value = 1, 128#define AUTOGAIN_DEF 1
129 .default_value = AUTOGAIN_DEF,
135 .flags = 0, 130 .flags = 0,
136 }, 131 },
137 .set = sd_setautogain, 132 .set = sd_setautogain,
@@ -181,9 +176,6 @@ static const __u8 pac207_sensor_init[][8] = {
181 /* 48 reg_72 Rate Control end BalSize_4a =0x36 */ 176 /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
182static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; 177static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
183 178
184static const unsigned char pac207_sof_marker[5] =
185 { 0xff, 0xff, 0x00, 0xff, 0x96 };
186
187static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, 179static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
188 const u8 *buffer, u16 length) 180 const u8 *buffer, u16 length)
189{ 181{
@@ -259,35 +251,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
259 return -ENODEV; 251 return -ENODEV;
260 } 252 }
261 253
262 pac207_write_reg(gspca_dev, 0x41, 0x00);
263 /* Bit_0=Image Format,
264 * Bit_1=LED,
265 * Bit_2=Compression test mode enable */
266 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
267 pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
268
269 PDEBUG(D_PROBE, 254 PDEBUG(D_PROBE,
270 "Pixart PAC207BCA Image Processor and Control Chip detected" 255 "Pixart PAC207BCA Image Processor and Control Chip detected"
271 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 256 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
272 257
273 cam = &gspca_dev->cam; 258 cam = &gspca_dev->cam;
274 cam->dev_name = (char *) id->driver_info;
275 cam->epaddr = 0x05; 259 cam->epaddr = 0x05;
276 cam->cam_mode = sif_mode; 260 cam->cam_mode = sif_mode;
277 cam->nmodes = ARRAY_SIZE(sif_mode); 261 cam->nmodes = ARRAY_SIZE(sif_mode);
278 sd->brightness = PAC207_BRIGHTNESS_DEFAULT; 262 sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
279 sd->exposure = PAC207_EXPOSURE_DEFAULT; 263 sd->exposure = PAC207_EXPOSURE_DEFAULT;
280 sd->gain = PAC207_GAIN_DEFAULT; 264 sd->gain = PAC207_GAIN_DEFAULT;
265 sd->autogain = AUTOGAIN_DEF;
281 266
282 return 0; 267 return 0;
283} 268}
284 269
285/* this function is called at open time */ 270/* this function is called at probe and resume time */
286static int sd_open(struct gspca_dev *gspca_dev) 271static int sd_init(struct gspca_dev *gspca_dev)
287{ 272{
288 struct sd *sd = (struct sd *) gspca_dev; 273 pac207_write_reg(gspca_dev, 0x41, 0x00);
274 /* Bit_0=Image Format,
275 * Bit_1=LED,
276 * Bit_2=Compression test mode enable */
277 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
278 pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
289 279
290 sd->autogain = 1;
291 return 0; 280 return 0;
292} 281}
293 282
@@ -343,14 +332,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
343 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ 332 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
344} 333}
345 334
346static void sd_stop0(struct gspca_dev *gspca_dev) 335/* Include pac common sof detection functions */
347{ 336#include "pac_common.h"
348}
349
350/* this function is called at close time */
351static void sd_close(struct gspca_dev *gspca_dev)
352{
353}
354 337
355static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) 338static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
356{ 339{
@@ -365,33 +348,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
365 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 348 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
366 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, 349 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
367 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) 350 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
368 sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; 351 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
369}
370
371static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
372 unsigned char *m, int len)
373{
374 struct sd *sd = (struct sd *) gspca_dev;
375 int i;
376
377 /* Search for the SOF marker (fixed part) in the header */
378 for (i = 0; i < len; i++) {
379 if (m[i] == pac207_sof_marker[sd->sof_read]) {
380 sd->sof_read++;
381 if (sd->sof_read == sizeof(pac207_sof_marker)) {
382 PDEBUG(D_STREAM,
383 "SOF found, bytes to analyze: %u."
384 " Frame starts at byte #%u",
385 len, i + 1);
386 sd->sof_read = 0;
387 return m + i + 1;
388 }
389 } else {
390 sd->sof_read = 0;
391 }
392 }
393
394 return NULL;
395} 352}
396 353
397static void sd_pkt_scan(struct gspca_dev *gspca_dev, 354static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -402,14 +359,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
402 struct sd *sd = (struct sd *) gspca_dev; 359 struct sd *sd = (struct sd *) gspca_dev;
403 unsigned char *sof; 360 unsigned char *sof;
404 361
405 sof = pac207_find_sof(gspca_dev, data, len); 362 sof = pac_find_sof(gspca_dev, data, len);
406 if (sof) { 363 if (sof) {
407 int n; 364 int n;
408 365
409 /* finish decoding current frame */ 366 /* finish decoding current frame */
410 n = sof - data; 367 n = sof - data;
411 if (n > sizeof pac207_sof_marker) 368 if (n > sizeof pac_sof_marker)
412 n -= sizeof pac207_sof_marker; 369 n -= sizeof pac_sof_marker;
413 else 370 else
414 n = 0; 371 n = 0;
415 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 372 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -537,7 +494,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
537 sd->gain = PAC207_GAIN_DEFAULT; 494 sd->gain = PAC207_GAIN_DEFAULT;
538 if (gspca_dev->streaming) { 495 if (gspca_dev->streaming) {
539 sd->autogain_ignore_frames = 496 sd->autogain_ignore_frames =
540 PAC207_AUTOGAIN_IGNORE_FRAMES; 497 PAC_AUTOGAIN_IGNORE_FRAMES;
541 setexposure(gspca_dev); 498 setexposure(gspca_dev);
542 setgain(gspca_dev); 499 setgain(gspca_dev);
543 } 500 }
@@ -560,11 +517,9 @@ static const struct sd_desc sd_desc = {
560 .ctrls = sd_ctrls, 517 .ctrls = sd_ctrls,
561 .nctrls = ARRAY_SIZE(sd_ctrls), 518 .nctrls = ARRAY_SIZE(sd_ctrls),
562 .config = sd_config, 519 .config = sd_config,
563 .open = sd_open, 520 .init = sd_init,
564 .start = sd_start, 521 .start = sd_start,
565 .stopN = sd_stopN, 522 .stopN = sd_stopN,
566 .stop0 = sd_stop0,
567 .close = sd_close,
568 .dq_callback = pac207_do_auto_gain, 523 .dq_callback = pac207_do_auto_gain,
569 .pkt_scan = sd_pkt_scan, 524 .pkt_scan = sd_pkt_scan,
570}; 525};
@@ -597,6 +552,10 @@ static struct usb_driver sd_driver = {
597 .id_table = device_table, 552 .id_table = device_table,
598 .probe = sd_probe, 553 .probe = sd_probe,
599 .disconnect = gspca_disconnect, 554 .disconnect = gspca_disconnect,
555#ifdef CONFIG_PM
556 .suspend = gspca_suspend,
557 .resume = gspca_resume,
558#endif
600}; 559};
601 560
602/* -- module insert / remove -- */ 561/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 815bea6edc44..d4be51843286 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -19,6 +19,36 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22/* Some documentation about various registers as determined by trial and error.
23 When the register addresses differ between the 7202 and the 7311 the 2
24 different addresses are written as 7302addr/7311addr, when one of the 2
25 addresses is a - sign that register description is not valid for the
26 matching IC.
27
28 Register page 1:
29
30 Address Description
31 -/0x08 Unknown compressor related, must always be 8 except when not
32 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
33 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
34 bits 345 seem to toggle per color gains on/off (inverted)
35 0x78 Global control, bit 6 controls the LED (inverted)
36 -/0x80 JPEG compression ratio ? Best not touched
37
38 Register page 3/4:
39
40 Address Description
41 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
43 -/0x0f Master gain 1-245, low value = high gain
44 0x10/- Master gain 0-31
45 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
48 completely disable the analog amplification block. Set to 0x68
49 for max gain, 0x14 for minimal gain.
50*/
51
22#define MODULE_NAME "pac7311" 52#define MODULE_NAME "pac7311"
23 53
24#include "gspca.h" 54#include "gspca.h"
@@ -31,18 +61,23 @@ MODULE_LICENSE("GPL");
31struct sd { 61struct sd {
32 struct gspca_dev gspca_dev; /* !! must be the first item */ 62 struct gspca_dev gspca_dev; /* !! must be the first item */
33 63
34 int lum_sum;
35 atomic_t avg_lum;
36 atomic_t do_gain;
37
38 unsigned char brightness; 64 unsigned char brightness;
39 unsigned char contrast; 65 unsigned char contrast;
40 unsigned char colors; 66 unsigned char colors;
67 unsigned char gain;
68 unsigned char exposure;
41 unsigned char autogain; 69 unsigned char autogain;
70 __u8 hflip;
71 __u8 vflip;
72
73 __u8 sensor;
74#define SENSOR_PAC7302 0
75#define SENSOR_PAC7311 1
42 76
43 char ffseq; 77 u8 sof_read;
44 signed char ag_cnt; 78 u8 autogain_ignore_frames;
45#define AG_CNT_START 13 79
80 atomic_t avg_lum;
46}; 81};
47 82
48/* V4L2 controls supported by the driver */ 83/* V4L2 controls supported by the driver */
@@ -54,8 +89,18 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 89static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
55static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 90static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 91static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
98static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
57 100
58static struct ctrl sd_ctrls[] = { 101static struct ctrl sd_ctrls[] = {
102/* This control is pac7302 only */
103#define BRIGHTNESS_IDX 0
59 { 104 {
60 { 105 {
61 .id = V4L2_CID_BRIGHTNESS, 106 .id = V4L2_CID_BRIGHTNESS,
@@ -71,13 +116,15 @@ static struct ctrl sd_ctrls[] = {
71 .set = sd_setbrightness, 116 .set = sd_setbrightness,
72 .get = sd_getbrightness, 117 .get = sd_getbrightness,
73 }, 118 },
119/* This control is for both the 7302 and the 7311 */
74 { 120 {
75 { 121 {
76 .id = V4L2_CID_CONTRAST, 122 .id = V4L2_CID_CONTRAST,
77 .type = V4L2_CTRL_TYPE_INTEGER, 123 .type = V4L2_CTRL_TYPE_INTEGER,
78 .name = "Contrast", 124 .name = "Contrast",
79 .minimum = 0, 125 .minimum = 0,
80 .maximum = 255, 126#define CONTRAST_MAX 255
127 .maximum = CONTRAST_MAX,
81 .step = 1, 128 .step = 1,
82#define CONTRAST_DEF 127 129#define CONTRAST_DEF 127
83 .default_value = CONTRAST_DEF, 130 .default_value = CONTRAST_DEF,
@@ -85,13 +132,16 @@ static struct ctrl sd_ctrls[] = {
85 .set = sd_setcontrast, 132 .set = sd_setcontrast,
86 .get = sd_getcontrast, 133 .get = sd_getcontrast,
87 }, 134 },
135/* This control is pac7302 only */
136#define SATURATION_IDX 2
88 { 137 {
89 { 138 {
90 .id = V4L2_CID_SATURATION, 139 .id = V4L2_CID_SATURATION,
91 .type = V4L2_CTRL_TYPE_INTEGER, 140 .type = V4L2_CTRL_TYPE_INTEGER,
92 .name = "Color", 141 .name = "Saturation",
93 .minimum = 0, 142 .minimum = 0,
94 .maximum = 255, 143#define COLOR_MAX 255
144 .maximum = COLOR_MAX,
95 .step = 1, 145 .step = 1,
96#define COLOR_DEF 127 146#define COLOR_DEF 127
97 .default_value = COLOR_DEF, 147 .default_value = COLOR_DEF,
@@ -99,6 +149,39 @@ static struct ctrl sd_ctrls[] = {
99 .set = sd_setcolors, 149 .set = sd_setcolors,
100 .get = sd_getcolors, 150 .get = sd_getcolors,
101 }, 151 },
152/* All controls below are for both the 7302 and the 7311 */
153 {
154 {
155 .id = V4L2_CID_GAIN,
156 .type = V4L2_CTRL_TYPE_INTEGER,
157 .name = "Gain",
158 .minimum = 0,
159#define GAIN_MAX 255
160 .maximum = GAIN_MAX,
161 .step = 1,
162#define GAIN_DEF 127
163#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
164 .default_value = GAIN_DEF,
165 },
166 .set = sd_setgain,
167 .get = sd_getgain,
168 },
169 {
170 {
171 .id = V4L2_CID_EXPOSURE,
172 .type = V4L2_CTRL_TYPE_INTEGER,
173 .name = "Exposure",
174 .minimum = 0,
175#define EXPOSURE_MAX 255
176 .maximum = EXPOSURE_MAX,
177 .step = 1,
178#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
179#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
180 .default_value = EXPOSURE_DEF,
181 },
182 .set = sd_setexposure,
183 .get = sd_getexposure,
184 },
102 { 185 {
103 { 186 {
104 .id = V4L2_CID_AUTOGAIN, 187 .id = V4L2_CID_AUTOGAIN,
@@ -113,101 +196,207 @@ static struct ctrl sd_ctrls[] = {
113 .set = sd_setautogain, 196 .set = sd_setautogain,
114 .get = sd_getautogain, 197 .get = sd_getautogain,
115 }, 198 },
199 {
200 {
201 .id = V4L2_CID_HFLIP,
202 .type = V4L2_CTRL_TYPE_BOOLEAN,
203 .name = "Mirror",
204 .minimum = 0,
205 .maximum = 1,
206 .step = 1,
207#define HFLIP_DEF 0
208 .default_value = HFLIP_DEF,
209 },
210 .set = sd_sethflip,
211 .get = sd_gethflip,
212 },
213 {
214 {
215 .id = V4L2_CID_VFLIP,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "Vflip",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221#define VFLIP_DEF 0
222 .default_value = VFLIP_DEF,
223 },
224 .set = sd_setvflip,
225 .get = sd_getvflip,
226 },
116}; 227};
117 228
118static struct v4l2_pix_format vga_mode[] = { 229static struct v4l2_pix_format vga_mode[] = {
119 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 230 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
120 .bytesperline = 160, 231 .bytesperline = 160,
121 .sizeimage = 160 * 120 * 3 / 8 + 590, 232 .sizeimage = 160 * 120 * 3 / 8 + 590,
122 .colorspace = V4L2_COLORSPACE_JPEG, 233 .colorspace = V4L2_COLORSPACE_JPEG,
123 .priv = 2}, 234 .priv = 2},
124 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 235 {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
125 .bytesperline = 320, 236 .bytesperline = 320,
126 .sizeimage = 320 * 240 * 3 / 8 + 590, 237 .sizeimage = 320 * 240 * 3 / 8 + 590,
127 .colorspace = V4L2_COLORSPACE_JPEG, 238 .colorspace = V4L2_COLORSPACE_JPEG,
128 .priv = 1}, 239 .priv = 1},
129 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 240 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
130 .bytesperline = 640, 241 .bytesperline = 640,
131 .sizeimage = 640 * 480 * 3 / 8 + 590, 242 .sizeimage = 640 * 480 * 3 / 8 + 590,
132 .colorspace = V4L2_COLORSPACE_JPEG, 243 .colorspace = V4L2_COLORSPACE_JPEG,
133 .priv = 0}, 244 .priv = 0},
134}; 245};
135 246
136#define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ 247/* pac 7302 */
137 248static const __u8 init_7302[] = {
138static const __u8 pac7311_jpeg_header[] = { 249/* index,value */
139 0xff, 0xd8, 250 0xff, 0x01, /* page 1 */
140 0xff, 0xe0, 0x00, 0x03, 0x20, 251 0x78, 0x00, /* deactivate */
141 0xff, 0xc0, 0x00, 0x11, 0x08, 252 0xff, 0x01,
142 0x01, 0xe0, /* 12: height */ 253 0x78, 0x40, /* led off */
143 0x02, 0x80, /* 14: width */ 254};
144 0x03, /* 16 */ 255static const __u8 start_7302[] = {
145 0x01, 0x21, 0x00, 256/* index, len, [value]* */
146 0x02, 0x11, 0x01, 257 0xff, 1, 0x00, /* page 0 */
147 0x03, 0x11, 0x01, 258 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
148 0xff, 0xdb, 0x00, 0x84, 259 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 260 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
150 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 261 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
151 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 262 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
152 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 263 0x26, 2, 0xaa, 0xaa,
153 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f, 264 0x2e, 1, 0x31,
154 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64, 265 0x38, 1, 0x01,
155 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18, 266 0x3a, 3, 0x14, 0xff, 0x5a,
156 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 267 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
157 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 268 0x00, 0x54, 0x11,
158 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 269 0x55, 1, 0x00,
159 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 270 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
160 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 271 0x6b, 1, 0x00,
161 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 272 0x6e, 3, 0x08, 0x06, 0x00,
162 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 273 0x72, 3, 0x00, 0xff, 0x00,
163 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 274 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
164 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 275 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
165 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 276 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
166 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 277 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
167 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 278 0xd2, 0xeb,
168 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 279 0xaf, 1, 0x02,
169 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 280 0xb5, 2, 0x08, 0x08,
170 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 281 0xb8, 2, 0x08, 0x88,
171 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 282 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
172 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 283 0xcc, 1, 0x00,
173 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 284 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
174 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 285 0xc1, 0xd7, 0xec,
175 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 286 0xdc, 1, 0x01,
176 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 287 0xff, 1, 0x01, /* page 1 */
177 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 288 0x12, 3, 0x02, 0x00, 0x01,
178 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 289 0x3e, 2, 0x00, 0x00,
179 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 290 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
180 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 291 0x7c, 1, 0x00,
181 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 292 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
182 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 293 0x02, 0x00,
183 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 294 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
184 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 295 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
185 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 296 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
186 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 297 0xd8, 1, 0x01,
187 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 298 0xdb, 2, 0x00, 0x01,
188 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 299 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
189 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 300 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
190 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 301 0xeb, 1, 0x00,
191 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 302 0xff, 1, 0x02, /* page 2 */
192 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 303 0x22, 1, 0x00,
193 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 304 0xff, 1, 0x03, /* page 3 */
194 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 305 0x00, 255, /* load the page 3 */
195 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 306 0x11, 1, 0x01,
196 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 307 0xff, 1, 0x02, /* page 2 */
197 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 308 0x13, 1, 0x00,
198 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 309 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
199 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 310 0x27, 2, 0x14, 0x0c,
200 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 311 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
201 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 312 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
202 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 313 0x6e, 1, 0x08,
203 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 314 0xff, 1, 0x01, /* page 1 */
204 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 315 0x78, 1, 0x00,
205 0x11, 0x00, 0x3f, 0x00 316 0, 0 /* end of sequence */
317};
318
319/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
320static const __u8 page3_7302[] = {
321 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
322 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
323 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
325 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
326 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
327 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
328 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
331 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
335 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
336 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
337 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
340 0x00
341};
342
343/* pac 7311 */
344static const __u8 init_7311[] = {
345 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
346 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
347 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */
348 0xff, 0x04,
349 0x27, 0x80,
350 0x28, 0xca,
351 0x29, 0x53,
352 0x2a, 0x0e,
353 0xff, 0x01,
354 0x3e, 0x20,
355};
356
357static const __u8 start_7311[] = {
358/* index, len, [value]* */
359 0xff, 1, 0x01, /* page 1 */
360 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
361 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
362 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
363 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00,
366 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
367 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
368 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
369 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
370 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
371 0xd0, 0xff,
372 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
373 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
374 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
375 0x18, 0x20,
376 0x96, 3, 0x01, 0x08, 0x04,
377 0xa0, 4, 0x44, 0x44, 0x44, 0x04,
378 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
379 0x3f, 0x00, 0x0a, 0x01, 0x00,
380 0xff, 1, 0x04, /* page 4 */
381 0x00, 254, /* load the page 4 */
382 0x11, 1, 0x01,
383 0, 0 /* end of sequence */
384};
385
386/* page 4 - the value 0xaa says skip the index - see reg_w_page() */
387static const __u8 page4_7311[] = {
388 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
389 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
390 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
392 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68,
393 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
394 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
206}; 395};
207 396
208static void reg_w_buf(struct gspca_dev *gspca_dev, 397static void reg_w_buf(struct gspca_dev *gspca_dev,
209 __u16 index, 398 __u8 index,
210 const char *buffer, __u16 len) 399 const char *buffer, int len)
211{ 400{
212 memcpy(gspca_dev->usb_buf, buffer, len); 401 memcpy(gspca_dev->usb_buf, buffer, len);
213 usb_control_msg(gspca_dev->dev, 402 usb_control_msg(gspca_dev->dev,
@@ -219,21 +408,9 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
219 500); 408 500);
220} 409}
221 410
222static __u8 reg_r(struct gspca_dev *gspca_dev,
223 __u16 index)
224{
225 usb_control_msg(gspca_dev->dev,
226 usb_rcvctrlpipe(gspca_dev->dev, 0),
227 0, /* request */
228 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
229 0, /* value */
230 index, gspca_dev->usb_buf, 1,
231 500);
232 return gspca_dev->usb_buf[0];
233}
234 411
235static void reg_w(struct gspca_dev *gspca_dev, 412static void reg_w(struct gspca_dev *gspca_dev,
236 __u16 index, 413 __u8 index,
237 __u8 value) 414 __u8 value)
238{ 415{
239 gspca_dev->usb_buf[0] = value; 416 gspca_dev->usb_buf[0] = value;
@@ -241,10 +418,78 @@ static void reg_w(struct gspca_dev *gspca_dev,
241 usb_sndctrlpipe(gspca_dev->dev, 0), 418 usb_sndctrlpipe(gspca_dev->dev, 0),
242 0, /* request */ 419 0, /* request */
243 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 420 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
244 value, index, gspca_dev->usb_buf, 1, 421 0, index, gspca_dev->usb_buf, 1,
245 500); 422 500);
246} 423}
247 424
425static void reg_w_seq(struct gspca_dev *gspca_dev,
426 const __u8 *seq, int len)
427{
428 while (--len >= 0) {
429 reg_w(gspca_dev, seq[0], seq[1]);
430 seq += 2;
431 }
432}
433
434/* load the beginning of a page */
435static void reg_w_page(struct gspca_dev *gspca_dev,
436 const __u8 *page, int len)
437{
438 int index;
439
440 for (index = 0; index < len; index++) {
441 if (page[index] == 0xaa) /* skip this index */
442 continue;
443 gspca_dev->usb_buf[0] = page[index];
444 usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, index, gspca_dev->usb_buf, 1,
449 500);
450 }
451}
452
453/* output a variable sequence */
454static void reg_w_var(struct gspca_dev *gspca_dev,
455 const __u8 *seq)
456{
457 int index, len;
458
459 for (;;) {
460 index = *seq++;
461 len = *seq++;
462 switch (len) {
463 case 0:
464 return;
465 case 254:
466 reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
467 break;
468 case 255:
469 reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
470 break;
471 default:
472 if (len > 64) {
473 PDEBUG(D_ERR|D_STREAM,
474 "Incorrect variable sequence");
475 return;
476 }
477 while (len > 0) {
478 if (len < 8) {
479 reg_w_buf(gspca_dev, index, seq, len);
480 seq += len;
481 break;
482 }
483 reg_w_buf(gspca_dev, index, seq, 8);
484 seq += 8;
485 index += 8;
486 len -= 8;
487 }
488 }
489 }
490 /* not reached */
491}
492
248/* this function is called at probe time */ 493/* this function is called at probe time */
249static int sd_config(struct gspca_dev *gspca_dev, 494static int sd_config(struct gspca_dev *gspca_dev,
250 const struct usb_device_id *id) 495 const struct usb_device_id *id)
@@ -252,203 +497,245 @@ static int sd_config(struct gspca_dev *gspca_dev,
252 struct sd *sd = (struct sd *) gspca_dev; 497 struct sd *sd = (struct sd *) gspca_dev;
253 struct cam *cam; 498 struct cam *cam;
254 499
255 PDEBUG(D_CONF, "Find Sensor PAC7311");
256 reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
257 reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
258 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
259 reg_w(gspca_dev, 0xff, 0x04);
260 reg_w(gspca_dev, 0x27, 0x80);
261 reg_w(gspca_dev, 0x28, 0xca);
262 reg_w(gspca_dev, 0x29, 0x53);
263 reg_w(gspca_dev, 0x2a, 0x0e);
264 reg_w(gspca_dev, 0xff, 0x01);
265 reg_w(gspca_dev, 0x3e, 0x20);
266
267 cam = &gspca_dev->cam; 500 cam = &gspca_dev->cam;
268 cam->epaddr = 0x05; 501 cam->epaddr = 0x05;
269 cam->cam_mode = vga_mode; 502
270 cam->nmodes = ARRAY_SIZE(vga_mode); 503 sd->sensor = id->driver_info;
504 if (sd->sensor == SENSOR_PAC7302) {
505 PDEBUG(D_CONF, "Find Sensor PAC7302");
506 cam->cam_mode = &vga_mode[2]; /* only 640x480 */
507 cam->nmodes = 1;
508 } else {
509 PDEBUG(D_CONF, "Find Sensor PAC7311");
510 cam->cam_mode = vga_mode;
511 cam->nmodes = ARRAY_SIZE(vga_mode);
512 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
513 | (1 << SATURATION_IDX);
514 }
271 515
272 sd->brightness = BRIGHTNESS_DEF; 516 sd->brightness = BRIGHTNESS_DEF;
273 sd->contrast = CONTRAST_DEF; 517 sd->contrast = CONTRAST_DEF;
274 sd->colors = COLOR_DEF; 518 sd->colors = COLOR_DEF;
519 sd->gain = GAIN_DEF;
520 sd->exposure = EXPOSURE_DEF;
275 sd->autogain = AUTOGAIN_DEF; 521 sd->autogain = AUTOGAIN_DEF;
276 sd->ag_cnt = -1; 522 sd->hflip = HFLIP_DEF;
523 sd->vflip = VFLIP_DEF;
277 return 0; 524 return 0;
278} 525}
279 526
280static void setbrightness(struct gspca_dev *gspca_dev) 527/* This function is used by pac7302 only */
528static void setbrightcont(struct gspca_dev *gspca_dev)
529{
530 struct sd *sd = (struct sd *) gspca_dev;
531 int i, v;
532 static const __u8 max[10] =
533 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
534 0xd4, 0xec};
535 static const __u8 delta[10] =
536 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
537 0x11, 0x0b};
538
539 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
540 for (i = 0; i < 10; i++) {
541 v = max[i];
542 v += (sd->brightness - BRIGHTNESS_MAX)
543 * 150 / BRIGHTNESS_MAX; /* 200 ? */
544 v -= delta[i] * sd->contrast / CONTRAST_MAX;
545 if (v < 0)
546 v = 0;
547 else if (v > 0xff)
548 v = 0xff;
549 reg_w(gspca_dev, 0xa2 + i, v);
550 }
551 reg_w(gspca_dev, 0xdc, 0x01);
552}
553
554/* This function is used by pac7311 only */
555static void setcontrast(struct gspca_dev *gspca_dev)
281{ 556{
282 struct sd *sd = (struct sd *) gspca_dev; 557 struct sd *sd = (struct sd *) gspca_dev;
283 int brightness;
284 558
285/*jfm: inverted?*/
286 brightness = BRIGHTNESS_MAX - sd->brightness;
287 reg_w(gspca_dev, 0xff, 0x04); 559 reg_w(gspca_dev, 0xff, 0x04);
288/* reg_w(gspca_dev, 0x0e, 0x00); */ 560 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
289 reg_w(gspca_dev, 0x0f, brightness);
290 /* load registers to sensor (Bit 0, auto clear) */ 561 /* load registers to sensor (Bit 0, auto clear) */
291 reg_w(gspca_dev, 0x11, 0x01); 562 reg_w(gspca_dev, 0x11, 0x01);
292 PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
293} 563}
294 564
295static void setcontrast(struct gspca_dev *gspca_dev) 565/* This function is used by pac7302 only */
566static void setcolors(struct gspca_dev *gspca_dev)
296{ 567{
297 struct sd *sd = (struct sd *) gspca_dev; 568 struct sd *sd = (struct sd *) gspca_dev;
569 int i, v;
570 static const int a[9] =
571 {217, -212, 0, -101, 170, -67, -38, -315, 355};
572 static const int b[9] =
573 {19, 106, 0, 19, 106, 1, 19, 106, 1};
298 574
299 reg_w(gspca_dev, 0xff, 0x01); 575 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
300 reg_w(gspca_dev, 0x80, sd->contrast);
301 /* load registers to sensor (Bit 0, auto clear) */
302 reg_w(gspca_dev, 0x11, 0x01); 576 reg_w(gspca_dev, 0x11, 0x01);
303 PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); 577 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
578 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
579 for (i = 0; i < 9; i++) {
580 v = a[i] * sd->colors / COLOR_MAX + b[i];
581 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
582 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
583 }
584 reg_w(gspca_dev, 0xdc, 0x01);
585 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
304} 586}
305 587
306static void setcolors(struct gspca_dev *gspca_dev) 588static void setgain(struct gspca_dev *gspca_dev)
307{ 589{
308 struct sd *sd = (struct sd *) gspca_dev; 590 struct sd *sd = (struct sd *) gspca_dev;
309 591
310 reg_w(gspca_dev, 0xff, 0x01); 592 if (sd->sensor == SENSOR_PAC7302) {
311 reg_w(gspca_dev, 0x10, sd->colors); 593 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
594 reg_w(gspca_dev, 0x10, sd->gain >> 3);
595 } else {
596 int gain = GAIN_MAX - sd->gain;
597 if (gain < 1)
598 gain = 1;
599 else if (gain > 245)
600 gain = 245;
601 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
602 reg_w(gspca_dev, 0x0e, 0x00);
603 reg_w(gspca_dev, 0x0f, gain);
604 }
312 /* load registers to sensor (Bit 0, auto clear) */ 605 /* load registers to sensor (Bit 0, auto clear) */
313 reg_w(gspca_dev, 0x11, 0x01); 606 reg_w(gspca_dev, 0x11, 0x01);
314 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
315} 607}
316 608
317static void setautogain(struct gspca_dev *gspca_dev) 609static void setexposure(struct gspca_dev *gspca_dev)
318{ 610{
319 struct sd *sd = (struct sd *) gspca_dev; 611 struct sd *sd = (struct sd *) gspca_dev;
612 __u8 reg;
613
614 /* register 2 of frame 3/4 contains the clock divider configuring the
615 no fps according to the formula: 60 / reg. sd->exposure is the
616 desired exposure time in ms. */
617 reg = 120 * sd->exposure / 1000;
618 if (reg < 2)
619 reg = 2;
620 else if (reg > 63)
621 reg = 63;
622
623 if (sd->sensor == SENSOR_PAC7302) {
624 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
625 the nearest multiple of 3, except when between 6 and 12? */
626 if (reg < 6 || reg > 12)
627 reg = ((reg + 1) / 3) * 3;
628 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
629 reg_w(gspca_dev, 0x02, reg);
630 } else {
631 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
632 reg_w(gspca_dev, 0x02, reg);
633 /* Page 1 register 8 must always be 0x08 except when not in
634 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
635 reg_w(gspca_dev, 0xff, 0x01);
636 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
637 reg <= 3)
638 reg_w(gspca_dev, 0x08, 0x09);
639 else
640 reg_w(gspca_dev, 0x08, 0x08);
641 }
642 /* load registers to sensor (Bit 0, auto clear) */
643 reg_w(gspca_dev, 0x11, 0x01);
644}
320 645
321 if (sd->autogain) { 646static void sethvflip(struct gspca_dev *gspca_dev)
322 sd->lum_sum = 0; 647{
323 sd->ag_cnt = AG_CNT_START; 648 struct sd *sd = (struct sd *) gspca_dev;
649 __u8 data;
650
651 if (sd->sensor == SENSOR_PAC7302) {
652 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
653 data = (sd->hflip ? 0x08 : 0x00)
654 | (sd->vflip ? 0x04 : 0x00);
324 } else { 655 } else {
325 sd->ag_cnt = -1; 656 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
657 data = (sd->hflip ? 0x04 : 0x00)
658 | (sd->vflip ? 0x08 : 0x00);
326 } 659 }
660 reg_w(gspca_dev, 0x21, data);
661 /* load registers to sensor (Bit 0, auto clear) */
662 reg_w(gspca_dev, 0x11, 0x01);
327} 663}
328 664
329/* this function is called at open time */ 665/* this function is called at probe and resume time */
330static int sd_open(struct gspca_dev *gspca_dev) 666static int sd_init(struct gspca_dev *gspca_dev)
331{ 667{
332 reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */ 668 struct sd *sd = (struct sd *) gspca_dev;
669
670 if (sd->sensor == SENSOR_PAC7302)
671 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
672 else
673 reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
674
333 return 0; 675 return 0;
334} 676}
335 677
336static void sd_start(struct gspca_dev *gspca_dev) 678static void sd_start(struct gspca_dev *gspca_dev)
337{ 679{
338 reg_w(gspca_dev, 0xff, 0x01); 680 struct sd *sd = (struct sd *) gspca_dev;
339 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
340 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
341 reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8);
342 reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8);
343 reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8);
344 reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3);
345 reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8);
346 reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8);
347 reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8);
348 reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8);
349 reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8);
350 reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2);
351 reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6);
352 reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8);
353 reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8);
354 reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2);
355 reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3);
356 reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4);
357 reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8);
358 reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5);
359 681
360 reg_w(gspca_dev, 0xff, 0x04); 682 sd->sof_read = 0;
361 reg_w(gspca_dev, 0x02, 0x04); 683
362 reg_w(gspca_dev, 0x03, 0x54); 684 if (sd->sensor == SENSOR_PAC7302) {
363 reg_w(gspca_dev, 0x04, 0x07); 685 reg_w_var(gspca_dev, start_7302);
364 reg_w(gspca_dev, 0x05, 0x2b); 686 setbrightcont(gspca_dev);
365 reg_w(gspca_dev, 0x06, 0x09); 687 setcolors(gspca_dev);
366 reg_w(gspca_dev, 0x07, 0x0f); 688 } else {
367 reg_w(gspca_dev, 0x08, 0x09); 689 reg_w_var(gspca_dev, start_7311);
368 reg_w(gspca_dev, 0x09, 0x00); 690 setcontrast(gspca_dev);
369 reg_w(gspca_dev, 0x0c, 0x07); 691 }
370 reg_w(gspca_dev, 0x0d, 0x00); 692 setgain(gspca_dev);
371 reg_w(gspca_dev, 0x0e, 0x00); 693 setexposure(gspca_dev);
372 reg_w(gspca_dev, 0x0f, 0x62); 694 sethvflip(gspca_dev);
373 reg_w(gspca_dev, 0x10, 0x08);
374 reg_w(gspca_dev, 0x12, 0x07);
375 reg_w(gspca_dev, 0x13, 0x00);
376 reg_w(gspca_dev, 0x14, 0x00);
377 reg_w(gspca_dev, 0x15, 0x00);
378 reg_w(gspca_dev, 0x16, 0x00);
379 reg_w(gspca_dev, 0x17, 0x00);
380 reg_w(gspca_dev, 0x18, 0x00);
381 reg_w(gspca_dev, 0x19, 0x00);
382 reg_w(gspca_dev, 0x1a, 0x00);
383 reg_w(gspca_dev, 0x1b, 0x03);
384 reg_w(gspca_dev, 0x1c, 0xa0);
385 reg_w(gspca_dev, 0x1d, 0x01);
386 reg_w(gspca_dev, 0x1e, 0xf4);
387 reg_w(gspca_dev, 0x21, 0x00);
388 reg_w(gspca_dev, 0x22, 0x08);
389 reg_w(gspca_dev, 0x24, 0x03);
390 reg_w(gspca_dev, 0x26, 0x00);
391 reg_w(gspca_dev, 0x27, 0x01);
392 reg_w(gspca_dev, 0x28, 0xca);
393 reg_w(gspca_dev, 0x29, 0x10);
394 reg_w(gspca_dev, 0x2a, 0x06);
395 reg_w(gspca_dev, 0x2b, 0x78);
396 reg_w(gspca_dev, 0x2c, 0x00);
397 reg_w(gspca_dev, 0x2d, 0x00);
398 reg_w(gspca_dev, 0x2e, 0x00);
399 reg_w(gspca_dev, 0x2f, 0x00);
400 reg_w(gspca_dev, 0x30, 0x23);
401 reg_w(gspca_dev, 0x31, 0x28);
402 reg_w(gspca_dev, 0x32, 0x04);
403 reg_w(gspca_dev, 0x33, 0x11);
404 reg_w(gspca_dev, 0x34, 0x00);
405 reg_w(gspca_dev, 0x35, 0x00);
406 reg_w(gspca_dev, 0x11, 0x01);
407 setcontrast(gspca_dev);
408 setbrightness(gspca_dev);
409 setcolors(gspca_dev);
410 setautogain(gspca_dev);
411 695
412 /* set correct resolution */ 696 /* set correct resolution */
413 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 697 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
414 case 2: /* 160x120 */ 698 case 2: /* 160x120 pac7311 */
415 reg_w(gspca_dev, 0xff, 0x04);
416 reg_w(gspca_dev, 0x02, 0x03);
417 reg_w(gspca_dev, 0xff, 0x01); 699 reg_w(gspca_dev, 0xff, 0x01);
418 reg_w(gspca_dev, 0x08, 0x09);
419 reg_w(gspca_dev, 0x17, 0x20); 700 reg_w(gspca_dev, 0x17, 0x20);
420 reg_w(gspca_dev, 0x1b, 0x00);
421/* reg_w(gspca_dev, 0x80, 0x69); */
422 reg_w(gspca_dev, 0x87, 0x10); 701 reg_w(gspca_dev, 0x87, 0x10);
423 break; 702 break;
424 case 1: /* 320x240 */ 703 case 1: /* 320x240 pac7311 */
425 reg_w(gspca_dev, 0xff, 0x04);
426 reg_w(gspca_dev, 0x02, 0x03);
427 reg_w(gspca_dev, 0xff, 0x01); 704 reg_w(gspca_dev, 0xff, 0x01);
428 reg_w(gspca_dev, 0x08, 0x09);
429 reg_w(gspca_dev, 0x17, 0x30); 705 reg_w(gspca_dev, 0x17, 0x30);
430/* reg_w(gspca_dev, 0x80, 0x3f); */
431 reg_w(gspca_dev, 0x87, 0x11); 706 reg_w(gspca_dev, 0x87, 0x11);
432 break; 707 break;
433 case 0: /* 640x480 */ 708 case 0: /* 640x480 */
434 reg_w(gspca_dev, 0xff, 0x04); 709 if (sd->sensor == SENSOR_PAC7302)
435 reg_w(gspca_dev, 0x02, 0x03); 710 break;
436 reg_w(gspca_dev, 0xff, 0x01); 711 reg_w(gspca_dev, 0xff, 0x01);
437 reg_w(gspca_dev, 0x08, 0x08);
438 reg_w(gspca_dev, 0x17, 0x00); 712 reg_w(gspca_dev, 0x17, 0x00);
439/* reg_w(gspca_dev, 0x80, 0x1c); */
440 reg_w(gspca_dev, 0x87, 0x12); 713 reg_w(gspca_dev, 0x87, 0x12);
441 break; 714 break;
442 } 715 }
443 716
717 sd->sof_read = 0;
718 sd->autogain_ignore_frames = 0;
719 atomic_set(&sd->avg_lum, -1);
720
444 /* start stream */ 721 /* start stream */
445 reg_w(gspca_dev, 0xff, 0x01); 722 reg_w(gspca_dev, 0xff, 0x01);
446 reg_w(gspca_dev, 0x78, 0x04); 723 if (sd->sensor == SENSOR_PAC7302)
447 reg_w(gspca_dev, 0x78, 0x05); 724 reg_w(gspca_dev, 0x78, 0x01);
725 else
726 reg_w(gspca_dev, 0x78, 0x05);
448} 727}
449 728
450static void sd_stopN(struct gspca_dev *gspca_dev) 729static void sd_stopN(struct gspca_dev *gspca_dev)
451{ 730{
731 struct sd *sd = (struct sd *) gspca_dev;
732
733 if (sd->sensor == SENSOR_PAC7302) {
734 reg_w(gspca_dev, 0xff, 0x01);
735 reg_w(gspca_dev, 0x78, 0x00);
736 reg_w(gspca_dev, 0x78, 0x00);
737 return;
738 }
452 reg_w(gspca_dev, 0xff, 0x04); 739 reg_w(gspca_dev, 0xff, 0x04);
453 reg_w(gspca_dev, 0x27, 0x80); 740 reg_w(gspca_dev, 0x27, 0x80);
454 reg_w(gspca_dev, 0x28, 0xca); 741 reg_w(gspca_dev, 0x28, 0xca);
@@ -456,187 +743,147 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
456 reg_w(gspca_dev, 0x2a, 0x0e); 743 reg_w(gspca_dev, 0x2a, 0x0e);
457 reg_w(gspca_dev, 0xff, 0x01); 744 reg_w(gspca_dev, 0xff, 0x01);
458 reg_w(gspca_dev, 0x3e, 0x20); 745 reg_w(gspca_dev, 0x3e, 0x20);
459 reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ 746 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
460 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ 747 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
461 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ 748 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
462} 749}
463 750
464static void sd_stop0(struct gspca_dev *gspca_dev) 751static void sd_stop0(struct gspca_dev *gspca_dev)
465{ 752{
466} 753 struct sd *sd = (struct sd *) gspca_dev;
467 754
468/* this function is called at close time */ 755 if (sd->sensor == SENSOR_PAC7302) {
469static void sd_close(struct gspca_dev *gspca_dev) 756 reg_w(gspca_dev, 0xff, 0x01);
470{ 757 reg_w(gspca_dev, 0x78, 0x40);
471 reg_w(gspca_dev, 0xff, 0x04); 758 }
472 reg_w(gspca_dev, 0x27, 0x80);
473 reg_w(gspca_dev, 0x28, 0xca);
474 reg_w(gspca_dev, 0x29, 0x53);
475 reg_w(gspca_dev, 0x2a, 0x0e);
476 reg_w(gspca_dev, 0xff, 0x01);
477 reg_w(gspca_dev, 0x3e, 0x20);
478 reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
479 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
480 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
481} 759}
482 760
761/* Include pac common sof detection functions */
762#include "pac_common.h"
763
483static void do_autogain(struct gspca_dev *gspca_dev) 764static void do_autogain(struct gspca_dev *gspca_dev)
484{ 765{
485 struct sd *sd = (struct sd *) gspca_dev; 766 struct sd *sd = (struct sd *) gspca_dev;
486 int luma; 767 int avg_lum = atomic_read(&sd->avg_lum);
487 int luma_mean = 128; 768 int desired_lum, deadzone;
488 int luma_delta = 20;
489 __u8 spring = 5;
490 int Gbright;
491 769
492 if (!atomic_read(&sd->do_gain)) 770 if (avg_lum == -1)
493 return; 771 return;
494 atomic_set(&sd->do_gain, 0); 772
495 773 if (sd->sensor == SENSOR_PAC7302) {
496 luma = atomic_read(&sd->avg_lum); 774 desired_lum = 270 + sd->brightness * 4;
497 Gbright = reg_r(gspca_dev, 0x02); 775 /* Hack hack, with the 7202 the first exposure step is
498 PDEBUG(D_FRAM, "luma mean %d", luma); 776 pretty large, so if we're about to make the first
499 if (luma < luma_mean - luma_delta || 777 exposure increase make the deadzone large to avoid
500 luma > luma_mean + luma_delta) { 778 oscilating */
501 Gbright += (luma_mean - luma) >> spring; 779 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
502 if (Gbright > 0x1a) 780 sd->exposure > EXPOSURE_DEF &&
503 Gbright = 0x1a; 781 sd->exposure < 42)
504 else if (Gbright < 4) 782 deadzone = 90;
505 Gbright = 4; 783 else
506 PDEBUG(D_FRAM, "gbright %d", Gbright); 784 deadzone = 30;
507 reg_w(gspca_dev, 0xff, 0x04); 785 } else {
508 reg_w(gspca_dev, 0x0f, Gbright); 786 desired_lum = 200;
509 /* load registers to sensor (Bit 0, auto clear) */ 787 deadzone = 20;
510 reg_w(gspca_dev, 0x11, 0x01);
511 } 788 }
789
790 if (sd->autogain_ignore_frames > 0)
791 sd->autogain_ignore_frames--;
792 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
793 deadzone, GAIN_KNEE, EXPOSURE_KNEE))
794 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
512} 795}
513 796
797static const unsigned char pac7311_jpeg_header1[] = {
798 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
799};
800
801static const unsigned char pac7311_jpeg_header2[] = {
802 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
803 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
804};
805
806/* this function is run at interrupt level */
514static void sd_pkt_scan(struct gspca_dev *gspca_dev, 807static void sd_pkt_scan(struct gspca_dev *gspca_dev,
515 struct gspca_frame *frame, /* target */ 808 struct gspca_frame *frame, /* target */
516 __u8 *data, /* isoc packet */ 809 __u8 *data, /* isoc packet */
517 int len) /* iso packet length */ 810 int len) /* iso packet length */
518{ 811{
519 struct sd *sd = (struct sd *) gspca_dev; 812 struct sd *sd = (struct sd *) gspca_dev;
520 unsigned char tmpbuf[4]; 813 unsigned char *sof;
521 int i, p, ffseq; 814
522 815 sof = pac_find_sof(gspca_dev, data, len);
523/* if (len < 5) { */ 816 if (sof) {
524 if (len < 6) { 817 unsigned char tmpbuf[4];
525/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 818 int n, lum_offset, footer_length;
526 return; 819
527 } 820 if (sd->sensor == SENSOR_PAC7302) {
528 821 /* 6 bytes after the FF D9 EOF marker a number of lumination
529 ffseq = sd->ffseq; 822 bytes are send corresponding to different parts of the
530 823 image, the 14th and 15th byte after the EOF seem to
531 for (p = 0; p < len - 6; p++) { 824 correspond to the center of the image */
532 if ((data[0 + p] == 0xff) 825 lum_offset = 61 + sizeof pac_sof_marker;
533 && (data[1 + p] == 0xff) 826 footer_length = 74;
534 && (data[2 + p] == 0x00) 827 } else {
535 && (data[3 + p] == 0xff) 828 lum_offset = 24 + sizeof pac_sof_marker;
536 && (data[4 + p] == 0x96)) { 829 footer_length = 26;
537 830 }
538 /* start of frame */
539 if (sd->ag_cnt >= 0 && p > 28) {
540 sd->lum_sum += data[p - 23];
541 if (--sd->ag_cnt < 0) {
542 sd->ag_cnt = AG_CNT_START;
543 atomic_set(&sd->avg_lum,
544 sd->lum_sum / AG_CNT_START);
545 sd->lum_sum = 0;
546 atomic_set(&sd->do_gain, 1);
547 }
548 }
549 831
550 /* copy the end of data to the current frame */ 832 /* Finish decoding current frame */
833 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
834 if (n < 0) {
835 frame->data_end += n;
836 n = 0;
837 }
838 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
839 data, n);
840 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
841 frame->data_end[-2] == 0xff &&
842 frame->data_end[-1] == 0xd9)
551 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 843 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
552 data, p); 844 NULL, 0);
553 845
554 /* put the JPEG header in the new frame */ 846 n = sof - data;
555 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 847 len -= n;
556 (unsigned char *) pac7311_jpeg_header, 848 data = sof;
557 12); 849
850 /* Get average lumination */
851 if (gspca_dev->last_packet_type == LAST_PACKET &&
852 n >= lum_offset)
853 atomic_set(&sd->avg_lum, data[-lum_offset] +
854 data[-lum_offset + 1]);
855 else
856 atomic_set(&sd->avg_lum, -1);
857
858 /* Start the new frame with the jpeg header */
859 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
860 pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
861 if (sd->sensor == SENSOR_PAC7302) {
862 /* The PAC7302 has the image rotated 90 degrees */
863 tmpbuf[0] = gspca_dev->width >> 8;
864 tmpbuf[1] = gspca_dev->width & 0xff;
865 tmpbuf[2] = gspca_dev->height >> 8;
866 tmpbuf[3] = gspca_dev->height & 0xff;
867 } else {
558 tmpbuf[0] = gspca_dev->height >> 8; 868 tmpbuf[0] = gspca_dev->height >> 8;
559 tmpbuf[1] = gspca_dev->height & 0xff; 869 tmpbuf[1] = gspca_dev->height & 0xff;
560 tmpbuf[2] = gspca_dev->width >> 8; 870 tmpbuf[2] = gspca_dev->width >> 8;
561 tmpbuf[3] = gspca_dev->width & 0xff; 871 tmpbuf[3] = gspca_dev->width & 0xff;
562 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
563 tmpbuf, 4);
564 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
565 (unsigned char *) &pac7311_jpeg_header[16],
566 PAC7311_JPEG_HEADER_SIZE - 16);
567
568 data += p + 7;
569 len -= p + 7;
570 ffseq = 0;
571 break;
572 } 872 }
873 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
874 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
875 pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
573 } 876 }
574
575 /* remove the 'ff ff ff xx' sequences */
576 switch (ffseq) {
577 case 3:
578 data += 1;
579 len -= 1;
580 break;
581 case 2:
582 if (data[0] == 0xff) {
583 data += 2;
584 len -= 2;
585 frame->data_end -= 2;
586 }
587 break;
588 case 1:
589 if (data[0] == 0xff
590 && data[1] == 0xff) {
591 data += 3;
592 len -= 3;
593 frame->data_end -= 1;
594 }
595 break;
596 }
597 for (i = 0; i < len - 4; i++) {
598 if (data[i] == 0xff
599 && data[i + 1] == 0xff
600 && data[i + 2] == 0xff) {
601 memmove(&data[i], &data[i + 4], len - i - 4);
602 len -= 4;
603 }
604 }
605 ffseq = 0;
606 if (data[len - 4] == 0xff) {
607 if (data[len - 3] == 0xff
608 && data[len - 2] == 0xff) {
609 len -= 4;
610 }
611 } else if (data[len - 3] == 0xff) {
612 if (data[len - 2] == 0xff
613 && data[len - 1] == 0xff)
614 ffseq = 3;
615 } else if (data[len - 2] == 0xff) {
616 if (data[len - 1] == 0xff)
617 ffseq = 2;
618 } else if (data[len - 1] == 0xff)
619 ffseq = 1;
620 sd->ffseq = ffseq;
621 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 877 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
622} 878}
623 879
624static void getbrightness(struct gspca_dev *gspca_dev)
625{
626/* sd->brightness = reg_r(gspca_dev, 0x08);
627 return sd->brightness; */
628/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */
629}
630
631
632
633static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 880static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
634{ 881{
635 struct sd *sd = (struct sd *) gspca_dev; 882 struct sd *sd = (struct sd *) gspca_dev;
636 883
637 sd->brightness = val; 884 sd->brightness = val;
638 if (gspca_dev->streaming) 885 if (gspca_dev->streaming)
639 setbrightness(gspca_dev); 886 setbrightcont(gspca_dev);
640 return 0; 887 return 0;
641} 888}
642 889
@@ -644,7 +891,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
644{ 891{
645 struct sd *sd = (struct sd *) gspca_dev; 892 struct sd *sd = (struct sd *) gspca_dev;
646 893
647 getbrightness(gspca_dev);
648 *val = sd->brightness; 894 *val = sd->brightness;
649 return 0; 895 return 0;
650} 896}
@@ -654,8 +900,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
654 struct sd *sd = (struct sd *) gspca_dev; 900 struct sd *sd = (struct sd *) gspca_dev;
655 901
656 sd->contrast = val; 902 sd->contrast = val;
657 if (gspca_dev->streaming) 903 if (gspca_dev->streaming) {
658 setcontrast(gspca_dev); 904 if (sd->sensor == SENSOR_PAC7302)
905 setbrightcont(gspca_dev);
906 else
907 setcontrast(gspca_dev);
908 }
659 return 0; 909 return 0;
660} 910}
661 911
@@ -663,7 +913,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
663{ 913{
664 struct sd *sd = (struct sd *) gspca_dev; 914 struct sd *sd = (struct sd *) gspca_dev;
665 915
666/* getcontrast(gspca_dev); */
667 *val = sd->contrast; 916 *val = sd->contrast;
668 return 0; 917 return 0;
669} 918}
@@ -682,18 +931,66 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
682{ 931{
683 struct sd *sd = (struct sd *) gspca_dev; 932 struct sd *sd = (struct sd *) gspca_dev;
684 933
685/* getcolors(gspca_dev); */
686 *val = sd->colors; 934 *val = sd->colors;
687 return 0; 935 return 0;
688} 936}
689 937
938static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
939{
940 struct sd *sd = (struct sd *) gspca_dev;
941
942 sd->gain = val;
943 if (gspca_dev->streaming)
944 setgain(gspca_dev);
945 return 0;
946}
947
948static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
949{
950 struct sd *sd = (struct sd *) gspca_dev;
951
952 *val = sd->gain;
953 return 0;
954}
955
956static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
957{
958 struct sd *sd = (struct sd *) gspca_dev;
959
960 sd->exposure = val;
961 if (gspca_dev->streaming)
962 setexposure(gspca_dev);
963 return 0;
964}
965
966static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
967{
968 struct sd *sd = (struct sd *) gspca_dev;
969
970 *val = sd->exposure;
971 return 0;
972}
973
690static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 974static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
691{ 975{
692 struct sd *sd = (struct sd *) gspca_dev; 976 struct sd *sd = (struct sd *) gspca_dev;
693 977
694 sd->autogain = val; 978 sd->autogain = val;
695 if (gspca_dev->streaming) 979 /* when switching to autogain set defaults to make sure
696 setautogain(gspca_dev); 980 we are on a valid point of the autogain gain /
981 exposure knee graph, and give this change time to
982 take effect before doing autogain. */
983 if (sd->autogain) {
984 sd->exposure = EXPOSURE_DEF;
985 sd->gain = GAIN_DEF;
986 if (gspca_dev->streaming) {
987 sd->autogain_ignore_frames =
988 PAC_AUTOGAIN_IGNORE_FRAMES;
989 setexposure(gspca_dev);
990 setgain(gspca_dev);
991 }
992 }
993
697 return 0; 994 return 0;
698} 995}
699 996
@@ -705,30 +1002,67 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
705 return 0; 1002 return 0;
706} 1003}
707 1004
1005static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1006{
1007 struct sd *sd = (struct sd *) gspca_dev;
1008
1009 sd->hflip = val;
1010 if (gspca_dev->streaming)
1011 sethvflip(gspca_dev);
1012 return 0;
1013}
1014
1015static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1016{
1017 struct sd *sd = (struct sd *) gspca_dev;
1018
1019 *val = sd->hflip;
1020 return 0;
1021}
1022
1023static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1024{
1025 struct sd *sd = (struct sd *) gspca_dev;
1026
1027 sd->vflip = val;
1028 if (gspca_dev->streaming)
1029 sethvflip(gspca_dev);
1030 return 0;
1031}
1032
1033static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1034{
1035 struct sd *sd = (struct sd *) gspca_dev;
1036
1037 *val = sd->vflip;
1038 return 0;
1039}
1040
708/* sub-driver description */ 1041/* sub-driver description */
709static struct sd_desc sd_desc = { 1042static struct sd_desc sd_desc = {
710 .name = MODULE_NAME, 1043 .name = MODULE_NAME,
711 .ctrls = sd_ctrls, 1044 .ctrls = sd_ctrls,
712 .nctrls = ARRAY_SIZE(sd_ctrls), 1045 .nctrls = ARRAY_SIZE(sd_ctrls),
713 .config = sd_config, 1046 .config = sd_config,
714 .open = sd_open, 1047 .init = sd_init,
715 .start = sd_start, 1048 .start = sd_start,
716 .stopN = sd_stopN, 1049 .stopN = sd_stopN,
717 .stop0 = sd_stop0, 1050 .stop0 = sd_stop0,
718 .close = sd_close,
719 .pkt_scan = sd_pkt_scan, 1051 .pkt_scan = sd_pkt_scan,
720 .dq_callback = do_autogain, 1052 .dq_callback = do_autogain,
721}; 1053};
722 1054
723/* -- module initialisation -- */ 1055/* -- module initialisation -- */
724static __devinitdata struct usb_device_id device_table[] = { 1056static __devinitdata struct usb_device_id device_table[] = {
725 {USB_DEVICE(0x093a, 0x2600)}, 1057 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
726 {USB_DEVICE(0x093a, 0x2601)}, 1058 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
727 {USB_DEVICE(0x093a, 0x2603)}, 1059 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
728 {USB_DEVICE(0x093a, 0x2608)}, 1060 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
729 {USB_DEVICE(0x093a, 0x260e)}, 1061 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
730 {USB_DEVICE(0x093a, 0x260f)}, 1062 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
731 {USB_DEVICE(0x093a, 0x2621)}, 1063 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1064 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1065 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
732 {} 1066 {}
733}; 1067};
734MODULE_DEVICE_TABLE(usb, device_table); 1068MODULE_DEVICE_TABLE(usb, device_table);
@@ -746,6 +1080,10 @@ static struct usb_driver sd_driver = {
746 .id_table = device_table, 1080 .id_table = device_table,
747 .probe = sd_probe, 1081 .probe = sd_probe,
748 .disconnect = gspca_disconnect, 1082 .disconnect = gspca_disconnect,
1083#ifdef CONFIG_PM
1084 .suspend = gspca_suspend,
1085 .resume = gspca_resume,
1086#endif
749}; 1087};
750 1088
751/* -- module insert / remove -- */ 1089/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
new file mode 100644
index 000000000000..34d4b1494cd5
--- /dev/null
+++ b/drivers/media/video/gspca/pac_common.h
@@ -0,0 +1,60 @@
1/*
2 * Pixart PAC207BCA / PAC73xx common functions
3 *
4 * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
7 *
8 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26/* We calculate the autogain at the end of the transfer of a frame, at this
27 moment a frame with the old settings is being transmitted, and a frame is
28 being captured with the old settings. So if we adjust the autogain we must
29 ignore atleast the 2 next frames for the new settings to come into effect
30 before doing any other adjustments */
31#define PAC_AUTOGAIN_IGNORE_FRAMES 3
32
33static const unsigned char pac_sof_marker[5] =
34 { 0xff, 0xff, 0x00, 0xff, 0x96 };
35
36static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
37 unsigned char *m, int len)
38{
39 struct sd *sd = (struct sd *) gspca_dev;
40 int i;
41
42 /* Search for the SOF marker (fixed part) in the header */
43 for (i = 0; i < len; i++) {
44 if (m[i] == pac_sof_marker[sd->sof_read]) {
45 sd->sof_read++;
46 if (sd->sof_read == sizeof(pac_sof_marker)) {
47 PDEBUG(D_FRAM,
48 "SOF found, bytes to analyze: %u."
49 " Frame starts at byte #%u",
50 len, i + 1);
51 sd->sof_read = 0;
52 return m + i + 1;
53 }
54 } else {
55 sd->sof_read = 0;
56 }
57 }
58
59 return NULL;
60}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 11210c71f66c..5dd78c6766ea 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -20,6 +20,26 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23/* Some documentation on known sonixb registers:
24
25Reg Use
260x10 high nibble red gain low nibble blue gain
270x11 low nibble green gain
280x12 hstart
290x13 vstart
300x15 hsize (hsize = register-value * 16)
310x16 vsize (vsize = register-value * 16)
320x17 bit 0 toggle compression quality (according to sn9c102 driver)
330x18 bit 7 enables compression, bit 4-5 set image down scaling:
34 00 scale 1, 01 scale 1/2, 10, scale 1/4
350x19 high-nibble is sensor clock divider, changes exposure on sensors which
36 use a clock generated by the bridge. Some sensors have their own clock.
370x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
380x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
390x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
400x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
41*/
42
23#define MODULE_NAME "sonixb" 43#define MODULE_NAME "sonixb"
24 44
25#include "gspca.h" 45#include "gspca.h"
@@ -31,10 +51,8 @@ MODULE_LICENSE("GPL");
31/* specific webcam descriptor */ 51/* specific webcam descriptor */
32struct sd { 52struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 53 struct gspca_dev gspca_dev; /* !! must be the first item */
34
35 struct sd_desc sd_desc; /* our nctrls differ dependend upon the
36 sensor, so we use a per cam copy */
37 atomic_t avg_lum; 54 atomic_t avg_lum;
55 int prev_avg_lum;
38 56
39 unsigned char gain; 57 unsigned char gain;
40 unsigned char exposure; 58 unsigned char exposure;
@@ -44,8 +62,12 @@ struct sd {
44 unsigned char frames_to_drop; 62 unsigned char frames_to_drop;
45 unsigned char freq; /* light freq filter setting */ 63 unsigned char freq; /* light freq filter setting */
46 64
47 unsigned char fr_h_sz; /* size of frame header */ 65 __u8 bridge; /* Type of bridge */
48 char sensor; /* Type of image sensor chip */ 66#define BRIDGE_101 0
67#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
68#define BRIDGE_103 1
69
70 __u8 sensor; /* Type of image sensor chip */
49#define SENSOR_HV7131R 0 71#define SENSOR_HV7131R 0
50#define SENSOR_OV6650 1 72#define SENSOR_OV6650 1
51#define SENSOR_OV7630 2 73#define SENSOR_OV7630 2
@@ -53,16 +75,35 @@ struct sd {
53#define SENSOR_PAS202 4 75#define SENSOR_PAS202 4
54#define SENSOR_TAS5110 5 76#define SENSOR_TAS5110 5
55#define SENSOR_TAS5130CXX 6 77#define SENSOR_TAS5130CXX 6
56 char sensor_has_gain;
57 __u8 sensor_addr;
58 __u8 reg11; 78 __u8 reg11;
59}; 79};
60 80
61/* flags used in the device id table */ 81typedef const __u8 sensor_init_t[8];
82
83struct sensor_data {
84 const __u8 *bridge_init[2];
85 int bridge_init_size[2];
86 sensor_init_t *sensor_init;
87 int sensor_init_size;
88 sensor_init_t *sensor_bridge_init[2];
89 int sensor_bridge_init_size[2];
90 int flags;
91 unsigned ctrl_dis;
92 __u8 sensor_addr;
93};
94
95/* sensor_data flags */
62#define F_GAIN 0x01 /* has gain */ 96#define F_GAIN 0x01 /* has gain */
63#define F_AUTO 0x02 /* has autogain */ 97#define F_SIF 0x02 /* sif or vga */
64#define F_SIF 0x04 /* sif or vga */ 98
65#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */ 99/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100#define MODE_RAW 0x10 /* raw bayer mode */
101#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
102
103/* ctrl_dis helper macros */
104#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
105#define NO_FREQ (1 << FREQ_IDX)
106#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
66 107
67#define COMP2 0x8f 108#define COMP2 0x8f
68#define COMP 0xc7 /* 0x87 //0x07 */ 109#define COMP 0xc7 /* 0x87 //0x07 */
@@ -73,6 +114,18 @@ struct sd {
73 114
74#define SYS_CLK 0x04 115#define SYS_CLK 0x04
75 116
117#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
118 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
119{ \
120 .bridge_init = { bridge_1, bridge_3 }, \
121 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
122 .sensor_init = sensor, \
123 .sensor_init_size = sizeof(sensor), \
124 .sensor_bridge_init = { sensor_1, sensor_3,}, \
125 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
126 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
127}
128
76/* We calculate the autogain at the end of the transfer of a frame, at this 129/* We calculate the autogain at the end of the transfer of a frame, at this
77 moment a frame with the old settings is being transmitted, and a frame is 130 moment a frame with the old settings is being transmitted, and a frame is
78 being captured with the old settings. So if we adjust the autogain we must 131 being captured with the old settings. So if we adjust the autogain we must
@@ -95,6 +148,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 148static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
96 149
97static struct ctrl sd_ctrls[] = { 150static struct ctrl sd_ctrls[] = {
151#define BRIGHTNESS_IDX 0
98 { 152 {
99 { 153 {
100 .id = V4L2_CID_BRIGHTNESS, 154 .id = V4L2_CID_BRIGHTNESS,
@@ -109,6 +163,7 @@ static struct ctrl sd_ctrls[] = {
109 .set = sd_setbrightness, 163 .set = sd_setbrightness,
110 .get = sd_getbrightness, 164 .get = sd_getbrightness,
111 }, 165 },
166#define GAIN_IDX 1
112 { 167 {
113 { 168 {
114 .id = V4L2_CID_GAIN, 169 .id = V4L2_CID_GAIN,
@@ -124,6 +179,7 @@ static struct ctrl sd_ctrls[] = {
124 .set = sd_setgain, 179 .set = sd_setgain,
125 .get = sd_getgain, 180 .get = sd_getgain,
126 }, 181 },
182#define EXPOSURE_IDX 2
127 { 183 {
128 { 184 {
129 .id = V4L2_CID_EXPOSURE, 185 .id = V4L2_CID_EXPOSURE,
@@ -140,6 +196,7 @@ static struct ctrl sd_ctrls[] = {
140 .set = sd_setexposure, 196 .set = sd_setexposure,
141 .get = sd_getexposure, 197 .get = sd_getexposure,
142 }, 198 },
199#define AUTOGAIN_IDX 3
143 { 200 {
144 { 201 {
145 .id = V4L2_CID_AUTOGAIN, 202 .id = V4L2_CID_AUTOGAIN,
@@ -155,6 +212,7 @@ static struct ctrl sd_ctrls[] = {
155 .set = sd_setautogain, 212 .set = sd_setautogain,
156 .get = sd_getautogain, 213 .get = sd_getautogain,
157 }, 214 },
215#define FREQ_IDX 4
158 { 216 {
159 { 217 {
160 .id = V4L2_CID_POWER_LINE_FREQUENCY, 218 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -172,31 +230,56 @@ static struct ctrl sd_ctrls[] = {
172}; 230};
173 231
174static struct v4l2_pix_format vga_mode[] = { 232static struct v4l2_pix_format vga_mode[] = {
233 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
234 .bytesperline = 160,
235 .sizeimage = 160 * 120 * 5 / 4,
236 .colorspace = V4L2_COLORSPACE_SRGB,
237 .priv = 2 | MODE_RAW},
175 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 238 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
176 .bytesperline = 160, 239 .bytesperline = 160,
177 .sizeimage = 160 * 120, 240 .sizeimage = 160 * 120 * 5 / 4,
178 .colorspace = V4L2_COLORSPACE_SRGB, 241 .colorspace = V4L2_COLORSPACE_SRGB,
179 .priv = 2}, 242 .priv = 2},
180 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 243 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
181 .bytesperline = 320, 244 .bytesperline = 320,
182 .sizeimage = 320 * 240, 245 .sizeimage = 320 * 240 * 5 / 4,
183 .colorspace = V4L2_COLORSPACE_SRGB, 246 .colorspace = V4L2_COLORSPACE_SRGB,
184 .priv = 1}, 247 .priv = 1},
185 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 248 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
186 .bytesperline = 640, 249 .bytesperline = 640,
187 .sizeimage = 640 * 480, 250 .sizeimage = 640 * 480 * 5 / 4,
188 .colorspace = V4L2_COLORSPACE_SRGB, 251 .colorspace = V4L2_COLORSPACE_SRGB,
189 .priv = 0}, 252 .priv = 0},
190}; 253};
191static struct v4l2_pix_format sif_mode[] = { 254static struct v4l2_pix_format sif_mode[] = {
255 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
256 .bytesperline = 160,
257 .sizeimage = 160 * 120,
258 .colorspace = V4L2_COLORSPACE_SRGB,
259 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
260 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
261 .bytesperline = 160,
262 .sizeimage = 160 * 120 * 5 / 4,
263 .colorspace = V4L2_COLORSPACE_SRGB,
264 .priv = 1 | MODE_REDUCED_SIF},
265 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
266 .bytesperline = 176,
267 .sizeimage = 176 * 144 * 5 / 4,
268 .colorspace = V4L2_COLORSPACE_SRGB,
269 .priv = 1 | MODE_RAW},
192 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 270 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
193 .bytesperline = 176, 271 .bytesperline = 176,
194 .sizeimage = 176 * 144, 272 .sizeimage = 176 * 144 * 5 / 4,
195 .colorspace = V4L2_COLORSPACE_SRGB, 273 .colorspace = V4L2_COLORSPACE_SRGB,
196 .priv = 1}, 274 .priv = 1},
275 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
276 .bytesperline = 320,
277 .sizeimage = 320 * 240 * 5 / 4,
278 .colorspace = V4L2_COLORSPACE_SRGB,
279 .priv = 0 | MODE_REDUCED_SIF},
197 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 280 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
198 .bytesperline = 352, 281 .bytesperline = 352,
199 .sizeimage = 352 * 288, 282 .sizeimage = 352 * 288 * 5 / 4,
200 .colorspace = V4L2_COLORSPACE_SRGB, 283 .colorspace = V4L2_COLORSPACE_SRGB,
201 .priv = 0}, 284 .priv = 0},
202}; 285};
@@ -204,7 +287,7 @@ static struct v4l2_pix_format sif_mode[] = {
204static const __u8 initHv7131[] = { 287static const __u8 initHv7131[] = {
205 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 288 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
206 0x00, 0x00, 289 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ 290 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
208 0x28, 0x1e, 0x60, 0x8a, 0x20, 291 0x28, 0x1e, 0x60, 0x8a, 0x20,
209 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c 292 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
210}; 293};
@@ -218,8 +301,8 @@ static const __u8 hv7131_sensor_init[][8] = {
218static const __u8 initOv6650[] = { 301static const __u8 initOv6650[] = {
219 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 302 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
220 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 303 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, 304 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
222 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 305 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
223}; 306};
224static const __u8 ov6650_sensor_init[][8] = 307static const __u8 ov6650_sensor_init[][8] =
225{ 308{
@@ -257,15 +340,15 @@ static const __u8 ov6650_sensor_init[][8] =
257static const __u8 initOv7630[] = { 340static const __u8 initOv7630[] = {
258 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ 341 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
259 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ 342 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
260 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 343 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
261 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 344 0x28, 0x1e, /* H & V sizes r15 .. r16 */
262 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ 345 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
263 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ 346 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
264}; 347};
265static const __u8 initOv7630_3[] = { 348static const __u8 initOv7630_3[] = {
266 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 349 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
267 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ 350 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
268 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ 351 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
269 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 352 0x28, 0x1e, /* H & V sizes r15 .. r16 */
270 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 353 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
271 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ 354 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
@@ -294,47 +377,65 @@ static const __u8 ov7630_sensor_init[][8] = {
294 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, 377 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
295}; 378};
296 379
380static const __u8 ov7630_sensor_init_3[][8] = {
381 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
382};
383
297static const __u8 initPas106[] = { 384static const __u8 initPas106[] = {
298 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 385 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
299 0x00, 0x00, 386 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 387 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
301 0x16, 0x12, 0x28, COMP1, MCK_INIT1, 388 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
302 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 389 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
303}; 390};
304/* compression 0x86 mckinit1 0x2b */ 391/* compression 0x86 mckinit1 0x2b */
305static const __u8 pas106_data[][2] = { 392static const __u8 pas106_sensor_init[][8] = {
306 {0x02, 0x04}, /* Pixel Clock Divider 6 */ 393 /* Pixel Clock Divider 6 */
307 {0x03, 0x13}, /* Frame Time MSB */ 394 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
308/* {0x03, 0x12}, * Frame Time MSB */ 395 /* Frame Time MSB (also seen as 0x12) */
309 {0x04, 0x06}, /* Frame Time LSB */ 396 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
310/* {0x04, 0x05}, * Frame Time LSB */ 397 /* Frame Time LSB (also seen as 0x05) */
311 {0x05, 0x65}, /* Shutter Time Line Offset */ 398 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
312/* {0x05, 0x6d}, * Shutter Time Line Offset */ 399 /* Shutter Time Line Offset (also seen as 0x6d) */
313/* {0x06, 0xb1}, * Shutter Time Pixel Offset */ 400 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
314 {0x06, 0xcd}, /* Shutter Time Pixel Offset */ 401 /* Shutter Time Pixel Offset (also seen as 0xb1) */
315 {0x07, 0xc1}, /* Black Level Subtract Sign */ 402 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
316/* {0x07, 0x00}, * Black Level Subtract Sign */ 403 /* Black Level Subtract Sign (also seen 0x00) */
317 {0x08, 0x06}, /* Black Level Subtract Level */ 404 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
318 {0x08, 0x06}, /* Black Level Subtract Level */ 405 /* Black Level Subtract Level (also seen 0x01) */
319/* {0x08, 0x01}, * Black Level Subtract Level */ 406 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
320 {0x09, 0x05}, /* Color Gain B Pixel 5 a */ 407 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
321 {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ 408 /* Color Gain B Pixel 5 a */
322 {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ 409 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
323 {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ 410 /* Color Gain G1 Pixel 1 5 */
324 {0x0d, 0x00}, /* Color GainH Pixel */ 411 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
325 {0x0e, 0x0e}, /* Global Gain */ 412 /* Color Gain G2 Pixel 1 0 5 */
326 {0x0f, 0x00}, /* Contrast */ 413 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
327 {0x10, 0x06}, /* H&V synchro polarity */ 414 /* Color Gain R Pixel 3 1 */
328 {0x11, 0x06}, /* ?default */ 415 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
329 {0x12, 0x06}, /* DAC scale */ 416 /* Color GainH Pixel */
330 {0x14, 0x02}, /* ?default */ 417 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
331 {0x13, 0x01}, /* Validate Settings */ 418 /* Global Gain */
419 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
420 /* Contrast */
421 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
422 /* H&V synchro polarity */
423 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
424 /* ?default */
425 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
426 /* DAC scale */
427 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
428 /* ?default */
429 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
430 /* Validate Settings */
431 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
332}; 432};
433
333static const __u8 initPas202[] = { 434static const __u8 initPas202[] = {
334 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 435 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
335 0x00, 0x00, 436 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ 437 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
337 0x28, 0x1e, 0x28, 0x89, 0x30, 438 0x28, 0x1e, 0x28, 0x89, 0x20,
338 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c 439 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
339}; 440};
340static const __u8 pas202_sensor_init[][8] = { 441static const __u8 pas202_sensor_init[][8] = {
@@ -364,7 +465,7 @@ static const __u8 pas202_sensor_init[][8] = {
364static const __u8 initTas5110[] = { 465static const __u8 initTas5110[] = {
365 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 466 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
366 0x00, 0x00, 467 0x00, 0x00,
367 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ 468 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
368 0x16, 0x12, 0x60, 0x86, 0x2b, 469 0x16, 0x12, 0x60, 0x86, 0x2b,
369 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 470 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
370}; 471};
@@ -377,7 +478,7 @@ static const __u8 tas5110_sensor_init[][8] = {
377static const __u8 initTas5130[] = { 478static const __u8 initTas5130[] = {
378 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 479 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
379 0x00, 0x00, 480 0x00, 0x00,
380 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, 481 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
381 0x28, 0x1e, 0x60, COMP, MCK_INIT, 482 0x28, 0x1e, 0x60, COMP, MCK_INIT,
382 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 483 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
383}; 484};
@@ -389,6 +490,21 @@ static const __u8 tas5130_sensor_init[][8] = {
389 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, 490 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
390}; 491};
391 492
493struct sensor_data sensor_data[] = {
494SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
495SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
496SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
497 F_GAIN, 0, 0x21),
498SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
499 0),
500SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
501 NO_EXPO|NO_FREQ, 0),
502SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
503 NO_BRIGHTNESS|NO_FREQ, 0),
504SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
505 0),
506};
507
392/* get one byte in gspca_dev->usb_buf */ 508/* get one byte in gspca_dev->usb_buf */
393static void reg_r(struct gspca_dev *gspca_dev, 509static void reg_r(struct gspca_dev *gspca_dev,
394 __u16 value) 510 __u16 value)
@@ -409,7 +525,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
409 int len) 525 int len)
410{ 526{
411#ifdef GSPCA_DEBUG 527#ifdef GSPCA_DEBUG
412 if (len > sizeof gspca_dev->usb_buf) { 528 if (len > USB_BUF_SZ) {
413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); 529 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
414 return; 530 return;
415 } 531 }
@@ -425,26 +541,6 @@ static void reg_w(struct gspca_dev *gspca_dev,
425 500); 541 500);
426} 542}
427 543
428static void reg_w_big(struct gspca_dev *gspca_dev,
429 __u16 value,
430 const __u8 *buffer,
431 int len)
432{
433 __u8 *tmpbuf;
434
435 tmpbuf = kmalloc(len, GFP_KERNEL);
436 memcpy(tmpbuf, buffer, len);
437 usb_control_msg(gspca_dev->dev,
438 usb_sndctrlpipe(gspca_dev->dev, 0),
439 0x08, /* request */
440 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
441 value,
442 0, /* index */
443 tmpbuf, len,
444 500);
445 kfree(tmpbuf);
446}
447
448static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) 544static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
449{ 545{
450 int retry = 60; 546 int retry = 60;
@@ -487,7 +583,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
487 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; 583 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
488 584
489 /* change reg 0x06 */ 585 /* change reg 0x06 */
490 i2cOV[1] = sd->sensor_addr; 586 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
491 i2cOV[3] = sd->brightness; 587 i2cOV[3] = sd->brightness;
492 if (i2c_w(gspca_dev, i2cOV) < 0) 588 if (i2c_w(gspca_dev, i2cOV) < 0)
493 goto err; 589 goto err;
@@ -545,9 +641,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
545 goto err; 641 goto err;
546 break; 642 break;
547 } 643 }
548 case SENSOR_TAS5110:
549 /* FIXME figure out howto control brightness on TAS5110 */
550 break;
551 } 644 }
552 return; 645 return;
553err: 646err:
@@ -577,7 +670,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
577 case SENSOR_OV7630: { 670 case SENSOR_OV7630: {
578 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 671 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
579 672
580 i2c[1] = sd->sensor_addr; 673 i2c[1] = sensor_data[sd->sensor].sensor_addr;
581 i2c[3] = gain >> 2; 674 i2c[3] = gain >> 2;
582 if (i2c_w(gspca_dev, i2c) < 0) 675 if (i2c_w(gspca_dev, i2c) < 0)
583 goto err; 676 goto err;
@@ -604,7 +697,7 @@ static void setgain(struct gspca_dev *gspca_dev)
604 rgb_value = gain; 697 rgb_value = gain;
605 reg_w(gspca_dev, 0x11, &rgb_value, 1); 698 reg_w(gspca_dev, 0x11, &rgb_value, 1);
606 699
607 if (sd->sensor_has_gain) 700 if (sensor_data[sd->sensor].flags & F_GAIN)
608 setsensorgain(gspca_dev); 701 setsensorgain(gspca_dev);
609} 702}
610 703
@@ -665,6 +758,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
665 else if (reg11 > 16) 758 else if (reg11 > 16)
666 reg11 = 16; 759 reg11 = 16;
667 760
761 /* In 640x480, if the reg11 has less than 3, the image is
762 unstable (not enough bandwidth). */
763 if (gspca_dev->width == 640 && reg11 < 3)
764 reg11 = 3;
765
668 /* frame exposure time in ms = 1000 * reg11 / 30 -> 766 /* frame exposure time in ms = 1000 * reg11 / 30 ->
669 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ 767 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
670 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); 768 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
@@ -678,13 +776,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
678 else if (reg10 > reg10_max) 776 else if (reg10 > reg10_max)
679 reg10 = reg10_max; 777 reg10 = reg10_max;
680 778
681 /* In 640x480, if the reg11 has less than 3, the image is
682 unstable (not enough bandwidth). */
683 if (gspca_dev->width == 640 && reg11 < 3)
684 reg11 = 3;
685
686 /* Write reg 10 and reg11 low nibble */ 779 /* Write reg 10 and reg11 low nibble */
687 i2c[1] = sd->sensor_addr; 780 i2c[1] = sensor_data[sd->sensor].sensor_addr;
688 i2c[3] = reg10; 781 i2c[3] = reg10;
689 i2c[4] |= reg11 - 1; 782 i2c[4] |= reg11 - 1;
690 783
@@ -724,7 +817,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
724 ? 0x4f : 0x8a; 817 ? 0x4f : 0x8a;
725 break; 818 break;
726 } 819 }
727 i2c[1] = sd->sensor_addr; 820 i2c[1] = sensor_data[sd->sensor].sensor_addr;
728 if (i2c_w(gspca_dev, i2c) < 0) 821 if (i2c_w(gspca_dev, i2c) < 0)
729 PDEBUG(D_ERR, "i2c error setfreq"); 822 PDEBUG(D_ERR, "i2c error setfreq");
730 break; 823 break;
@@ -757,30 +850,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
757{ 850{
758 struct sd *sd = (struct sd *) gspca_dev; 851 struct sd *sd = (struct sd *) gspca_dev;
759 struct cam *cam; 852 struct cam *cam;
760 int sif = 0;
761 853
762 /* nctrls depends upon the sensor, so we use a per cam copy */ 854 reg_r(gspca_dev, 0x00);
763 memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); 855 if (gspca_dev->usb_buf[0] != 0x10)
764 gspca_dev->sd_desc = &sd->sd_desc; 856 return -ENODEV;
765 857
766 /* copy the webcam info from the device id */ 858 /* copy the webcam info from the device id */
767 sd->sensor = (id->driver_info >> 24) & 0xff; 859 sd->sensor = id->driver_info >> 8;
768 if (id->driver_info & (F_GAIN << 16)) 860 sd->bridge = id->driver_info & 0xff;
769 sd->sensor_has_gain = 1; 861 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
770 if (id->driver_info & (F_AUTO << 16))
771 sd->sd_desc.dq_callback = do_autogain;
772 if (id->driver_info & (F_SIF << 16))
773 sif = 1;
774 if (id->driver_info & (F_H18 << 16))
775 sd->fr_h_sz = 18; /* size of frame header */
776 else
777 sd->fr_h_sz = 12;
778 sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
779 sd->sensor_addr = id->driver_info & 0xff;
780 862
781 cam = &gspca_dev->cam; 863 cam = &gspca_dev->cam;
782 cam->epaddr = 0x01; 864 cam->epaddr = 0x01;
783 if (!sif) { 865 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
784 cam->cam_mode = vga_mode; 866 cam->cam_mode = vga_mode;
785 cam->nmodes = ARRAY_SIZE(vga_mode); 867 cam->nmodes = ARRAY_SIZE(vga_mode);
786 } else { 868 } else {
@@ -790,157 +872,98 @@ static int sd_config(struct gspca_dev *gspca_dev,
790 sd->brightness = BRIGHTNESS_DEF; 872 sd->brightness = BRIGHTNESS_DEF;
791 sd->gain = GAIN_DEF; 873 sd->gain = GAIN_DEF;
792 sd->exposure = EXPOSURE_DEF; 874 sd->exposure = EXPOSURE_DEF;
793 sd->autogain = AUTOGAIN_DEF; 875 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
876 sd->autogain = 0; /* Disable do_autogain callback */
877 else
878 sd->autogain = AUTOGAIN_DEF;
794 sd->freq = FREQ_DEF; 879 sd->freq = FREQ_DEF;
795 880
796 return 0; 881 return 0;
797} 882}
798 883
799/* this function is called at open time */ 884/* this function is called at probe and resume time */
800static int sd_open(struct gspca_dev *gspca_dev) 885static int sd_init(struct gspca_dev *gspca_dev)
801{ 886{
802 reg_r(gspca_dev, 0x00); 887 const __u8 stop = 0x09; /* Disable stream turn of LED */
803 if (gspca_dev->usb_buf[0] != 0x10)
804 return -ENODEV;
805 return 0;
806}
807 888
808static void pas106_i2cinit(struct gspca_dev *gspca_dev) 889 reg_w(gspca_dev, 0x01, &stop, 1);
809{ 890
810 int i; 891 return 0;
811 const __u8 *data;
812 __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
813
814 i = ARRAY_SIZE(pas106_data);
815 data = pas106_data[0];
816 while (--i >= 0) {
817 memcpy(&i2c1[2], data, 2);
818 /* copy 2 bytes from the template */
819 if (i2c_w(gspca_dev, i2c1) < 0)
820 PDEBUG(D_ERR, "i2c error pas106");
821 data += 2;
822 }
823} 892}
824 893
825/* -- start the camera -- */ 894/* -- start the camera -- */
826static void sd_start(struct gspca_dev *gspca_dev) 895static void sd_start(struct gspca_dev *gspca_dev)
827{ 896{
828 struct sd *sd = (struct sd *) gspca_dev; 897 struct sd *sd = (struct sd *) gspca_dev;
829 int mode, l = 0x1f; 898 struct cam *cam = &gspca_dev->cam;
899 int mode, l;
830 const __u8 *sn9c10x; 900 const __u8 *sn9c10x;
831 __u8 reg17_19[3]; 901 __u8 reg12_19[8];
832 902
833 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 903 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
904 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
905 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
906 memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
907 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
908 /* Special cases where reg 17 and or 19 value depends on mode */
834 switch (sd->sensor) { 909 switch (sd->sensor) {
835 case SENSOR_HV7131R:
836 sn9c10x = initHv7131;
837 reg17_19[0] = 0x60;
838 reg17_19[1] = (mode << 4) | 0x8a;
839 reg17_19[2] = 0x20;
840 break;
841 case SENSOR_OV6650:
842 sn9c10x = initOv6650;
843 reg17_19[0] = 0x68;
844 reg17_19[1] = (mode << 4) | 0x8b;
845 reg17_19[2] = 0x20;
846 break;
847 case SENSOR_OV7630:
848 if (sd->fr_h_sz == 18) { /* SN9C103 */
849 sn9c10x = initOv7630_3;
850 l = sizeof initOv7630_3;
851 } else
852 sn9c10x = initOv7630;
853 reg17_19[0] = 0x68;
854 reg17_19[1] = (mode << 4) | COMP2;
855 reg17_19[2] = MCK_INIT1;
856 break;
857 case SENSOR_PAS106:
858 sn9c10x = initPas106;
859 reg17_19[0] = 0x24; /* 0x28 */
860 reg17_19[1] = (mode << 4) | COMP1;
861 reg17_19[2] = MCK_INIT1;
862 break;
863 case SENSOR_PAS202: 910 case SENSOR_PAS202:
864 sn9c10x = initPas202; 911 reg12_19[5] = mode ? 0x24 : 0x20;
865 reg17_19[0] = mode ? 0x24 : 0x20;
866 reg17_19[1] = (mode << 4) | 0x89;
867 reg17_19[2] = 0x20;
868 break; 912 break;
869 case SENSOR_TAS5110: 913 case SENSOR_TAS5130CXX:
870 sn9c10x = initTas5110; 914 /* probably not mode specific at all most likely the upper
871 reg17_19[0] = 0x60; 915 nibble of 0x19 is exposure (clock divider) just as with
872 reg17_19[1] = (mode << 4) | 0x86; 916 the tas5110, we need someone to test this. */
873 reg17_19[2] = 0x2b; /* 0xf3; */ 917 reg12_19[7] = mode ? 0x23 : 0x43;
874 break;
875 default:
876/* case SENSOR_TAS5130CXX: */
877 sn9c10x = initTas5130;
878 reg17_19[0] = 0x60;
879 reg17_19[1] = (mode << 4) | COMP;
880 reg17_19[2] = mode ? 0x23 : 0x43;
881 break; 918 break;
882 } 919 }
920 /* Disable compression when the raw bayer format has been selected */
921 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
922 reg12_19[6] &= ~0x80;
923
924 /* Vga mode emulation on SIF sensor? */
925 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
926 reg12_19[0] += 16; /* 0x12: hstart adjust */
927 reg12_19[1] += 24; /* 0x13: vstart adjust */
928 reg12_19[3] = 320 / 16; /* 0x15: hsize */
929 reg12_19[4] = 240 / 16; /* 0x16: vsize */
930 }
883 931
884 /* reg 0x01 bit 2 video transfert on */ 932 /* reg 0x01 bit 2 video transfert on */
885 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); 933 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
886 /* reg 0x17 SensorClk enable inv Clk 0x60 */ 934 /* reg 0x17 SensorClk enable inv Clk 0x60 */
887 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); 935 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
888 /* Set the registers from the template */ 936 /* Set the registers from the template */
889 reg_w_big(gspca_dev, 0x01, sn9c10x, l); 937 reg_w(gspca_dev, 0x01, sn9c10x, l);
890 switch (sd->sensor) { 938
891 case SENSOR_HV7131R: 939 /* Init the sensor */
892 i2c_w_vector(gspca_dev, hv7131_sensor_init, 940 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
893 sizeof hv7131_sensor_init); 941 sensor_data[sd->sensor].sensor_init_size);
894 break; 942 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
895 case SENSOR_OV6650: 943 i2c_w_vector(gspca_dev,
896 i2c_w_vector(gspca_dev, ov6650_sensor_init, 944 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
897 sizeof ov6650_sensor_init); 945 sensor_data[sd->sensor].sensor_bridge_init_size[
898 break; 946 sd->bridge]);
899 case SENSOR_OV7630: 947
900 i2c_w_vector(gspca_dev, ov7630_sensor_init,
901 sizeof ov7630_sensor_init);
902 if (sd->fr_h_sz == 18) { /* SN9C103 */
903 const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
904 0x00, 0x00, 0x10 };
905 i2c_w(gspca_dev, i2c);
906 }
907 break;
908 case SENSOR_PAS106:
909 pas106_i2cinit(gspca_dev);
910 break;
911 case SENSOR_PAS202:
912 i2c_w_vector(gspca_dev, pas202_sensor_init,
913 sizeof pas202_sensor_init);
914 break;
915 case SENSOR_TAS5110:
916 i2c_w_vector(gspca_dev, tas5110_sensor_init,
917 sizeof tas5110_sensor_init);
918 break;
919 default:
920/* case SENSOR_TAS5130CXX: */
921 i2c_w_vector(gspca_dev, tas5130_sensor_init,
922 sizeof tas5130_sensor_init);
923 break;
924 }
925 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 948 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
926 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); 949 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
927 /* compression register */ 950 /* compression register */
928 reg_w(gspca_dev, 0x18, &reg17_19[1], 1); 951 reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
929 /* H_start */ 952 /* H_start */
930 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); 953 reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
931 /* V_START */ 954 /* V_START */
932 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); 955 reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
933 /* reset 0x17 SensorClk enable inv Clk 0x60 */ 956 /* reset 0x17 SensorClk enable inv Clk 0x60 */
934 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ 957 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
935 reg_w(gspca_dev, 0x17, &reg17_19[0], 1); 958 reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
936 /*MCKSIZE ->3 */ /*fixme: not ov7630*/ 959 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
937 reg_w(gspca_dev, 0x19, &reg17_19[2], 1); 960 reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
938 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ 961 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
939 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); 962 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
940 /* Enable video transfert */ 963 /* Enable video transfert */
941 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); 964 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
942 /* Compression */ 965 /* Compression */
943 reg_w(gspca_dev, 0x18, &reg17_19[1], 2); 966 reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
944 msleep(20); 967 msleep(20);
945 968
946 sd->reg11 = -1; 969 sd->reg11 = -1;
@@ -957,18 +980,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
957 980
958static void sd_stopN(struct gspca_dev *gspca_dev) 981static void sd_stopN(struct gspca_dev *gspca_dev)
959{ 982{
960 __u8 ByteSend; 983 sd_init(gspca_dev);
961
962 ByteSend = 0x09; /* 0X00 */
963 reg_w(gspca_dev, 0x01, &ByteSend, 1);
964}
965
966static void sd_stop0(struct gspca_dev *gspca_dev)
967{
968}
969
970static void sd_close(struct gspca_dev *gspca_dev)
971{
972} 984}
973 985
974static void sd_pkt_scan(struct gspca_dev *gspca_dev, 986static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -978,6 +990,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
978{ 990{
979 int i; 991 int i;
980 struct sd *sd = (struct sd *) gspca_dev; 992 struct sd *sd = (struct sd *) gspca_dev;
993 struct cam *cam = &gspca_dev->cam;
981 994
982 /* frames start with: 995 /* frames start with:
983 * ff ff 00 c4 c4 96 synchro 996 * ff ff 00 c4 c4 96 synchro
@@ -998,20 +1011,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
998 && data[5 + i] == 0x96) { /* start of frame */ 1011 && data[5 + i] == 0x96) { /* start of frame */
999 int lum = -1; 1012 int lum = -1;
1000 int pkt_type = LAST_PACKET; 1013 int pkt_type = LAST_PACKET;
1014 int fr_h_sz = (sd->bridge == BRIDGE_103) ?
1015 18 : 12;
1001 1016
1002 if (len - i < sd->fr_h_sz) { 1017 if (len - i < fr_h_sz) {
1003 PDEBUG(D_STREAM, "packet too short to" 1018 PDEBUG(D_STREAM, "packet too short to"
1004 " get avg brightness"); 1019 " get avg brightness");
1005 } else if (sd->fr_h_sz == 12) { 1020 } else if (sd->bridge == BRIDGE_103) {
1006 lum = data[i + 8] + (data[i + 9] << 8);
1007 } else {
1008 lum = data[i + 9] + 1021 lum = data[i + 9] +
1009 (data[i + 10] << 8); 1022 (data[i + 10] << 8);
1023 } else {
1024 lum = data[i + 8] + (data[i + 9] << 8);
1010 } 1025 }
1011 if (lum == 0) { 1026 /* When exposure changes midway a frame we
1027 get a lum of 0 in this case drop 2 frames
1028 as the frames directly after an exposure
1029 change have an unstable image. Sometimes lum
1030 *really* is 0 (cam used in low light with
1031 low exposure setting), so do not drop frames
1032 if the previous lum was 0 too. */
1033 if (lum == 0 && sd->prev_avg_lum != 0) {
1012 lum = -1; 1034 lum = -1;
1013 sd->frames_to_drop = 2; 1035 sd->frames_to_drop = 2;
1014 } 1036 sd->prev_avg_lum = 0;
1037 } else
1038 sd->prev_avg_lum = lum;
1015 atomic_set(&sd->avg_lum, lum); 1039 atomic_set(&sd->avg_lum, lum);
1016 1040
1017 if (sd->frames_to_drop) { 1041 if (sd->frames_to_drop) {
@@ -1021,14 +1045,25 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1021 1045
1022 frame = gspca_frame_add(gspca_dev, pkt_type, 1046 frame = gspca_frame_add(gspca_dev, pkt_type,
1023 frame, data, 0); 1047 frame, data, 0);
1024 data += i + sd->fr_h_sz; 1048 data += i + fr_h_sz;
1025 len -= i + sd->fr_h_sz; 1049 len -= i + fr_h_sz;
1026 gspca_frame_add(gspca_dev, FIRST_PACKET, 1050 gspca_frame_add(gspca_dev, FIRST_PACKET,
1027 frame, data, len); 1051 frame, data, len);
1028 return; 1052 return;
1029 } 1053 }
1030 } 1054 }
1031 } 1055 }
1056
1057 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1058 /* In raw mode we sometimes get some garbage after the frame
1059 ignore this */
1060 int used = frame->data_end - frame->data;
1061 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1062
1063 if (used + len > size)
1064 len = size - used;
1065 }
1066
1032 gspca_frame_add(gspca_dev, INTER_PACKET, 1067 gspca_frame_add(gspca_dev, INTER_PACKET,
1033 frame, data, len); 1068 frame, data, len);
1034} 1069}
@@ -1162,58 +1197,45 @@ static const struct sd_desc sd_desc = {
1162 .ctrls = sd_ctrls, 1197 .ctrls = sd_ctrls,
1163 .nctrls = ARRAY_SIZE(sd_ctrls), 1198 .nctrls = ARRAY_SIZE(sd_ctrls),
1164 .config = sd_config, 1199 .config = sd_config,
1165 .open = sd_open, 1200 .init = sd_init,
1166 .start = sd_start, 1201 .start = sd_start,
1167 .stopN = sd_stopN, 1202 .stopN = sd_stopN,
1168 .stop0 = sd_stop0,
1169 .close = sd_close,
1170 .pkt_scan = sd_pkt_scan, 1203 .pkt_scan = sd_pkt_scan,
1171 .querymenu = sd_querymenu, 1204 .querymenu = sd_querymenu,
1205 .dq_callback = do_autogain,
1172}; 1206};
1173 1207
1174/* -- module initialisation -- */ 1208/* -- module initialisation -- */
1175#define SFCI(sensor, flags, nctrls, i2c_addr) \ 1209#define SB(sensor, bridge) \
1176 .driver_info = (SENSOR_ ## sensor << 24) \ 1210 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1177 | ((flags) << 16) \ 1211
1178 | ((nctrls) << 8) \ 1212
1179 | (i2c_addr)
1180static __devinitdata struct usb_device_id device_table[] = { 1213static __devinitdata struct usb_device_id device_table[] = {
1181#ifndef CONFIG_USB_SN9C102 1214 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
1182 {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ 1215 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
1183 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, 1216#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1184 {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ 1217 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
1185 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, 1218 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1186 {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ 1219 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1187 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1188 {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
1189 SFCI(PAS106, F_SIF, 2, 0)},
1190 {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
1191 SFCI(PAS106, F_SIF, 2, 0)},
1192#endif 1220#endif
1193 {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ 1221 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1194 SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, 1222#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1195#ifndef CONFIG_USB_SN9C102 1223 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1196 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ 1224 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1197 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, 1225 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1198 {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ 1226 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1199 SFCI(TAS5130CXX, 0, 2, 0)}, 1227 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1200 {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ 1228 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1201 SFCI(TAS5130CXX, 0, 2, 0)},
1202 {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
1203 SFCI(PAS202, 0, 2, 0)},
1204 {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
1205 SFCI(PAS106, F_SIF, 2, 0)},
1206 {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
1207 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1208 {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
1209 SFCI(HV7131R, 0, 2, 0)},
1210 {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
1211 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1212 {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
1213 SFCI(PAS202, F_H18, 2, 0)},
1214 {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
1215 SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
1216#endif 1229#endif
1230 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1231#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1232 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1233#endif
1234 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1235#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1236 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1237#endif
1238 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1217 {} 1239 {}
1218}; 1240};
1219MODULE_DEVICE_TABLE(usb, device_table); 1241MODULE_DEVICE_TABLE(usb, device_table);
@@ -1231,6 +1253,10 @@ static struct usb_driver sd_driver = {
1231 .id_table = device_table, 1253 .id_table = device_table,
1232 .probe = sd_probe, 1254 .probe = sd_probe,
1233 .disconnect = gspca_disconnect, 1255 .disconnect = gspca_disconnect,
1256#ifdef CONFIG_PM
1257 .suspend = gspca_suspend,
1258 .resume = gspca_resume,
1259#endif
1234}; 1260};
1235 1261
1236/* -- module insert / remove -- */ 1262/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 245a30ec5fb1..d75b1d20b318 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -54,8 +54,10 @@ struct sd {
54#define SENSOR_HV7131R 0 54#define SENSOR_HV7131R 0
55#define SENSOR_MI0360 1 55#define SENSOR_MI0360 1
56#define SENSOR_MO4000 2 56#define SENSOR_MO4000 2
57#define SENSOR_OV7648 3 57#define SENSOR_OM6802 3
58#define SENSOR_OV7660 4 58#define SENSOR_OV7630 4
59#define SENSOR_OV7648 5
60#define SENSOR_OV7660 6
59 unsigned char i2c_base; 61 unsigned char i2c_base;
60}; 62};
61 63
@@ -76,7 +78,8 @@ static struct ctrl sd_ctrls[] = {
76 .type = V4L2_CTRL_TYPE_INTEGER, 78 .type = V4L2_CTRL_TYPE_INTEGER,
77 .name = "Brightness", 79 .name = "Brightness",
78 .minimum = 0, 80 .minimum = 0,
79 .maximum = 0xffff, 81#define BRIGHTNESS_MAX 0xffff
82 .maximum = BRIGHTNESS_MAX,
80 .step = 1, 83 .step = 1,
81#define BRIGHTNESS_DEF 0x7fff 84#define BRIGHTNESS_DEF 0x7fff
82 .default_value = BRIGHTNESS_DEF, 85 .default_value = BRIGHTNESS_DEF,
@@ -90,7 +93,8 @@ static struct ctrl sd_ctrls[] = {
90 .type = V4L2_CTRL_TYPE_INTEGER, 93 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Contrast", 94 .name = "Contrast",
92 .minimum = 0, 95 .minimum = 0,
93 .maximum = 127, 96#define CONTRAST_MAX 127
97 .maximum = CONTRAST_MAX,
94 .step = 1, 98 .step = 1,
95#define CONTRAST_DEF 63 99#define CONTRAST_DEF 63
96 .default_value = CONTRAST_DEF, 100 .default_value = CONTRAST_DEF,
@@ -104,14 +108,15 @@ static struct ctrl sd_ctrls[] = {
104 .type = V4L2_CTRL_TYPE_INTEGER, 108 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Color", 109 .name = "Color",
106 .minimum = 0, 110 .minimum = 0,
107 .maximum = 255, 111 .maximum = 64,
108 .step = 1, 112 .step = 1,
109#define COLOR_DEF 127 113#define COLOR_DEF 32
110 .default_value = COLOR_DEF, 114 .default_value = COLOR_DEF,
111 }, 115 },
112 .set = sd_setcolors, 116 .set = sd_setcolors,
113 .get = sd_getcolors, 117 .get = sd_getcolors,
114 }, 118 },
119#define AUTOGAIN_IDX 3
115 { 120 {
116 { 121 {
117 .id = V4L2_CID_AUTOGAIN, 122 .id = V4L2_CID_AUTOGAIN,
@@ -131,7 +136,7 @@ static struct ctrl sd_ctrls[] = {
131static struct v4l2_pix_format vga_mode[] = { 136static struct v4l2_pix_format vga_mode[] = {
132 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 137 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133 .bytesperline = 160, 138 .bytesperline = 160,
134 .sizeimage = 160 * 120 * 3 / 8 + 590, 139 .sizeimage = 160 * 120 * 4 / 8 + 590,
135 .colorspace = V4L2_COLORSPACE_JPEG, 140 .colorspace = V4L2_COLORSPACE_JPEG,
136 .priv = 2}, 141 .priv = 2},
137 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 142 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -180,6 +185,31 @@ static const __u8 sn_mo4000[] = {
180 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 185 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
181}; 186};
182 187
188static const __u8 sn_om6802[] = {
189/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
190 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
191/* reg8 reg9 rega regb regc regd rege regf */
192 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
194 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
195/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
196 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
198 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
199 0xf7
200};
201
202static const __u8 sn_ov7630[] = {
203/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
204 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
205/* reg8 reg9 rega regb regc regd rege regf */
206 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
207/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
208 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
209/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
210 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
211};
212
183static const __u8 sn_ov7648[] = { 213static const __u8 sn_ov7648[] = {
184/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 214/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
185 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 215 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -207,31 +237,22 @@ static const __u8 *sn_tb[] = {
207 sn_hv7131, 237 sn_hv7131,
208 sn_mi0360, 238 sn_mi0360,
209 sn_mo4000, 239 sn_mo4000,
240 sn_om6802,
241 sn_ov7630,
210 sn_ov7648, 242 sn_ov7648,
211 sn_ov7660 243 sn_ov7660
212}; 244};
213 245
214static const __u8 regsn20[] = { 246static const __u8 gamma_def[] = {
215 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 247 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
216 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 248 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
217}; 249};
218static const __u8 regsn20_sn9c325[] = {
219 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
220 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
221};
222 250
223static const __u8 reg84[] = { 251static const __u8 reg84[] = {
224 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 252 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
225 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, 253 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
226/* 0x00, 0x00, 0x00, 0x00, 0x00 */ 254 0xf7, 0x0f, 0x00, 0x00, 0x00
227 0xf7, 0x0f, 0x0a, 0x00, 0x00
228};
229static const __u8 reg84_sn9c325[] = {
230 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
231 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
232 0xf8, 0x0f, 0x00, 0x00, 0x00
233}; 255};
234
235static const __u8 hv7131r_sensor_init[][8] = { 256static const __u8 hv7131r_sensor_init[][8] = {
236 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 257 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
237 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, 258 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
@@ -340,6 +361,92 @@ static const __u8 mo4000_sensor_init[][8] = {
340 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, 361 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
341 {} 362 {}
342}; 363};
364static __u8 om6802_sensor_init[][8] = {
365 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
366 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
367 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
368 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
369/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
370 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
371 /* white balance & auto-exposure */
372/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
373 * set color mode */
374/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
375 * max AGC value in AE */
376/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
377 * preset AGC */
378/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
379 * preset brightness */
380/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
381 * preset contrast */
382/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
383 * preset gamma */
384 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
385 /* luminance mode (0x4f = AE) */
386 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
387 /* preset shutter */
388/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
389 * auto frame rate */
390/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
391
392/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
393/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
394/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
395/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
396 {}
397};
398static const __u8 ov7630_sensor_init[][8] = {
399 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
400 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
401/* win: delay 20ms */
402 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
403 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
404/* win: delay 20ms */
405 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
406/* win: i2c_r from 00 to 80 */
407 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
408 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
409 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
410 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
411 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
412 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
413 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
414 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
415 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
416 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
417 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
418 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
422 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
424 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
425 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
426 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
427 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
428 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
429 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
430 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
431 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
432 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
433/* */
434 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
436/*fixme: + 0x12, 0x04*/
437 {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
441/* */
442 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
445/* */
446 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
447/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
448 {}
449};
343static const __u8 ov7660_sensor_init[][8] = { 450static const __u8 ov7660_sensor_init[][8] = {
344 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 451 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
345/* (delay 20ms) */ 452/* (delay 20ms) */
@@ -506,10 +613,16 @@ static const __u8 qtable4[] = {
506 0x29, 0x29, 0x29, 0x29 613 0x29, 0x29, 0x29, 0x29
507}; 614};
508 615
509/* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */ 616/* read <len> bytes to gspca_dev->usb_buf */
510static void reg_r(struct gspca_dev *gspca_dev, 617static void reg_r(struct gspca_dev *gspca_dev,
511 __u16 value, int len) 618 __u16 value, int len)
512{ 619{
620#ifdef GSPCA_DEBUG
621 if (len > USB_BUF_SZ) {
622 err("reg_r: buffer overflow");
623 return;
624 }
625#endif
513 usb_control_msg(gspca_dev->dev, 626 usb_control_msg(gspca_dev->dev,
514 usb_rcvctrlpipe(gspca_dev->dev, 0), 627 usb_rcvctrlpipe(gspca_dev->dev, 0),
515 0, 628 0,
@@ -542,29 +655,20 @@ static void reg_w(struct gspca_dev *gspca_dev,
542{ 655{
543 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", 656 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
544 value, buffer[0], buffer[1]); 657 value, buffer[0], buffer[1]);
545 if (len <= sizeof gspca_dev->usb_buf) { 658#ifdef GSPCA_DEBUG
546 memcpy(gspca_dev->usb_buf, buffer, len); 659 if (len > USB_BUF_SZ) {
547 usb_control_msg(gspca_dev->dev, 660 err("reg_w: buffer overflow");
548 usb_sndctrlpipe(gspca_dev->dev, 0), 661 return;
549 0x08,
550 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
551 value, 0,
552 gspca_dev->usb_buf, len,
553 500);
554 } else {
555 __u8 *tmpbuf;
556
557 tmpbuf = kmalloc(len, GFP_KERNEL);
558 memcpy(tmpbuf, buffer, len);
559 usb_control_msg(gspca_dev->dev,
560 usb_sndctrlpipe(gspca_dev->dev, 0),
561 0x08,
562 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
563 value, 0,
564 tmpbuf, len,
565 500);
566 kfree(tmpbuf);
567 } 662 }
663#endif
664 memcpy(gspca_dev->usb_buf, buffer, len);
665 usb_control_msg(gspca_dev->dev,
666 usb_sndctrlpipe(gspca_dev->dev, 0),
667 0x08,
668 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
669 value, 0,
670 gspca_dev->usb_buf, len,
671 500);
568} 672}
569 673
570/* I2C write 1 byte */ 674/* I2C write 1 byte */
@@ -665,7 +769,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
665 static const __u8 regd4[] = {0x60, 0x00, 0x00}; 769 static const __u8 regd4[] = {0x60, 0x00, 0x00};
666 770
667 reg_w1(gspca_dev, 0xf1, 0x00); 771 reg_w1(gspca_dev, 0xf1, 0x00);
668 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ 772 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
669 773
670 /* configure gpio */ 774 /* configure gpio */
671 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 775 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -685,21 +789,41 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
685 789
686 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 790 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
687 791
688 switch (sd->bridge) { 792 switch (sd->sensor) {
689 case BRIDGE_SN9C325: 793 case SENSOR_OM6802:
794 reg_w1(gspca_dev, 0x02, 0x71);
795 reg_w1(gspca_dev, 0x01, 0x42);
796 reg_w1(gspca_dev, 0x17, 0x64);
797 reg_w1(gspca_dev, 0x01, 0x42);
798 break;
799/*jfm: from win trace */
800 case SENSOR_OV7630:
801 reg_w1(gspca_dev, 0x01, 0x61);
802 reg_w1(gspca_dev, 0x17, 0xe2);
803 reg_w1(gspca_dev, 0x01, 0x60);
804 reg_w1(gspca_dev, 0x01, 0x40);
805 break;
806 case SENSOR_OV7648:
690 reg_w1(gspca_dev, 0x01, 0x43); 807 reg_w1(gspca_dev, 0x01, 0x43);
691 reg_w1(gspca_dev, 0x17, 0xae); 808 reg_w1(gspca_dev, 0x17, 0xae);
692 reg_w1(gspca_dev, 0x01, 0x42); 809 reg_w1(gspca_dev, 0x01, 0x42);
693 break; 810 break;
811/*jfm: from win trace */
812 case SENSOR_OV7660:
813 reg_w1(gspca_dev, 0x01, 0x61);
814 reg_w1(gspca_dev, 0x17, 0x20);
815 reg_w1(gspca_dev, 0x01, 0x60);
816 reg_w1(gspca_dev, 0x01, 0x40);
817 break;
694 default: 818 default:
695 reg_w1(gspca_dev, 0x01, 0x43); 819 reg_w1(gspca_dev, 0x01, 0x43);
696 reg_w1(gspca_dev, 0x17, 0x61); 820 reg_w1(gspca_dev, 0x17, 0x61);
697 reg_w1(gspca_dev, 0x01, 0x42); 821 reg_w1(gspca_dev, 0x01, 0x42);
698 } 822 if (sd->sensor == SENSOR_HV7131R) {
699 823 if (probesensor(gspca_dev) < 0)
700 if (sd->sensor == SENSOR_HV7131R) { 824 return -ENODEV;
701 if (probesensor(gspca_dev) < 0) 825 }
702 return -ENODEV; 826 break;
703 } 827 }
704 return 0; 828 return 0;
705} 829}
@@ -737,6 +861,40 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
737 } 861 }
738} 862}
739 863
864static void om6802_InitSensor(struct gspca_dev *gspca_dev)
865{
866 int i = 0;
867
868 while (om6802_sensor_init[i][0]) {
869 i2c_w8(gspca_dev, om6802_sensor_init[i]);
870 i++;
871 }
872}
873
874static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
875{
876 int i = 0;
877
878 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
879 i++;
880 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
881 i++;
882 msleep(20);
883 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
884 i++;
885 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
886 i++;
887 msleep(20);
888 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
889 i++;
890/*jfm:win i2c_r from 00 to 80*/
891
892 while (ov7630_sensor_init[i][0]) {
893 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
894 i++;
895 }
896}
897
740static void ov7648_InitSensor(struct gspca_dev *gspca_dev) 898static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
741{ 899{
742 int i = 0; 900 int i = 0;
@@ -783,11 +941,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
783 sd->autogain = AUTOGAIN_DEF; 941 sd->autogain = AUTOGAIN_DEF;
784 sd->ag_cnt = -1; 942 sd->ag_cnt = -1;
785 943
944 switch (sd->sensor) {
945 case SENSOR_OV7630:
946 case SENSOR_OV7648:
947 case SENSOR_OV7660:
948 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
949 break;
950 }
951
786 return 0; 952 return 0;
787} 953}
788 954
789/* this function is called at open time */ 955/* this function is called at probe and resume time */
790static int sd_open(struct gspca_dev *gspca_dev) 956static int sd_init(struct gspca_dev *gspca_dev)
791{ 957{
792 struct sd *sd = (struct sd *) gspca_dev; 958 struct sd *sd = (struct sd *) gspca_dev;
793/* const __u8 *sn9c1xx; */ 959/* const __u8 *sn9c1xx; */
@@ -891,16 +1057,53 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
891 | ((expoMo10[3] & 0x30) >> 4)); 1057 | ((expoMo10[3] & 0x30) >> 4));
892 break; 1058 break;
893 } 1059 }
1060 case SENSOR_OM6802: {
1061 __u8 gainOm[] =
1062 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1063
1064 if (expo > 0x03ff)
1065 expo = 0x03ff;
1066 if (expo < 0x0001)
1067 expo = 0x0001;
1068 gainOm[3] = expo >> 2;
1069 i2c_w8(gspca_dev, gainOm);
1070 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1071 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1072 break;
1073 }
894 } 1074 }
895 return expo; 1075 return expo;
896} 1076}
897 1077
1078/* this function is used for sensors o76xx only */
1079static void setbrightcont(struct gspca_dev *gspca_dev)
1080{
1081 struct sd *sd = (struct sd *) gspca_dev;
1082 unsigned val;
1083 __u8 reg84_full[0x15];
1084
1085 memset(reg84_full, 0, sizeof reg84_full);
1086 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1087 reg84_full[2] = val;
1088 reg84_full[0] = (val + 1) / 2;
1089 reg84_full[4] = (val + 1) / 5;
1090 if (val > BRIGHTNESS_DEF)
1091 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1092 / BRIGHTNESS_MAX;
1093 else
1094 val = 0;
1095 reg84_full[0x12] = val; /* 00..1f */
1096 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1097}
1098
1099/* sensor != ov76xx */
898static void setbrightness(struct gspca_dev *gspca_dev) 1100static void setbrightness(struct gspca_dev *gspca_dev)
899{ 1101{
900 struct sd *sd = (struct sd *) gspca_dev; 1102 struct sd *sd = (struct sd *) gspca_dev;
901 unsigned int expo; 1103 unsigned int expo;
902 __u8 k2; 1104 __u8 k2;
903 1105
1106 k2 = sd->brightness >> 10;
904 switch (sd->sensor) { 1107 switch (sd->sensor) {
905 case SENSOR_HV7131R: 1108 case SENSOR_HV7131R:
906 expo = sd->brightness << 4; 1109 expo = sd->brightness << 4;
@@ -915,12 +1118,17 @@ static void setbrightness(struct gspca_dev *gspca_dev)
915 expo = sd->brightness >> 4; 1118 expo = sd->brightness >> 4;
916 sd->exposure = setexposure(gspca_dev, expo); 1119 sd->exposure = setexposure(gspca_dev, expo);
917 break; 1120 break;
1121 case SENSOR_OM6802:
1122 expo = sd->brightness >> 6;
1123 sd->exposure = setexposure(gspca_dev, expo);
1124 k2 = sd->brightness >> 11;
1125 break;
918 } 1126 }
919 1127
920 k2 = sd->brightness >> 10;
921 reg_w1(gspca_dev, 0x96, k2); 1128 reg_w1(gspca_dev, 0x96, k2);
922} 1129}
923 1130
1131/* sensor != ov76xx */
924static void setcontrast(struct gspca_dev *gspca_dev) 1132static void setcontrast(struct gspca_dev *gspca_dev)
925{ 1133{
926 struct sd *sd = (struct sd *) gspca_dev; 1134 struct sd *sd = (struct sd *) gspca_dev;
@@ -937,31 +1145,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
937static void setcolors(struct gspca_dev *gspca_dev) 1145static void setcolors(struct gspca_dev *gspca_dev)
938{ 1146{
939 struct sd *sd = (struct sd *) gspca_dev; 1147 struct sd *sd = (struct sd *) gspca_dev;
940 __u8 data; 1148 __u8 blue, red;
941 int colour;
942 1149
943 colour = sd->colors - 128; 1150 if (sd->colors >= 32) {
944 if (colour > 0) 1151 red = 32 + (sd->colors - 32) / 2;
945 data = (colour + 32) & 0x7f; /* blue */ 1152 blue = 64 - sd->colors;
946 else 1153 } else {
947 data = (-colour + 32) & 0x7f; /* red */ 1154 red = sd->colors;
948 reg_w1(gspca_dev, 0x05, data); 1155 blue = 32 + (32 - sd->colors) / 2;
1156 }
1157 reg_w1(gspca_dev, 0x05, red);
1158/* reg_w1(gspca_dev, 0x07, 32); */
1159 reg_w1(gspca_dev, 0x06, blue);
949} 1160}
950 1161
951static void setautogain(struct gspca_dev *gspca_dev) 1162static void setautogain(struct gspca_dev *gspca_dev)
952{ 1163{
953 struct sd *sd = (struct sd *) gspca_dev; 1164 struct sd *sd = (struct sd *) gspca_dev;
954 1165
955 switch (sd->sensor) { 1166 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
956 case SENSOR_HV7131R: 1167 return;
957 case SENSOR_MO4000: 1168 if (sd->autogain)
958 case SENSOR_MI0360: 1169 sd->ag_cnt = AG_CNT_START;
959 if (sd->autogain) 1170 else
960 sd->ag_cnt = AG_CNT_START; 1171 sd->ag_cnt = -1;
961 else
962 sd->ag_cnt = -1;
963 break;
964 }
965} 1172}
966 1173
967/* -- start the camera -- */ 1174/* -- start the camera -- */
@@ -975,13 +1182,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
975 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1182 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
976 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1183 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
977 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 1184 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
978 static const __u8 CE_sn9c325[] = 1185 static const __u8 CE_ov76xx[] =
979 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ 1186 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7630/48 */
980 1187
981 sn9c1xx = sn_tb[(int) sd->sensor]; 1188 sn9c1xx = sn_tb[(int) sd->sensor];
982 configure_gpio(gspca_dev, sn9c1xx); 1189 configure_gpio(gspca_dev, sn9c1xx);
983 1190
984/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
985 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 1191 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
986 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 1192 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
987 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 1193 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
@@ -994,10 +1200,17 @@ static void sd_start(struct gspca_dev *gspca_dev)
994 reg_w1(gspca_dev, 0xc8, 0x50); 1200 reg_w1(gspca_dev, 0xc8, 0x50);
995 reg_w1(gspca_dev, 0xc9, 0x3c); 1201 reg_w1(gspca_dev, 0xc9, 0x3c);
996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1202 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
997 switch (sd->bridge) { 1203 switch (sd->sensor) {
998 case BRIDGE_SN9C325: 1204 case SENSOR_OV7630:
1205 reg17 = 0xe2;
1206 break;
1207 case SENSOR_OV7648:
999 reg17 = 0xae; 1208 reg17 = 0xae;
1000 break; 1209 break;
1210/*jfm: from win trace */
1211 case SENSOR_OV7660:
1212 reg17 = 0xa0;
1213 break;
1001 default: 1214 default:
1002 reg17 = 0x60; 1215 reg17 = 0x60;
1003 break; 1216 break;
@@ -1007,24 +1220,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
1007 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1220 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1008 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1221 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1009 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1222 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1010 switch (sd->bridge) { 1223 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1011 case BRIDGE_SN9C325: 1224 for (i = 0; i < 8; i++)
1012 reg_w(gspca_dev, 0x20, regsn20_sn9c325, 1225 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1013 sizeof regsn20_sn9c325);
1014 for (i = 0; i < 8; i++)
1015 reg_w(gspca_dev, 0x84, reg84_sn9c325,
1016 sizeof reg84_sn9c325);
1017 reg_w1(gspca_dev, 0x9a, 0x0a);
1018 reg_w1(gspca_dev, 0x99, 0x60);
1019 break;
1020 default:
1021 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1022 for (i = 0; i < 8; i++)
1023 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1024 reg_w1(gspca_dev, 0x9a, 0x08); 1226 reg_w1(gspca_dev, 0x9a, 0x08);
1025 reg_w1(gspca_dev, 0x99, 0x59); 1227 reg_w1(gspca_dev, 0x99, 0x59);
1026 break;
1027 }
1028 1228
1029 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1229 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1030 if (mode) 1230 if (mode)
@@ -1049,6 +1249,15 @@ static void sd_start(struct gspca_dev *gspca_dev)
1049/* reg1 = 0x06; * 640 clk 24Mz (done) */ 1249/* reg1 = 0x06; * 640 clk 24Mz (done) */
1050 } 1250 }
1051 break; 1251 break;
1252 case SENSOR_OM6802:
1253 om6802_InitSensor(gspca_dev);
1254 reg17 = 0x64; /* 640 MCKSIZE */
1255 break;
1256 case SENSOR_OV7630:
1257 ov7630_InitSensor(gspca_dev);
1258 reg17 = 0xe2;
1259 reg1 = 0x44;
1260 break;
1052 case SENSOR_OV7648: 1261 case SENSOR_OV7648:
1053 ov7648_InitSensor(gspca_dev); 1262 ov7648_InitSensor(gspca_dev);
1054 reg17 = 0xa2; 1263 reg17 = 0xa2;
@@ -1073,9 +1282,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
1073 } 1282 }
1074 reg_w(gspca_dev, 0xc0, C0, 6); 1283 reg_w(gspca_dev, 0xc0, C0, 6);
1075 reg_w(gspca_dev, 0xca, CA, 4); 1284 reg_w(gspca_dev, 0xca, CA, 4);
1076 switch (sd->bridge) { 1285 switch (sd->sensor) {
1077 case BRIDGE_SN9C325: 1286 case SENSOR_OV7630:
1078 reg_w(gspca_dev, 0xce, CE_sn9c325, 4); 1287 case SENSOR_OV7648:
1288 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1079 break; 1289 break;
1080 default: 1290 default:
1081 reg_w(gspca_dev, 0xce, CE, 4); 1291 reg_w(gspca_dev, 0xce, CE, 4);
@@ -1093,10 +1303,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
1093 reg_w1(gspca_dev, 0x18, reg18); 1303 reg_w1(gspca_dev, 0x18, reg18);
1094 1304
1095 reg_w1(gspca_dev, 0x17, reg17); 1305 reg_w1(gspca_dev, 0x17, reg17);
1096 reg_w1(gspca_dev, 0x01, reg1); 1306 switch (sd->sensor) {
1097 setbrightness(gspca_dev); 1307 case SENSOR_HV7131R:
1098 setcontrast(gspca_dev); 1308 case SENSOR_MI0360:
1309 case SENSOR_MO4000:
1310 case SENSOR_OM6802:
1311 setbrightness(gspca_dev);
1312 setcontrast(gspca_dev);
1313 break;
1314 default: /* OV76xx */
1315 setbrightcont(gspca_dev);
1316 break;
1317 }
1099 setautogain(gspca_dev); 1318 setautogain(gspca_dev);
1319 reg_w1(gspca_dev, 0x01, reg1);
1100} 1320}
1101 1321
1102static void sd_stopN(struct gspca_dev *gspca_dev) 1322static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1119,6 +1339,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1119 i2c_w8(gspca_dev, stopmi0360); 1339 i2c_w8(gspca_dev, stopmi0360);
1120 data = 0x29; 1340 data = 0x29;
1121 break; 1341 break;
1342 case SENSOR_OV7630:
1122 case SENSOR_OV7648: 1343 case SENSOR_OV7648:
1123 data = 0x29; 1344 data = 0x29;
1124 break; 1345 break;
@@ -1132,15 +1353,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1132 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 1353 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1133 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 1354 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1134 reg_w1(gspca_dev, 0x01, data); 1355 reg_w1(gspca_dev, 0x01, data);
1135 reg_w1(gspca_dev, 0xf1, 0x01); 1356 reg_w1(gspca_dev, 0xf1, 0x00);
1136}
1137
1138static void sd_stop0(struct gspca_dev *gspca_dev)
1139{
1140}
1141
1142static void sd_close(struct gspca_dev *gspca_dev)
1143{
1144} 1357}
1145 1358
1146static void do_autogain(struct gspca_dev *gspca_dev) 1359static void do_autogain(struct gspca_dev *gspca_dev)
@@ -1174,6 +1387,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1174 default: 1387 default:
1175/* case SENSOR_MO4000: */ 1388/* case SENSOR_MO4000: */
1176/* case SENSOR_MI0360: */ 1389/* case SENSOR_MI0360: */
1390/* case SENSOR_OM6802: */
1177 expotimes = sd->exposure; 1391 expotimes = sd->exposure;
1178 expotimes += (luma_mean - delta) >> 6; 1392 expotimes += (luma_mean - delta) >> 6;
1179 if (expotimes < 0) 1393 if (expotimes < 0)
@@ -1229,69 +1443,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1229 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1443 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1230} 1444}
1231 1445
1232static unsigned int getexposure(struct gspca_dev *gspca_dev)
1233{
1234 struct sd *sd = (struct sd *) gspca_dev;
1235 __u8 hexpo, mexpo, lexpo;
1236
1237 switch (sd->sensor) {
1238 case SENSOR_HV7131R:
1239 /* read sensor exposure */
1240 i2c_r5(gspca_dev, 0x25);
1241 return (gspca_dev->usb_buf[0] << 16)
1242 | (gspca_dev->usb_buf[1] << 8)
1243 | gspca_dev->usb_buf[2];
1244 case SENSOR_MI0360:
1245 /* read sensor exposure */
1246 i2c_r5(gspca_dev, 0x09);
1247 return (gspca_dev->usb_buf[0] << 8)
1248 | gspca_dev->usb_buf[1];
1249 case SENSOR_MO4000:
1250 i2c_r5(gspca_dev, 0x0e);
1251 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1252 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1253 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1254 PDEBUG(D_CONF, "exposure %d",
1255 (hexpo << 10) | (mexpo << 2) | lexpo);
1256 return (hexpo << 10) | (mexpo << 2) | lexpo;
1257 default:
1258/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1259/* case SENSOR_OV7660: */
1260 /* read sensor exposure */
1261 i2c_r5(gspca_dev, 0x04);
1262 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1263 lexpo = gspca_dev->usb_buf[0] & 0x02;
1264 i2c_r5(gspca_dev, 0x08);
1265 mexpo = gspca_dev->usb_buf[2];
1266 return (hexpo << 10) | (mexpo << 2) | lexpo;
1267 }
1268}
1269
1270static void getbrightness(struct gspca_dev *gspca_dev)
1271{
1272 struct sd *sd = (struct sd *) gspca_dev;
1273
1274 /* hardcoded registers seem not readable */
1275 switch (sd->sensor) {
1276 case SENSOR_HV7131R:
1277 sd->brightness = getexposure(gspca_dev) >> 4;
1278 break;
1279 case SENSOR_MI0360:
1280 sd->brightness = getexposure(gspca_dev) << 4;
1281 break;
1282 case SENSOR_MO4000:
1283 sd->brightness = getexposure(gspca_dev) << 4;
1284 break;
1285 }
1286}
1287
1288static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1446static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1289{ 1447{
1290 struct sd *sd = (struct sd *) gspca_dev; 1448 struct sd *sd = (struct sd *) gspca_dev;
1291 1449
1292 sd->brightness = val; 1450 sd->brightness = val;
1293 if (gspca_dev->streaming) 1451 if (gspca_dev->streaming) {
1294 setbrightness(gspca_dev); 1452 switch (sd->sensor) {
1453 case SENSOR_HV7131R:
1454 case SENSOR_MI0360:
1455 case SENSOR_MO4000:
1456 case SENSOR_OM6802:
1457 setbrightness(gspca_dev);
1458 break;
1459 default: /* OV76xx */
1460 setbrightcont(gspca_dev);
1461 break;
1462 }
1463 }
1295 return 0; 1464 return 0;
1296} 1465}
1297 1466
@@ -1299,7 +1468,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1299{ 1468{
1300 struct sd *sd = (struct sd *) gspca_dev; 1469 struct sd *sd = (struct sd *) gspca_dev;
1301 1470
1302 getbrightness(gspca_dev);
1303 *val = sd->brightness; 1471 *val = sd->brightness;
1304 return 0; 1472 return 0;
1305} 1473}
@@ -1309,8 +1477,19 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1309 struct sd *sd = (struct sd *) gspca_dev; 1477 struct sd *sd = (struct sd *) gspca_dev;
1310 1478
1311 sd->contrast = val; 1479 sd->contrast = val;
1312 if (gspca_dev->streaming) 1480 if (gspca_dev->streaming) {
1313 setcontrast(gspca_dev); 1481 switch (sd->sensor) {
1482 case SENSOR_HV7131R:
1483 case SENSOR_MI0360:
1484 case SENSOR_MO4000:
1485 case SENSOR_OM6802:
1486 setcontrast(gspca_dev);
1487 break;
1488 default: /* OV76xx */
1489 setbrightcont(gspca_dev);
1490 break;
1491 }
1492 }
1314 return 0; 1493 return 0;
1315} 1494}
1316 1495
@@ -1364,11 +1543,9 @@ static const struct sd_desc sd_desc = {
1364 .ctrls = sd_ctrls, 1543 .ctrls = sd_ctrls,
1365 .nctrls = ARRAY_SIZE(sd_ctrls), 1544 .nctrls = ARRAY_SIZE(sd_ctrls),
1366 .config = sd_config, 1545 .config = sd_config,
1367 .open = sd_open, 1546 .init = sd_init,
1368 .start = sd_start, 1547 .start = sd_start,
1369 .stopN = sd_stopN, 1548 .stopN = sd_stopN,
1370 .stop0 = sd_stop0,
1371 .close = sd_close,
1372 .pkt_scan = sd_pkt_scan, 1549 .pkt_scan = sd_pkt_scan,
1373 .dq_callback = do_autogain, 1550 .dq_callback = do_autogain,
1374}; 1551};
@@ -1379,7 +1556,7 @@ static const struct sd_desc sd_desc = {
1379 | (SENSOR_ ## sensor << 8) \ 1556 | (SENSOR_ ## sensor << 8) \
1380 | (i2c_addr) 1557 | (i2c_addr)
1381static const __devinitdata struct usb_device_id device_table[] = { 1558static const __devinitdata struct usb_device_id device_table[] = {
1382#ifndef CONFIG_USB_SN9C102 1559#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1383 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1560 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1384 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1561 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1385 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1562 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
@@ -1406,15 +1583,17 @@ static const __devinitdata struct usb_device_id device_table[] = {
1406/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 1583/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1407/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 1584/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1408/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1585/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1409 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, 1586 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1410/* bw600.inf: 1587/*bw600.inf:*/
1411 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ 1588 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1412 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 1589 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1413/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ 1590 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1414/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 1591/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1415#ifndef CONFIG_USB_SN9C102 1592#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1416 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 1593 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1594#endif
1417 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 1595 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1596#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1418/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */ 1597/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1419 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 1598 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1420 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 1599 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
@@ -1438,6 +1617,10 @@ static struct usb_driver sd_driver = {
1438 .id_table = device_table, 1617 .id_table = device_table,
1439 .probe = sd_probe, 1618 .probe = sd_probe,
1440 .disconnect = gspca_disconnect, 1619 .disconnect = gspca_disconnect,
1620#ifdef CONFIG_PM
1621 .suspend = gspca_suspend,
1622 .resume = gspca_resume,
1623#endif
1441}; 1624};
1442 1625
1443/* -- module insert / remove -- */ 1626/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 17fe2c2a440d..6e733901fcca 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -645,8 +645,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
645 return 0; 645 return 0;
646} 646}
647 647
648/* this function is called at open time */ 648/* this function is called at probe and resume time */
649static int sd_open(struct gspca_dev *gspca_dev) 649static int sd_init(struct gspca_dev *gspca_dev)
650{ 650{
651 struct sd *sd = (struct sd *) gspca_dev; 651 struct sd *sd = (struct sd *) gspca_dev;
652 652
@@ -880,14 +880,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
880 gspca_dev->usb_buf[0]); 880 gspca_dev->usb_buf[0]);
881} 881}
882 882
883static void sd_stop0(struct gspca_dev *gspca_dev)
884{
885}
886
887static void sd_close(struct gspca_dev *gspca_dev)
888{
889}
890
891static void sd_pkt_scan(struct gspca_dev *gspca_dev, 883static void sd_pkt_scan(struct gspca_dev *gspca_dev,
892 struct gspca_frame *frame, /* target */ 884 struct gspca_frame *frame, /* target */
893 __u8 *data, /* isoc packet */ 885 __u8 *data, /* isoc packet */
@@ -1051,11 +1043,9 @@ static struct sd_desc sd_desc = {
1051 .ctrls = sd_ctrls, 1043 .ctrls = sd_ctrls,
1052 .nctrls = ARRAY_SIZE(sd_ctrls), 1044 .nctrls = ARRAY_SIZE(sd_ctrls),
1053 .config = sd_config, 1045 .config = sd_config,
1054 .open = sd_open, 1046 .init = sd_init,
1055 .start = sd_start, 1047 .start = sd_start,
1056 .stopN = sd_stopN, 1048 .stopN = sd_stopN,
1057 .stop0 = sd_stop0,
1058 .close = sd_close,
1059 .pkt_scan = sd_pkt_scan, 1049 .pkt_scan = sd_pkt_scan,
1060}; 1050};
1061 1051
@@ -1093,6 +1083,10 @@ static struct usb_driver sd_driver = {
1093 .id_table = device_table, 1083 .id_table = device_table,
1094 .probe = sd_probe, 1084 .probe = sd_probe,
1095 .disconnect = gspca_disconnect, 1085 .disconnect = gspca_disconnect,
1086#ifdef CONFIG_PM
1087 .suspend = gspca_suspend,
1088 .resume = gspca_resume,
1089#endif
1096}; 1090};
1097 1091
1098/* -- module insert / remove -- */ 1092/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 51a3c3429ef0..e9eb59bae4fb 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1953,8 +1953,8 @@ error:
1953 return -EINVAL; 1953 return -EINVAL;
1954} 1954}
1955 1955
1956/* this function is called at open time */ 1956/* this function is called at probe and resume time */
1957static int sd_open(struct gspca_dev *gspca_dev) 1957static int sd_init(struct gspca_dev *gspca_dev)
1958{ 1958{
1959 struct sd *sd = (struct sd *) gspca_dev; 1959 struct sd *sd = (struct sd *) gspca_dev;
1960 1960
@@ -2023,11 +2023,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2023 2023
2024static void sd_stop0(struct gspca_dev *gspca_dev) 2024static void sd_stop0(struct gspca_dev *gspca_dev)
2025{ 2025{
2026}
2027
2028/* this function is called at close time */
2029static void sd_close(struct gspca_dev *gspca_dev)
2030{
2031 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); 2026 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
2032} 2027}
2033 2028
@@ -2120,11 +2115,10 @@ static const struct sd_desc sd_desc = {
2120 .ctrls = sd_ctrls, 2115 .ctrls = sd_ctrls,
2121 .nctrls = ARRAY_SIZE(sd_ctrls), 2116 .nctrls = ARRAY_SIZE(sd_ctrls),
2122 .config = sd_config, 2117 .config = sd_config,
2123 .open = sd_open, 2118 .init = sd_init,
2124 .start = sd_start, 2119 .start = sd_start,
2125 .stopN = sd_stopN, 2120 .stopN = sd_stopN,
2126 .stop0 = sd_stop0, 2121 .stop0 = sd_stop0,
2127 .close = sd_close,
2128 .pkt_scan = sd_pkt_scan, 2122 .pkt_scan = sd_pkt_scan,
2129}; 2123};
2130 2124
@@ -2154,6 +2148,10 @@ static struct usb_driver sd_driver = {
2154 .id_table = device_table, 2148 .id_table = device_table,
2155 .probe = sd_probe, 2149 .probe = sd_probe,
2156 .disconnect = gspca_disconnect, 2150 .disconnect = gspca_disconnect,
2151#ifdef CONFIG_PM
2152 .suspend = gspca_suspend,
2153 .resume = gspca_resume,
2154#endif
2157}; 2155};
2158 2156
2159/* -- module insert / remove -- */ 2157/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index eda29d609359..f601daf19ebe 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -655,8 +655,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
655 return 0; 655 return 0;
656} 656}
657 657
658/* this function is called at open time */ 658/* this function is called at probe and resume time */
659static int sd_open(struct gspca_dev *gspca_dev) 659static int sd_init(struct gspca_dev *gspca_dev)
660{ 660{
661 struct sd *sd = (struct sd *) gspca_dev; 661 struct sd *sd = (struct sd *) gspca_dev;
662 int ret; 662 int ret;
@@ -743,11 +743,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
743 743
744static void sd_stop0(struct gspca_dev *gspca_dev) 744static void sd_stop0(struct gspca_dev *gspca_dev)
745{ 745{
746}
747
748/* this function is called at close time */
749static void sd_close(struct gspca_dev *gspca_dev)
750{
751 /* This maybe reset or power control */ 746 /* This maybe reset or power control */
752 reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); 747 reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
753 reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); 748 reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
@@ -825,11 +820,10 @@ static const struct sd_desc sd_desc = {
825 .ctrls = sd_ctrls, 820 .ctrls = sd_ctrls,
826 .nctrls = ARRAY_SIZE(sd_ctrls), 821 .nctrls = ARRAY_SIZE(sd_ctrls),
827 .config = sd_config, 822 .config = sd_config,
828 .open = sd_open, 823 .init = sd_init,
829 .start = sd_start, 824 .start = sd_start,
830 .stopN = sd_stopN, 825 .stopN = sd_stopN,
831 .stop0 = sd_stop0, 826 .stop0 = sd_stop0,
832 .close = sd_close,
833 .pkt_scan = sd_pkt_scan, 827 .pkt_scan = sd_pkt_scan,
834}; 828};
835 829
@@ -855,6 +849,10 @@ static struct usb_driver sd_driver = {
855 .id_table = device_table, 849 .id_table = device_table,
856 .probe = sd_probe, 850 .probe = sd_probe,
857 .disconnect = gspca_disconnect, 851 .disconnect = gspca_disconnect,
852#ifdef CONFIG_PM
853 .suspend = gspca_suspend,
854 .resume = gspca_resume,
855#endif
858}; 856};
859 857
860/* -- module insert / remove -- */ 858/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index f622fa75766d..195dce96ef06 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -313,8 +313,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
313 return 0; 313 return 0;
314} 314}
315 315
316/* this function is called at open time */ 316/* this function is called at probe and resume time */
317static int sd_open(struct gspca_dev *gspca_dev) 317static int sd_init(struct gspca_dev *gspca_dev)
318{ 318{
319 struct usb_device *dev = gspca_dev->dev; 319 struct usb_device *dev = gspca_dev->dev;
320 320
@@ -560,14 +560,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
560 reg_w(dev, 0x03, 0x00, 0x0003); 560 reg_w(dev, 0x03, 0x00, 0x0003);
561} 561}
562 562
563static void sd_stop0(struct gspca_dev *gspca_dev)
564{
565}
566
567static void sd_close(struct gspca_dev *gspca_dev)
568{
569}
570
571static void sd_pkt_scan(struct gspca_dev *gspca_dev, 563static void sd_pkt_scan(struct gspca_dev *gspca_dev,
572 struct gspca_frame *frame, /* target */ 564 struct gspca_frame *frame, /* target */
573 __u8 *data, /* isoc packet */ 565 __u8 *data, /* isoc packet */
@@ -740,11 +732,9 @@ static struct sd_desc sd_desc = {
740 .ctrls = sd_ctrls, 732 .ctrls = sd_ctrls,
741 .nctrls = ARRAY_SIZE(sd_ctrls), 733 .nctrls = ARRAY_SIZE(sd_ctrls),
742 .config = sd_config, 734 .config = sd_config,
743 .open = sd_open, 735 .init = sd_init,
744 .start = sd_start, 736 .start = sd_start,
745 .stopN = sd_stopN, 737 .stopN = sd_stopN,
746 .stop0 = sd_stop0,
747 .close = sd_close,
748 .pkt_scan = sd_pkt_scan, 738 .pkt_scan = sd_pkt_scan,
749}; 739};
750 740
@@ -772,6 +762,10 @@ static struct usb_driver sd_driver = {
772 .id_table = device_table, 762 .id_table = device_table,
773 .probe = sd_probe, 763 .probe = sd_probe,
774 .disconnect = gspca_disconnect, 764 .disconnect = gspca_disconnect,
765#ifdef CONFIG_PM
766 .suspend = gspca_suspend,
767 .resume = gspca_resume,
768#endif
775}; 769};
776 770
777/* -- module insert / remove -- */ 771/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 699340c17dea..281ce02103a3 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1521,8 +1521,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1521 return 0; /* success */ 1521 return 0; /* success */
1522} 1522}
1523 1523
1524/* this function is called at open time */ 1524/* this function is called at probe and resume time */
1525static int sd_open(struct gspca_dev *gspca_dev) 1525static int sd_init(struct gspca_dev *gspca_dev)
1526{ 1526{
1527/* write_vector(gspca_dev, spca508_open_data); */ 1527/* write_vector(gspca_dev, spca508_open_data); */
1528 return 0; 1528 return 0;
@@ -1554,15 +1554,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1554 reg_write(gspca_dev->dev, 0x8112, 0x20); 1554 reg_write(gspca_dev->dev, 0x8112, 0x20);
1555} 1555}
1556 1556
1557static void sd_stop0(struct gspca_dev *gspca_dev)
1558{
1559}
1560
1561/* this function is called at close time */
1562static void sd_close(struct gspca_dev *gspca_dev)
1563{
1564}
1565
1566static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1557static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1567 struct gspca_frame *frame, /* target */ 1558 struct gspca_frame *frame, /* target */
1568 __u8 *data, /* isoc packet */ 1559 __u8 *data, /* isoc packet */
@@ -1633,11 +1624,9 @@ static const struct sd_desc sd_desc = {
1633 .ctrls = sd_ctrls, 1624 .ctrls = sd_ctrls,
1634 .nctrls = ARRAY_SIZE(sd_ctrls), 1625 .nctrls = ARRAY_SIZE(sd_ctrls),
1635 .config = sd_config, 1626 .config = sd_config,
1636 .open = sd_open, 1627 .init = sd_init,
1637 .start = sd_start, 1628 .start = sd_start,
1638 .stopN = sd_stopN, 1629 .stopN = sd_stopN,
1639 .stop0 = sd_stop0,
1640 .close = sd_close,
1641 .pkt_scan = sd_pkt_scan, 1630 .pkt_scan = sd_pkt_scan,
1642}; 1631};
1643 1632
@@ -1667,6 +1656,10 @@ static struct usb_driver sd_driver = {
1667 .id_table = device_table, 1656 .id_table = device_table,
1668 .probe = sd_probe, 1657 .probe = sd_probe,
1669 .disconnect = gspca_disconnect, 1658 .disconnect = gspca_disconnect,
1659#ifdef CONFIG_PM
1660 .suspend = gspca_suspend,
1661 .resume = gspca_resume,
1662#endif
1670}; 1663};
1671 1664
1672/* -- module insert / remove -- */ 1665/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 1073ac3d2ec6..1c29c279a982 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -32,69 +32,48 @@ 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 unsigned short contrast; 35 __u16 contrast; /* rev72a only */
36 __u8 brightness; 36#define CONTRAST_MIN 0x0000
37#define CONTRAST_DEF 0x2000
38#define CONTRAST_MAX 0x3fff
39
40 __u16 exposure; /* rev12a only */
41#define EXPOSURE_MIN 1
42#define EXPOSURE_DEF 200
43#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
44
45 __u8 brightness; /* rev72a only */
46#define BRIGHTNESS_MIN 0
47#define BRIGHTNESS_DEF 32
48#define BRIGHTNESS_MAX 63
49
50 __u8 white; /* rev12a only */
51#define WHITE_MIN 1
52#define WHITE_DEF 0x40
53#define WHITE_MAX 0x7f
54
37 __u8 autogain; 55 __u8 autogain;
56#define AUTOGAIN_MIN 0
57#define AUTOGAIN_DEF 1
58#define AUTOGAIN_MAX 1
59
60 __u8 gain; /* rev12a only */
61#define GAIN_MIN 0x0
62#define GAIN_DEF 0x24
63#define GAIN_MAX 0x24
64
65#define EXPO12A_DEF 3
66 __u8 expo12a; /* expo/gain? for rev 12a */
38 67
39 __u8 chip_revision; 68 __u8 chip_revision;
69#define Rev012A 0
70#define Rev072A 1
71
40 signed char ag_cnt; 72 signed char ag_cnt;
41#define AG_CNT_START 13 73#define AG_CNT_START 13
42}; 74};
43 75
44/* V4L2 controls supported by the driver */ 76static struct v4l2_pix_format sif_012a_mode[] = {
45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
47static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
49static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
51
52static struct ctrl sd_ctrls[] = {
53#define SD_BRIGHTNESS 0
54 {
55 {
56 .id = V4L2_CID_BRIGHTNESS,
57 .type = V4L2_CTRL_TYPE_INTEGER,
58 .name = "Brightness",
59 .minimum = 0,
60 .maximum = 63,
61 .step = 1,
62 .default_value = 32,
63 },
64 .set = sd_setbrightness,
65 .get = sd_getbrightness,
66 },
67#define SD_CONTRAST 1
68 {
69 {
70 .id = V4L2_CID_CONTRAST,
71 .type = V4L2_CTRL_TYPE_INTEGER,
72 .name = "Contrast",
73 .minimum = 0,
74 .maximum = 0x3fff,
75 .step = 1,
76 .default_value = 0x2000,
77 },
78 .set = sd_setcontrast,
79 .get = sd_getcontrast,
80 },
81#define SD_AUTOGAIN 2
82 {
83 {
84 .id = V4L2_CID_AUTOGAIN,
85 .type = V4L2_CTRL_TYPE_BOOLEAN,
86 .name = "Auto Gain",
87 .minimum = 0,
88 .maximum = 1,
89 .step = 1,
90 .default_value = 1,
91 },
92 .set = sd_setautogain,
93 .get = sd_getautogain,
94 },
95};
96
97static struct v4l2_pix_format sif_mode[] = {
98 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
99 .bytesperline = 160, 78 .bytesperline = 160,
100 .sizeimage = 160 * 120, 79 .sizeimage = 160 * 120,
@@ -117,6 +96,29 @@ static struct v4l2_pix_format sif_mode[] = {
117 .priv = 0}, 96 .priv = 0},
118}; 97};
119 98
99static struct v4l2_pix_format sif_072a_mode[] = {
100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
101 .bytesperline = 160,
102 .sizeimage = 160 * 120,
103 .colorspace = V4L2_COLORSPACE_SRGB,
104 .priv = 3},
105 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
106 .bytesperline = 176,
107 .sizeimage = 176 * 144,
108 .colorspace = V4L2_COLORSPACE_SRGB,
109 .priv = 2},
110 {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
111 .bytesperline = 320,
112 .sizeimage = 320 * 240,
113 .colorspace = V4L2_COLORSPACE_SRGB,
114 .priv = 1},
115 {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
116 .bytesperline = 352,
117 .sizeimage = 352 * 288,
118 .colorspace = V4L2_COLORSPACE_SRGB,
119 .priv = 0},
120};
121
120/* 122/*
121 * Initialization data 123 * Initialization data
122 * I'm not very sure how to split initialization from open data 124 * I'm not very sure how to split initialization from open data
@@ -143,12 +145,8 @@ static struct v4l2_pix_format sif_mode[] = {
143#define SPCA561_INDEX_I2C_BASE 0x8800 145#define SPCA561_INDEX_I2C_BASE 0x8800
144#define SPCA561_SNAPBIT 0x20 146#define SPCA561_SNAPBIT 0x20
145#define SPCA561_SNAPCTRL 0x40 147#define SPCA561_SNAPCTRL 0x40
146enum {
147 Rev072A = 0,
148 Rev012A,
149};
150 148
151static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) 149static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
152{ 150{
153 int ret; 151 int ret;
154 152
@@ -198,12 +196,6 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
198 index, gspca_dev->usb_buf, len, 500); 196 index, gspca_dev->usb_buf, len, 500);
199} 197}
200 198
201static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
202{
203 reg_w_val(gspca_dev->dev, 0x92, 0x8804);
204 reg_w_val(gspca_dev->dev, mode, 0x8802);
205}
206
207static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) 199static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
208{ 200{
209 int retry = 60; 201 int retry = 60;
@@ -212,9 +204,9 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
212 204
213 DataLow = valeur; 205 DataLow = valeur;
214 DataHight = valeur >> 8; 206 DataHight = valeur >> 8;
215 reg_w_val(gspca_dev->dev, reg, 0x8801); 207 reg_w_val(gspca_dev->dev, 0x8801, reg);
216 reg_w_val(gspca_dev->dev, DataLow, 0x8805); 208 reg_w_val(gspca_dev->dev, 0x8805, DataLow);
217 reg_w_val(gspca_dev->dev, DataHight, 0x8800); 209 reg_w_val(gspca_dev->dev, 0x8800, DataHight);
218 while (retry--) { 210 while (retry--) {
219 reg_r(gspca_dev, 0x8803, 1); 211 reg_r(gspca_dev, 0x8803, 1);
220 if (!gspca_dev->usb_buf[0]) 212 if (!gspca_dev->usb_buf[0])
@@ -228,9 +220,9 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
228 __u8 value; 220 __u8 value;
229 __u8 vallsb; 221 __u8 vallsb;
230 222
231 reg_w_val(gspca_dev->dev, 0x92, 0x8804); 223 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
232 reg_w_val(gspca_dev->dev, reg, 0x8801); 224 reg_w_val(gspca_dev->dev, 0x8801, reg);
233 reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); 225 reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
234 while (retry--) { 226 while (retry--) {
235 reg_r(gspca_dev, 0x8803, 1); 227 reg_r(gspca_dev, 0x8803, 1);
236 if (!gspca_dev->usb_buf) 228 if (!gspca_dev->usb_buf)
@@ -438,21 +430,10 @@ static const __u16 spca561_init_data[][2] = {
438 {0x0035, 0x8801}, /* 0x14 - set gain general */ 430 {0x0035, 0x8801}, /* 0x14 - set gain general */
439 {0x001f, 0x8805}, /* 0x14 */ 431 {0x001f, 0x8805}, /* 0x14 */
440 {0x0000, 0x8800}, 432 {0x0000, 0x8800},
441 {0x0030, 0x8112}, 433 {0x000e, 0x8112}, /* white balance - was 30 */
442 {} 434 {}
443}; 435};
444 436
445static void sensor_reset(struct gspca_dev *gspca_dev)
446{
447 reg_w_val(gspca_dev->dev, 0x8631, 0xc8);
448 reg_w_val(gspca_dev->dev, 0x8634, 0xc8);
449 reg_w_val(gspca_dev->dev, 0x8112, 0x00);
450 reg_w_val(gspca_dev->dev, 0x8114, 0x00);
451 reg_w_val(gspca_dev->dev, 0x8118, 0x21);
452 i2c_init(gspca_dev, 0x14);
453 i2c_write(gspca_dev, 1, 0x0d);
454 i2c_write(gspca_dev, 0, 0x0d);
455}
456 437
457/******************** QC Express etch2 stuff ********************/ 438/******************** QC Express etch2 stuff ********************/
458static const __u16 Pb100_1map8300[][2] = { 439static const __u16 Pb100_1map8300[][2] = {
@@ -462,9 +443,9 @@ static const __u16 Pb100_1map8300[][2] = {
462 {0x8303, 0x0125}, /* image area */ 443 {0x8303, 0x0125}, /* image area */
463 {0x8304, 0x0169}, 444 {0x8304, 0x0169},
464 {0x8328, 0x000b}, 445 {0x8328, 0x000b},
465 {0x833c, 0x0001}, 446 {0x833c, 0x0001}, /*fixme: win:07*/
466 447
467 {0x832f, 0x0419}, 448 {0x832f, 0x1904}, /*fixme: was 0419*/
468 {0x8307, 0x00aa}, 449 {0x8307, 0x00aa},
469 {0x8301, 0x0003}, 450 {0x8301, 0x0003},
470 {0x8302, 0x000e}, 451 {0x8302, 0x000e},
@@ -478,9 +459,10 @@ static const __u16 Pb100_2map8300[][2] = {
478}; 459};
479 460
480static const __u16 spca561_161rev12A_data1[][2] = { 461static const __u16 spca561_161rev12A_data1[][2] = {
481 {0x21, 0x8118}, 462 {0x29, 0x8118}, /* white balance - was 21 */
482 {0x01, 0x8114}, 463 {0x08, 0x8114}, /* white balance - was 01 */
483 {0x00, 0x8112}, 464 {0x0e, 0x8112}, /* white balance - was 00 */
465 {0x00, 0x8102}, /* white balance - new */
484 {0x92, 0x8804}, 466 {0x92, 0x8804},
485 {0x04, 0x8802}, /* windows uses 08 */ 467 {0x04, 0x8802}, /* windows uses 08 */
486 {} 468 {}
@@ -505,14 +487,16 @@ static const __u16 spca561_161rev12A_data2[][2] = {
505 {0xb0, 0x8603}, 487 {0xb0, 0x8603},
506 488
507 /* sensor gains */ 489 /* sensor gains */
490 {0x07, 0x8601}, /* white balance - new */
491 {0x07, 0x8602}, /* white balance - new */
508 {0x00, 0x8610}, /* *red */ 492 {0x00, 0x8610}, /* *red */
509 {0x00, 0x8611}, /* 3f *green */ 493 {0x00, 0x8611}, /* 3f *green */
510 {0x00, 0x8612}, /* green *blue */ 494 {0x00, 0x8612}, /* green *blue */
511 {0x00, 0x8613}, /* blue *green */ 495 {0x00, 0x8613}, /* blue *green */
512 {0x35, 0x8614}, /* green *red */ 496 {0x43, 0x8614}, /* green *red - white balance - was 0x35 */
513 {0x35, 0x8615}, /* 40 *green */ 497 {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */
514 {0x35, 0x8616}, /* 7a *blue */ 498 {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */
515 {0x35, 0x8617}, /* 40 *green */ 499 {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */
516 500
517 {0x0c, 0x8620}, /* 0c */ 501 {0x0c, 0x8620}, /* 0c */
518 {0xc8, 0x8631}, /* c8 */ 502 {0xc8, 0x8631}, /* c8 */
@@ -527,6 +511,7 @@ static const __u16 spca561_161rev12A_data2[][2] = {
527 {0xdf, 0x863c}, /* df */ 511 {0xdf, 0x863c}, /* df */
528 {0xf0, 0x8505}, 512 {0xf0, 0x8505},
529 {0x32, 0x850a}, 513 {0x32, 0x850a},
514/* {0x99, 0x8700}, * - white balance - new (removed) */
530 {} 515 {}
531}; 516};
532 517
@@ -545,9 +530,10 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev,
545} 530}
546static void init_161rev12A(struct gspca_dev *gspca_dev) 531static void init_161rev12A(struct gspca_dev *gspca_dev)
547{ 532{
548 sensor_reset(gspca_dev); 533/* sensor_reset(gspca_dev); (not in win) */
549 write_vector(gspca_dev, spca561_161rev12A_data1); 534 write_vector(gspca_dev, spca561_161rev12A_data1);
550 sensor_mapwrite(gspca_dev, Pb100_1map8300); 535 sensor_mapwrite(gspca_dev, Pb100_1map8300);
536/*fixme: should be in sd_start*/
551 write_vector(gspca_dev, spca561_161rev12A_data2); 537 write_vector(gspca_dev, spca561_161rev12A_data2);
552 sensor_mapwrite(gspca_dev, Pb100_2map8300); 538 sensor_mapwrite(gspca_dev, Pb100_2map8300);
553} 539}
@@ -581,35 +567,38 @@ static int sd_config(struct gspca_dev *gspca_dev,
581 } 567 }
582 568
583 cam = &gspca_dev->cam; 569 cam = &gspca_dev->cam;
584 cam->dev_name = (char *) id->driver_info;
585 cam->epaddr = 0x01; 570 cam->epaddr = 0x01;
586 gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ 571 gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
587 cam->cam_mode = sif_mode;
588 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
589 572
590 sd->chip_revision = id->driver_info; 573 sd->chip_revision = id->driver_info;
591 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 574 if (sd->chip_revision == Rev012A) {
592 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 575 cam->cam_mode = sif_012a_mode;
593 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; 576 cam->nmodes = ARRAY_SIZE(sif_012a_mode);
577 } else {
578 cam->cam_mode = sif_072a_mode;
579 cam->nmodes = ARRAY_SIZE(sif_072a_mode);
580 }
581 sd->brightness = BRIGHTNESS_DEF;
582 sd->contrast = CONTRAST_DEF;
583 sd->white = WHITE_DEF;
584 sd->exposure = EXPOSURE_DEF;
585 sd->autogain = AUTOGAIN_DEF;
586 sd->gain = GAIN_DEF;
587 sd->expo12a = EXPO12A_DEF;
594 return 0; 588 return 0;
595} 589}
596 590
597/* this function is called at open time */ 591/* this function is called at probe and resume time */
598static int sd_open(struct gspca_dev *gspca_dev) 592static int sd_init_12a(struct gspca_dev *gspca_dev)
599{ 593{
600 struct sd *sd = (struct sd *) gspca_dev; 594 PDEBUG(D_STREAM, "Chip revision: 012a");
601 595 init_161rev12A(gspca_dev);
602 switch (sd->chip_revision) { 596 return 0;
603 case Rev072A: 597}
604 PDEBUG(D_STREAM, "Chip revision id: 072a"); 598static int sd_init_72a(struct gspca_dev *gspca_dev)
605 write_vector(gspca_dev, spca561_init_data); 599{
606 break; 600 PDEBUG(D_STREAM, "Chip revision: 072a");
607 default: 601 write_vector(gspca_dev, spca561_init_data);
608/* case Rev012A: */
609 PDEBUG(D_STREAM, "Chip revision id: 012a");
610 init_161rev12A(gspca_dev);
611 break;
612 }
613 return 0; 602 return 0;
614} 603}
615 604
@@ -618,25 +607,20 @@ static void setcontrast(struct gspca_dev *gspca_dev)
618 struct sd *sd = (struct sd *) gspca_dev; 607 struct sd *sd = (struct sd *) gspca_dev;
619 struct usb_device *dev = gspca_dev->dev; 608 struct usb_device *dev = gspca_dev->dev;
620 __u8 lowb; 609 __u8 lowb;
621 int expotimes;
622 610
623 switch (sd->chip_revision) { 611 switch (sd->chip_revision) {
624 case Rev072A: 612 case Rev072A:
625 lowb = sd->contrast >> 8; 613 lowb = sd->contrast >> 8;
626 reg_w_val(dev, lowb, 0x8651); 614 reg_w_val(dev, 0x8651, lowb);
627 reg_w_val(dev, lowb, 0x8652); 615 reg_w_val(dev, 0x8652, lowb);
628 reg_w_val(dev, lowb, 0x8653); 616 reg_w_val(dev, 0x8653, lowb);
629 reg_w_val(dev, lowb, 0x8654); 617 reg_w_val(dev, 0x8654, lowb);
630 break; 618 break;
631 case Rev012A: { 619 default: {
632 __u8 Reg8391[] = 620/* case Rev012A: { */
633 { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; 621 static const __u8 Reg8391[] =
634 622 { 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
635 /* Write camera sensor settings */ 623
636 expotimes = (sd->contrast >> 5) & 0x07ff;
637 Reg8391[0] = expotimes & 0xff; /* exposure */
638 Reg8391[1] = 0x18 | (expotimes >> 8);
639 Reg8391[2] = sd->brightness; /* gain */
640 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); 624 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
641 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); 625 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
642 break; 626 break;
@@ -644,93 +628,151 @@ static void setcontrast(struct gspca_dev *gspca_dev)
644 } 628 }
645} 629}
646 630
647static void setautogain(struct gspca_dev *gspca_dev) 631/* rev12a only */
632static void setwhite(struct gspca_dev *gspca_dev)
648{ 633{
649 struct sd *sd = (struct sd *) gspca_dev; 634 struct sd *sd = (struct sd *) gspca_dev;
635 __u16 white;
636 __u8 reg8614, reg8616;
637
638 white = sd->white;
639 /* try to emulate MS-win as possible */
640 reg8616 = 0x90 - white * 5 / 8;
641 reg_w_val(gspca_dev->dev, 0x8616, reg8616);
642 reg8614 = 0x20 + white * 3 / 8;
643 reg_w_val(gspca_dev->dev, 0x8614, reg8614);
644}
650 645
651 if (sd->chip_revision == Rev072A) { 646/* rev 12a only */
652 if (sd->autogain) 647static void setexposure(struct gspca_dev *gspca_dev)
653 sd->ag_cnt = AG_CNT_START; 648{
654 else 649 struct sd *sd = (struct sd *) gspca_dev;
655 sd->ag_cnt = -1; 650 int expo;
651 int clock_divider;
652 __u8 data[2];
653
654 /* Register 0x8309 controls exposure for the spca561,
655 the basic exposure setting goes from 1-2047, where 1 is completely
656 dark and 2047 is very bright. It not only influences exposure but
657 also the framerate (to allow for longer exposure) from 1 - 300 it
658 only raises the exposure time then from 300 - 600 it halves the
659 framerate to be able to further raise the exposure time and for every
660 300 more it halves the framerate again. This allows for a maximum
661 exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
662 Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
663 configure a divider for the base framerate which us used at the
664 exposure setting of 1-300. These bits configure the base framerate
665 according to the following formula: fps = 60 / (value + 2) */
666 if (sd->exposure < 2048) {
667 expo = sd->exposure;
668 clock_divider = 0;
669 } else {
670 /* Add 900 to make the 0 setting of the second part of the
671 exposure equal to the 2047 setting of the first part. */
672 expo = (sd->exposure - 2048) + 900;
673 clock_divider = 3;
656 } 674 }
675 expo |= clock_divider << 11;
676 data[0] = expo;
677 data[1] = expo >> 8;
678 reg_w_buf(gspca_dev, 0x8309, data, 2);
679}
680
681/* rev 12a only */
682static void setgain(struct gspca_dev *gspca_dev)
683{
684 struct sd *sd = (struct sd *) gspca_dev;
685 __u8 data[2];
686
687 data[0] = sd->gain;
688 data[1] = 0;
689 reg_w_buf(gspca_dev, 0x8335, data, 2);
657} 690}
658 691
659static void sd_start(struct gspca_dev *gspca_dev) 692static void setautogain(struct gspca_dev *gspca_dev)
660{ 693{
661 struct sd *sd = (struct sd *) gspca_dev; 694 struct sd *sd = (struct sd *) gspca_dev;
695
696 if (sd->autogain)
697 sd->ag_cnt = AG_CNT_START;
698 else
699 sd->ag_cnt = -1;
700}
701
702static void sd_start_12a(struct gspca_dev *gspca_dev)
703{
662 struct usb_device *dev = gspca_dev->dev; 704 struct usb_device *dev = gspca_dev->dev;
663 int Clck; 705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
664 __u8 Reg8307[] = { 0xaa, 0x00 }; 706 __u8 Reg8307[] = { 0xaa, 0x00 };
665 int mode; 707 int mode;
666 708
667 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 709 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
668 switch (sd->chip_revision) { 710 if (mode <= 1) {
669 case Rev072A: 711 /* Use compression on 320x240 and above */
670 switch (mode) { 712 reg_w_val(dev, 0x8500, 0x10 | mode);
671 default: 713 } else {
672/* case 0: 714 /* I couldn't get the compression to work below 320x240
673 case 1: */ 715 * Fortunately at these resolutions the bandwidth
674 Clck = 0x25; 716 * is sufficient to push raw frames at ~20fps */
675 break; 717 reg_w_val(dev, 0x8500, mode);
676 case 2: 718 } /* -- qq@kuku.eu.org */
677 Clck = 0x22; 719 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
678 break; 720 reg_w_val(gspca_dev->dev, 0x8700, Clck);
679 case 3: 721 /* 0x8f 0x85 0x27 clock */
680 Clck = 0x21; 722 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
681 break; 723 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
682 } 724 setcontrast(gspca_dev);
683 reg_w_val(dev, 0x8500, mode); /* mode */ 725 setwhite(gspca_dev);
684 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 726 setautogain(gspca_dev);
685 reg_w_val(dev, 0x8112, 0x10 | 0x20); 727 setexposure(gspca_dev);
686 setautogain(gspca_dev); 728}
687 break; 729static void sd_start_72a(struct gspca_dev *gspca_dev)
730{
731 struct usb_device *dev = gspca_dev->dev;
732 int Clck;
733 int mode;
734
735 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
736 switch (mode) {
688 default: 737 default:
689/* case Rev012A: */ 738/* case 0:
690 switch (mode) { 739 case 1: */
691 case 0: 740 Clck = 0x25;
692 case 1: 741 break;
693 Clck = 0x8a; 742 case 2:
694 break; 743 Clck = 0x22;
695 case 2: 744 break;
696 Clck = 0x85; 745 case 3:
697 break; 746 Clck = 0x21;
698 default:
699 Clck = 0x83;
700 break;
701 }
702 if (mode <= 1) {
703 /* Use compression on 320x240 and above */
704 reg_w_val(dev, 0x8500, 0x10 | mode);
705 } else {
706 /* I couldn't get the compression to work below 320x240
707 * Fortunately at these resolutions the bandwidth
708 * is sufficient to push raw frames at ~20fps */
709 reg_w_val(dev, 0x8500, mode);
710 } /* -- qq@kuku.eu.org */
711 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
712 reg_w_val(gspca_dev->dev, 0x8700, Clck);
713 /* 0x8f 0x85 0x27 clock */
714 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
715 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
716 setcontrast(gspca_dev);
717 break; 747 break;
718 } 748 }
749 reg_w_val(dev, 0x8500, mode); /* mode */
750 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
751 reg_w_val(dev, 0x8112, 0x10 | 0x20);
752 setautogain(gspca_dev);
719} 753}
720 754
721static void sd_stopN(struct gspca_dev *gspca_dev) 755static void sd_stopN(struct gspca_dev *gspca_dev)
722{ 756{
723 reg_w_val(gspca_dev->dev, 0x8112, 0x20); 757 struct sd *sd = (struct sd *) gspca_dev;
758
759 if (sd->chip_revision == Rev012A) {
760 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
761 } else {
762 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
763/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
764 }
724} 765}
725 766
726static void sd_stop0(struct gspca_dev *gspca_dev) 767static void sd_stop0(struct gspca_dev *gspca_dev)
727{ 768{
728} 769 struct sd *sd = (struct sd *) gspca_dev;
729 770
730/* this function is called at close time */ 771 if (sd->chip_revision == Rev012A) {
731static void sd_close(struct gspca_dev *gspca_dev) 772 reg_w_val(gspca_dev->dev, 0x8118, 0x29);
732{ 773 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
733 reg_w_val(gspca_dev->dev, 0x8114, 0); 774 }
775/* reg_w_val(gspca_dev->dev, 0x8114, 0); */
734} 776}
735 777
736static void do_autogain(struct gspca_dev *gspca_dev) 778static void do_autogain(struct gspca_dev *gspca_dev)
@@ -744,6 +786,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
744 __u8 luma_mean = 110; 786 __u8 luma_mean = 110;
745 __u8 luma_delta = 20; 787 __u8 luma_delta = 20;
746 __u8 spring = 4; 788 __u8 spring = 4;
789 __u8 reg8339[2];
747 790
748 if (sd->ag_cnt < 0) 791 if (sd->ag_cnt < 0)
749 return; 792 return;
@@ -798,13 +841,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
798 } 841 }
799 break; 842 break;
800 case Rev012A: 843 case Rev012A:
801 /* sensor registers is access and memory mapped to 0x8300 */ 844 reg_r(gspca_dev, 0x8330, 2);
802 /* readind all 0x83xx block the sensor */ 845 if (gspca_dev->usb_buf[1] > 0x08) {
803 /* 846 reg8339[0] = ++sd->expo12a;
804 * The data from the header seem wrong where is the luma 847 reg8339[1] = 0;
805 * and chroma mean value 848 reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
806 * at the moment set exposure in contrast set 849 } else if (gspca_dev->usb_buf[1] < 0x02) {
807 */ 850 reg8339[0] = --sd->expo12a;
851 reg8339[1] = 0;
852 reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
853 }
808 break; 854 break;
809 } 855 }
810} 856}
@@ -814,6 +860,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
814 __u8 *data, /* isoc packet */ 860 __u8 *data, /* isoc packet */
815 int len) /* iso packet length */ 861 int len) /* iso packet length */
816{ 862{
863 struct sd *sd = (struct sd *) gspca_dev;
864
817 switch (data[0]) { 865 switch (data[0]) {
818 case 0: /* start of frame */ 866 case 0: /* start of frame */
819 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 867 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -826,8 +874,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
826 frame, data, len); 874 frame, data, len);
827 } else { 875 } else {
828 /* raw bayer (with a header, which we skip) */ 876 /* raw bayer (with a header, which we skip) */
829 data += 20; 877 if (sd->chip_revision == Rev012A) {
830 len -= 20; 878 data += 20;
879 len -= 20;
880 } else {
881 data += 16;
882 len -= 16;
883 }
831 gspca_frame_add(gspca_dev, FIRST_PACKET, 884 gspca_frame_add(gspca_dev, FIRST_PACKET,
832 frame, data, len); 885 frame, data, len);
833 } 886 }
@@ -841,24 +894,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
841 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 894 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
842} 895}
843 896
897/* rev 72a only */
844static void setbrightness(struct gspca_dev *gspca_dev) 898static void setbrightness(struct gspca_dev *gspca_dev)
845{ 899{
846 struct sd *sd = (struct sd *) gspca_dev; 900 struct sd *sd = (struct sd *) gspca_dev;
847 __u8 value; 901 __u8 value;
848 902
849 switch (sd->chip_revision) { 903 value = sd->brightness;
850 case Rev072A: 904 reg_w_val(gspca_dev->dev, 0x8611, value);
851 value = sd->brightness; 905 reg_w_val(gspca_dev->dev, 0x8612, value);
852 reg_w_val(gspca_dev->dev, value, 0x8611); 906 reg_w_val(gspca_dev->dev, 0x8613, value);
853 reg_w_val(gspca_dev->dev, value, 0x8612); 907 reg_w_val(gspca_dev->dev, 0x8614, value);
854 reg_w_val(gspca_dev->dev, value, 0x8613);
855 reg_w_val(gspca_dev->dev, value, 0x8614);
856 break;
857 default:
858/* case Rev012A: */
859 setcontrast(gspca_dev);
860 break;
861 }
862} 908}
863 909
864static void getbrightness(struct gspca_dev *gspca_dev) 910static void getbrightness(struct gspca_dev *gspca_dev)
@@ -866,52 +912,38 @@ static void getbrightness(struct gspca_dev *gspca_dev)
866 struct sd *sd = (struct sd *) gspca_dev; 912 struct sd *sd = (struct sd *) gspca_dev;
867 __u16 tot; 913 __u16 tot;
868 914
869 switch (sd->chip_revision) { 915 tot = 0;
870 case Rev072A: 916 reg_r(gspca_dev, 0x8611, 1);
871 tot = 0; 917 tot += gspca_dev->usb_buf[0];
872 reg_r(gspca_dev, 0x8611, 1); 918 reg_r(gspca_dev, 0x8612, 1);
873 tot += gspca_dev->usb_buf[0]; 919 tot += gspca_dev->usb_buf[0];
874 reg_r(gspca_dev, 0x8612, 1); 920 reg_r(gspca_dev, 0x8613, 1);
875 tot += gspca_dev->usb_buf[0]; 921 tot += gspca_dev->usb_buf[0];
876 reg_r(gspca_dev, 0x8613, 1); 922 reg_r(gspca_dev, 0x8614, 1);
877 tot += gspca_dev->usb_buf[0]; 923 tot += gspca_dev->usb_buf[0];
878 reg_r(gspca_dev, 0x8614, 1); 924 sd->brightness = tot >> 2;
879 tot += gspca_dev->usb_buf[0];
880 sd->brightness = tot >> 2;
881 break;
882 default:
883/* case Rev012A: */
884 /* no way to read sensor settings */
885 break;
886 }
887} 925}
888 926
927/* rev72a only */
889static void getcontrast(struct gspca_dev *gspca_dev) 928static void getcontrast(struct gspca_dev *gspca_dev)
890{ 929{
891 struct sd *sd = (struct sd *) gspca_dev; 930 struct sd *sd = (struct sd *) gspca_dev;
892 __u16 tot; 931 __u16 tot;
893 932
894 switch (sd->chip_revision) { 933 tot = 0;
895 case Rev072A: 934 reg_r(gspca_dev, 0x8651, 1);
896 tot = 0; 935 tot += gspca_dev->usb_buf[0];
897 reg_r(gspca_dev, 0x8651, 1); 936 reg_r(gspca_dev, 0x8652, 1);
898 tot += gspca_dev->usb_buf[0]; 937 tot += gspca_dev->usb_buf[0];
899 reg_r(gspca_dev, 0x8652, 1); 938 reg_r(gspca_dev, 0x8653, 1);
900 tot += gspca_dev->usb_buf[0]; 939 tot += gspca_dev->usb_buf[0];
901 reg_r(gspca_dev, 0x8653, 1); 940 reg_r(gspca_dev, 0x8654, 1);
902 tot += gspca_dev->usb_buf[0]; 941 tot += gspca_dev->usb_buf[0];
903 reg_r(gspca_dev, 0x8654, 1); 942 sd->contrast = tot << 6;
904 tot += gspca_dev->usb_buf[0];
905 sd->contrast = tot << 6;
906 break;
907 default:
908/* case Rev012A: */
909 /* no way to read sensor settings */
910 break;
911 }
912 PDEBUG(D_CONF, "get contrast %d", sd->contrast); 943 PDEBUG(D_CONF, "get contrast %d", sd->contrast);
913} 944}
914 945
946/* rev 72a only */
915static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 947static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
916{ 948{
917 struct sd *sd = (struct sd *) gspca_dev; 949 struct sd *sd = (struct sd *) gspca_dev;
@@ -931,6 +963,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
931 return 0; 963 return 0;
932} 964}
933 965
966/* rev 72a only */
934static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 967static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
935{ 968{
936 struct sd *sd = (struct sd *) gspca_dev; 969 struct sd *sd = (struct sd *) gspca_dev;
@@ -968,20 +1001,190 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
968 return 0; 1001 return 0;
969} 1002}
970 1003
1004/* rev12a only */
1005static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
1006{
1007 struct sd *sd = (struct sd *) gspca_dev;
1008
1009 sd->white = val;
1010 if (gspca_dev->streaming)
1011 setwhite(gspca_dev);
1012 return 0;
1013}
1014
1015static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
1016{
1017 struct sd *sd = (struct sd *) gspca_dev;
1018
1019 *val = sd->white;
1020 return 0;
1021}
1022
1023/* rev12a only */
1024static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1025{
1026 struct sd *sd = (struct sd *) gspca_dev;
1027
1028 sd->exposure = val;
1029 if (gspca_dev->streaming)
1030 setexposure(gspca_dev);
1031 return 0;
1032}
1033
1034static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1035{
1036 struct sd *sd = (struct sd *) gspca_dev;
1037
1038 *val = sd->exposure;
1039 return 0;
1040}
1041
1042/* rev12a only */
1043static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1044{
1045 struct sd *sd = (struct sd *) gspca_dev;
1046
1047 sd->gain = val;
1048 if (gspca_dev->streaming)
1049 setgain(gspca_dev);
1050 return 0;
1051}
1052
1053static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1054{
1055 struct sd *sd = (struct sd *) gspca_dev;
1056
1057 *val = sd->gain;
1058 return 0;
1059}
1060
1061/* control tables */
1062static struct ctrl sd_ctrls_12a[] = {
1063 {
1064 {
1065 .id = V4L2_CID_DO_WHITE_BALANCE,
1066 .type = V4L2_CTRL_TYPE_INTEGER,
1067 .name = "While Balance",
1068 .minimum = WHITE_MIN,
1069 .maximum = WHITE_MAX,
1070 .step = 1,
1071 .default_value = WHITE_DEF,
1072 },
1073 .set = sd_setwhite,
1074 .get = sd_getwhite,
1075 },
1076 {
1077 {
1078 .id = V4L2_CID_EXPOSURE,
1079 .type = V4L2_CTRL_TYPE_INTEGER,
1080 .name = "Exposure",
1081 .minimum = EXPOSURE_MIN,
1082 .maximum = EXPOSURE_MAX,
1083 .step = 1,
1084 .default_value = EXPOSURE_DEF,
1085 },
1086 .set = sd_setexposure,
1087 .get = sd_getexposure,
1088 },
1089 {
1090 {
1091 .id = V4L2_CID_AUTOGAIN,
1092 .type = V4L2_CTRL_TYPE_BOOLEAN,
1093 .name = "Auto Gain",
1094 .minimum = AUTOGAIN_MIN,
1095 .maximum = AUTOGAIN_MAX,
1096 .step = 1,
1097 .default_value = AUTOGAIN_DEF,
1098 },
1099 .set = sd_setautogain,
1100 .get = sd_getautogain,
1101 },
1102 {
1103 {
1104 .id = V4L2_CID_GAIN,
1105 .type = V4L2_CTRL_TYPE_INTEGER,
1106 .name = "Gain",
1107 .minimum = GAIN_MIN,
1108 .maximum = GAIN_MAX,
1109 .step = 1,
1110 .default_value = GAIN_DEF,
1111 },
1112 .set = sd_setgain,
1113 .get = sd_getgain,
1114 },
1115};
1116
1117static struct ctrl sd_ctrls_72a[] = {
1118 {
1119 {
1120 .id = V4L2_CID_BRIGHTNESS,
1121 .type = V4L2_CTRL_TYPE_INTEGER,
1122 .name = "Brightness",
1123 .minimum = BRIGHTNESS_MIN,
1124 .maximum = BRIGHTNESS_MAX,
1125 .step = 1,
1126 .default_value = BRIGHTNESS_DEF,
1127 },
1128 .set = sd_setbrightness,
1129 .get = sd_getbrightness,
1130 },
1131 {
1132 {
1133 .id = V4L2_CID_CONTRAST,
1134 .type = V4L2_CTRL_TYPE_INTEGER,
1135 .name = "Contrast",
1136 .minimum = CONTRAST_MIN,
1137 .maximum = CONTRAST_MAX,
1138 .step = 1,
1139 .default_value = CONTRAST_DEF,
1140 },
1141 .set = sd_setcontrast,
1142 .get = sd_getcontrast,
1143 },
1144 {
1145 {
1146 .id = V4L2_CID_AUTOGAIN,
1147 .type = V4L2_CTRL_TYPE_BOOLEAN,
1148 .name = "Auto Gain",
1149 .minimum = AUTOGAIN_MIN,
1150 .maximum = AUTOGAIN_MAX,
1151 .step = 1,
1152 .default_value = AUTOGAIN_DEF,
1153 },
1154 .set = sd_setautogain,
1155 .get = sd_getautogain,
1156 },
1157};
1158
971/* sub-driver description */ 1159/* sub-driver description */
972static const struct sd_desc sd_desc = { 1160static const struct sd_desc sd_desc_12a = {
1161 .name = MODULE_NAME,
1162 .ctrls = sd_ctrls_12a,
1163 .nctrls = ARRAY_SIZE(sd_ctrls_12a),
1164 .config = sd_config,
1165 .init = sd_init_12a,
1166 .start = sd_start_12a,
1167 .stopN = sd_stopN,
1168 .stop0 = sd_stop0,
1169 .pkt_scan = sd_pkt_scan,
1170/* .dq_callback = do_autogain, * fixme */
1171};
1172static const struct sd_desc sd_desc_72a = {
973 .name = MODULE_NAME, 1173 .name = MODULE_NAME,
974 .ctrls = sd_ctrls, 1174 .ctrls = sd_ctrls_72a,
975 .nctrls = ARRAY_SIZE(sd_ctrls), 1175 .nctrls = ARRAY_SIZE(sd_ctrls_72a),
976 .config = sd_config, 1176 .config = sd_config,
977 .open = sd_open, 1177 .init = sd_init_72a,
978 .start = sd_start, 1178 .start = sd_start_72a,
979 .stopN = sd_stopN, 1179 .stopN = sd_stopN,
980 .stop0 = sd_stop0, 1180 .stop0 = sd_stop0,
981 .close = sd_close,
982 .pkt_scan = sd_pkt_scan, 1181 .pkt_scan = sd_pkt_scan,
983 .dq_callback = do_autogain, 1182 .dq_callback = do_autogain,
984}; 1183};
1184static const struct sd_desc *sd_desc[2] = {
1185 &sd_desc_12a,
1186 &sd_desc_72a
1187};
985 1188
986/* -- module initialisation -- */ 1189/* -- module initialisation -- */
987static const __devinitdata struct usb_device_id device_table[] = { 1190static const __devinitdata struct usb_device_id device_table[] = {
@@ -1009,7 +1212,9 @@ MODULE_DEVICE_TABLE(usb, device_table);
1009static int sd_probe(struct usb_interface *intf, 1212static int sd_probe(struct usb_interface *intf,
1010 const struct usb_device_id *id) 1213 const struct usb_device_id *id)
1011{ 1214{
1012 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 1215 return gspca_dev_probe(intf, id,
1216 sd_desc[id->driver_info],
1217 sizeof(struct sd),
1013 THIS_MODULE); 1218 THIS_MODULE);
1014} 1219}
1015 1220
@@ -1018,6 +1223,10 @@ static struct usb_driver sd_driver = {
1018 .id_table = device_table, 1223 .id_table = device_table,
1019 .probe = sd_probe, 1224 .probe = sd_probe,
1020 .disconnect = gspca_disconnect, 1225 .disconnect = gspca_disconnect,
1226#ifdef CONFIG_PM
1227 .suspend = gspca_suspend,
1228 .resume = gspca_resume,
1229#endif
1021}; 1230};
1022 1231
1023/* -- module insert / remove -- */ 1232/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 16219cf6a6d5..2f2de429e273 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -306,8 +306,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
306 return 0; 306 return 0;
307} 307}
308 308
309/* this function is called at open time */ 309/* this function is called at probe and resume time */
310static int sd_open(struct gspca_dev *gspca_dev) 310static int sd_init(struct gspca_dev *gspca_dev)
311{ 311{
312 int ret; 312 int ret;
313 313
@@ -398,14 +398,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
398 PDEBUG(D_STREAM, "camera stopped"); 398 PDEBUG(D_STREAM, "camera stopped");
399} 399}
400 400
401static void sd_stop0(struct gspca_dev *gspca_dev)
402{
403}
404
405static void sd_close(struct gspca_dev *gspca_dev)
406{
407}
408
409static void sd_pkt_scan(struct gspca_dev *gspca_dev, 401static void sd_pkt_scan(struct gspca_dev *gspca_dev,
410 struct gspca_frame *frame, /* target */ 402 struct gspca_frame *frame, /* target */
411 __u8 *data, /* isoc packet */ 403 __u8 *data, /* isoc packet */
@@ -535,11 +527,9 @@ static const struct sd_desc sd_desc = {
535 .ctrls = sd_ctrls, 527 .ctrls = sd_ctrls,
536 .nctrls = ARRAY_SIZE(sd_ctrls), 528 .nctrls = ARRAY_SIZE(sd_ctrls),
537 .config = sd_config, 529 .config = sd_config,
538 .open = sd_open, 530 .init = sd_init,
539 .start = sd_start, 531 .start = sd_start,
540 .stopN = sd_stopN, 532 .stopN = sd_stopN,
541 .stop0 = sd_stop0,
542 .close = sd_close,
543 .pkt_scan = sd_pkt_scan, 533 .pkt_scan = sd_pkt_scan,
544 .querymenu = sd_querymenu, 534 .querymenu = sd_querymenu,
545}; 535};
@@ -564,6 +554,10 @@ static struct usb_driver sd_driver = {
564 .id_table = device_table, 554 .id_table = device_table,
565 .probe = sd_probe, 555 .probe = sd_probe,
566 .disconnect = gspca_disconnect, 556 .disconnect = gspca_disconnect,
557#ifdef CONFIG_PM
558 .suspend = gspca_suspend,
559 .resume = gspca_resume,
560#endif
567}; 561};
568 562
569/* -- module insert / remove -- */ 563/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 54efa48bee01..1cfcc6c49558 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -449,31 +449,47 @@ static const __u8 qtable_spca504_default[2][64] = {
449 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} 449 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
450}; 450};
451 451
452static void reg_r(struct usb_device *dev, 452/* read <len> bytes to gspca_dev->usb_buf */
453 __u16 req, 453static void reg_r(struct gspca_dev *gspca_dev,
454 __u16 index, 454 __u16 req,
455 __u8 *buffer, __u16 length) 455 __u16 index,
456 __u16 len)
456{ 457{
457 usb_control_msg(dev, 458#ifdef GSPCA_DEBUG
458 usb_rcvctrlpipe(dev, 0), 459 if (len > USB_BUF_SZ) {
460 err("reg_r: buffer overflow");
461 return;
462 }
463#endif
464 usb_control_msg(gspca_dev->dev,
465 usb_rcvctrlpipe(gspca_dev->dev, 0),
459 req, 466 req,
460 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 467 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
461 0, /* value */ 468 0, /* value */
462 index, buffer, length, 469 index,
470 len ? gspca_dev->usb_buf : NULL, len,
463 500); 471 500);
464} 472}
465 473
466static void reg_w(struct usb_device *dev, 474/* write <len> bytes from gspca_dev->usb_buf */
467 __u16 req, 475static void reg_w(struct gspca_dev *gspca_dev,
468 __u16 value, 476 __u16 req,
469 __u16 index, 477 __u16 value,
470 __u8 *buffer, __u16 length) 478 __u16 index,
479 __u16 len)
471{ 480{
472 usb_control_msg(dev, 481#ifdef GSPCA_DEBUG
473 usb_sndctrlpipe(dev, 0), 482 if (len > USB_BUF_SZ) {
483 err("reg_w: buffer overflow");
484 return;
485 }
486#endif
487 usb_control_msg(gspca_dev->dev,
488 usb_sndctrlpipe(gspca_dev->dev, 0),
474 req, 489 req,
475 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 490 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
476 value, index, buffer, length, 491 value, index,
492 len ? gspca_dev->usb_buf : NULL, len,
477 500); 493 500);
478} 494}
479 495
@@ -634,7 +650,7 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
634 int count = 10; 650 int count = 10;
635 651
636 while (--count > 0) { 652 while (--count > 0) {
637 reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1); 653 reg_r(gspca_dev, 0x21, 0, 1);
638 if ((gspca_dev->usb_buf[0] & 0x01) == 0) 654 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
639 break; 655 break;
640 msleep(10); 656 msleep(10);
@@ -644,15 +660,14 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
644 660
645static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) 661static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
646{ 662{
647 struct usb_device *dev = gspca_dev->dev;
648 int count = 50; 663 int count = 50;
649 664
650 while (--count > 0) { 665 while (--count > 0) {
651 reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); 666 reg_r(gspca_dev, 0x21, 1, 1);
652 if (gspca_dev->usb_buf[0] != 0) { 667 if (gspca_dev->usb_buf[0] != 0) {
653 gspca_dev->usb_buf[0] = 0; 668 gspca_dev->usb_buf[0] = 0;
654 reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1); 669 reg_w(gspca_dev, 0x21, 0, 1, 1);
655 reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); 670 reg_r(gspca_dev, 0x21, 1, 1);
656 spca504B_PollingDataReady(gspca_dev); 671 spca504B_PollingDataReady(gspca_dev);
657 break; 672 break;
658 } 673 }
@@ -662,16 +677,14 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
662 677
663static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) 678static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
664{ 679{
665 struct usb_device *dev = gspca_dev->dev;
666 __u8 *data; 680 __u8 *data;
667 681
668 data = kmalloc(64, GFP_KERNEL); 682 data = gspca_dev->usb_buf;
669 reg_r(dev, 0x20, 0, data, 5); 683 reg_r(gspca_dev, 0x20, 0, 5);
670 PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", 684 PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
671 data[0], data[1], data[2], data[3], data[4]); 685 data[0], data[1], data[2], data[3], data[4]);
672 reg_r(dev, 0x23, 0, data, 64); 686 reg_r(gspca_dev, 0x23, 0, 64);
673 reg_r(dev, 0x23, 1, data, 64); 687 reg_r(gspca_dev, 0x23, 1, 64);
674 kfree(data);
675} 688}
676 689
677static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) 690static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
@@ -686,21 +699,21 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
686 Type = 0; 699 Type = 0;
687 switch (sd->bridge) { 700 switch (sd->bridge) {
688 case BRIDGE_SPCA533: 701 case BRIDGE_SPCA533:
689 reg_w(dev, 0x31, 0, 0, NULL, 0); 702 reg_w(gspca_dev, 0x31, 0, 0, 0);
690 spca504B_WaitCmdStatus(gspca_dev); 703 spca504B_WaitCmdStatus(gspca_dev);
691 rc = spca504B_PollingDataReady(gspca_dev); 704 rc = spca504B_PollingDataReady(gspca_dev);
692 spca50x_GetFirmware(gspca_dev); 705 spca50x_GetFirmware(gspca_dev);
693 gspca_dev->usb_buf[0] = 2; /* type */ 706 gspca_dev->usb_buf[0] = 2; /* type */
694 reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1); 707 reg_w(gspca_dev, 0x24, 0, 8, 1);
695 reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1); 708 reg_r(gspca_dev, 0x24, 8, 1);
696 709
697 gspca_dev->usb_buf[0] = Size; 710 gspca_dev->usb_buf[0] = Size;
698 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); 711 reg_w(gspca_dev, 0x25, 0, 4, 1);
699 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ 712 reg_r(gspca_dev, 0x25, 4, 1); /* size */
700 rc = spca504B_PollingDataReady(gspca_dev); 713 rc = spca504B_PollingDataReady(gspca_dev);
701 714
702 /* Init the cam width height with some values get on init ? */ 715 /* Init the cam width height with some values get on init ? */
703 reg_w(dev, 0x31, 0, 4, NULL, 0); 716 reg_w(gspca_dev, 0x31, 0, 4, 0);
704 spca504B_WaitCmdStatus(gspca_dev); 717 spca504B_WaitCmdStatus(gspca_dev);
705 rc = spca504B_PollingDataReady(gspca_dev); 718 rc = spca504B_PollingDataReady(gspca_dev);
706 break; 719 break;
@@ -708,12 +721,12 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
708/* case BRIDGE_SPCA504B: */ 721/* case BRIDGE_SPCA504B: */
709/* case BRIDGE_SPCA536: */ 722/* case BRIDGE_SPCA536: */
710 gspca_dev->usb_buf[0] = Size; 723 gspca_dev->usb_buf[0] = Size;
711 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); 724 reg_w(gspca_dev, 0x25, 0, 4, 1);
712 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ 725 reg_r(gspca_dev, 0x25, 4, 1); /* size */
713 Type = 6; 726 Type = 6;
714 gspca_dev->usb_buf[0] = Type; 727 gspca_dev->usb_buf[0] = Type;
715 reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1); 728 reg_w(gspca_dev, 0x27, 0, 0, 1);
716 reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */ 729 reg_r(gspca_dev, 0x27, 0, 1); /* type */
717 rc = spca504B_PollingDataReady(gspca_dev); 730 rc = spca504B_PollingDataReady(gspca_dev);
718 break; 731 break;
719 case BRIDGE_SPCA504: 732 case BRIDGE_SPCA504:
@@ -752,18 +765,15 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
752 765
753static void spca504B_setQtable(struct gspca_dev *gspca_dev) 766static void spca504B_setQtable(struct gspca_dev *gspca_dev)
754{ 767{
755 struct usb_device *dev = gspca_dev->dev;
756
757 gspca_dev->usb_buf[0] = 3; 768 gspca_dev->usb_buf[0] = 3;
758 reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1); 769 reg_w(gspca_dev, 0x26, 0, 0, 1);
759 reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1); 770 reg_r(gspca_dev, 0x26, 0, 1);
760 spca504B_PollingDataReady(gspca_dev); 771 spca504B_PollingDataReady(gspca_dev);
761} 772}
762 773
763static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) 774static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
764{ 775{
765 struct sd *sd = (struct sd *) gspca_dev; 776 struct sd *sd = (struct sd *) gspca_dev;
766 struct usb_device *dev = gspca_dev->dev;
767 int pollreg = 1; 777 int pollreg = 1;
768 778
769 switch (sd->bridge) { 779 switch (sd->bridge) {
@@ -774,20 +784,20 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
774 default: 784 default:
775/* case BRIDGE_SPCA533: */ 785/* case BRIDGE_SPCA533: */
776/* case BRIDGE_SPCA504B: */ 786/* case BRIDGE_SPCA504B: */
777 reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ 787 reg_w(gspca_dev, 0, 0, 0x21a7, 0); /* brightness */
778 reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ 788 reg_w(gspca_dev, 0, 0x20, 0x21a8, 0); /* contrast */
779 reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ 789 reg_w(gspca_dev, 0, 0, 0x21ad, 0); /* hue */
780 reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ 790 reg_w(gspca_dev, 0, 1, 0x21ac, 0); /* sat/hue */
781 reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ 791 reg_w(gspca_dev, 0, 0x20, 0x21ae, 0); /* saturation */
782 reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ 792 reg_w(gspca_dev, 0, 0, 0x21a3, 0); /* gamma */
783 break; 793 break;
784 case BRIDGE_SPCA536: 794 case BRIDGE_SPCA536:
785 reg_w(dev, 0, 0, 0x20f0, NULL, 0); 795 reg_w(gspca_dev, 0, 0, 0x20f0, 0);
786 reg_w(dev, 0, 0x21, 0x20f1, NULL, 0); 796 reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
787 reg_w(dev, 0, 0x40, 0x20f5, NULL, 0); 797 reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
788 reg_w(dev, 0, 1, 0x20f4, NULL, 0); 798 reg_w(gspca_dev, 0, 1, 0x20f4, 0);
789 reg_w(dev, 0, 0x40, 0x20f6, NULL, 0); 799 reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
790 reg_w(dev, 0, 0, 0x2089, NULL, 0); 800 reg_w(gspca_dev, 0, 0, 0x2089, 0);
791 break; 801 break;
792 } 802 }
793 if (pollreg) 803 if (pollreg)
@@ -799,7 +809,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
799 const struct usb_device_id *id) 809 const struct usb_device_id *id)
800{ 810{
801 struct sd *sd = (struct sd *) gspca_dev; 811 struct sd *sd = (struct sd *) gspca_dev;
802 struct usb_device *dev = gspca_dev->dev;
803 struct cam *cam; 812 struct cam *cam;
804 813
805 cam = &gspca_dev->cam; 814 cam = &gspca_dev->cam;
@@ -811,7 +820,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
811 if (sd->subtype == AiptekMiniPenCam13) { 820 if (sd->subtype == AiptekMiniPenCam13) {
812/* try to get the firmware as some cam answer 2.0.1.2.2 821/* try to get the firmware as some cam answer 2.0.1.2.2
813 * and should be a spca504b then overwrite that setting */ 822 * and should be a spca504b then overwrite that setting */
814 reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); 823 reg_r(gspca_dev, 0x20, 0, 1);
815 switch (gspca_dev->usb_buf[0]) { 824 switch (gspca_dev->usb_buf[0]) {
816 case 1: 825 case 1:
817 break; /* (right bridge/subtype) */ 826 break; /* (right bridge/subtype) */
@@ -848,8 +857,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
848 return 0; 857 return 0;
849} 858}
850 859
851/* this function is called at open time */ 860/* this function is called at probe and resume time */
852static int sd_open(struct gspca_dev *gspca_dev) 861static int sd_init(struct gspca_dev *gspca_dev)
853{ 862{
854 struct sd *sd = (struct sd *) gspca_dev; 863 struct sd *sd = (struct sd *) gspca_dev;
855 struct usb_device *dev = gspca_dev->dev; 864 struct usb_device *dev = gspca_dev->dev;
@@ -860,12 +869,12 @@ static int sd_open(struct gspca_dev *gspca_dev)
860 869
861 switch (sd->bridge) { 870 switch (sd->bridge) {
862 case BRIDGE_SPCA504B: 871 case BRIDGE_SPCA504B:
863 reg_w(dev, 0x1d, 0, 0, NULL, 0); 872 reg_w(gspca_dev, 0x1d, 0, 0, 0);
864 reg_w(dev, 0, 1, 0x2306, NULL, 0); 873 reg_w(gspca_dev, 0, 1, 0x2306, 0);
865 reg_w(dev, 0, 0, 0x0d04, NULL, 0); 874 reg_w(gspca_dev, 0, 0, 0x0d04, 0);
866 reg_w(dev, 0, 0, 0x2000, NULL, 0); 875 reg_w(gspca_dev, 0, 0, 0x2000, 0);
867 reg_w(dev, 0, 0x13, 0x2301, NULL, 0); 876 reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
868 reg_w(dev, 0, 0, 0x2306, NULL, 0); 877 reg_w(gspca_dev, 0, 0, 0x2306, 0);
869 /* fall thru */ 878 /* fall thru */
870 case BRIDGE_SPCA533: 879 case BRIDGE_SPCA533:
871 rc = spca504B_PollingDataReady(gspca_dev); 880 rc = spca504B_PollingDataReady(gspca_dev);
@@ -873,12 +882,12 @@ static int sd_open(struct gspca_dev *gspca_dev)
873 break; 882 break;
874 case BRIDGE_SPCA536: 883 case BRIDGE_SPCA536:
875 spca50x_GetFirmware(gspca_dev); 884 spca50x_GetFirmware(gspca_dev);
876 reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1); 885 reg_r(gspca_dev, 0x00, 0x5002, 1);
877 gspca_dev->usb_buf[0] = 0; 886 gspca_dev->usb_buf[0] = 0;
878 reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1); 887 reg_w(gspca_dev, 0x24, 0, 0, 1);
879 reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1); 888 reg_r(gspca_dev, 0x24, 0, 1);
880 rc = spca504B_PollingDataReady(gspca_dev); 889 rc = spca504B_PollingDataReady(gspca_dev);
881 reg_w(dev, 0x34, 0, 0, NULL, 0); 890 reg_w(gspca_dev, 0x34, 0, 0, 0);
882 spca504B_WaitCmdStatus(gspca_dev); 891 spca504B_WaitCmdStatus(gspca_dev);
883 break; 892 break;
884 case BRIDGE_SPCA504C: /* pccam600 */ 893 case BRIDGE_SPCA504C: /* pccam600 */
@@ -971,12 +980,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
971/* case BRIDGE_SPCA536: */ 980/* case BRIDGE_SPCA536: */
972 if (sd->subtype == MegapixV4 || 981 if (sd->subtype == MegapixV4 ||
973 sd->subtype == LogitechClickSmart820) { 982 sd->subtype == LogitechClickSmart820) {
974 reg_w(dev, 0xf0, 0, 0, NULL, 0); 983 reg_w(gspca_dev, 0xf0, 0, 0, 0);
975 spca504B_WaitCmdStatus(gspca_dev); 984 spca504B_WaitCmdStatus(gspca_dev);
976 reg_r(dev, 0xf0, 4, NULL, 0); 985 reg_r(gspca_dev, 0xf0, 4, 0);
977 spca504B_WaitCmdStatus(gspca_dev); 986 spca504B_WaitCmdStatus(gspca_dev);
978 } else { 987 } else {
979 reg_w(dev, 0x31, 0, 4, NULL, 0); 988 reg_w(gspca_dev, 0x31, 0, 4, 0);
980 spca504B_WaitCmdStatus(gspca_dev); 989 spca504B_WaitCmdStatus(gspca_dev);
981 rc = spca504B_PollingDataReady(gspca_dev); 990 rc = spca504B_PollingDataReady(gspca_dev);
982 } 991 }
@@ -1045,7 +1054,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1045/* case BRIDGE_SPCA533: */ 1054/* case BRIDGE_SPCA533: */
1046/* case BRIDGE_SPCA536: */ 1055/* case BRIDGE_SPCA536: */
1047/* case BRIDGE_SPCA504B: */ 1056/* case BRIDGE_SPCA504B: */
1048 reg_w(dev, 0x31, 0, 0, NULL, 0); 1057 reg_w(gspca_dev, 0x31, 0, 0, 0);
1049 spca504B_WaitCmdStatus(gspca_dev); 1058 spca504B_WaitCmdStatus(gspca_dev);
1050 spca504B_PollingDataReady(gspca_dev); 1059 spca504B_PollingDataReady(gspca_dev);
1051 break; 1060 break;
@@ -1069,14 +1078,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1069 } 1078 }
1070} 1079}
1071 1080
1072static void sd_stop0(struct gspca_dev *gspca_dev)
1073{
1074}
1075
1076static void sd_close(struct gspca_dev *gspca_dev)
1077{
1078}
1079
1080static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1081static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1081 struct gspca_frame *frame, /* target */ 1082 struct gspca_frame *frame, /* target */
1082 __u8 *data, /* isoc packet */ 1083 __u8 *data, /* isoc packet */
@@ -1369,11 +1370,9 @@ static const struct sd_desc sd_desc = {
1369 .ctrls = sd_ctrls, 1370 .ctrls = sd_ctrls,
1370 .nctrls = ARRAY_SIZE(sd_ctrls), 1371 .nctrls = ARRAY_SIZE(sd_ctrls),
1371 .config = sd_config, 1372 .config = sd_config,
1372 .open = sd_open, 1373 .init = sd_init,
1373 .start = sd_start, 1374 .start = sd_start,
1374 .stopN = sd_stopN, 1375 .stopN = sd_stopN,
1375 .stop0 = sd_stop0,
1376 .close = sd_close,
1377 .pkt_scan = sd_pkt_scan, 1376 .pkt_scan = sd_pkt_scan,
1378}; 1377};
1379 1378
@@ -1456,6 +1455,10 @@ static struct usb_driver sd_driver = {
1456 .id_table = device_table, 1455 .id_table = device_table,
1457 .probe = sd_probe, 1456 .probe = sd_probe,
1458 .disconnect = gspca_disconnect, 1457 .disconnect = gspca_disconnect,
1458#ifdef CONFIG_PM
1459 .suspend = gspca_suspend,
1460 .resume = gspca_resume,
1461#endif
1459}; 1462};
1460 1463
1461/* -- module insert / remove -- */ 1464/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 91b555c34c68..f034c748fc7e 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -30,7 +30,7 @@
30 30
31#define MAX_GAMMA 0x10 /* 0 to 15 */ 31#define MAX_GAMMA 0x10 /* 0 to 15 */
32 32
33#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) 33#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
34 34
35MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); 35MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
36MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); 36MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
@@ -233,7 +233,7 @@ static char *effects_control[] = {
233static struct v4l2_pix_format vga_mode_t16[] = { 233static struct v4l2_pix_format vga_mode_t16[] = {
234 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 234 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
235 .bytesperline = 160, 235 .bytesperline = 160,
236 .sizeimage = 160 * 120 * 3 / 8 + 590, 236 .sizeimage = 160 * 120 * 4 / 8 + 590,
237 .colorspace = V4L2_COLORSPACE_JPEG, 237 .colorspace = V4L2_COLORSPACE_JPEG,
238 .priv = 4}, 238 .priv = 4},
239 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 239 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -391,7 +391,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
391 NULL, 0, 500); 391 NULL, 0, 500);
392 return; 392 return;
393 } 393 }
394 if (len <= sizeof gspca_dev->usb_buf) { 394 if (len <= USB_BUF_SZ) {
395 memcpy(gspca_dev->usb_buf, buffer, len); 395 memcpy(gspca_dev->usb_buf, buffer, len);
396 usb_control_msg(gspca_dev->dev, 396 usb_control_msg(gspca_dev->dev,
397 usb_sndctrlpipe(gspca_dev->dev, 0), 397 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -552,6 +552,13 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
552 return 0; 552 return 0;
553} 553}
554 554
555/* this function is called at probe and resume time */
556static int sd_init(struct gspca_dev *gspca_dev)
557{
558 init_default_parameters(gspca_dev);
559 return 0;
560}
561
555static void setbrightness(struct gspca_dev *gspca_dev) 562static void setbrightness(struct gspca_dev *gspca_dev)
556{ 563{
557 struct sd *sd = (struct sd *) gspca_dev; 564 struct sd *sd = (struct sd *) gspca_dev;
@@ -893,18 +900,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
893 setcolors(gspca_dev); 900 setcolors(gspca_dev);
894} 901}
895 902
896static void sd_stopN(struct gspca_dev *gspca_dev)
897{
898}
899
900static void sd_stop0(struct gspca_dev *gspca_dev)
901{
902}
903
904static void sd_close(struct gspca_dev *gspca_dev)
905{
906}
907
908static void sd_pkt_scan(struct gspca_dev *gspca_dev, 903static void sd_pkt_scan(struct gspca_dev *gspca_dev,
909 struct gspca_frame *frame, /* target */ 904 struct gspca_frame *frame, /* target */
910 __u8 *data, /* isoc packet */ 905 __u8 *data, /* isoc packet */
@@ -972,24 +967,14 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
972 return -EINVAL; 967 return -EINVAL;
973} 968}
974 969
975/* this function is called at open time */
976static int sd_open(struct gspca_dev *gspca_dev)
977{
978 init_default_parameters(gspca_dev);
979 return 0;
980}
981
982/* sub-driver description */ 970/* sub-driver description */
983static const struct sd_desc sd_desc = { 971static const struct sd_desc sd_desc = {
984 .name = MODULE_NAME, 972 .name = MODULE_NAME,
985 .ctrls = sd_ctrls, 973 .ctrls = sd_ctrls,
986 .nctrls = ARRAY_SIZE(sd_ctrls), 974 .nctrls = ARRAY_SIZE(sd_ctrls),
987 .config = sd_config, 975 .config = sd_config,
988 .open = sd_open, 976 .init = sd_init,
989 .start = sd_start, 977 .start = sd_start,
990 .stopN = sd_stopN,
991 .stop0 = sd_stop0,
992 .close = sd_close,
993 .pkt_scan = sd_pkt_scan, 978 .pkt_scan = sd_pkt_scan,
994 .querymenu = sd_querymenu, 979 .querymenu = sd_querymenu,
995}; 980};
@@ -1014,6 +999,10 @@ static struct usb_driver sd_driver = {
1014 .id_table = device_table, 999 .id_table = device_table,
1015 .probe = sd_probe, 1000 .probe = sd_probe,
1016 .disconnect = gspca_disconnect, 1001 .disconnect = gspca_disconnect,
1002#ifdef CONFIG_PM
1003 .suspend = gspca_suspend,
1004 .resume = gspca_resume,
1005#endif
1017}; 1006};
1018 1007
1019/* -- module insert / remove -- */ 1008/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 1ff8ba2f7fe5..084af05302a0 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -331,8 +331,8 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
331 } 331 }
332} 332}
333 333
334/* this function is called at open time */ 334/* this function is called at probe and resume time */
335static int sd_open(struct gspca_dev *gspca_dev) 335static int sd_init(struct gspca_dev *gspca_dev)
336{ 336{
337 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); 337 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
338 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); 338 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
@@ -450,14 +450,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
450 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); 450 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
451} 451}
452 452
453static void sd_stop0(struct gspca_dev *gspca_dev)
454{
455}
456
457static void sd_close(struct gspca_dev *gspca_dev)
458{
459}
460
461static void tv8532_preprocess(struct gspca_dev *gspca_dev) 453static void tv8532_preprocess(struct gspca_dev *gspca_dev)
462{ 454{
463 struct sd *sd = (struct sd *) gspca_dev; 455 struct sd *sd = (struct sd *) gspca_dev;
@@ -611,11 +603,9 @@ static const struct sd_desc sd_desc = {
611 .ctrls = sd_ctrls, 603 .ctrls = sd_ctrls,
612 .nctrls = ARRAY_SIZE(sd_ctrls), 604 .nctrls = ARRAY_SIZE(sd_ctrls),
613 .config = sd_config, 605 .config = sd_config,
614 .open = sd_open, 606 .init = sd_init,
615 .start = sd_start, 607 .start = sd_start,
616 .stopN = sd_stopN, 608 .stopN = sd_stopN,
617 .stop0 = sd_stop0,
618 .close = sd_close,
619 .pkt_scan = sd_pkt_scan, 609 .pkt_scan = sd_pkt_scan,
620}; 610};
621 611
@@ -644,6 +634,10 @@ static struct usb_driver sd_driver = {
644 .id_table = device_table, 634 .id_table = device_table,
645 .probe = sd_probe, 635 .probe = sd_probe,
646 .disconnect = gspca_disconnect, 636 .disconnect = gspca_disconnect,
637#ifdef CONFIG_PM
638 .suspend = gspca_suspend,
639 .resume = gspca_resume,
640#endif
647}; 641};
648 642
649/* -- module insert / remove -- */ 643/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index f4a52956e0d9..bd4c226c9a07 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -69,6 +69,7 @@ static struct ctrl sd_ctrls[] = {
69 .set = sd_setautogain, 69 .set = sd_setautogain,
70 .get = sd_getautogain, 70 .get = sd_getautogain,
71 }, 71 },
72#define LIGHTFREQ_IDX 1
72 { 73 {
73 { 74 {
74 .id = V4L2_CID_POWER_LINE_FREQUENCY, 75 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -87,12 +88,12 @@ static struct ctrl sd_ctrls[] = {
87}; 88};
88 89
89static struct v4l2_pix_format vc0321_mode[] = { 90static struct v4l2_pix_format vc0321_mode[] = {
90 {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 91 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
91 .bytesperline = 320, 92 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 2, 93 .sizeimage = 320 * 240 * 2,
93 .colorspace = V4L2_COLORSPACE_SRGB, 94 .colorspace = V4L2_COLORSPACE_SRGB,
94 .priv = 1}, 95 .priv = 1},
95 {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 96 {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
96 .bytesperline = 640, 97 .bytesperline = 640,
97 .sizeimage = 640 * 480 * 2, 98 .sizeimage = 640 * 480 * 2,
98 .colorspace = V4L2_COLORSPACE_SRGB, 99 .colorspace = V4L2_COLORSPACE_SRGB,
@@ -1463,6 +1464,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1463 sd->qindex = 7; 1464 sd->qindex = 7;
1464 sd->autogain = AUTOGAIN_DEF; 1465 sd->autogain = AUTOGAIN_DEF;
1465 sd->lightfreq = FREQ_DEF; 1466 sd->lightfreq = FREQ_DEF;
1467 if (sd->sensor != SENSOR_OV7670)
1468 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
1466 1469
1467 if (sd->bridge == BRIDGE_VC0321) { 1470 if (sd->bridge == BRIDGE_VC0321) {
1468 reg_r(gspca_dev, 0x8a, 0, 3); 1471 reg_r(gspca_dev, 0x8a, 0, 3);
@@ -1474,8 +1477,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1474 return 0; 1477 return 0;
1475} 1478}
1476 1479
1477/* this function is called at open time */ 1480/* this function is called at probe and time */
1478static int sd_open(struct gspca_dev *gspca_dev) 1481static int sd_init(struct gspca_dev *gspca_dev)
1479{ 1482{
1480 return 0; 1483 return 0;
1481} 1484}
@@ -1637,19 +1640,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
1637 reg_w(dev, 0x89, 0xffff, 0xffff); 1640 reg_w(dev, 0x89, 0xffff, 0xffff);
1638} 1641}
1639 1642
1640/* this function is called at close time */
1641static void sd_close(struct gspca_dev *gspca_dev)
1642{
1643/* struct usb_device *dev = gspca_dev->dev;
1644 __u8 buffread;
1645
1646 reg_w(dev, 0x89, 0xffff, 0xffff);
1647 reg_w(dev, 0xa0, 0x01, 0xb301);
1648 reg_w(dev, 0xa0, 0x09, 0xb303);
1649 reg_w(dev, 0x89, 0xffff, 0xffff);
1650*/
1651}
1652
1653static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1643static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1654 struct gspca_frame *frame, /* target */ 1644 struct gspca_frame *frame, /* target */
1655 __u8 *data, /* isoc packet */ 1645 __u8 *data, /* isoc packet */
@@ -1738,11 +1728,10 @@ static const struct sd_desc sd_desc = {
1738 .ctrls = sd_ctrls, 1728 .ctrls = sd_ctrls,
1739 .nctrls = ARRAY_SIZE(sd_ctrls), 1729 .nctrls = ARRAY_SIZE(sd_ctrls),
1740 .config = sd_config, 1730 .config = sd_config,
1741 .open = sd_open, 1731 .init = sd_init,
1742 .start = sd_start, 1732 .start = sd_start,
1743 .stopN = sd_stopN, 1733 .stopN = sd_stopN,
1744 .stop0 = sd_stop0, 1734 .stop0 = sd_stop0,
1745 .close = sd_close,
1746 .pkt_scan = sd_pkt_scan, 1735 .pkt_scan = sd_pkt_scan,
1747 .querymenu = sd_querymenu, 1736 .querymenu = sd_querymenu,
1748}; 1737};
@@ -1774,6 +1763,10 @@ static struct usb_driver sd_driver = {
1774 .id_table = device_table, 1763 .id_table = device_table,
1775 .probe = sd_probe, 1764 .probe = sd_probe,
1776 .disconnect = gspca_disconnect, 1765 .disconnect = gspca_disconnect,
1766#ifdef CONFIG_PM
1767 .suspend = gspca_suspend,
1768 .resume = gspca_resume,
1769#endif
1777}; 1770};
1778 1771
1779/* -- module insert / remove -- */ 1772/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index bc7d0eedcd81..8d7c27e6ac77 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -85,6 +85,7 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 85static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
86 86
87static struct ctrl sd_ctrls[] = { 87static struct ctrl sd_ctrls[] = {
88#define BRIGHTNESS_IDX 0
88#define SD_BRIGHTNESS 0 89#define SD_BRIGHTNESS 0
89 { 90 {
90 { 91 {
@@ -141,6 +142,7 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_setautogain, 142 .set = sd_setautogain,
142 .get = sd_getautogain, 143 .get = sd_getautogain,
143 }, 144 },
145#define LIGHTFREQ_IDX 4
144#define SD_FREQ 4 146#define SD_FREQ 4
145 { 147 {
146 { 148 {
@@ -6964,8 +6966,13 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
6964 case SENSOR_MC501CB: 6966 case SENSOR_MC501CB:
6965 return -1; /* don't probe */ 6967 return -1; /* don't probe */
6966 case SENSOR_TAS5130C_VF0250: 6968 case SENSOR_TAS5130C_VF0250:
6967 /* may probe but with write in reg 0x0010 */ 6969 /* may probe but with no write in reg 0x0010 */
6968 return -1; /* don't probe */ 6970 return -1; /* don't probe */
6971 case SENSOR_PAS106:
6972 sensor = sif_probe(gspca_dev);
6973 if (sensor >= 0)
6974 return sensor;
6975 break;
6969 } 6976 }
6970 sensor = vga_2wr_probe(gspca_dev); 6977 sensor = vga_2wr_probe(gspca_dev);
6971 if (sensor >= 0) { 6978 if (sensor >= 0) {
@@ -6974,12 +6981,10 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
6974 /* next probe is needed for OmniVision ? */ 6981 /* next probe is needed for OmniVision ? */
6975 } 6982 }
6976 sensor2 = vga_3wr_probe(gspca_dev); 6983 sensor2 = vga_3wr_probe(gspca_dev);
6977 if (sensor2 >= 0) { 6984 if (sensor2 >= 0
6978 if (sensor >= 0) 6985 && sensor >= 0)
6979 return sensor; 6986 return sensor;
6980 return sensor2; 6987 return sensor2;
6981 }
6982 return sif_probe(gspca_dev);
6983} 6988}
6984 6989
6985/* this function is called at probe time */ 6990/* this function is called at probe time */
@@ -7147,13 +7152,27 @@ static int sd_config(struct gspca_dev *gspca_dev,
7147 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; 7152 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
7148 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; 7153 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
7149 7154
7155 switch (sd->sensor) {
7156 case SENSOR_GC0305:
7157 case SENSOR_OV7620:
7158 case SENSOR_PO2030:
7159 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
7160 break;
7161 case SENSOR_HDCS2020:
7162 case SENSOR_HV7131B:
7163 case SENSOR_HV7131C:
7164 case SENSOR_OV7630C:
7165 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
7166 break;
7167 }
7168
7150 /* switch the led off */ 7169 /* switch the led off */
7151 reg_w(gspca_dev->dev, 0x01, 0x0000); 7170 reg_w(gspca_dev->dev, 0x01, 0x0000);
7152 return 0; 7171 return 0;
7153} 7172}
7154 7173
7155/* this function is called at open time */ 7174/* this function is called at probe and resume time */
7156static int sd_open(struct gspca_dev *gspca_dev) 7175static int sd_init(struct gspca_dev *gspca_dev)
7157{ 7176{
7158 reg_w(gspca_dev->dev, 0x01, 0x0000); 7177 reg_w(gspca_dev->dev, 0x01, 0x0000);
7159 return 0; 7178 return 0;
@@ -7314,10 +7333,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
7314 } 7333 }
7315} 7334}
7316 7335
7317static void sd_stopN(struct gspca_dev *gspca_dev)
7318{
7319}
7320
7321static void sd_stop0(struct gspca_dev *gspca_dev) 7336static void sd_stop0(struct gspca_dev *gspca_dev)
7322{ 7337{
7323 struct sd *sd = (struct sd *) gspca_dev; 7338 struct sd *sd = (struct sd *) gspca_dev;
@@ -7325,11 +7340,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
7325 send_unknown(gspca_dev->dev, sd->sensor); 7340 send_unknown(gspca_dev->dev, sd->sensor);
7326} 7341}
7327 7342
7328/* this function is called at close time */
7329static void sd_close(struct gspca_dev *gspca_dev)
7330{
7331}
7332
7333static void sd_pkt_scan(struct gspca_dev *gspca_dev, 7343static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7334 struct gspca_frame *frame, 7344 struct gspca_frame *frame,
7335 __u8 *data, 7345 __u8 *data,
@@ -7489,37 +7499,30 @@ static const struct sd_desc sd_desc = {
7489 .ctrls = sd_ctrls, 7499 .ctrls = sd_ctrls,
7490 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], 7500 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
7491 .config = sd_config, 7501 .config = sd_config,
7492 .open = sd_open, 7502 .init = sd_init,
7493 .start = sd_start, 7503 .start = sd_start,
7494 .stopN = sd_stopN,
7495 .stop0 = sd_stop0, 7504 .stop0 = sd_stop0,
7496 .close = sd_close,
7497 .pkt_scan = sd_pkt_scan, 7505 .pkt_scan = sd_pkt_scan,
7498 .querymenu = sd_querymenu, 7506 .querymenu = sd_querymenu,
7499}; 7507};
7500 7508
7501static const __devinitdata struct usb_device_id device_table[] = { 7509static const __devinitdata struct usb_device_id device_table[] = {
7502 {USB_DEVICE(0x041e, 0x041e)}, 7510 {USB_DEVICE(0x041e, 0x041e)},
7503#ifndef CONFIG_USB_ZC0301
7504 {USB_DEVICE(0x041e, 0x4017)}, 7511 {USB_DEVICE(0x041e, 0x4017)},
7505 {USB_DEVICE(0x041e, 0x401c)}, 7512 {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},
7506 {USB_DEVICE(0x041e, 0x401e)}, 7513 {USB_DEVICE(0x041e, 0x401e)},
7507 {USB_DEVICE(0x041e, 0x401f)}, 7514 {USB_DEVICE(0x041e, 0x401f)},
7508#endif 7515 {USB_DEVICE(0x041e, 0x4022)},
7509 {USB_DEVICE(0x041e, 0x4029)}, 7516 {USB_DEVICE(0x041e, 0x4029)},
7510#ifndef CONFIG_USB_ZC0301 7517 {USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106},
7511 {USB_DEVICE(0x041e, 0x4034)}, 7518 {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106},
7512 {USB_DEVICE(0x041e, 0x4035)},
7513 {USB_DEVICE(0x041e, 0x4036)}, 7519 {USB_DEVICE(0x041e, 0x4036)},
7514 {USB_DEVICE(0x041e, 0x403a)}, 7520 {USB_DEVICE(0x041e, 0x403a)},
7515#endif
7516 {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250}, 7521 {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250},
7517 {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250}, 7522 {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250},
7518#ifndef CONFIG_USB_ZC0301
7519 {USB_DEVICE(0x0458, 0x7007)}, 7523 {USB_DEVICE(0x0458, 0x7007)},
7520 {USB_DEVICE(0x0458, 0x700c)}, 7524 {USB_DEVICE(0x0458, 0x700c)},
7521 {USB_DEVICE(0x0458, 0x700f)}, 7525 {USB_DEVICE(0x0458, 0x700f)},
7522#endif
7523 {USB_DEVICE(0x0461, 0x0a00)}, 7526 {USB_DEVICE(0x0461, 0x0a00)},
7524 {USB_DEVICE(0x046d, 0x08a0)}, 7527 {USB_DEVICE(0x046d, 0x08a0)},
7525 {USB_DEVICE(0x046d, 0x08a1)}, 7528 {USB_DEVICE(0x046d, 0x08a1)},
@@ -7531,7 +7534,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
7531 {USB_DEVICE(0x046d, 0x08aa)}, 7534 {USB_DEVICE(0x046d, 0x08aa)},
7532 {USB_DEVICE(0x046d, 0x08ac)}, 7535 {USB_DEVICE(0x046d, 0x08ac)},
7533 {USB_DEVICE(0x046d, 0x08ad)}, 7536 {USB_DEVICE(0x046d, 0x08ad)},
7534#ifndef CONFIG_USB_ZC0301 7537#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
7535 {USB_DEVICE(0x046d, 0x08ae)}, 7538 {USB_DEVICE(0x046d, 0x08ae)},
7536#endif 7539#endif
7537 {USB_DEVICE(0x046d, 0x08af)}, 7540 {USB_DEVICE(0x046d, 0x08af)},
@@ -7541,27 +7544,25 @@ static const __devinitdata struct usb_device_id device_table[] = {
7541 {USB_DEVICE(0x046d, 0x08d8)}, 7544 {USB_DEVICE(0x046d, 0x08d8)},
7542 {USB_DEVICE(0x046d, 0x08da)}, 7545 {USB_DEVICE(0x046d, 0x08da)},
7543 {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, 7546 {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
7544 {USB_DEVICE(0x0471, 0x0325)}, 7547 {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106},
7545 {USB_DEVICE(0x0471, 0x0326)}, 7548 {USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106},
7546 {USB_DEVICE(0x0471, 0x032d)}, 7549 {USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106},
7547 {USB_DEVICE(0x0471, 0x032e)}, 7550 {USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106},
7548 {USB_DEVICE(0x055f, 0xc005)}, 7551 {USB_DEVICE(0x055f, 0xc005)},
7549#ifndef CONFIG_USB_ZC0301
7550 {USB_DEVICE(0x055f, 0xd003)}, 7552 {USB_DEVICE(0x055f, 0xd003)},
7551 {USB_DEVICE(0x055f, 0xd004)}, 7553 {USB_DEVICE(0x055f, 0xd004)},
7552#endif
7553 {USB_DEVICE(0x0698, 0x2003)}, 7554 {USB_DEVICE(0x0698, 0x2003)},
7555 {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
7554 {USB_DEVICE(0x0ac8, 0x0302)}, 7556 {USB_DEVICE(0x0ac8, 0x0302)},
7555#ifndef CONFIG_USB_ZC0301
7556 {USB_DEVICE(0x0ac8, 0x301b)}, 7557 {USB_DEVICE(0x0ac8, 0x301b)},
7558#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
7557 {USB_DEVICE(0x0ac8, 0x303b)}, 7559 {USB_DEVICE(0x0ac8, 0x303b)},
7558#endif 7560#endif
7559 {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, 7561 {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
7560#ifndef CONFIG_USB_ZC0301
7561 {USB_DEVICE(0x0ac8, 0x307b)}, 7562 {USB_DEVICE(0x0ac8, 0x307b)},
7562 {USB_DEVICE(0x10fd, 0x0128)}, 7563 {USB_DEVICE(0x10fd, 0x0128)},
7564 {USB_DEVICE(0x10fd, 0x804d)},
7563 {USB_DEVICE(0x10fd, 0x8050)}, 7565 {USB_DEVICE(0x10fd, 0x8050)},
7564#endif
7565 {} /* end of entry */ 7566 {} /* end of entry */
7566}; 7567};
7567#undef DVNAME 7568#undef DVNAME
@@ -7581,6 +7582,10 @@ static struct usb_driver sd_driver = {
7581 .id_table = device_table, 7582 .id_table = device_table,
7582 .probe = sd_probe, 7583 .probe = sd_probe,
7583 .disconnect = gspca_disconnect, 7584 .disconnect = gspca_disconnect,
7585#ifdef CONFIG_PM
7586 .suspend = gspca_suspend,
7587 .resume = gspca_resume,
7588#endif
7584}; 7589};
7585 7590
7586static int __init sd_mod_init(void) 7591static int __init sd_mod_init(void)