diff options
Diffstat (limited to 'drivers/media/video/gspca')
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 */ |
830 | static int sd_open(struct gspca_dev *gspca_dev) | 830 | static 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 | ||
848 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
849 | { | ||
850 | } | ||
851 | |||
852 | static void sd_stop0(struct gspca_dev *gspca_dev) | 848 | static 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 | ||
874 | static void sd_close(struct gspca_dev *gspca_dev) | ||
875 | { | ||
876 | } | ||
877 | |||
878 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 870 | static 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 */ |
678 | static int sd_open(struct gspca_dev *gspca_dev) | 680 | static 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 | ||
712 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
713 | { | ||
714 | } | ||
715 | |||
716 | static void sd_close(struct gspca_dev *gspca_dev) | ||
717 | { | ||
718 | } | ||
719 | |||
720 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) | 714 | static __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 -- */ |
906 | static __devinitdata struct usb_device_id device_table[] = { | 898 | static __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; | ||
795 | out: | 789 | out: |
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 */ | ||
857 | static int vidioc_queryctrl(struct file *file, void *priv, | 850 | static 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 | ||
894 | static int vidioc_s_ctrl(struct file *file, void *priv, | 890 | static 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; |
1773 | out: | 1782 | out: |
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 | } |
1809 | EXPORT_SYMBOL(gspca_disconnect); | 1820 | EXPORT_SYMBOL(gspca_disconnect); |
1810 | 1821 | ||
1822 | #ifdef CONFIG_PM | ||
1823 | int 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 | } | ||
1838 | EXPORT_SYMBOL(gspca_suspend); | ||
1839 | |||
1840 | int 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 | } | ||
1850 | EXPORT_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 */ |
58 | struct cam { | 58 | struct 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 | ||
181 | int gspca_suspend(struct usb_interface *intf, pm_message_t message); | ||
182 | int gspca_resume(struct usb_interface *intf); | ||
183 | #endif | ||
177 | int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, | 184 | int 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 | ||
103 | static 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 | |||
119 | static void bulk_w(struct gspca_dev *gspca_dev, | 103 | static 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 */ |
148 | static int sd_open(struct gspca_dev *gspca_dev) | 132 | static 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 | ||
361 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
362 | { | ||
363 | } | ||
364 | |||
365 | static void sd_close(struct gspca_dev *gspca_dev) | ||
366 | { | ||
367 | } | ||
368 | |||
369 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 342 | static 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 | ||
297 | struct ov_regvals { | ||
298 | __u8 reg; | ||
299 | __u8 val; | ||
300 | }; | ||
301 | struct ov_i2c_regvals { | ||
302 | __u8 reg; | ||
303 | __u8 val; | ||
304 | }; | ||
305 | |||
306 | static 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 | |||
349 | static 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 | */ | ||
445 | static 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 | |||
475 | static 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. */ | ||
542 | static 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 */ | ||
549 | static 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 | |||
744 | static 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 | |||
296 | static unsigned char ov7670_abs_to_sm(unsigned char v) | 832 | static 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 | ||
543 | struct ov_regvals { | ||
544 | __u8 reg; | ||
545 | __u8 val; | ||
546 | }; | ||
547 | struct ov_i2c_regvals { | ||
548 | __u8 reg; | ||
549 | __u8 val; | ||
550 | }; | ||
551 | |||
552 | static int write_regvals(struct sd *sd, | 1080 | static 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, | |||
591 | static int ov8xx0_configure(struct sd *sd) | 1119 | static 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) | |||
1073 | static int ov6xx0_configure(struct sd *sd) | 1235 | static 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; |
1359 | error: | 1379 | error: |
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 */ |
1365 | static int sd_open(struct gspca_dev *gspca_dev) | 1385 | static 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 | ||
1830 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1831 | { | ||
1832 | } | ||
1833 | |||
1834 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1835 | { | ||
1836 | } | ||
1837 | |||
1838 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1885 | static 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 */ |
67 | struct sd { | 61 | struct 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 */ |
182 | static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; | 177 | static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; |
183 | 178 | ||
184 | static const unsigned char pac207_sof_marker[5] = | ||
185 | { 0xff, 0xff, 0x00, 0xff, 0x96 }; | ||
186 | |||
187 | static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, | 179 | static 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 */ |
286 | static int sd_open(struct gspca_dev *gspca_dev) | 271 | static 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 | ||
346 | static 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 */ | ||
351 | static void sd_close(struct gspca_dev *gspca_dev) | ||
352 | { | ||
353 | } | ||
354 | 337 | ||
355 | static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) | 338 | static 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 | |||
371 | static 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 | ||
397 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 354 | static 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"); | |||
31 | struct sd { | 61 | struct 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); | |||
54 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 89 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
55 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 90 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
56 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 91 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); |
92 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
93 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
94 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
95 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
96 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
97 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
98 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
99 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | 100 | ||
58 | static struct ctrl sd_ctrls[] = { | 101 | static 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 | ||
118 | static struct v4l2_pix_format vga_mode[] = { | 229 | static 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 | 248 | static const __u8 init_7302[] = { | |
138 | static 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 */ | 255 | static 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() */ | ||
320 | static 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 */ | ||
344 | static 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 | |||
357 | static 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() */ | ||
387 | static 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 | ||
208 | static void reg_w_buf(struct gspca_dev *gspca_dev, | 397 | static 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 | ||
222 | static __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 | ||
235 | static void reg_w(struct gspca_dev *gspca_dev, | 412 | static 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 | ||
425 | static 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 */ | ||
435 | static 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 */ | ||
454 | static 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 */ |
249 | static int sd_config(struct gspca_dev *gspca_dev, | 494 | static 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 | ||
280 | static void setbrightness(struct gspca_dev *gspca_dev) | 527 | /* This function is used by pac7302 only */ |
528 | static 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 */ | ||
555 | static 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 | ||
295 | static void setcontrast(struct gspca_dev *gspca_dev) | 565 | /* This function is used by pac7302 only */ |
566 | static 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 | ||
306 | static void setcolors(struct gspca_dev *gspca_dev) | 588 | static 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 | ||
317 | static void setautogain(struct gspca_dev *gspca_dev) | 609 | static 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) { | 646 | static 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 */ |
330 | static int sd_open(struct gspca_dev *gspca_dev) | 666 | static 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 | ||
336 | static void sd_start(struct gspca_dev *gspca_dev) | 678 | static 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 | ||
450 | static void sd_stopN(struct gspca_dev *gspca_dev) | 729 | static 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 | ||
464 | static void sd_stop0(struct gspca_dev *gspca_dev) | 751 | static 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) { |
469 | static 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 | |||
483 | static void do_autogain(struct gspca_dev *gspca_dev) | 764 | static 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 | ||
797 | static const unsigned char pac7311_jpeg_header1[] = { | ||
798 | 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08 | ||
799 | }; | ||
800 | |||
801 | static 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 */ | ||
514 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 807 | static 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 | ||
624 | static 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 | |||
633 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 880 | static 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 | ||
938 | static 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 | |||
948 | static 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 | |||
956 | static 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 | |||
966 | static 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 | |||
690 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 974 | static 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 | ||
1005 | static 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 | |||
1015 | static 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 | |||
1023 | static 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 | |||
1033 | static 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 */ |
709 | static struct sd_desc sd_desc = { | 1042 | static 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 -- */ |
724 | static __devinitdata struct usb_device_id device_table[] = { | 1056 | static __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 | }; |
734 | MODULE_DEVICE_TABLE(usb, device_table); | 1068 | MODULE_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 | |||
33 | static const unsigned char pac_sof_marker[5] = | ||
34 | { 0xff, 0xff, 0x00, 0xff, 0x96 }; | ||
35 | |||
36 | static 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 | |||
25 | Reg Use | ||
26 | 0x10 high nibble red gain low nibble blue gain | ||
27 | 0x11 low nibble green gain | ||
28 | 0x12 hstart | ||
29 | 0x13 vstart | ||
30 | 0x15 hsize (hsize = register-value * 16) | ||
31 | 0x16 vsize (vsize = register-value * 16) | ||
32 | 0x17 bit 0 toggle compression quality (according to sn9c102 driver) | ||
33 | 0x18 bit 7 enables compression, bit 4-5 set image down scaling: | ||
34 | 00 scale 1, 01 scale 1/2, 10, scale 1/4 | ||
35 | 0x19 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. | ||
37 | 0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32) | ||
38 | 0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32) | ||
39 | 0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32) | ||
40 | 0x1f 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 */ |
32 | struct sd { | 52 | struct 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 */ | 81 | typedef const __u8 sensor_init_t[8]; |
82 | |||
83 | struct 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); | |||
95 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 148 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
96 | 149 | ||
97 | static struct ctrl sd_ctrls[] = { | 150 | static 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 | ||
174 | static struct v4l2_pix_format vga_mode[] = { | 232 | static 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 | }; |
191 | static struct v4l2_pix_format sif_mode[] = { | 254 | static 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[] = { | |||
204 | static const __u8 initHv7131[] = { | 287 | static 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] = { | |||
218 | static const __u8 initOv6650[] = { | 301 | static 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 | }; |
224 | static const __u8 ov6650_sensor_init[][8] = | 307 | static const __u8 ov6650_sensor_init[][8] = |
225 | { | 308 | { |
@@ -257,15 +340,15 @@ static const __u8 ov6650_sensor_init[][8] = | |||
257 | static const __u8 initOv7630[] = { | 340 | static 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 | }; |
265 | static const __u8 initOv7630_3[] = { | 348 | static 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 | ||
380 | static const __u8 ov7630_sensor_init_3[][8] = { | ||
381 | {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
382 | }; | ||
383 | |||
297 | static const __u8 initPas106[] = { | 384 | static 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 */ |
305 | static const __u8 pas106_data[][2] = { | 392 | static 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 | |||
333 | static const __u8 initPas202[] = { | 434 | static 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 | }; |
340 | static const __u8 pas202_sensor_init[][8] = { | 441 | static const __u8 pas202_sensor_init[][8] = { |
@@ -364,7 +465,7 @@ static const __u8 pas202_sensor_init[][8] = { | |||
364 | static const __u8 initTas5110[] = { | 465 | static 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] = { | |||
377 | static const __u8 initTas5130[] = { | 478 | static 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 | ||
493 | struct sensor_data sensor_data[] = { | ||
494 | SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), | ||
495 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), | ||
496 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, | ||
497 | F_GAIN, 0, 0x21), | ||
498 | SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, | ||
499 | 0), | ||
500 | SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, | ||
501 | NO_EXPO|NO_FREQ, 0), | ||
502 | SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, | ||
503 | NO_BRIGHTNESS|NO_FREQ, 0), | ||
504 | SENS(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 */ |
393 | static void reg_r(struct gspca_dev *gspca_dev, | 509 | static 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 | ||
428 | static 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 | |||
448 | static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) | 544 | static 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; |
553 | err: | 646 | err: |
@@ -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 */ |
800 | static int sd_open(struct gspca_dev *gspca_dev) | 885 | static 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 | ||
808 | static 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 -- */ |
826 | static void sd_start(struct gspca_dev *gspca_dev) | 895 | static 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, ®12_19[3], 2); |
927 | /* compression register */ | 950 | /* compression register */ |
928 | reg_w(gspca_dev, 0x18, ®17_19[1], 1); | 951 | reg_w(gspca_dev, 0x18, ®12_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, ®12_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, ®12_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, ®17_19[0], 1); | 958 | reg_w(gspca_dev, 0x17, ®12_19[5], 1); |
936 | /*MCKSIZE ->3 */ /*fixme: not ov7630*/ | 959 | /*MCKSIZE ->3 */ /*fixme: not ov7630*/ |
937 | reg_w(gspca_dev, 0x19, ®17_19[2], 1); | 960 | reg_w(gspca_dev, 0x19, ®12_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, ®17_19[1], 2); | 966 | reg_w(gspca_dev, 0x18, ®12_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 | ||
958 | static void sd_stopN(struct gspca_dev *gspca_dev) | 981 | static 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 | |||
966 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
967 | { | ||
968 | } | ||
969 | |||
970 | static void sd_close(struct gspca_dev *gspca_dev) | ||
971 | { | ||
972 | } | 984 | } |
973 | 985 | ||
974 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 986 | static 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) | ||
1180 | static __devinitdata struct usb_device_id device_table[] = { | 1213 | static __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 | }; |
1219 | MODULE_DEVICE_TABLE(usb, device_table); | 1241 | MODULE_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[] = { | |||
131 | static struct v4l2_pix_format vga_mode[] = { | 136 | static 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 | ||
188 | static 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 | |||
202 | static 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 | |||
183 | static const __u8 sn_ov7648[] = { | 213 | static 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 | ||
214 | static const __u8 regsn20[] = { | 246 | static 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 | }; |
218 | static 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 | ||
223 | static const __u8 reg84[] = { | 251 | static 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 | }; | ||
229 | static 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 | |||
235 | static const __u8 hv7131r_sensor_init[][8] = { | 256 | static 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 | }; |
364 | static __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 | }; | ||
398 | static 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 | }; | ||
343 | static const __u8 ov7660_sensor_init[][8] = { | 450 | static 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 */ |
510 | static void reg_r(struct gspca_dev *gspca_dev, | 617 | static 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 | ||
864 | static 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 | |||
874 | static 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 | |||
740 | static void ov7648_InitSensor(struct gspca_dev *gspca_dev) | 898 | static 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 */ |
790 | static int sd_open(struct gspca_dev *gspca_dev) | 956 | static 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 */ | ||
1079 | static 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 */ | ||
898 | static void setbrightness(struct gspca_dev *gspca_dev) | 1100 | static 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 */ | ||
924 | static void setcontrast(struct gspca_dev *gspca_dev) | 1132 | static 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) | |||
937 | static void setcolors(struct gspca_dev *gspca_dev) | 1145 | static 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 | ||
951 | static void setautogain(struct gspca_dev *gspca_dev) | 1162 | static 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 | ||
1102 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1322 | static 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 | |||
1138 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1139 | { | ||
1140 | } | ||
1141 | |||
1142 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1143 | { | ||
1144 | } | 1357 | } |
1145 | 1358 | ||
1146 | static void do_autogain(struct gspca_dev *gspca_dev) | 1359 | static 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 | ||
1232 | static 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 | |||
1270 | static 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 | |||
1288 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1446 | static 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) |
1381 | static const __devinitdata struct usb_device_id device_table[] = { | 1558 | static 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 */ |
649 | static int sd_open(struct gspca_dev *gspca_dev) | 649 | static 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 | ||
883 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
884 | { | ||
885 | } | ||
886 | |||
887 | static void sd_close(struct gspca_dev *gspca_dev) | ||
888 | { | ||
889 | } | ||
890 | |||
891 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 883 | static 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 */ |
1957 | static int sd_open(struct gspca_dev *gspca_dev) | 1957 | static 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 | ||
2024 | static void sd_stop0(struct gspca_dev *gspca_dev) | 2024 | static void sd_stop0(struct gspca_dev *gspca_dev) |
2025 | { | 2025 | { |
2026 | } | ||
2027 | |||
2028 | /* this function is called at close time */ | ||
2029 | static 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 */ |
659 | static int sd_open(struct gspca_dev *gspca_dev) | 659 | static 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 | ||
744 | static void sd_stop0(struct gspca_dev *gspca_dev) | 744 | static void sd_stop0(struct gspca_dev *gspca_dev) |
745 | { | 745 | { |
746 | } | ||
747 | |||
748 | /* this function is called at close time */ | ||
749 | static 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 */ |
317 | static int sd_open(struct gspca_dev *gspca_dev) | 317 | static 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 | ||
563 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
564 | { | ||
565 | } | ||
566 | |||
567 | static void sd_close(struct gspca_dev *gspca_dev) | ||
568 | { | ||
569 | } | ||
570 | |||
571 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 563 | static 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 */ |
1525 | static int sd_open(struct gspca_dev *gspca_dev) | 1525 | static 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 | ||
1557 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1558 | { | ||
1559 | } | ||
1560 | |||
1561 | /* this function is called at close time */ | ||
1562 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1563 | { | ||
1564 | } | ||
1565 | |||
1566 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1557 | static 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"); | |||
32 | struct sd { | 32 | struct 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 */ | 76 | static struct v4l2_pix_format sif_012a_mode[] = { |
45 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
46 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
47 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | |||
52 | static 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 | |||
97 | static 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 | ||
99 | static 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 |
146 | enum { | ||
147 | Rev072A = 0, | ||
148 | Rev012A, | ||
149 | }; | ||
150 | 148 | ||
151 | static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) | 149 | static 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 | ||
201 | static 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 | |||
207 | static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) | 199 | static 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 | ||
445 | static 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 ********************/ |
458 | static const __u16 Pb100_1map8300[][2] = { | 439 | static 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 | ||
480 | static const __u16 spca561_161rev12A_data1[][2] = { | 461 | static 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 | } |
546 | static void init_161rev12A(struct gspca_dev *gspca_dev) | 531 | static 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 */ |
598 | static int sd_open(struct gspca_dev *gspca_dev) | 592 | static 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"); | 598 | static 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 | ||
647 | static void setautogain(struct gspca_dev *gspca_dev) | 631 | /* rev12a only */ |
632 | static 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) | 647 | static 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 */ | ||
682 | static 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 | ||
659 | static void sd_start(struct gspca_dev *gspca_dev) | 692 | static 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 | |||
702 | static 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; | 729 | static 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 | ||
721 | static void sd_stopN(struct gspca_dev *gspca_dev) | 755 | static 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 | ||
726 | static void sd_stop0(struct gspca_dev *gspca_dev) | 767 | static 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) { |
731 | static 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 | ||
736 | static void do_autogain(struct gspca_dev *gspca_dev) | 778 | static 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 */ | ||
844 | static void setbrightness(struct gspca_dev *gspca_dev) | 898 | static 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 | ||
864 | static void getbrightness(struct gspca_dev *gspca_dev) | 910 | static 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 */ | ||
889 | static void getcontrast(struct gspca_dev *gspca_dev) | 928 | static 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 */ | ||
915 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 947 | static 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 */ | ||
934 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | 967 | static 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 */ | ||
1005 | static 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 | |||
1015 | static 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 */ | ||
1024 | static 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 | |||
1034 | static 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 */ | ||
1043 | static 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 | |||
1053 | static 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 */ | ||
1062 | static 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 | |||
1117 | static 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 */ |
972 | static const struct sd_desc sd_desc = { | 1160 | static 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 | }; | ||
1172 | static 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 | }; |
1184 | static const struct sd_desc *sd_desc[2] = { | ||
1185 | &sd_desc_12a, | ||
1186 | &sd_desc_72a | ||
1187 | }; | ||
985 | 1188 | ||
986 | /* -- module initialisation -- */ | 1189 | /* -- module initialisation -- */ |
987 | static const __devinitdata struct usb_device_id device_table[] = { | 1190 | static const __devinitdata struct usb_device_id device_table[] = { |
@@ -1009,7 +1212,9 @@ MODULE_DEVICE_TABLE(usb, device_table); | |||
1009 | static int sd_probe(struct usb_interface *intf, | 1212 | static 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 */ |
310 | static int sd_open(struct gspca_dev *gspca_dev) | 310 | static 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 | ||
401 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
402 | { | ||
403 | } | ||
404 | |||
405 | static void sd_close(struct gspca_dev *gspca_dev) | ||
406 | { | ||
407 | } | ||
408 | |||
409 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 401 | static 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 | ||
452 | static void reg_r(struct usb_device *dev, | 452 | /* read <len> bytes to gspca_dev->usb_buf */ |
453 | __u16 req, | 453 | static 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 | ||
466 | static void reg_w(struct usb_device *dev, | 474 | /* write <len> bytes from gspca_dev->usb_buf */ |
467 | __u16 req, | 475 | static 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 | ||
645 | static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) | 661 | static 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 | ||
663 | static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) | 678 | static 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 | ||
677 | static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | 690 | static 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 | ||
753 | static void spca504B_setQtable(struct gspca_dev *gspca_dev) | 766 | static 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 | ||
763 | static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) | 774 | static 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 */ |
852 | static int sd_open(struct gspca_dev *gspca_dev) | 861 | static 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 | ||
1072 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1073 | { | ||
1074 | } | ||
1075 | |||
1076 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1077 | { | ||
1078 | } | ||
1079 | |||
1080 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1081 | static 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 | ||
35 | MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); | 35 | MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); |
36 | MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); | 36 | MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); |
@@ -233,7 +233,7 @@ static char *effects_control[] = { | |||
233 | static struct v4l2_pix_format vga_mode_t16[] = { | 233 | static 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 */ | ||
556 | static int sd_init(struct gspca_dev *gspca_dev) | ||
557 | { | ||
558 | init_default_parameters(gspca_dev); | ||
559 | return 0; | ||
560 | } | ||
561 | |||
555 | static void setbrightness(struct gspca_dev *gspca_dev) | 562 | static 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 | ||
896 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
897 | { | ||
898 | } | ||
899 | |||
900 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
901 | { | ||
902 | } | ||
903 | |||
904 | static void sd_close(struct gspca_dev *gspca_dev) | ||
905 | { | ||
906 | } | ||
907 | |||
908 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 903 | static 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 */ | ||
976 | static 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 */ |
983 | static const struct sd_desc sd_desc = { | 971 | static 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 */ |
335 | static int sd_open(struct gspca_dev *gspca_dev) | 335 | static 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 | ||
453 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
454 | { | ||
455 | } | ||
456 | |||
457 | static void sd_close(struct gspca_dev *gspca_dev) | ||
458 | { | ||
459 | } | ||
460 | |||
461 | static void tv8532_preprocess(struct gspca_dev *gspca_dev) | 453 | static 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 | ||
89 | static struct v4l2_pix_format vc0321_mode[] = { | 90 | static 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 */ |
1478 | static int sd_open(struct gspca_dev *gspca_dev) | 1481 | static 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 */ | ||
1641 | static 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 | |||
1653 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1643 | static 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); | |||
85 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | 85 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); |
86 | 86 | ||
87 | static struct ctrl sd_ctrls[] = { | 87 | static 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 */ |
7156 | static int sd_open(struct gspca_dev *gspca_dev) | 7175 | static 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 | ||
7317 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
7318 | { | ||
7319 | } | ||
7320 | |||
7321 | static void sd_stop0(struct gspca_dev *gspca_dev) | 7336 | static 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 */ | ||
7329 | static void sd_close(struct gspca_dev *gspca_dev) | ||
7330 | { | ||
7331 | } | ||
7332 | |||
7333 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 7343 | static 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 | ||
7501 | static const __devinitdata struct usb_device_id device_table[] = { | 7509 | static 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 | ||
7586 | static int __init sd_mod_init(void) | 7591 | static int __init sd_mod_init(void) |