diff options
Diffstat (limited to 'drivers/media/video')
26 files changed, 674 insertions, 587 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d4a6e56a7135..ecbfa1b39b70 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -630,7 +630,7 @@ config VIDEO_ZORAN_ZR36060 | |||
630 | depends on VIDEO_ZORAN | 630 | depends on VIDEO_ZORAN |
631 | help | 631 | help |
632 | Say Y to support Zoran boards based on 36060 chips. | 632 | Say Y to support Zoran boards based on 36060 chips. |
633 | This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33 | 633 | This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 |
634 | and 33 R10 and AverMedia 6 boards. | 634 | and 33 R10 and AverMedia 6 boards. |
635 | 635 | ||
636 | config VIDEO_ZORAN_BUZ | 636 | config VIDEO_ZORAN_BUZ |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 56ebfd5ef6fa..9e436ad3d34b 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/videodev.h> | 30 | #include <linux/videodev.h> |
31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
32 | #include <media/v4l2-ioctl.h> | ||
32 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
33 | 34 | ||
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
@@ -755,7 +756,6 @@ static const struct file_operations ar_fops = { | |||
755 | 756 | ||
756 | static struct video_device ar_template = { | 757 | static struct video_device ar_template = { |
757 | .name = "Colour AR VGA", | 758 | .name = "Colour AR VGA", |
758 | .type = VID_TYPE_CAPTURE, | ||
759 | .fops = &ar_fops, | 759 | .fops = &ar_fops, |
760 | .release = ar_release, | 760 | .release = ar_release, |
761 | .minor = -1, | 761 | .minor = -1, |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 476ae44a62d2..452da70e719f 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -1015,6 +1015,7 @@ struct em28xx_board em28xx_boards[] = { | |||
1015 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1015 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
1016 | .vchannels = 3, | 1016 | .vchannels = 3, |
1017 | .tuner_type = TUNER_XC2028, | 1017 | .tuner_type = TUNER_XC2028, |
1018 | .mts_firmware = 1, | ||
1018 | .decoder = EM28XX_TVP5150, | 1019 | .decoder = EM28XX_TVP5150, |
1019 | .input = { { | 1020 | .input = { { |
1020 | .type = EM28XX_VMUX_TELEVISION, | 1021 | .type = EM28XX_VMUX_TELEVISION, |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 44b0bffeb20e..cd3a3f5829b2 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
@@ -123,7 +123,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
123 | { | 123 | { |
124 | struct usb_device *dev = gspca_dev->dev; | 124 | struct usb_device *dev = gspca_dev->dev; |
125 | 125 | ||
126 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 126 | #ifdef GSPCA_DEBUG |
127 | if (len > sizeof gspca_dev->usb_buf) { | 127 | if (len > sizeof gspca_dev->usb_buf) { |
128 | err("reg_r: buffer overflow"); | 128 | err("reg_r: buffer overflow"); |
129 | return; | 129 | return; |
@@ -163,7 +163,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
163 | { | 163 | { |
164 | struct usb_device *dev = gspca_dev->dev; | 164 | struct usb_device *dev = gspca_dev->dev; |
165 | 165 | ||
166 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 166 | #ifdef GSPCA_DEBUG |
167 | if (len > sizeof gspca_dev->usb_buf) { | 167 | if (len > sizeof gspca_dev->usb_buf) { |
168 | err("reg_w: buffer overflow"); | 168 | err("reg_w: buffer overflow"); |
169 | return; | 169 | return; |
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index c8c2f02fcf00..1dbe92d01e6a 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -233,7 +233,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
233 | { | 233 | { |
234 | struct usb_device *dev = gspca_dev->dev; | 234 | struct usb_device *dev = gspca_dev->dev; |
235 | 235 | ||
236 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 236 | #ifdef GSPCA_DEBUG |
237 | if (len > sizeof gspca_dev->usb_buf) { | 237 | if (len > sizeof gspca_dev->usb_buf) { |
238 | err("reg_r: buffer overflow"); | 238 | err("reg_r: buffer overflow"); |
239 | return; | 239 | return; |
@@ -271,7 +271,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
271 | { | 271 | { |
272 | struct usb_device *dev = gspca_dev->dev; | 272 | struct usb_device *dev = gspca_dev->dev; |
273 | 273 | ||
274 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 274 | #ifdef GSPCA_DEBUG |
275 | if (len > sizeof gspca_dev->usb_buf) { | 275 | if (len > sizeof gspca_dev->usb_buf) { |
276 | err("reg_w: buffer overflow"); | 276 | err("reg_w: buffer overflow"); |
277 | return; | 277 | return; |
@@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev) | |||
461 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ | 461 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ |
462 | } | 462 | } |
463 | 463 | ||
464 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
465 | { | ||
466 | struct sd *sd = (struct sd *) gspca_dev; | ||
467 | int i; | ||
468 | __u8 brightness = sd->brightness; | ||
469 | |||
470 | for (i = 0; i < 4; i++) | ||
471 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
472 | } | ||
473 | |||
474 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
475 | { | ||
476 | struct sd *sd = (struct sd *) gspca_dev; | ||
477 | int i; | ||
478 | int brightness = 0; | ||
479 | |||
480 | for (i = 0; i < 4; i++) { | ||
481 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
482 | brightness += gspca_dev->usb_buf[0]; | ||
483 | } | ||
484 | sd->brightness = brightness >> 3; | ||
485 | } | ||
486 | |||
487 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
488 | { | ||
489 | struct sd *sd = (struct sd *) gspca_dev; | ||
490 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
491 | __u8 contrast = sd->contrast; | ||
492 | |||
493 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
494 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
495 | } | ||
496 | |||
497 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
498 | { | ||
499 | struct sd *sd = (struct sd *) gspca_dev; | ||
500 | int i; | ||
501 | int contrast = 0; | ||
502 | |||
503 | for (i = 0; i < 4; i++) { | ||
504 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
505 | contrast += gspca_dev->usb_buf[0]; | ||
506 | } | ||
507 | sd->contrast = contrast >> 2; | ||
508 | } | ||
509 | |||
464 | static void setcolors(struct gspca_dev *gspca_dev) | 510 | static void setcolors(struct gspca_dev *gspca_dev) |
465 | { | 511 | { |
466 | struct sd *sd = (struct sd *) gspca_dev; | 512 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev) | |||
492 | } | 538 | } |
493 | } | 539 | } |
494 | 540 | ||
541 | static void setautogain(struct gspca_dev *gspca_dev) | ||
542 | { | ||
543 | struct sd *sd = (struct sd *) gspca_dev; | ||
544 | |||
545 | if (sd->autogain) | ||
546 | sd->ag_cnt = AG_CNT_START; | ||
547 | else | ||
548 | sd->ag_cnt = -1; | ||
549 | } | ||
550 | |||
495 | static void Et_init1(struct gspca_dev *gspca_dev) | 551 | static void Et_init1(struct gspca_dev *gspca_dev) |
496 | { | 552 | { |
497 | __u8 value; | 553 | __u8 value; |
@@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
614 | sd->contrast = CONTRAST_DEF; | 670 | sd->contrast = CONTRAST_DEF; |
615 | sd->colors = COLOR_DEF; | 671 | sd->colors = COLOR_DEF; |
616 | sd->autogain = AUTOGAIN_DEF; | 672 | sd->autogain = AUTOGAIN_DEF; |
673 | sd->ag_cnt = -1; | ||
617 | return 0; | 674 | return 0; |
618 | } | 675 | } |
619 | 676 | ||
@@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
641 | else | 698 | else |
642 | Et_init2(gspca_dev); | 699 | Et_init2(gspca_dev); |
643 | 700 | ||
701 | setautogain(gspca_dev); | ||
702 | |||
644 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); | 703 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); |
645 | et_video(gspca_dev, 1); /* video on */ | 704 | et_video(gspca_dev, 1); /* video on */ |
646 | } | 705 | } |
@@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
658 | { | 717 | { |
659 | } | 718 | } |
660 | 719 | ||
661 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
662 | { | ||
663 | struct sd *sd = (struct sd *) gspca_dev; | ||
664 | int i; | ||
665 | __u8 brightness = sd->brightness; | ||
666 | |||
667 | for (i = 0; i < 4; i++) | ||
668 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
669 | } | ||
670 | |||
671 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
672 | { | ||
673 | struct sd *sd = (struct sd *) gspca_dev; | ||
674 | int i; | ||
675 | int brightness = 0; | ||
676 | |||
677 | for (i = 0; i < 4; i++) { | ||
678 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
679 | brightness += gspca_dev->usb_buf[0]; | ||
680 | } | ||
681 | sd->brightness = brightness >> 3; | ||
682 | } | ||
683 | |||
684 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
685 | { | ||
686 | struct sd *sd = (struct sd *) gspca_dev; | ||
687 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
688 | __u8 contrast = sd->contrast; | ||
689 | |||
690 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
691 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
692 | } | ||
693 | |||
694 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
695 | { | ||
696 | struct sd *sd = (struct sd *) gspca_dev; | ||
697 | int i; | ||
698 | int contrast = 0; | ||
699 | |||
700 | for (i = 0; i < 4; i++) { | ||
701 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
702 | contrast += gspca_dev->usb_buf[0]; | ||
703 | } | ||
704 | sd->contrast = contrast >> 2; | ||
705 | } | ||
706 | |||
707 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) | 720 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) |
708 | { | 721 | { |
709 | struct sd *sd = (struct sd *) gspca_dev; | 722 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -733,15 +746,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) | |||
733 | #define LIMIT(color) \ | 746 | #define LIMIT(color) \ |
734 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) | 747 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) |
735 | 748 | ||
736 | static void setautogain(struct gspca_dev *gspca_dev) | 749 | static void do_autogain(struct gspca_dev *gspca_dev) |
737 | { | 750 | { |
738 | __u8 luma = 0; | 751 | struct sd *sd = (struct sd *) gspca_dev; |
752 | __u8 luma; | ||
739 | __u8 luma_mean = 128; | 753 | __u8 luma_mean = 128; |
740 | __u8 luma_delta = 20; | 754 | __u8 luma_delta = 20; |
741 | __u8 spring = 4; | 755 | __u8 spring = 4; |
742 | int Gbright = 0; | 756 | int Gbright; |
743 | __u8 r, g, b; | 757 | __u8 r, g, b; |
744 | 758 | ||
759 | if (sd->ag_cnt < 0) | ||
760 | return; | ||
761 | if (--sd->ag_cnt >= 0) | ||
762 | return; | ||
763 | sd->ag_cnt = AG_CNT_START; | ||
764 | |||
745 | Gbright = Et_getgainG(gspca_dev); | 765 | Gbright = Et_getgainG(gspca_dev); |
746 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); | 766 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); |
747 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; | 767 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; |
@@ -768,7 +788,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
768 | __u8 *data, /* isoc packet */ | 788 | __u8 *data, /* isoc packet */ |
769 | int len) /* iso packet length */ | 789 | int len) /* iso packet length */ |
770 | { | 790 | { |
771 | struct sd *sd; | ||
772 | int seqframe; | 791 | int seqframe; |
773 | 792 | ||
774 | seqframe = data[0] & 0x3f; | 793 | seqframe = data[0] & 0x3f; |
@@ -783,13 +802,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
783 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
784 | data, 0); | 803 | data, 0); |
785 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | 804 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); |
786 | sd = (struct sd *) gspca_dev; | ||
787 | if (sd->ag_cnt >= 0) { | ||
788 | if (--sd->ag_cnt < 0) { | ||
789 | sd->ag_cnt = AG_CNT_START; | ||
790 | setautogain(gspca_dev); | ||
791 | } | ||
792 | } | ||
793 | return; | 805 | return; |
794 | } | 806 | } |
795 | if (len) { | 807 | if (len) { |
@@ -862,10 +874,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
862 | struct sd *sd = (struct sd *) gspca_dev; | 874 | struct sd *sd = (struct sd *) gspca_dev; |
863 | 875 | ||
864 | sd->autogain = val; | 876 | sd->autogain = val; |
865 | if (val) | 877 | if (gspca_dev->streaming) |
866 | sd->ag_cnt = AG_CNT_START; | 878 | setautogain(gspca_dev); |
867 | else | ||
868 | sd->ag_cnt = -1; | ||
869 | return 0; | 879 | return 0; |
870 | } | 880 | } |
871 | 881 | ||
@@ -889,6 +899,7 @@ static struct sd_desc sd_desc = { | |||
889 | .stop0 = sd_stop0, | 899 | .stop0 = sd_stop0, |
890 | .close = sd_close, | 900 | .close = sd_close, |
891 | .pkt_scan = sd_pkt_scan, | 901 | .pkt_scan = sd_pkt_scan, |
902 | .dq_callback = do_autogain, | ||
892 | }; | 903 | }; |
893 | 904 | ||
894 | /* -- module initialisation -- */ | 905 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 3a051c925ff6..15d302b28b79 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -47,7 +47,7 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | static int video_nr = -1; | 48 | static int video_nr = -1; |
49 | 49 | ||
50 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 50 | #ifdef GSPCA_DEBUG |
51 | int gspca_debug = D_ERR | D_PROBE; | 51 | int gspca_debug = D_ERR | D_PROBE; |
52 | EXPORT_SYMBOL(gspca_debug); | 52 | EXPORT_SYMBOL(gspca_debug); |
53 | 53 | ||
@@ -677,7 +677,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, | |||
677 | w = fmt->fmt.pix.width; | 677 | w = fmt->fmt.pix.width; |
678 | h = fmt->fmt.pix.height; | 678 | h = fmt->fmt.pix.height; |
679 | 679 | ||
680 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 680 | #ifdef GSPCA_DEBUG |
681 | if (gspca_debug & D_CONF) | 681 | if (gspca_debug & D_CONF) |
682 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); | 682 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); |
683 | #endif | 683 | #endif |
@@ -785,7 +785,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
785 | } | 785 | } |
786 | gspca_dev->users++; | 786 | gspca_dev->users++; |
787 | file->private_data = gspca_dev; | 787 | file->private_data = gspca_dev; |
788 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 788 | #ifdef GSPCA_DEBUG |
789 | /* activate the v4l2 debug */ | 789 | /* activate the v4l2 debug */ |
790 | if (gspca_debug & D_V4L2) | 790 | if (gspca_debug & D_V4L2) |
791 | gspca_dev->vdev.debug |= 3; | 791 | gspca_dev->vdev.debug |= 3; |
@@ -904,7 +904,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
904 | if (ctrl->id != ctrls->qctrl.id) | 904 | if (ctrl->id != ctrls->qctrl.id) |
905 | continue; | 905 | continue; |
906 | if (ctrl->value < ctrls->qctrl.minimum | 906 | if (ctrl->value < ctrls->qctrl.minimum |
907 | && ctrl->value > ctrls->qctrl.maximum) | 907 | || ctrl->value > ctrls->qctrl.maximum) |
908 | return -ERANGE; | 908 | return -ERANGE; |
909 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 909 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
910 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 910 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
@@ -1080,7 +1080,7 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1080 | if (ret < 0) | 1080 | if (ret < 0) |
1081 | goto out; | 1081 | goto out; |
1082 | } | 1082 | } |
1083 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1083 | #ifdef GSPCA_DEBUG |
1084 | if (gspca_debug & D_STREAM) { | 1084 | if (gspca_debug & D_STREAM) { |
1085 | PDEBUG_MODE("stream on OK", | 1085 | PDEBUG_MODE("stream on OK", |
1086 | gspca_dev->pixfmt, | 1086 | gspca_dev->pixfmt, |
@@ -1913,7 +1913,7 @@ static void __exit gspca_exit(void) | |||
1913 | module_init(gspca_init); | 1913 | module_init(gspca_init); |
1914 | module_exit(gspca_exit); | 1914 | module_exit(gspca_exit); |
1915 | 1915 | ||
1916 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1916 | #ifdef GSPCA_DEBUG |
1917 | module_param_named(debug, gspca_debug, int, 0644); | 1917 | module_param_named(debug, gspca_debug, int, 0644); |
1918 | MODULE_PARM_DESC(debug, | 1918 | MODULE_PARM_DESC(debug, |
1919 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" | 1919 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 3fd2c4eee204..67e448940eaa 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -9,7 +9,10 @@ | |||
9 | #include <media/v4l2-common.h> | 9 | #include <media/v4l2-common.h> |
10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
11 | 11 | ||
12 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 12 | /* compilation option */ |
13 | #define GSPCA_DEBUG 1 | ||
14 | |||
15 | #ifdef GSPCA_DEBUG | ||
13 | /* GSPCA our debug messages */ | 16 | /* GSPCA our debug messages */ |
14 | extern int gspca_debug; | 17 | extern int gspca_debug; |
15 | #define PDEBUG(level, fmt, args...) \ | 18 | #define PDEBUG(level, fmt, args...) \ |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 83139efc4629..b4f00ec0885c 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -40,14 +40,15 @@ struct sd { | |||
40 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 40 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
41 | 41 | ||
42 | /* Determined by sensor type */ | 42 | /* Determined by sensor type */ |
43 | short maxwidth; | 43 | char sif; |
44 | short maxheight; | ||
45 | 44 | ||
46 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | 45 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ |
47 | 46 | ||
48 | unsigned char brightness; | 47 | unsigned char brightness; |
49 | unsigned char contrast; | 48 | unsigned char contrast; |
50 | unsigned char colors; | 49 | unsigned char colors; |
50 | __u8 hflip; | ||
51 | __u8 vflip; | ||
51 | 52 | ||
52 | char compress; /* Should the next frame be compressed? */ | 53 | char compress; /* Should the next frame be compressed? */ |
53 | char compress_inited; /* Are compression params uploaded? */ | 54 | char compress_inited; /* Are compression params uploaded? */ |
@@ -77,9 +78,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | |||
77 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 78 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
78 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 79 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
79 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 80 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
81 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
80 | 85 | ||
81 | static struct ctrl sd_ctrls[] = { | 86 | static struct ctrl sd_ctrls[] = { |
82 | #define SD_BRIGHTNESS 0 | ||
83 | { | 87 | { |
84 | { | 88 | { |
85 | .id = V4L2_CID_BRIGHTNESS, | 89 | .id = V4L2_CID_BRIGHTNESS, |
@@ -88,12 +92,12 @@ static struct ctrl sd_ctrls[] = { | |||
88 | .minimum = 0, | 92 | .minimum = 0, |
89 | .maximum = 255, | 93 | .maximum = 255, |
90 | .step = 1, | 94 | .step = 1, |
91 | .default_value = 127, | 95 | #define BRIGHTNESS_DEF 127 |
96 | .default_value = BRIGHTNESS_DEF, | ||
92 | }, | 97 | }, |
93 | .set = sd_setbrightness, | 98 | .set = sd_setbrightness, |
94 | .get = sd_getbrightness, | 99 | .get = sd_getbrightness, |
95 | }, | 100 | }, |
96 | #define SD_CONTRAST 1 | ||
97 | { | 101 | { |
98 | { | 102 | { |
99 | .id = V4L2_CID_CONTRAST, | 103 | .id = V4L2_CID_CONTRAST, |
@@ -102,31 +106,61 @@ static struct ctrl sd_ctrls[] = { | |||
102 | .minimum = 0, | 106 | .minimum = 0, |
103 | .maximum = 255, | 107 | .maximum = 255, |
104 | .step = 1, | 108 | .step = 1, |
105 | .default_value = 127, | 109 | #define CONTRAST_DEF 127 |
110 | .default_value = CONTRAST_DEF, | ||
106 | }, | 111 | }, |
107 | .set = sd_setcontrast, | 112 | .set = sd_setcontrast, |
108 | .get = sd_getcontrast, | 113 | .get = sd_getcontrast, |
109 | }, | 114 | }, |
110 | #define SD_COLOR 2 | ||
111 | { | 115 | { |
112 | { | 116 | { |
113 | .id = V4L2_CID_SATURATION, | 117 | .id = V4L2_CID_SATURATION, |
114 | .type = V4L2_CTRL_TYPE_INTEGER, | 118 | .type = V4L2_CTRL_TYPE_INTEGER, |
115 | .name = "Saturation", | 119 | .name = "Color", |
116 | .minimum = 0, | 120 | .minimum = 0, |
117 | .maximum = 255, | 121 | .maximum = 255, |
118 | .step = 1, | 122 | .step = 1, |
119 | .default_value = 127, | 123 | #define COLOR_DEF 127 |
124 | .default_value = COLOR_DEF, | ||
120 | }, | 125 | }, |
121 | .set = sd_setcolors, | 126 | .set = sd_setcolors, |
122 | .get = sd_getcolors, | 127 | .get = sd_getcolors, |
123 | }, | 128 | }, |
129 | /* next controls work with ov7670 only */ | ||
130 | { | ||
131 | { | ||
132 | .id = V4L2_CID_HFLIP, | ||
133 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
134 | .name = "Mirror", | ||
135 | .minimum = 0, | ||
136 | .maximum = 1, | ||
137 | .step = 1, | ||
138 | #define HFLIP_DEF 0 | ||
139 | .default_value = HFLIP_DEF, | ||
140 | }, | ||
141 | .set = sd_sethflip, | ||
142 | .get = sd_gethflip, | ||
143 | }, | ||
144 | { | ||
145 | { | ||
146 | .id = V4L2_CID_VFLIP, | ||
147 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
148 | .name = "Vflip", | ||
149 | .minimum = 0, | ||
150 | .maximum = 1, | ||
151 | .step = 1, | ||
152 | #define VFLIP_DEF 0 | ||
153 | .default_value = VFLIP_DEF, | ||
154 | }, | ||
155 | .set = sd_setvflip, | ||
156 | .get = sd_getvflip, | ||
157 | }, | ||
124 | }; | 158 | }; |
125 | 159 | ||
126 | static struct v4l2_pix_format vga_mode[] = { | 160 | static struct v4l2_pix_format vga_mode[] = { |
127 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 161 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
128 | .bytesperline = 320, | 162 | .bytesperline = 320, |
129 | .sizeimage = 320 * 240 * 3 / 8 + 589, | 163 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
130 | .colorspace = V4L2_COLORSPACE_JPEG, | 164 | .colorspace = V4L2_COLORSPACE_JPEG, |
131 | .priv = 1}, | 165 | .priv = 1}, |
132 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 166 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
@@ -138,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = { | |||
138 | static struct v4l2_pix_format sif_mode[] = { | 172 | static struct v4l2_pix_format sif_mode[] = { |
139 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 173 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
140 | .bytesperline = 176, | 174 | .bytesperline = 176, |
141 | .sizeimage = 176 * 144 * 3 / 8 + 589, | 175 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
142 | .colorspace = V4L2_COLORSPACE_JPEG, | 176 | .colorspace = V4L2_COLORSPACE_JPEG, |
143 | .priv = 1}, | 177 | .priv = 1}, |
144 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 178 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
145 | .bytesperline = 352, | 179 | .bytesperline = 352, |
146 | .sizeimage = 352 * 288 * 3 / 8 + 589, | 180 | .sizeimage = 352 * 288 * 3 / 8 + 590, |
147 | .colorspace = V4L2_COLORSPACE_JPEG, | 181 | .colorspace = V4L2_COLORSPACE_JPEG, |
148 | .priv = 0}, | 182 | .priv = 0}, |
149 | }; | 183 | }; |
@@ -225,6 +259,7 @@ static struct v4l2_pix_format sif_mode[] = { | |||
225 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ | 259 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ |
226 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ | 260 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ |
227 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ | 261 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ |
262 | #define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ | ||
228 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ | 263 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ |
229 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ | 264 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ |
230 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ | 265 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ |
@@ -258,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = { | |||
258 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | 293 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ |
259 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | 294 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ |
260 | 295 | ||
261 | struct ovsensor_window { | ||
262 | short x; | ||
263 | short y; | ||
264 | short width; | ||
265 | short height; | ||
266 | /* int format; */ | ||
267 | short quarter; /* Scale width and height down 2x */ | ||
268 | short clockdiv; /* Clock divisor setting */ | ||
269 | }; | ||
270 | |||
271 | static unsigned char ov7670_abs_to_sm(unsigned char v) | 296 | static unsigned char ov7670_abs_to_sm(unsigned char v) |
272 | { | 297 | { |
273 | if (v > 127) | 298 | if (v > 127) |
@@ -499,19 +524,6 @@ static int init_ov_sensor(struct sd *sd) | |||
499 | return 0; | 524 | return 0; |
500 | } | 525 | } |
501 | 526 | ||
502 | /* Switch on standard JPEG compression. Returns 0 for success. */ | ||
503 | static int ov519_init_compression(struct sd *sd) | ||
504 | { | ||
505 | if (!sd->compress_inited) { | ||
506 | if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { | ||
507 | PDEBUG(D_ERR, "Error switching to compressed mode"); | ||
508 | return -EIO; | ||
509 | } | ||
510 | sd->compress_inited = 1; | ||
511 | } | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | 527 | /* Set the read and write slave IDs. The "slave" argument is the write slave, |
516 | * and the read slave will be set to (slave + 1). | 528 | * and the read slave will be set to (slave + 1). |
517 | * This should not be called from outside the i2c I/O functions. | 529 | * This should not be called from outside the i2c I/O functions. |
@@ -681,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd) | |||
681 | return -1; | 693 | return -1; |
682 | } | 694 | } |
683 | if ((rc & 3) == 1) { | 695 | if ((rc & 3) == 1) { |
684 | PDEBUG(D_PROBE, "Sensor is an OV8610"); | ||
685 | sd->sensor = SEN_OV8610; | 696 | sd->sensor = SEN_OV8610; |
686 | } else { | 697 | } else { |
687 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | 698 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); |
688 | return -1; | 699 | return -1; |
689 | } | 700 | } |
690 | PDEBUG(D_PROBE, "Writing 8610 registers"); | 701 | PDEBUG(D_PROBE, "Writing 8610 registers"); |
691 | if (write_i2c_regvals(sd, | 702 | if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610))) |
692 | norm_8610, | ||
693 | sizeof norm_8610 / sizeof norm_8610[0])) | ||
694 | return -1; | 703 | return -1; |
695 | 704 | ||
696 | /* Set sensor-specific vars */ | 705 | /* Set sensor-specific vars */ |
697 | sd->maxwidth = 640; | 706 | /* sd->sif = 0; already done */ |
698 | sd->maxheight = 480; | ||
699 | return 0; | 707 | return 0; |
700 | } | 708 | } |
701 | 709 | ||
@@ -825,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
825 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | 833 | { OV7670_REG_COM7, OV7670_COM7_RESET }, |
826 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | 834 | { OV7670_REG_TSLB, 0x04 }, /* OV */ |
827 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | 835 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ |
828 | { OV7670_REG_CLKRC, 0x1 }, | 836 | { OV7670_REG_CLKRC, 0x01 }, |
829 | /* | 837 | /* |
830 | * Set the hardware window. These values from OV don't entirely | 838 | * Set the hardware window. These values from OV don't entirely |
831 | * make sense - hstop is less than hstart. But they work... | 839 | * make sense - hstop is less than hstart. But they work... |
@@ -839,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd) | |||
839 | { 0x70, 0x3a }, { 0x71, 0x35 }, | 847 | { 0x70, 0x3a }, { 0x71, 0x35 }, |
840 | { 0x72, 0x11 }, { 0x73, 0xf0 }, | 848 | { 0x72, 0x11 }, { 0x73, 0xf0 }, |
841 | { 0xa2, 0x02 }, | 849 | { 0xa2, 0x02 }, |
842 | /* jfm */ | 850 | /* { OV7670_REG_COM10, 0x0 }, */ |
843 | /* { OV7670_REG_COM10, 0x0 }, */ | ||
844 | 851 | ||
845 | /* Gamma curve values */ | 852 | /* Gamma curve values */ |
846 | { 0x7a, 0x20 }, | 853 | { 0x7a, 0x20 }, |
847 | /* jfm:win 7b=1c */ | ||
848 | { 0x7b, 0x10 }, | 854 | { 0x7b, 0x10 }, |
849 | /* jfm:win 7c=28 */ | ||
850 | { 0x7c, 0x1e }, | 855 | { 0x7c, 0x1e }, |
851 | /* jfm:win 7d=3c */ | ||
852 | { 0x7d, 0x35 }, | 856 | { 0x7d, 0x35 }, |
853 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, | 857 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, |
854 | { 0x80, 0x76 }, { 0x81, 0x80 }, | 858 | { 0x80, 0x76 }, { 0x81, 0x80 }, |
@@ -864,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd) | |||
864 | | OV7670_COM8_BFILT }, | 868 | | OV7670_COM8_BFILT }, |
865 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, | 869 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, |
866 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | 870 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ |
867 | /* jfm:win 14=38 */ | ||
868 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | 871 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ |
869 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, | 872 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, |
870 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, | 873 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, |
871 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, | 874 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, |
872 | { OV7670_REG_HAECC2, 0x68 }, | 875 | { OV7670_REG_HAECC2, 0x68 }, |
873 | /* jfm:win a1=0b */ | ||
874 | { 0xa1, 0x03 }, /* magic */ | 876 | { 0xa1, 0x03 }, /* magic */ |
875 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, | 877 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, |
876 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, | 878 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, |
@@ -884,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd) | |||
884 | /* Almost all of these are magic "reserved" values. */ | 886 | /* Almost all of these are magic "reserved" values. */ |
885 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, | 887 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, |
886 | { 0x16, 0x02 }, | 888 | { 0x16, 0x02 }, |
887 | /* jfm */ | ||
888 | /* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ | ||
889 | { OV7670_REG_MVFP, 0x07 }, | 889 | { OV7670_REG_MVFP, 0x07 }, |
890 | { 0x21, 0x02 }, { 0x22, 0x91 }, | 890 | { 0x21, 0x02 }, { 0x22, 0x91 }, |
891 | { 0x29, 0x07 }, { 0x33, 0x0b }, | 891 | { 0x29, 0x07 }, { 0x33, 0x0b }, |
@@ -930,7 +930,10 @@ static int ov7xx0_configure(struct sd *sd) | |||
930 | { OV7670_REG_EDGE, 0 }, | 930 | { OV7670_REG_EDGE, 0 }, |
931 | { 0x75, 0x05 }, { 0x76, 0xe1 }, | 931 | { 0x75, 0x05 }, { 0x76, 0xe1 }, |
932 | { 0x4c, 0 }, { 0x77, 0x01 }, | 932 | { 0x4c, 0 }, { 0x77, 0x01 }, |
933 | { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, | 933 | { OV7670_REG_COM13, OV7670_COM13_GAMMA |
934 | | OV7670_COM13_UVSAT | ||
935 | | 2}, /* was 3 */ | ||
936 | { 0x4b, 0x09 }, | ||
934 | { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, | 937 | { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, |
935 | { 0x56, 0x40 }, | 938 | { 0x56, 0x40 }, |
936 | 939 | ||
@@ -956,30 +959,10 @@ static int ov7xx0_configure(struct sd *sd) | |||
956 | { 0x79, 0x03 }, { 0xc8, 0x40 }, | 959 | { 0x79, 0x03 }, { 0xc8, 0x40 }, |
957 | { 0x79, 0x05 }, { 0xc8, 0x30 }, | 960 | { 0x79, 0x05 }, { 0xc8, 0x30 }, |
958 | { 0x79, 0x26 }, | 961 | { 0x79, 0x26 }, |
959 | 962 | }; | |
960 | /* Format YUV422 */ | ||
961 | { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ | ||
962 | { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ | ||
963 | { OV7670_REG_COM1, 0 }, | ||
964 | { OV7670_REG_COM15, OV7670_COM15_R00FF }, | ||
965 | { OV7670_REG_COM9, 0x18 }, | ||
966 | /* 4x gain ceiling; 0x8 is reserved bit */ | ||
967 | { 0x4f, 0x80 }, /* "matrix coefficient 1" */ | ||
968 | { 0x50, 0x80 }, /* "matrix coefficient 2" */ | ||
969 | { 0x52, 0x22 }, /* "matrix coefficient 4" */ | ||
970 | { 0x53, 0x5e }, /* "matrix coefficient 5" */ | ||
971 | { 0x54, 0x80 }, /* "matrix coefficient 6" */ | ||
972 | { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, | ||
973 | }; | ||
974 | 963 | ||
975 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | 964 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); |
976 | 965 | ||
977 | /* jfm:already done? */ | ||
978 | if (init_ov_sensor(sd) < 0) | ||
979 | PDEBUG(D_ERR, "Failed to read sensor ID"); | ||
980 | else | ||
981 | PDEBUG(D_PROBE, "OV7xx0 initialized"); | ||
982 | |||
983 | /* Detect sensor (sub)type */ | 966 | /* Detect sensor (sub)type */ |
984 | rc = i2c_r(sd, OV7610_REG_COM_I); | 967 | rc = i2c_r(sd, OV7610_REG_COM_I); |
985 | 968 | ||
@@ -1025,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd) | |||
1025 | return low; | 1008 | return low; |
1026 | } | 1009 | } |
1027 | if (high == 0x76) { | 1010 | if (high == 0x76) { |
1028 | if (low == 0x30) { | 1011 | switch (low) { |
1012 | case 0x30: | ||
1029 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); | 1013 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); |
1030 | sd->sensor = SEN_OV7630; | 1014 | sd->sensor = SEN_OV7630; |
1031 | } else if (low == 0x40) { | 1015 | break; |
1016 | case 0x40: | ||
1032 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | 1017 | PDEBUG(D_PROBE, "Sensor is an OV7645"); |
1033 | sd->sensor = SEN_OV7640; /* FIXME */ | 1018 | sd->sensor = SEN_OV7640; /* FIXME */ |
1034 | } else if (low == 0x45) { | 1019 | break; |
1020 | case 0x45: | ||
1035 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); | 1021 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); |
1036 | sd->sensor = SEN_OV7640; /* FIXME */ | 1022 | sd->sensor = SEN_OV7640; /* FIXME */ |
1037 | } else if (low == 0x48) { | 1023 | break; |
1024 | case 0x48: | ||
1038 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 1025 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
1039 | sd->sensor = SEN_OV7640; /* FIXME */ | 1026 | sd->sensor = SEN_OV7640; /* FIXME */ |
1040 | } else { | 1027 | break; |
1041 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); | 1028 | default: |
1029 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | ||
1042 | return -1; | 1030 | return -1; |
1043 | } | 1031 | } |
1044 | } else { | 1032 | } else { |
@@ -1050,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd) | |||
1050 | return -1; | 1038 | return -1; |
1051 | } | 1039 | } |
1052 | 1040 | ||
1053 | if (sd->sensor == SEN_OV7620) { | 1041 | switch (sd->sensor) { |
1042 | case SEN_OV7620: | ||
1054 | PDEBUG(D_PROBE, "Writing 7620 registers"); | 1043 | PDEBUG(D_PROBE, "Writing 7620 registers"); |
1055 | if (write_i2c_regvals(sd, norm_7620, | 1044 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) |
1056 | sizeof norm_7620 / sizeof norm_7620[0])) | ||
1057 | return -1; | 1045 | return -1; |
1058 | } else if (sd->sensor == SEN_OV7630) { | 1046 | break; |
1047 | case SEN_OV7630: | ||
1059 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); | 1048 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); |
1060 | return -1; | 1049 | return -1; |
1061 | } else if (sd->sensor == SEN_OV7640) { | 1050 | case SEN_OV7640: |
1062 | PDEBUG(D_PROBE, "Writing 7640 registers"); | 1051 | PDEBUG(D_PROBE, "Writing 7640 registers"); |
1063 | if (write_i2c_regvals(sd, norm_7640, | 1052 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) |
1064 | sizeof norm_7640 / sizeof norm_7640[0])) | ||
1065 | return -1; | 1053 | return -1; |
1066 | } else if (sd->sensor == SEN_OV7670) { | 1054 | break; |
1055 | case SEN_OV7670: | ||
1067 | PDEBUG(D_PROBE, "Writing 7670 registers"); | 1056 | PDEBUG(D_PROBE, "Writing 7670 registers"); |
1068 | if (write_i2c_regvals(sd, norm_7670, | 1057 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) |
1069 | sizeof norm_7670 / sizeof norm_7670[0])) | ||
1070 | return -1; | 1058 | return -1; |
1071 | } else { | 1059 | break; |
1060 | default: | ||
1072 | PDEBUG(D_PROBE, "Writing 7610 registers"); | 1061 | PDEBUG(D_PROBE, "Writing 7610 registers"); |
1073 | if (write_i2c_regvals(sd, norm_7610, | 1062 | if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) |
1074 | sizeof norm_7610 / sizeof norm_7610[0])) | ||
1075 | return -1; | 1063 | return -1; |
1064 | break; | ||
1076 | } | 1065 | } |
1077 | 1066 | ||
1078 | /* Set sensor-specific vars */ | 1067 | /* Set sensor-specific vars */ |
1079 | sd->maxwidth = 640; | 1068 | /* sd->sif = 0; already done */ |
1080 | sd->maxheight = 480; | ||
1081 | return 0; | 1069 | return 0; |
1082 | } | 1070 | } |
1083 | 1071 | ||
@@ -1231,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd) | |||
1231 | /* Ugh. The first two bits are the version bits, but | 1219 | /* Ugh. The first two bits are the version bits, but |
1232 | * the entire register value must be used. I guess OVT | 1220 | * the entire register value must be used. I guess OVT |
1233 | * underestimated how many variants they would make. */ | 1221 | * underestimated how many variants they would make. */ |
1234 | if (rc == 0x00) { | 1222 | switch (rc) { |
1223 | case 0x00: | ||
1235 | sd->sensor = SEN_OV6630; | 1224 | sd->sensor = SEN_OV6630; |
1236 | PDEBUG(D_ERR, | 1225 | PDEBUG(D_ERR, |
1237 | "WARNING: Sensor is an OV66308. Your camera may have"); | 1226 | "WARNING: Sensor is an OV66308. Your camera may have"); |
1238 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | 1227 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); |
1239 | } else if (rc == 0x01) { | 1228 | break; |
1229 | case 0x01: | ||
1240 | sd->sensor = SEN_OV6620; | 1230 | sd->sensor = SEN_OV6620; |
1241 | PDEBUG(D_PROBE, "Sensor is an OV6620"); | 1231 | break; |
1242 | } else if (rc == 0x02) { | 1232 | case 0x02: |
1243 | sd->sensor = SEN_OV6630; | 1233 | sd->sensor = SEN_OV6630; |
1244 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); | 1234 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); |
1245 | } else if (rc == 0x03) { | 1235 | break; |
1236 | case 0x03: | ||
1246 | sd->sensor = SEN_OV6630; | 1237 | sd->sensor = SEN_OV6630; |
1247 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); | 1238 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); |
1248 | } else if (rc == 0x90) { | 1239 | break; |
1240 | case 0x90: | ||
1249 | sd->sensor = SEN_OV6630; | 1241 | sd->sensor = SEN_OV6630; |
1250 | PDEBUG(D_ERR, | 1242 | PDEBUG(D_ERR, |
1251 | "WARNING: Sensor is an OV66307. Your camera may have"); | 1243 | "WARNING: Sensor is an OV66307. Your camera may have"); |
1252 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | 1244 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); |
1253 | } else { | 1245 | break; |
1246 | default: | ||
1254 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); | 1247 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); |
1255 | return -1; | 1248 | return -1; |
1256 | } | 1249 | } |
1257 | 1250 | ||
1258 | /* Set sensor-specific vars */ | 1251 | /* Set sensor-specific vars */ |
1259 | sd->maxwidth = 352; | 1252 | sd->sif = 1; |
1260 | sd->maxheight = 288; | ||
1261 | 1253 | ||
1262 | if (sd->sensor == SEN_OV6620) { | 1254 | if (sd->sensor == SEN_OV6620) { |
1263 | PDEBUG(D_PROBE, "Writing 6x20 registers"); | 1255 | PDEBUG(D_PROBE, "Writing 6x20 registers"); |
1264 | if (write_i2c_regvals(sd, norm_6x20, | 1256 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) |
1265 | sizeof norm_6x20 / sizeof norm_6x20[0])) | ||
1266 | return -1; | 1257 | return -1; |
1267 | } else { | 1258 | } else { |
1268 | PDEBUG(D_PROBE, "Writing 6x30 registers"); | 1259 | PDEBUG(D_PROBE, "Writing 6x30 registers"); |
1269 | if (write_i2c_regvals(sd, norm_6x30, | 1260 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) |
1270 | sizeof norm_6x30 / sizeof norm_6x30[0])) | ||
1271 | return -1; | 1261 | return -1; |
1272 | } | 1262 | } |
1273 | return 0; | 1263 | return 0; |
@@ -1276,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd) | |||
1276 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 1266 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
1277 | static void ov51x_led_control(struct sd *sd, int on) | 1267 | static void ov51x_led_control(struct sd *sd, int on) |
1278 | { | 1268 | { |
1279 | PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); | 1269 | /* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */ |
1280 | 1270 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | |
1281 | /* if (sd->bridge == BRG_OV511PLUS) */ | ||
1282 | /* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ | ||
1283 | /* else if (sd->bridge == BRG_OV519) */ | ||
1284 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1285 | /* else if (sd->bclass == BCL_OV518) */ | ||
1286 | /* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ | ||
1287 | } | 1271 | } |
1288 | 1272 | ||
1289 | /* this function is called at probe time */ | 1273 | /* this function is called at probe time */ |
@@ -1293,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1293 | struct sd *sd = (struct sd *) gspca_dev; | 1277 | struct sd *sd = (struct sd *) gspca_dev; |
1294 | struct cam *cam; | 1278 | struct cam *cam; |
1295 | 1279 | ||
1296 | /* (from ov519_configure) */ | ||
1297 | static const struct ov_regvals init_519[] = { | 1280 | static const struct ov_regvals init_519[] = { |
1298 | { 0x5a, 0x6d }, /* EnableSystem */ | 1281 | { 0x5a, 0x6d }, /* EnableSystem */ |
1299 | /* jfm trace usbsnoop3-1.txt */ | ||
1300 | /* jfm 53 = fb */ | ||
1301 | { 0x53, 0x9b }, | 1282 | { 0x53, 0x9b }, |
1302 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | 1283 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ |
1303 | { 0x5d, 0x03 }, | 1284 | { 0x5d, 0x03 }, |
@@ -1314,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1314 | 1295 | ||
1315 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | 1296 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) |
1316 | goto error; | 1297 | goto error; |
1317 | /* jfm: not seen in windows trace */ | ||
1318 | if (ov519_init_compression(sd)) | ||
1319 | goto error; | ||
1320 | ov51x_led_control(sd, 0); /* turn LED off */ | 1298 | ov51x_led_control(sd, 0); /* turn LED off */ |
1321 | 1299 | ||
1322 | /* Test for 76xx */ | 1300 | /* Test for 76xx */ |
@@ -1365,16 +1343,18 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1365 | 1343 | ||
1366 | cam = &gspca_dev->cam; | 1344 | cam = &gspca_dev->cam; |
1367 | cam->epaddr = OV511_ENDPOINT_ADDRESS; | 1345 | cam->epaddr = OV511_ENDPOINT_ADDRESS; |
1368 | if (sd->maxwidth == 640) { | 1346 | if (!sd->sif) { |
1369 | cam->cam_mode = vga_mode; | 1347 | cam->cam_mode = vga_mode; |
1370 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | 1348 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1371 | } else { | 1349 | } else { |
1372 | cam->cam_mode = sif_mode; | 1350 | cam->cam_mode = sif_mode; |
1373 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | 1351 | cam->nmodes = ARRAY_SIZE(sif_mode); |
1374 | } | 1352 | } |
1375 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | 1353 | sd->brightness = BRIGHTNESS_DEF; |
1376 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | 1354 | sd->contrast = CONTRAST_DEF; |
1377 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | 1355 | sd->colors = COLOR_DEF; |
1356 | sd->hflip = HFLIP_DEF; | ||
1357 | sd->vflip = VFLIP_DEF; | ||
1378 | return 0; | 1358 | return 0; |
1379 | error: | 1359 | error: |
1380 | PDEBUG(D_ERR, "OV519 Config failed"); | 1360 | PDEBUG(D_ERR, "OV519 Config failed"); |
@@ -1394,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
1394 | * | 1374 | * |
1395 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 1375 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
1396 | */ | 1376 | */ |
1397 | static int ov519_mode_init_regs(struct sd *sd, | 1377 | static int ov519_mode_init_regs(struct sd *sd) |
1398 | int width, int height) | ||
1399 | { | 1378 | { |
1400 | static const struct ov_regvals mode_init_519_ov7670[] = { | 1379 | static const struct ov_regvals mode_init_519_ov7670[] = { |
1401 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 1380 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
@@ -1441,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1441 | /* windows reads 0x55 at this point, why? */ | 1420 | /* windows reads 0x55 at this point, why? */ |
1442 | }; | 1421 | }; |
1443 | 1422 | ||
1444 | /* int hi_res; */ | ||
1445 | |||
1446 | PDEBUG(D_CONF, "mode init %dx%d", width, height); | ||
1447 | |||
1448 | /* if (width >= 800 && height >= 600) | ||
1449 | hi_res = 1; | ||
1450 | else | ||
1451 | hi_res = 0; */ | ||
1452 | |||
1453 | /* if (ov51x_stop(sd) < 0) | ||
1454 | return -EIO; */ | ||
1455 | |||
1456 | /******** Set the mode ********/ | 1423 | /******** Set the mode ********/ |
1457 | if (sd->sensor != SEN_OV7670) { | 1424 | if (sd->sensor != SEN_OV7670) { |
1458 | if (write_regvals(sd, mode_init_519, | 1425 | if (write_regvals(sd, mode_init_519, |
1459 | ARRAY_SIZE(mode_init_519))) | 1426 | ARRAY_SIZE(mode_init_519))) |
1460 | return -EIO; | 1427 | return -EIO; |
1428 | if (sd->sensor == SEN_OV7640) { | ||
1429 | /* Select 8-bit input mode */ | ||
1430 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
1431 | } | ||
1461 | } else { | 1432 | } else { |
1462 | if (write_regvals(sd, mode_init_519_ov7670, | 1433 | if (write_regvals(sd, mode_init_519_ov7670, |
1463 | ARRAY_SIZE(mode_init_519_ov7670))) | 1434 | ARRAY_SIZE(mode_init_519_ov7670))) |
1464 | return -EIO; | 1435 | return -EIO; |
1465 | } | 1436 | } |
1466 | 1437 | ||
1467 | if (sd->sensor == SEN_OV7640) { | 1438 | reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4); |
1468 | /* Select 8-bit input mode */ | 1439 | reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3); |
1469 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
1470 | } | ||
1471 | |||
1472 | reg_w(sd, OV519_CAM_H_SIZE, width >> 4); | ||
1473 | reg_w(sd, OV519_CAM_V_SIZE, height >> 3); | ||
1474 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); | 1440 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); |
1475 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); | 1441 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); |
1476 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); | 1442 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); |
@@ -1485,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1485 | 1451 | ||
1486 | /* FIXME: These are only valid at the max resolution. */ | 1452 | /* FIXME: These are only valid at the max resolution. */ |
1487 | sd->clockdiv = 0; | 1453 | sd->clockdiv = 0; |
1488 | if (sd->sensor == SEN_OV7640) { | 1454 | switch (sd->sensor) { |
1455 | case SEN_OV7640: | ||
1489 | switch (sd->frame_rate) { | 1456 | switch (sd->frame_rate) { |
1490 | /*jfm: default was 30 fps */ | 1457 | /*fixme: default was 30 fps */ |
1491 | case 30: | 1458 | case 30: |
1492 | reg_w(sd, 0xa4, 0x0c); | 1459 | reg_w(sd, 0xa4, 0x0c); |
1493 | reg_w(sd, 0x23, 0xff); | 1460 | reg_w(sd, 0x23, 0xff); |
@@ -1517,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1517 | sd->clockdiv = 1; | 1484 | sd->clockdiv = 1; |
1518 | break; | 1485 | break; |
1519 | } | 1486 | } |
1520 | } else if (sd->sensor == SEN_OV8610) { | 1487 | break; |
1488 | case SEN_OV8610: | ||
1521 | switch (sd->frame_rate) { | 1489 | switch (sd->frame_rate) { |
1522 | default: /* 15 fps */ | 1490 | default: /* 15 fps */ |
1523 | /* case 15: */ | 1491 | /* case 15: */ |
@@ -1533,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1533 | reg_w(sd, 0x23, 0x1b); | 1501 | reg_w(sd, 0x23, 0x1b); |
1534 | break; | 1502 | break; |
1535 | } | 1503 | } |
1536 | sd->clockdiv = 0; | 1504 | break; |
1537 | } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ | 1505 | case SEN_OV7670: /* guesses, based on 7640 */ |
1538 | PDEBUG(D_STREAM, "Setting framerate to %d fps", | 1506 | PDEBUG(D_STREAM, "Setting framerate to %d fps", |
1539 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); | 1507 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); |
1508 | reg_w(sd, 0xa4, 0x10); | ||
1540 | switch (sd->frame_rate) { | 1509 | switch (sd->frame_rate) { |
1541 | case 30: | 1510 | case 30: |
1542 | reg_w(sd, 0xa4, 0x10); | ||
1543 | reg_w(sd, 0x23, 0xff); | 1511 | reg_w(sd, 0x23, 0xff); |
1544 | break; | 1512 | break; |
1545 | case 20: | 1513 | case 20: |
1546 | reg_w(sd, 0xa4, 0x10); | ||
1547 | reg_w(sd, 0x23, 0x1b); | 1514 | reg_w(sd, 0x23, 0x1b); |
1548 | break; | 1515 | break; |
1549 | default: /* 15 fps */ | 1516 | default: |
1550 | /* case 15: */ | 1517 | /* case 15: */ |
1551 | reg_w(sd, 0xa4, 0x10); | ||
1552 | reg_w(sd, 0x23, 0xff); | 1518 | reg_w(sd, 0x23, 0xff); |
1553 | sd->clockdiv = 1; | 1519 | sd->clockdiv = 1; |
1554 | break; | 1520 | break; |
1555 | } | 1521 | } |
1522 | break; | ||
1556 | } | 1523 | } |
1557 | 1524 | ||
1558 | /* if (ov51x_restart(sd) < 0) | ||
1559 | return -EIO; */ | ||
1560 | |||
1561 | /* Reset it just for good measure */ | ||
1562 | /* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) | ||
1563 | return -EIO; */ | ||
1564 | return 0; | 1525 | return 0; |
1565 | } | 1526 | } |
1566 | 1527 | ||
1567 | static int mode_init_ov_sensor_regs(struct sd *sd, | 1528 | static int mode_init_ov_sensor_regs(struct sd *sd) |
1568 | struct ovsensor_window *win) | ||
1569 | { | 1529 | { |
1570 | int qvga = win->quarter; | 1530 | struct gspca_dev *gspca_dev; |
1531 | int qvga; | ||
1532 | |||
1533 | gspca_dev = &sd->gspca_dev; | ||
1534 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1571 | 1535 | ||
1572 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | 1536 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ |
1573 | switch (sd->sensor) { | 1537 | switch (sd->sensor) { |
@@ -1611,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1611 | OV7670_COM7_FMT_MASK); | 1575 | OV7670_COM7_FMT_MASK); |
1612 | break; | 1576 | break; |
1613 | case SEN_OV6620: | 1577 | case SEN_OV6620: |
1614 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1615 | break; | ||
1616 | case SEN_OV6630: | 1578 | case SEN_OV6630: |
1617 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 1579 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
1618 | break; | 1580 | break; |
@@ -1621,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1621 | } | 1583 | } |
1622 | 1584 | ||
1623 | /******** Palette-specific regs ********/ | 1585 | /******** Palette-specific regs ********/ |
1624 | /* Need to do work here for the OV7670 */ | 1586 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { |
1625 | 1587 | /* not valid on the OV6620/OV7620/6630? */ | |
1626 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | 1588 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); |
1627 | /* not valid on the OV6620/OV7620/6630? */ | 1589 | } |
1628 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); | ||
1629 | } | ||
1630 | 1590 | ||
1631 | /* The OV518 needs special treatment. Although both the OV518 | 1591 | /* The OV518 needs special treatment. Although both the OV518 |
1632 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y | 1592 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y |
1633 | * bus is actually used. The UV bus is tied to ground. | 1593 | * bus is actually used. The UV bus is tied to ground. |
1634 | * Therefore, the OV6630 needs to be in 8-bit multiplexed | 1594 | * Therefore, the OV6630 needs to be in 8-bit multiplexed |
1635 | * output mode */ | 1595 | * output mode */ |
1636 | 1596 | ||
1637 | /* OV7640 is 8-bit only */ | 1597 | /* OV7640 is 8-bit only */ |
1638 | 1598 | ||
1639 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) | 1599 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) |
1640 | i2c_w_mask(sd, 0x13, 0x00, 0x20); | 1600 | i2c_w_mask(sd, 0x13, 0x00, 0x20); |
1641 | /* } */ | ||
1642 | 1601 | ||
1643 | /******** Clock programming ********/ | 1602 | /******** Clock programming ********/ |
1644 | /* The OV6620 needs special handling. This prevents the | 1603 | /* The OV6620 needs special handling. This prevents the |
@@ -1647,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1647 | 1606 | ||
1648 | /* Clock down */ | 1607 | /* Clock down */ |
1649 | i2c_w(sd, 0x2a, 0x04); | 1608 | i2c_w(sd, 0x2a, 0x04); |
1650 | i2c_w(sd, 0x11, win->clockdiv); | 1609 | i2c_w(sd, 0x11, sd->clockdiv); |
1651 | i2c_w(sd, 0x2a, 0x84); | 1610 | i2c_w(sd, 0x2a, 0x84); |
1652 | /* This next setting is critical. It seems to improve | 1611 | /* This next setting is critical. It seems to improve |
1653 | * the gain or the contrast. The "reserved" bits seem | 1612 | * the gain or the contrast. The "reserved" bits seem |
1654 | * to have some effect in this case. */ | 1613 | * to have some effect in this case. */ |
1655 | i2c_w(sd, 0x2d, 0x85); | 1614 | i2c_w(sd, 0x2d, 0x85); |
1656 | } else if (win->clockdiv >= 0) { | 1615 | } else if (sd->clockdiv >= 0) { |
1657 | i2c_w(sd, 0x11, win->clockdiv); | 1616 | i2c_w(sd, 0x11, sd->clockdiv); |
1658 | } | 1617 | } |
1659 | 1618 | ||
1660 | /******** Special Features ********/ | 1619 | /******** Special Features ********/ |
@@ -1674,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1674 | /* is fully tested. */ | 1633 | /* is fully tested. */ |
1675 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ | 1634 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ |
1676 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | 1635 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { |
1677 | if (win->width == 640 /*&& win->height == 480*/) | 1636 | if (!qvga) |
1678 | i2c_w(sd, 0x35, 0x9e); | 1637 | i2c_w(sd, 0x35, 0x9e); |
1679 | else | 1638 | else |
1680 | i2c_w(sd, 0x35, 0x1e); | 1639 | i2c_w(sd, 0x35, 0x1e); |
@@ -1682,13 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1682 | return 0; | 1641 | return 0; |
1683 | } | 1642 | } |
1684 | 1643 | ||
1685 | static int set_ov_sensor_window(struct sd *sd, | 1644 | static void sethvflip(struct sd *sd) |
1686 | struct ovsensor_window *win) | ||
1687 | { | 1645 | { |
1646 | if (sd->sensor != SEN_OV7670) | ||
1647 | return; | ||
1648 | if (sd->gspca_dev.streaming) | ||
1649 | ov51x_stop(sd); | ||
1650 | i2c_w_mask(sd, OV7670_REG_MVFP, | ||
1651 | OV7670_MVFP_MIRROR * sd->hflip | ||
1652 | | OV7670_MVFP_VFLIP * sd->vflip, | ||
1653 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | ||
1654 | if (sd->gspca_dev.streaming) | ||
1655 | ov51x_restart(sd); | ||
1656 | } | ||
1657 | |||
1658 | static int set_ov_sensor_window(struct sd *sd) | ||
1659 | { | ||
1660 | struct gspca_dev *gspca_dev; | ||
1661 | int qvga; | ||
1688 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | 1662 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; |
1689 | int ret, hstart, hstop, vstop, vstart; | 1663 | int ret, hstart, hstop, vstop, vstart; |
1690 | __u8 v; | 1664 | __u8 v; |
1691 | 1665 | ||
1666 | gspca_dev = &sd->gspca_dev; | ||
1667 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1668 | |||
1692 | /* The different sensor ICs handle setting up of window differently. | 1669 | /* The different sensor ICs handle setting up of window differently. |
1693 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | 1670 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ |
1694 | switch (sd->sensor) { | 1671 | switch (sd->sensor) { |
@@ -1733,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1733 | switch (sd->sensor) { | 1710 | switch (sd->sensor) { |
1734 | case SEN_OV6620: | 1711 | case SEN_OV6620: |
1735 | case SEN_OV6630: | 1712 | case SEN_OV6630: |
1736 | if (win->quarter) { /* QCIF */ | 1713 | if (qvga) { /* QCIF */ |
1737 | hwscale = 0; | 1714 | hwscale = 0; |
1738 | vwscale = 0; | 1715 | vwscale = 0; |
1739 | } else { /* CIF */ | 1716 | } else { /* CIF */ |
@@ -1743,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1743 | } | 1720 | } |
1744 | break; | 1721 | break; |
1745 | case SEN_OV8610: | 1722 | case SEN_OV8610: |
1746 | if (win->quarter) { /* QSVGA */ | 1723 | if (qvga) { /* QSVGA */ |
1747 | hwscale = 1; | 1724 | hwscale = 1; |
1748 | vwscale = 1; | 1725 | vwscale = 1; |
1749 | } else { /* SVGA */ | 1726 | } else { /* SVGA */ |
@@ -1752,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1752 | } | 1729 | } |
1753 | break; | 1730 | break; |
1754 | default: /* SEN_OV7xx0 */ | 1731 | default: /* SEN_OV7xx0 */ |
1755 | if (win->quarter) { /* QVGA */ | 1732 | if (qvga) { /* QVGA */ |
1756 | hwscale = 1; | 1733 | hwscale = 1; |
1757 | vwscale = 0; | 1734 | vwscale = 0; |
1758 | } else { /* VGA */ | 1735 | } else { /* VGA */ |
@@ -1761,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1761 | } | 1738 | } |
1762 | } | 1739 | } |
1763 | 1740 | ||
1764 | ret = mode_init_ov_sensor_regs(sd, win); | 1741 | ret = mode_init_ov_sensor_regs(sd); |
1765 | if (ret < 0) | 1742 | if (ret < 0) |
1766 | return ret; | 1743 | return ret; |
1767 | 1744 | ||
@@ -1782,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1782 | /* I can hard code this for OV7670s */ | 1759 | /* I can hard code this for OV7670s */ |
1783 | /* Yes, these numbers do look odd, but they're tested and work! */ | 1760 | /* Yes, these numbers do look odd, but they're tested and work! */ |
1784 | if (sd->sensor == SEN_OV7670) { | 1761 | if (sd->sensor == SEN_OV7670) { |
1785 | if (win->quarter) { /* QVGA from ov7670.c by | 1762 | if (qvga) { /* QVGA from ov7670.c by |
1786 | * Jonathan Corbet */ | 1763 | * Jonathan Corbet */ |
1787 | hstart = 164; | 1764 | hstart = 164; |
1788 | hstop = 20; | 1765 | hstop = 20; |
@@ -1796,75 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1796 | } | 1773 | } |
1797 | /* OV7670 hardware window registers are split across | 1774 | /* OV7670 hardware window registers are split across |
1798 | * multiple locations */ | 1775 | * multiple locations */ |
1799 | i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); | 1776 | i2c_w(sd, OV7670_REG_HSTART, hstart >> 3); |
1800 | i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); | 1777 | i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3); |
1801 | v = i2c_r(sd, OV7670_REG_HREF); | 1778 | v = i2c_r(sd, OV7670_REG_HREF); |
1802 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); | 1779 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); |
1803 | msleep(10); /* need to sleep between read and write to | 1780 | msleep(10); /* need to sleep between read and write to |
1804 | * same reg! */ | 1781 | * same reg! */ |
1805 | i2c_w(sd, OV7670_REG_HREF, v); | 1782 | i2c_w(sd, OV7670_REG_HREF, v); |
1806 | 1783 | ||
1807 | i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); | 1784 | i2c_w(sd, OV7670_REG_VSTART, vstart >> 2); |
1808 | i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); | 1785 | i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2); |
1809 | v = i2c_r(sd, OV7670_REG_VREF); | 1786 | v = i2c_r(sd, OV7670_REG_VREF); |
1810 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); | 1787 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); |
1811 | msleep(10); /* need to sleep between read and write to | 1788 | msleep(10); /* need to sleep between read and write to |
1812 | * same reg! */ | 1789 | * same reg! */ |
1813 | i2c_w(sd, OV7670_REG_VREF, v); | 1790 | i2c_w(sd, OV7670_REG_VREF, v); |
1814 | 1791 | sethvflip(sd); | |
1815 | } else { | 1792 | } else { |
1816 | i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); | 1793 | i2c_w(sd, 0x17, hwsbase); |
1817 | i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); | 1794 | i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); |
1818 | i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); | 1795 | i2c_w(sd, 0x19, vwsbase); |
1819 | i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); | 1796 | i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); |
1820 | } | 1797 | } |
1821 | return 0; | 1798 | return 0; |
1822 | } | 1799 | } |
1823 | 1800 | ||
1824 | static int ov_sensor_mode_setup(struct sd *sd, | ||
1825 | int width, int height) | ||
1826 | { | ||
1827 | struct ovsensor_window win; | ||
1828 | |||
1829 | /* win.format = mode; */ | ||
1830 | |||
1831 | /* Unless subcapture is enabled, | ||
1832 | * center the image window and downsample | ||
1833 | * if possible to increase the field of view */ | ||
1834 | /* NOTE: OV518(+) and OV519 does downsampling on its own */ | ||
1835 | win.width = width; | ||
1836 | win.height = height; | ||
1837 | if (width == sd->maxwidth) | ||
1838 | win.quarter = 0; | ||
1839 | else | ||
1840 | win.quarter = 1; | ||
1841 | |||
1842 | /* Center it */ | ||
1843 | win.x = (win.width - width) / 2; | ||
1844 | win.y = (win.height - height) / 2; | ||
1845 | |||
1846 | /* Clock is determined by OV519 frame rate code */ | ||
1847 | win.clockdiv = sd->clockdiv; | ||
1848 | |||
1849 | PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); | ||
1850 | return set_ov_sensor_window(sd, &win); | ||
1851 | } | ||
1852 | |||
1853 | /* -- start the camera -- */ | 1801 | /* -- start the camera -- */ |
1854 | static void sd_start(struct gspca_dev *gspca_dev) | 1802 | static void sd_start(struct gspca_dev *gspca_dev) |
1855 | { | 1803 | { |
1856 | struct sd *sd = (struct sd *) gspca_dev; | 1804 | struct sd *sd = (struct sd *) gspca_dev; |
1857 | int ret; | 1805 | int ret; |
1858 | 1806 | ||
1859 | 1807 | ret = ov519_mode_init_regs(sd); | |
1860 | ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); | ||
1861 | if (ret < 0) | 1808 | if (ret < 0) |
1862 | goto out; | 1809 | goto out; |
1863 | ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); | 1810 | ret = set_ov_sensor_window(sd); |
1864 | if (ret < 0) | 1811 | if (ret < 0) |
1865 | goto out; | 1812 | goto out; |
1866 | 1813 | ||
1867 | ret = ov51x_restart((struct sd *) gspca_dev); | 1814 | ret = ov51x_restart(sd); |
1868 | if (ret < 0) | 1815 | if (ret < 0) |
1869 | goto out; | 1816 | goto out; |
1870 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | 1817 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); |
@@ -1938,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1938 | { | 1885 | { |
1939 | struct sd *sd = (struct sd *) gspca_dev; | 1886 | struct sd *sd = (struct sd *) gspca_dev; |
1940 | int val; | 1887 | int val; |
1941 | /* int was_streaming; */ | ||
1942 | 1888 | ||
1943 | val = sd->brightness; | 1889 | val = sd->brightness; |
1944 | PDEBUG(D_CONF, "brightness:%d", val); | 1890 | PDEBUG(D_CONF, "brightness:%d", val); |
1945 | /* was_streaming = gspca_dev->streaming; | 1891 | /* if (gspca_dev->streaming) |
1946 | * if (was_streaming) | ||
1947 | * ov51x_stop(sd); */ | 1892 | * ov51x_stop(sd); */ |
1948 | switch (sd->sensor) { | 1893 | switch (sd->sensor) { |
1949 | case SEN_OV8610: | 1894 | case SEN_OV8610: |
@@ -1961,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1961 | i2c_w(sd, OV7610_REG_BRT, val); | 1906 | i2c_w(sd, OV7610_REG_BRT, val); |
1962 | break; | 1907 | break; |
1963 | case SEN_OV7670: | 1908 | case SEN_OV7670: |
1964 | /*jfm - from windblows | 1909 | /*win trace |
1965 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | 1910 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ |
1966 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | 1911 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); |
1967 | break; | 1912 | break; |
1968 | } | 1913 | } |
1969 | /* if (was_streaming) | 1914 | /* if (gspca_dev->streaming) |
1970 | * ov51x_restart(sd); */ | 1915 | * ov51x_restart(sd); */ |
1971 | } | 1916 | } |
1972 | 1917 | ||
@@ -1974,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
1974 | { | 1919 | { |
1975 | struct sd *sd = (struct sd *) gspca_dev; | 1920 | struct sd *sd = (struct sd *) gspca_dev; |
1976 | int val; | 1921 | int val; |
1977 | /* int was_streaming; */ | ||
1978 | 1922 | ||
1979 | val = sd->contrast; | 1923 | val = sd->contrast; |
1980 | PDEBUG(D_CONF, "contrast:%d", val); | 1924 | PDEBUG(D_CONF, "contrast:%d", val); |
1981 | /* was_streaming = gspca_dev->streaming; | 1925 | /* if (gspca_dev->streaming) |
1982 | if (was_streaming) | ||
1983 | ov51x_stop(sd); */ | 1926 | ov51x_stop(sd); */ |
1984 | switch (sd->sensor) { | 1927 | switch (sd->sensor) { |
1985 | case SEN_OV7610: | 1928 | case SEN_OV7610: |
@@ -2016,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
2016 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | 1959 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); |
2017 | break; | 1960 | break; |
2018 | } | 1961 | } |
2019 | /* if (was_streaming) | 1962 | /* if (gspca_dev->streaming) |
2020 | ov51x_restart(sd); */ | 1963 | ov51x_restart(sd); */ |
2021 | } | 1964 | } |
2022 | 1965 | ||
@@ -2024,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
2024 | { | 1967 | { |
2025 | struct sd *sd = (struct sd *) gspca_dev; | 1968 | struct sd *sd = (struct sd *) gspca_dev; |
2026 | int val; | 1969 | int val; |
2027 | /* int was_streaming; */ | ||
2028 | 1970 | ||
2029 | val = sd->colors; | 1971 | val = sd->colors; |
2030 | PDEBUG(D_CONF, "saturation:%d", val); | 1972 | PDEBUG(D_CONF, "saturation:%d", val); |
2031 | /* was_streaming = gspca_dev->streaming; | 1973 | /* if (gspca_dev->streaming) |
2032 | if (was_streaming) | ||
2033 | ov51x_stop(sd); */ | 1974 | ov51x_stop(sd); */ |
2034 | switch (sd->sensor) { | 1975 | switch (sd->sensor) { |
2035 | case SEN_OV8610: | 1976 | case SEN_OV8610: |
@@ -2055,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
2055 | /* set REG_COM13 values for UV sat auto mode */ | 1996 | /* set REG_COM13 values for UV sat auto mode */ |
2056 | break; | 1997 | break; |
2057 | } | 1998 | } |
2058 | /* if (was_streaming) | 1999 | /* if (gspca_dev->streaming) |
2059 | ov51x_restart(sd); */ | 2000 | ov51x_restart(sd); */ |
2060 | } | 2001 | } |
2061 | 2002 | ||
@@ -2110,6 +2051,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | |||
2110 | return 0; | 2051 | return 0; |
2111 | } | 2052 | } |
2112 | 2053 | ||
2054 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2055 | { | ||
2056 | struct sd *sd = (struct sd *) gspca_dev; | ||
2057 | |||
2058 | sd->hflip = val; | ||
2059 | sethvflip(sd); | ||
2060 | return 0; | ||
2061 | } | ||
2062 | |||
2063 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2064 | { | ||
2065 | struct sd *sd = (struct sd *) gspca_dev; | ||
2066 | |||
2067 | *val = sd->hflip; | ||
2068 | return 0; | ||
2069 | } | ||
2070 | |||
2071 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2072 | { | ||
2073 | struct sd *sd = (struct sd *) gspca_dev; | ||
2074 | |||
2075 | sd->vflip = val; | ||
2076 | sethvflip(sd); | ||
2077 | return 0; | ||
2078 | } | ||
2079 | |||
2080 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2081 | { | ||
2082 | struct sd *sd = (struct sd *) gspca_dev; | ||
2083 | |||
2084 | *val = sd->vflip; | ||
2085 | return 0; | ||
2086 | } | ||
2087 | |||
2113 | /* sub-driver description */ | 2088 | /* sub-driver description */ |
2114 | static const struct sd_desc sd_desc = { | 2089 | static const struct sd_desc sd_desc = { |
2115 | .name = MODULE_NAME, | 2090 | .name = MODULE_NAME, |
@@ -2178,4 +2153,3 @@ module_exit(sd_mod_exit); | |||
2178 | 2153 | ||
2179 | module_param(frame_rate, int, 0644); | 2154 | module_param(frame_rate, int, 0644); |
2180 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); | 2155 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); |
2181 | |||
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index ea3d7021f401..815bea6edc44 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -31,7 +31,9 @@ MODULE_LICENSE("GPL"); | |||
31 | struct sd { | 31 | struct sd { |
32 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 32 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
33 | 33 | ||
34 | int avg_lum; | 34 | int lum_sum; |
35 | atomic_t avg_lum; | ||
36 | atomic_t do_gain; | ||
35 | 37 | ||
36 | unsigned char brightness; | 38 | unsigned char brightness; |
37 | unsigned char contrast; | 39 | unsigned char contrast; |
@@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
271 | sd->contrast = CONTRAST_DEF; | 273 | sd->contrast = CONTRAST_DEF; |
272 | sd->colors = COLOR_DEF; | 274 | sd->colors = COLOR_DEF; |
273 | sd->autogain = AUTOGAIN_DEF; | 275 | sd->autogain = AUTOGAIN_DEF; |
276 | sd->ag_cnt = -1; | ||
274 | return 0; | 277 | return 0; |
275 | } | 278 | } |
276 | 279 | ||
@@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
311 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); | 314 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); |
312 | } | 315 | } |
313 | 316 | ||
317 | static void setautogain(struct gspca_dev *gspca_dev) | ||
318 | { | ||
319 | struct sd *sd = (struct sd *) gspca_dev; | ||
320 | |||
321 | if (sd->autogain) { | ||
322 | sd->lum_sum = 0; | ||
323 | sd->ag_cnt = AG_CNT_START; | ||
324 | } else { | ||
325 | sd->ag_cnt = -1; | ||
326 | } | ||
327 | } | ||
328 | |||
314 | /* this function is called at open time */ | 329 | /* this function is called at open time */ |
315 | static int sd_open(struct gspca_dev *gspca_dev) | 330 | static int sd_open(struct gspca_dev *gspca_dev) |
316 | { | 331 | { |
@@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
320 | 335 | ||
321 | static void sd_start(struct gspca_dev *gspca_dev) | 336 | static void sd_start(struct gspca_dev *gspca_dev) |
322 | { | 337 | { |
323 | struct sd *sd = (struct sd *) gspca_dev; | ||
324 | |||
325 | reg_w(gspca_dev, 0xff, 0x01); | 338 | reg_w(gspca_dev, 0xff, 0x01); |
326 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); | 339 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); |
327 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); | 340 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); |
@@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
394 | setcontrast(gspca_dev); | 407 | setcontrast(gspca_dev); |
395 | setbrightness(gspca_dev); | 408 | setbrightness(gspca_dev); |
396 | setcolors(gspca_dev); | 409 | setcolors(gspca_dev); |
410 | setautogain(gspca_dev); | ||
397 | 411 | ||
398 | /* set correct resolution */ | 412 | /* set correct resolution */ |
399 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | 413 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { |
@@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
431 | reg_w(gspca_dev, 0xff, 0x01); | 445 | reg_w(gspca_dev, 0xff, 0x01); |
432 | reg_w(gspca_dev, 0x78, 0x04); | 446 | reg_w(gspca_dev, 0x78, 0x04); |
433 | reg_w(gspca_dev, 0x78, 0x05); | 447 | reg_w(gspca_dev, 0x78, 0x05); |
434 | |||
435 | if (sd->autogain) { | ||
436 | sd->ag_cnt = AG_CNT_START; | ||
437 | sd->avg_lum = 0; | ||
438 | } else { | ||
439 | sd->ag_cnt = -1; | ||
440 | } | ||
441 | } | 448 | } |
442 | 449 | ||
443 | static void sd_stopN(struct gspca_dev *gspca_dev) | 450 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
473 | 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 */ |
474 | } | 481 | } |
475 | 482 | ||
476 | static void setautogain(struct gspca_dev *gspca_dev, int luma) | 483 | static void do_autogain(struct gspca_dev *gspca_dev) |
477 | { | 484 | { |
485 | struct sd *sd = (struct sd *) gspca_dev; | ||
486 | int luma; | ||
478 | int luma_mean = 128; | 487 | int luma_mean = 128; |
479 | int luma_delta = 20; | 488 | int luma_delta = 20; |
480 | __u8 spring = 5; | 489 | __u8 spring = 5; |
481 | int Gbright; | 490 | int Gbright; |
482 | 491 | ||
492 | if (!atomic_read(&sd->do_gain)) | ||
493 | return; | ||
494 | atomic_set(&sd->do_gain, 0); | ||
495 | |||
496 | luma = atomic_read(&sd->avg_lum); | ||
483 | Gbright = reg_r(gspca_dev, 0x02); | 497 | Gbright = reg_r(gspca_dev, 0x02); |
484 | PDEBUG(D_FRAM, "luma mean %d", luma); | 498 | PDEBUG(D_FRAM, "luma mean %d", luma); |
485 | if (luma < luma_mean - luma_delta || | 499 | if (luma < luma_mean - luma_delta || |
@@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
523 | 537 | ||
524 | /* start of frame */ | 538 | /* start of frame */ |
525 | if (sd->ag_cnt >= 0 && p > 28) { | 539 | if (sd->ag_cnt >= 0 && p > 28) { |
526 | sd->avg_lum += data[p - 23]; | 540 | sd->lum_sum += data[p - 23]; |
527 | if (--sd->ag_cnt < 0) { | 541 | if (--sd->ag_cnt < 0) { |
528 | sd->ag_cnt = AG_CNT_START; | 542 | sd->ag_cnt = AG_CNT_START; |
529 | setautogain(gspca_dev, | 543 | atomic_set(&sd->avg_lum, |
530 | sd->avg_lum / AG_CNT_START); | 544 | sd->lum_sum / AG_CNT_START); |
531 | sd->avg_lum = 0; | 545 | sd->lum_sum = 0; |
546 | atomic_set(&sd->do_gain, 1); | ||
532 | } | 547 | } |
533 | } | 548 | } |
534 | 549 | ||
@@ -677,12 +692,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
677 | struct sd *sd = (struct sd *) gspca_dev; | 692 | struct sd *sd = (struct sd *) gspca_dev; |
678 | 693 | ||
679 | sd->autogain = val; | 694 | sd->autogain = val; |
680 | if (val) { | 695 | if (gspca_dev->streaming) |
681 | sd->ag_cnt = AG_CNT_START; | 696 | setautogain(gspca_dev); |
682 | sd->avg_lum = 0; | ||
683 | } else { | ||
684 | sd->ag_cnt = -1; | ||
685 | } | ||
686 | return 0; | 697 | return 0; |
687 | } | 698 | } |
688 | 699 | ||
@@ -706,6 +717,7 @@ static struct sd_desc sd_desc = { | |||
706 | .stop0 = sd_stop0, | 717 | .stop0 = sd_stop0, |
707 | .close = sd_close, | 718 | .close = sd_close, |
708 | .pkt_scan = sd_pkt_scan, | 719 | .pkt_scan = sd_pkt_scan, |
720 | .dq_callback = do_autogain, | ||
709 | }; | 721 | }; |
710 | 722 | ||
711 | /* -- module initialisation -- */ | 723 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index e18748c5a14d..11210c71f66c 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -408,7 +408,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
408 | const __u8 *buffer, | 408 | const __u8 *buffer, |
409 | int len) | 409 | int len) |
410 | { | 410 | { |
411 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 411 | #ifdef GSPCA_DEBUG |
412 | if (len > sizeof gspca_dev->usb_buf) { | 412 | if (len > sizeof gspca_dev->usb_buf) { |
413 | PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); | 413 | PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); |
414 | return; | 414 | return; |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 33a3df1f6915..245a30ec5fb1 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -32,7 +32,7 @@ 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 | int avg_lum; | 35 | atomic_t avg_lum; |
36 | unsigned int exposure; | 36 | unsigned int exposure; |
37 | 37 | ||
38 | unsigned short brightness; | 38 | unsigned short brightness; |
@@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = { | |||
148 | 148 | ||
149 | /*Data from sn9c102p+hv71331r */ | 149 | /*Data from sn9c102p+hv71331r */ |
150 | static const __u8 sn_hv7131[] = { | 150 | static const __u8 sn_hv7131[] = { |
151 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | 151 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
152 | 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, | 152 | 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, |
153 | /* rega regb regc regd rege regf reg10 reg11 */ | 153 | /* reg8 reg9 rega regb regc regd rege regf */ |
154 | 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ | 154 | 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, |
155 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | 155 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
156 | 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, | 156 | 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, |
157 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | 157 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 158 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static const __u8 sn_mi0360[] = { | 161 | static const __u8 sn_mi0360[] = { |
162 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | 162 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
163 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, | 163 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, |
164 | /* rega regb regc regd rege regf reg10 reg11 */ | 164 | /* reg8 reg9 rega regb regc regd rege regf */ |
165 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, | 165 | 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, |
166 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | 166 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
167 | 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, | 167 | 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, |
168 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | 168 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 169 | 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static const __u8 sn_mo4000[] = { | 172 | static const __u8 sn_mo4000[] = { |
173 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | 173 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
174 | 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, | 174 | 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, |
175 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | 175 | /* reg8 reg9 rega regb regc regd rege regf */ |
176 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | 176 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
177 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | 177 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
178 | 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, | 178 | 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, |
179 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | 179 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, | 180 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
181 | 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, | ||
182 | 0xd3, 0xdf, 0xea, 0xf5 | ||
183 | }; | 181 | }; |
184 | 182 | ||
185 | static const __u8 sn_ov7648[] = { | 183 | static const __u8 sn_ov7648[] = { |
186 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, | 184 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
187 | 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, | 185 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, |
188 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | 186 | /* reg8 reg9 rega regb regc regd rege regf */ |
187 | 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, | ||
188 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
189 | 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, | ||
190 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ | ||
191 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
189 | }; | 192 | }; |
190 | 193 | ||
191 | static const __u8 sn_ov7660[] = { | 194 | static const __u8 sn_ov7660[] = { |
192 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | 195 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
193 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, | 196 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, |
194 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | 197 | /* reg8 reg9 rega regb regc regd rege regf */ |
195 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | 198 | 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, |
196 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | 199 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
197 | 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, | 200 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, |
198 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | 201 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 202 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
200 | }; | 203 | }; |
201 | 204 | ||
202 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ | 205 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ |
@@ -212,10 +215,6 @@ static const __u8 regsn20[] = { | |||
212 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, | 215 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, |
213 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff | 216 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff |
214 | }; | 217 | }; |
215 | static const __u8 regsn20_sn9c120[] = { | ||
216 | 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90, | ||
217 | 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff | ||
218 | }; | ||
219 | static const __u8 regsn20_sn9c325[] = { | 218 | static const __u8 regsn20_sn9c325[] = { |
220 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, | 219 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, |
221 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 | 220 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 |
@@ -227,21 +226,6 @@ static const __u8 reg84[] = { | |||
227 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ | 226 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ |
228 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 | 227 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 |
229 | }; | 228 | }; |
230 | static const __u8 reg84_sn9c120_1[] = { | ||
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
233 | 0x00, 0x00, 0x0c, 0x00, 0x00 | ||
234 | }; | ||
235 | static const __u8 reg84_sn9c120_2[] = { | ||
236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
238 | 0x00, 0x00, 0x0c, 0x02, 0x3b | ||
239 | }; | ||
240 | static const __u8 reg84_sn9c120_3[] = { | ||
241 | 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f, | ||
242 | 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f, | ||
243 | 0xf5, 0x0f, 0x0c, 0x02, 0x3b | ||
244 | }; | ||
245 | static const __u8 reg84_sn9c325[] = { | 229 | static const __u8 reg84_sn9c325[] = { |
246 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, | 230 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, |
247 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, | 231 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, |
@@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
360 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | 344 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ |
361 | /* (delay 20ms) */ | 345 | /* (delay 20ms) */ |
362 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, | 346 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, |
363 | /* Outformat ?? rawRGB */ | 347 | /* Outformat = rawRGB */ |
364 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ | 348 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ |
365 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, | 349 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, |
366 | /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */ | ||
367 | /* GAIN BLUE RED VREF */ | 350 | /* GAIN BLUE RED VREF */ |
368 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, | 351 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, |
369 | /* COM 1 BAVE GEAVE AECHH */ | 352 | /* COM 1 BAVE GEAVE AECHH */ |
370 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ | 353 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ |
371 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ | 354 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ |
372 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, | 355 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, |
373 | /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */ | ||
374 | /* AECH CLKRC COM7 COM8 */ | 356 | /* AECH CLKRC COM7 COM8 */ |
375 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ | 357 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ |
376 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, | 358 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, |
@@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
379 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ | 361 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ |
380 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, | 362 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, |
381 | /* BOS GBOS GROS ROS (BGGR offset) */ | 363 | /* BOS GBOS GROS ROS (BGGR offset) */ |
382 | {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, | 364 | /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */ |
383 | /* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ | 365 | {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, |
384 | /* AEW AEB VPT BBIAS */ | 366 | /* AEW AEB VPT BBIAS */ |
385 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, | 367 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, |
386 | /* GbBIAS RSVD EXHCH EXHCL */ | 368 | /* GbBIAS RSVD EXHCH EXHCL */ |
@@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
407 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, | 389 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, |
408 | /* LCC1 LCC2 LCC3 LCC4 */ | 390 | /* LCC1 LCC2 LCC3 LCC4 */ |
409 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ | 391 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ |
410 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, | 392 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */ |
411 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 393 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, |
412 | /* band gap reference [0..3] DBLV */ | 394 | /* band gap reference [0:3] DBLV */ |
413 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ | 395 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ |
414 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ | 396 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ |
415 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ | 397 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ |
@@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
419 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ | 401 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ |
420 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | 402 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ |
421 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | 403 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ |
422 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, | 404 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ |
423 | /****** (some exchanges in the win trace) ******/ | 405 | /****** (some exchanges in the win trace) ******/ |
424 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | 406 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ |
425 | /* bits[3..0]reserved */ | 407 | /* bits[3..0]reserved */ |
426 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | 408 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, |
427 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | 409 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, |
428 | /* VREF vertical frame ctrl */ | 410 | /* VREF vertical frame ctrl */ |
429 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | 411 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, |
430 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ | 412 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */ |
431 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | 413 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */ |
432 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, | 414 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */ |
433 | /* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ | 415 | {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ |
434 | {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 416 | /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ |
435 | {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, | ||
436 | /****** (some exchanges in the win trace) ******/ | 417 | /****** (some exchanges in the win trace) ******/ |
437 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ | 418 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ |
438 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ | 419 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ |
439 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | 420 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ |
440 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, | 421 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */ |
441 | {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, | 422 | /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ |
442 | /****** (some exchanges in the win trace) ******/ | 423 | /****** (some exchanges in the win trace) ******/ |
443 | /**********startsensor KO if changed !!****/ | 424 | /******!! startsensor KO if changed !!****/ |
444 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, | 425 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, |
445 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, | 426 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, |
446 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | 427 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, |
447 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, | 428 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, |
448 | /* here may start the isoc exchanges */ | ||
449 | {} | 429 | {} |
450 | }; | 430 | }; |
451 | /* reg0x04 reg0x07 reg 0x10 */ | 431 | /* reg 0x04 reg 0x07 reg 0x10 */ |
452 | /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ | 432 | /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */ |
453 | 433 | ||
454 | static const __u8 ov7648_sensor_init[][8] = { | 434 | static const __u8 ov7648_sensor_init[][8] = { |
455 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | 435 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, |
@@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
680 | const __u8 *reg9a; | 660 | const __u8 *reg9a; |
681 | static const __u8 reg9a_def[] = | 661 | static const __u8 reg9a_def[] = |
682 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | 662 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; |
683 | static const __u8 reg9a_sn9c120[] = /* from win trace */ | ||
684 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
685 | static const __u8 reg9a_sn9c325[] = | 663 | static const __u8 reg9a_sn9c325[] = |
686 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | 664 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; |
665 | static const __u8 regd4[] = {0x60, 0x00, 0x00}; | ||
687 | 666 | ||
688 | reg_w1(gspca_dev, 0xf1, 0x00); | 667 | reg_w1(gspca_dev, 0xf1, 0x00); |
689 | reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ | 668 | reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ |
690 | 669 | ||
691 | /* configure gpio */ | 670 | /* configure gpio */ |
692 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | 671 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); |
@@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
696 | case BRIDGE_SN9C325: | 675 | case BRIDGE_SN9C325: |
697 | reg9a = reg9a_sn9c325; | 676 | reg9a = reg9a_sn9c325; |
698 | break; | 677 | break; |
699 | case BRIDGE_SN9C120: | ||
700 | reg9a = reg9a_sn9c120; | ||
701 | break; | ||
702 | default: | 678 | default: |
703 | reg9a = reg9a_def; | 679 | reg9a = reg9a_def; |
704 | break; | 680 | break; |
705 | } | 681 | } |
706 | reg_w(gspca_dev, 0x9a, reg9a, 6); | 682 | reg_w(gspca_dev, 0x9a, reg9a, 6); |
707 | 683 | ||
708 | reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ | 684 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ |
709 | 685 | ||
710 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | 686 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); |
711 | 687 | ||
712 | switch (sd->bridge) { | 688 | switch (sd->bridge) { |
713 | case BRIDGE_SN9C120: /* from win trace */ | ||
714 | reg_w1(gspca_dev, 0x01, 0x61); | ||
715 | reg_w1(gspca_dev, 0x17, 0x20); | ||
716 | reg_w1(gspca_dev, 0x01, 0x60); | ||
717 | break; | ||
718 | case BRIDGE_SN9C325: | 689 | case BRIDGE_SN9C325: |
719 | reg_w1(gspca_dev, 0x01, 0x43); | 690 | reg_w1(gspca_dev, 0x01, 0x43); |
720 | reg_w1(gspca_dev, 0x17, 0xae); | 691 | reg_w1(gspca_dev, 0x17, 0xae); |
@@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
810 | sd->contrast = CONTRAST_DEF; | 781 | sd->contrast = CONTRAST_DEF; |
811 | sd->colors = COLOR_DEF; | 782 | sd->colors = COLOR_DEF; |
812 | sd->autogain = AUTOGAIN_DEF; | 783 | sd->autogain = AUTOGAIN_DEF; |
784 | sd->ag_cnt = -1; | ||
785 | |||
813 | return 0; | 786 | return 0; |
814 | } | 787 | } |
815 | 788 | ||
@@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
823 | 796 | ||
824 | /* setup a selector by bridge */ | 797 | /* setup a selector by bridge */ |
825 | reg_w1(gspca_dev, 0xf1, 0x01); | 798 | reg_w1(gspca_dev, 0xf1, 0x01); |
826 | reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ | ||
827 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | ||
828 | reg_r(gspca_dev, 0x00, 1); | 799 | reg_r(gspca_dev, 0x00, 1); |
800 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | ||
801 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ | ||
829 | regF1 = gspca_dev->usb_buf[0]; | 802 | regF1 = gspca_dev->usb_buf[0]; |
803 | PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); | ||
830 | switch (sd->bridge) { | 804 | switch (sd->bridge) { |
831 | case BRIDGE_SN9C102P: | 805 | case BRIDGE_SN9C102P: |
832 | if (regF1 != 0x11) | 806 | if (regF1 != 0x11) |
@@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
937 | sd->exposure = setexposure(gspca_dev, expo); | 911 | sd->exposure = setexposure(gspca_dev, expo); |
938 | break; | 912 | break; |
939 | case SENSOR_MI0360: | 913 | case SENSOR_MI0360: |
940 | expo = sd->brightness >> 4; | ||
941 | sd->exposure = setexposure(gspca_dev, expo); | ||
942 | break; | ||
943 | case SENSOR_MO4000: | 914 | case SENSOR_MO4000: |
944 | expo = sd->brightness >> 4; | 915 | expo = sd->brightness >> 4; |
945 | sd->exposure = setexposure(gspca_dev, expo); | 916 | sd->exposure = setexposure(gspca_dev, expo); |
946 | break; | 917 | break; |
947 | case SENSOR_OV7660: | ||
948 | return; /*jfm??*/ | ||
949 | } | 918 | } |
950 | 919 | ||
951 | k2 = sd->brightness >> 10; | 920 | k2 = sd->brightness >> 10; |
@@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
958 | __u8 k2; | 927 | __u8 k2; |
959 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; | 928 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; |
960 | 929 | ||
961 | if (sd->sensor == SENSOR_OV7660) | ||
962 | return; /*jfm??*/ | ||
963 | k2 = sd->contrast; | 930 | k2 = sd->contrast; |
964 | contrast[2] = k2; | 931 | contrast[2] = k2; |
965 | contrast[0] = (k2 + 1) >> 1; | 932 | contrast[0] = (k2 + 1) >> 1; |
@@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
981 | reg_w1(gspca_dev, 0x05, data); | 948 | reg_w1(gspca_dev, 0x05, data); |
982 | } | 949 | } |
983 | 950 | ||
951 | static void setautogain(struct gspca_dev *gspca_dev) | ||
952 | { | ||
953 | struct sd *sd = (struct sd *) gspca_dev; | ||
954 | |||
955 | switch (sd->sensor) { | ||
956 | case SENSOR_HV7131R: | ||
957 | case SENSOR_MO4000: | ||
958 | case SENSOR_MI0360: | ||
959 | if (sd->autogain) | ||
960 | sd->ag_cnt = AG_CNT_START; | ||
961 | else | ||
962 | sd->ag_cnt = -1; | ||
963 | break; | ||
964 | } | ||
965 | } | ||
966 | |||
984 | /* -- start the camera -- */ | 967 | /* -- start the camera -- */ |
985 | static void sd_start(struct gspca_dev *gspca_dev) | 968 | static void sd_start(struct gspca_dev *gspca_dev) |
986 | { | 969 | { |
987 | struct sd *sd = (struct sd *) gspca_dev; | 970 | struct sd *sd = (struct sd *) gspca_dev; |
988 | int i; | 971 | int i; |
989 | __u8 data; | 972 | __u8 reg1, reg17, reg18; |
990 | __u8 reg1; | ||
991 | __u8 reg17; | ||
992 | const __u8 *sn9c1xx; | 973 | const __u8 *sn9c1xx; |
993 | int mode; | 974 | int mode; |
994 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | 975 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; |
995 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | 976 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; |
996 | static const __u8 CA_sn9c120[] = | ||
997 | { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ | ||
998 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ | 977 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ |
999 | static const __u8 CE_sn9c325[] = | 978 | static const __u8 CE_sn9c325[] = |
1000 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ | 979 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ |
@@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1002 | sn9c1xx = sn_tb[(int) sd->sensor]; | 981 | sn9c1xx = sn_tb[(int) sd->sensor]; |
1003 | configure_gpio(gspca_dev, sn9c1xx); | 982 | configure_gpio(gspca_dev, sn9c1xx); |
1004 | 983 | ||
1005 | /*fixme:jfm this sequence should appear at end of sd_start */ | 984 | /* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/ |
1006 | /* with | ||
1007 | reg_w1(gspca_dev, 0x01, 0x44); */ | ||
1008 | reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); | 985 | reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); |
1009 | reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); | 986 | reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); |
1010 | reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); | 987 | reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); |
@@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1016 | reg_w1(gspca_dev, 0xc7, 0x00); | 993 | reg_w1(gspca_dev, 0xc7, 0x00); |
1017 | reg_w1(gspca_dev, 0xc8, 0x50); | 994 | reg_w1(gspca_dev, 0xc8, 0x50); |
1018 | reg_w1(gspca_dev, 0xc9, 0x3c); | 995 | reg_w1(gspca_dev, 0xc9, 0x3c); |
1019 | /*fixme:jfm end of ending sequence */ | ||
1020 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 996 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
1021 | switch (sd->bridge) { | 997 | switch (sd->bridge) { |
1022 | case BRIDGE_SN9C325: | 998 | case BRIDGE_SN9C325: |
1023 | data = 0xae; | 999 | reg17 = 0xae; |
1024 | break; | ||
1025 | case BRIDGE_SN9C120: | ||
1026 | data = 0xa0; | ||
1027 | break; | 1000 | break; |
1028 | default: | 1001 | default: |
1029 | data = 0x60; | 1002 | reg17 = 0x60; |
1030 | break; | 1003 | break; |
1031 | } | 1004 | } |
1032 | reg_w1(gspca_dev, 0x17, data); | 1005 | reg_w1(gspca_dev, 0x17, reg17); |
1033 | reg_w1(gspca_dev, 0x05, sn9c1xx[5]); | 1006 | reg_w1(gspca_dev, 0x05, sn9c1xx[5]); |
1034 | reg_w1(gspca_dev, 0x07, sn9c1xx[7]); | 1007 | reg_w1(gspca_dev, 0x07, sn9c1xx[7]); |
1035 | reg_w1(gspca_dev, 0x06, sn9c1xx[6]); | 1008 | reg_w1(gspca_dev, 0x06, sn9c1xx[6]); |
@@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1044 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1017 | reg_w1(gspca_dev, 0x9a, 0x0a); |
1045 | reg_w1(gspca_dev, 0x99, 0x60); | 1018 | reg_w1(gspca_dev, 0x99, 0x60); |
1046 | break; | 1019 | break; |
1047 | case BRIDGE_SN9C120: | ||
1048 | reg_w(gspca_dev, 0x20, regsn20_sn9c120, | ||
1049 | sizeof regsn20_sn9c120); | ||
1050 | for (i = 0; i < 2; i++) | ||
1051 | reg_w(gspca_dev, 0x84, reg84_sn9c120_1, | ||
1052 | sizeof reg84_sn9c120_1); | ||
1053 | for (i = 0; i < 6; i++) | ||
1054 | reg_w(gspca_dev, 0x84, reg84_sn9c120_2, | ||
1055 | sizeof reg84_sn9c120_2); | ||
1056 | reg_w(gspca_dev, 0x84, reg84_sn9c120_3, | ||
1057 | sizeof reg84_sn9c120_3); | ||
1058 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1059 | reg_w1(gspca_dev, 0x99, 0x5b); | ||
1060 | break; | ||
1061 | default: | 1020 | default: |
1062 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); | 1021 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); |
1063 | for (i = 0; i < 8; i++) | 1022 | for (i = 0; i < 8; i++) |
@@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1107 | /* reg1 = 0x44; */ | 1066 | /* reg1 = 0x44; */ |
1108 | /* reg1 = 0x46; (done) */ | 1067 | /* reg1 = 0x46; (done) */ |
1109 | } else { | 1068 | } else { |
1110 | reg17 = 0xa2; /* 640 */ | 1069 | reg17 = 0x22; /* 640 MCKSIZE */ |
1111 | reg1 = 0x40; | 1070 | reg1 = 0x06; |
1112 | } | 1071 | } |
1113 | break; | 1072 | break; |
1114 | } | 1073 | } |
1115 | reg_w(gspca_dev, 0xc0, C0, 6); | 1074 | reg_w(gspca_dev, 0xc0, C0, 6); |
1075 | reg_w(gspca_dev, 0xca, CA, 4); | ||
1116 | switch (sd->bridge) { | 1076 | switch (sd->bridge) { |
1117 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
1118 | reg_w(gspca_dev, 0xca, CA_sn9c120, 4); | ||
1119 | break; | ||
1120 | default: | ||
1121 | reg_w(gspca_dev, 0xca, CA, 4); | ||
1122 | break; | ||
1123 | } | ||
1124 | switch (sd->bridge) { | ||
1125 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
1126 | case BRIDGE_SN9C325: | 1077 | case BRIDGE_SN9C325: |
1127 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); | 1078 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); |
1128 | break; | 1079 | break; |
@@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1133 | } | 1084 | } |
1134 | 1085 | ||
1135 | /* here change size mode 0 -> VGA; 1 -> CIF */ | 1086 | /* here change size mode 0 -> VGA; 1 -> CIF */ |
1136 | data = 0x40 | sn9c1xx[0x18] | (mode << 4); | 1087 | reg18 = sn9c1xx[0x18] | (mode << 4); |
1137 | reg_w1(gspca_dev, 0x18, data); | 1088 | reg_w1(gspca_dev, 0x18, reg18 | 0x40); |
1138 | 1089 | ||
1139 | reg_w(gspca_dev, 0x100, qtable4, 0x40); | 1090 | reg_w(gspca_dev, 0x100, qtable4, 0x40); |
1140 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); | 1091 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); |
1141 | 1092 | ||
1142 | data = sn9c1xx[0x18] | (mode << 4); | 1093 | reg_w1(gspca_dev, 0x18, reg18); |
1143 | reg_w1(gspca_dev, 0x18, data); | ||
1144 | 1094 | ||
1145 | reg_w1(gspca_dev, 0x17, reg17); | 1095 | reg_w1(gspca_dev, 0x17, reg17); |
1146 | reg_w1(gspca_dev, 0x01, reg1); | 1096 | reg_w1(gspca_dev, 0x01, reg1); |
1147 | setbrightness(gspca_dev); | 1097 | setbrightness(gspca_dev); |
1148 | setcontrast(gspca_dev); | 1098 | setcontrast(gspca_dev); |
1099 | setautogain(gspca_dev); | ||
1149 | } | 1100 | } |
1150 | 1101 | ||
1151 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1102 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1168 | i2c_w8(gspca_dev, stopmi0360); | 1119 | i2c_w8(gspca_dev, stopmi0360); |
1169 | data = 0x29; | 1120 | data = 0x29; |
1170 | break; | 1121 | break; |
1171 | case SENSOR_MO4000: | ||
1172 | break; | ||
1173 | case SENSOR_OV7648: | 1122 | case SENSOR_OV7648: |
1174 | data = 0x29; | 1123 | data = 0x29; |
1175 | break; | 1124 | break; |
1176 | default: | 1125 | default: |
1126 | /* case SENSOR_MO4000: */ | ||
1177 | /* case SENSOR_OV7660: */ | 1127 | /* case SENSOR_OV7660: */ |
1178 | break; | 1128 | break; |
1179 | } | 1129 | } |
@@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
1193 | { | 1143 | { |
1194 | } | 1144 | } |
1195 | 1145 | ||
1196 | static void setautogain(struct gspca_dev *gspca_dev) | 1146 | static void do_autogain(struct gspca_dev *gspca_dev) |
1197 | { | 1147 | { |
1198 | struct sd *sd = (struct sd *) gspca_dev; | 1148 | struct sd *sd = (struct sd *) gspca_dev; |
1199 | /* Thanks S., without your advice, autobright should not work :) */ | ||
1200 | int delta; | 1149 | int delta; |
1201 | int expotimes = 0; | 1150 | int expotimes; |
1202 | __u8 luma_mean = 130; | 1151 | __u8 luma_mean = 130; |
1203 | __u8 luma_delta = 20; | 1152 | __u8 luma_delta = 20; |
1204 | 1153 | ||
1205 | delta = sd->avg_lum; | 1154 | /* Thanks S., without your advice, autobright should not work :) */ |
1155 | if (sd->ag_cnt < 0) | ||
1156 | return; | ||
1157 | if (--sd->ag_cnt >= 0) | ||
1158 | return; | ||
1159 | sd->ag_cnt = AG_CNT_START; | ||
1160 | |||
1161 | delta = atomic_read(&sd->avg_lum); | ||
1162 | PDEBUG(D_FRAM, "mean lum %d", delta); | ||
1206 | if (delta < luma_mean - luma_delta || | 1163 | if (delta < luma_mean - luma_delta || |
1207 | delta > luma_mean + luma_delta) { | 1164 | delta > luma_mean + luma_delta) { |
1208 | switch (sd->sensor) { | 1165 | switch (sd->sensor) { |
@@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1214 | sd->exposure = setexposure(gspca_dev, | 1171 | sd->exposure = setexposure(gspca_dev, |
1215 | (unsigned int) (expotimes << 8)); | 1172 | (unsigned int) (expotimes << 8)); |
1216 | break; | 1173 | break; |
1217 | case SENSOR_MO4000: | 1174 | default: |
1218 | case SENSOR_MI0360: | 1175 | /* case SENSOR_MO4000: */ |
1176 | /* case SENSOR_MI0360: */ | ||
1219 | expotimes = sd->exposure; | 1177 | expotimes = sd->exposure; |
1220 | expotimes += (luma_mean - delta) >> 6; | 1178 | expotimes += (luma_mean - delta) >> 6; |
1221 | if (expotimes < 0) | 1179 | if (expotimes < 0) |
@@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1228 | } | 1186 | } |
1229 | } | 1187 | } |
1230 | 1188 | ||
1189 | /* scan the URB packets */ | ||
1190 | /* This function is run at interrupt level. */ | ||
1231 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1191 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
1232 | struct gspca_frame *frame, /* target */ | 1192 | struct gspca_frame *frame, /* target */ |
1233 | __u8 *data, /* isoc packet */ | 1193 | __u8 *data, /* isoc packet */ |
@@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1244 | frame, data, sof + 2); | 1204 | frame, data, sof + 2); |
1245 | if (sd->ag_cnt < 0) | 1205 | if (sd->ag_cnt < 0) |
1246 | return; | 1206 | return; |
1247 | if (--sd->ag_cnt >= 0) | ||
1248 | return; | ||
1249 | sd->ag_cnt = AG_CNT_START; | ||
1250 | /* w1 w2 w3 */ | 1207 | /* w1 w2 w3 */ |
1251 | /* w4 w5 w6 */ | 1208 | /* w4 w5 w6 */ |
1252 | /* w7 w8 */ | 1209 | /* w7 w8 */ |
@@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1261 | /* w5 */ | 1218 | /* w5 */ |
1262 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | 1219 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; |
1263 | avg_lum >>= 4; | 1220 | avg_lum >>= 4; |
1264 | sd->avg_lum = avg_lum; | 1221 | atomic_set(&sd->avg_lum, avg_lum); |
1265 | PDEBUG(D_PACK, "mean lum %d", avg_lum); | ||
1266 | setautogain(gspca_dev); | ||
1267 | return; | 1222 | return; |
1268 | } | 1223 | } |
1269 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 1224 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
@@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) | |||
1300 | (hexpo << 10) | (mexpo << 2) | lexpo); | 1255 | (hexpo << 10) | (mexpo << 2) | lexpo); |
1301 | return (hexpo << 10) | (mexpo << 2) | lexpo; | 1256 | return (hexpo << 10) | (mexpo << 2) | lexpo; |
1302 | default: | 1257 | default: |
1258 | /* case SENSOR_OV7648: * jfm: is it ok for 7648? */ | ||
1303 | /* case SENSOR_OV7660: */ | 1259 | /* case SENSOR_OV7660: */ |
1304 | /* read sensor exposure */ | 1260 | /* read sensor exposure */ |
1305 | i2c_r5(gspca_dev, 0x04); | 1261 | i2c_r5(gspca_dev, 0x04); |
@@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev) | |||
1318 | /* hardcoded registers seem not readable */ | 1274 | /* hardcoded registers seem not readable */ |
1319 | switch (sd->sensor) { | 1275 | switch (sd->sensor) { |
1320 | case SENSOR_HV7131R: | 1276 | case SENSOR_HV7131R: |
1321 | /* sd->brightness = 0x7fff; */ | ||
1322 | sd->brightness = getexposure(gspca_dev) >> 4; | 1277 | sd->brightness = getexposure(gspca_dev) >> 4; |
1323 | break; | 1278 | break; |
1324 | case SENSOR_MI0360: | 1279 | case SENSOR_MI0360: |
1325 | sd->brightness = getexposure(gspca_dev) << 4; | 1280 | sd->brightness = getexposure(gspca_dev) << 4; |
1326 | break; | 1281 | break; |
1327 | case SENSOR_MO4000: | 1282 | case SENSOR_MO4000: |
1328 | /* sd->brightness = 0x1fff; */ | ||
1329 | sd->brightness = getexposure(gspca_dev) << 4; | 1283 | sd->brightness = getexposure(gspca_dev) << 4; |
1330 | break; | 1284 | break; |
1331 | } | 1285 | } |
@@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
1391 | struct sd *sd = (struct sd *) gspca_dev; | 1345 | struct sd *sd = (struct sd *) gspca_dev; |
1392 | 1346 | ||
1393 | sd->autogain = val; | 1347 | sd->autogain = val; |
1394 | if (val) | 1348 | if (gspca_dev->streaming) |
1395 | sd->ag_cnt = AG_CNT_START; | 1349 | setautogain(gspca_dev); |
1396 | else | ||
1397 | sd->ag_cnt = -1; | ||
1398 | return 0; | 1350 | return 0; |
1399 | } | 1351 | } |
1400 | 1352 | ||
@@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = { | |||
1418 | .stop0 = sd_stop0, | 1370 | .stop0 = sd_stop0, |
1419 | .close = sd_close, | 1371 | .close = sd_close, |
1420 | .pkt_scan = sd_pkt_scan, | 1372 | .pkt_scan = sd_pkt_scan, |
1373 | .dq_callback = do_autogain, | ||
1421 | }; | 1374 | }; |
1422 | 1375 | ||
1423 | /* -- module initialisation -- */ | 1376 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 3c2be80cbd65..eda29d609359 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -61,27 +61,27 @@ static struct ctrl sd_ctrls[] = { | |||
61 | 61 | ||
62 | static struct v4l2_pix_format vga_mode[] = { | 62 | static struct v4l2_pix_format vga_mode[] = { |
63 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 63 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
64 | .bytesperline = 160 * 3, | 64 | .bytesperline = 160, |
65 | .sizeimage = 160 * 120 * 3 / 2, | 65 | .sizeimage = 160 * 120 * 3 / 2, |
66 | .colorspace = V4L2_COLORSPACE_SRGB, | 66 | .colorspace = V4L2_COLORSPACE_SRGB, |
67 | .priv = 5}, | 67 | .priv = 5}, |
68 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 68 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
69 | .bytesperline = 176 * 3, | 69 | .bytesperline = 176, |
70 | .sizeimage = 176 * 144 * 3 / 2, | 70 | .sizeimage = 176 * 144 * 3 / 2, |
71 | .colorspace = V4L2_COLORSPACE_SRGB, | 71 | .colorspace = V4L2_COLORSPACE_SRGB, |
72 | .priv = 4}, | 72 | .priv = 4}, |
73 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 73 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
74 | .bytesperline = 320 * 3, | 74 | .bytesperline = 320, |
75 | .sizeimage = 320 * 240 * 3 / 2, | 75 | .sizeimage = 320 * 240 * 3 / 2, |
76 | .colorspace = V4L2_COLORSPACE_SRGB, | 76 | .colorspace = V4L2_COLORSPACE_SRGB, |
77 | .priv = 2}, | 77 | .priv = 2}, |
78 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 78 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
79 | .bytesperline = 352 * 3, | 79 | .bytesperline = 352, |
80 | .sizeimage = 352 * 288 * 3 / 2, | 80 | .sizeimage = 352 * 288 * 3 / 2, |
81 | .colorspace = V4L2_COLORSPACE_SRGB, | 81 | .colorspace = V4L2_COLORSPACE_SRGB, |
82 | .priv = 1}, | 82 | .priv = 1}, |
83 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 83 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
84 | .bytesperline = 640 * 3, | 84 | .bytesperline = 640, |
85 | .sizeimage = 640 * 480 * 3 / 2, | 85 | .sizeimage = 640 * 480 * 3 / 2, |
86 | .colorspace = V4L2_COLORSPACE_SRGB, | 86 | .colorspace = V4L2_COLORSPACE_SRGB, |
87 | .priv = 0}, | 87 | .priv = 0}, |
@@ -776,7 +776,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
776 | default: | 776 | default: |
777 | data += 1; | 777 | data += 1; |
778 | len -= 1; | 778 | len -= 1; |
779 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 779 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
780 | data, len); | 780 | data, len); |
781 | break; | 781 | break; |
782 | } | 782 | } |
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 6fe715c80ad2..f622fa75766d 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -112,27 +112,27 @@ static struct ctrl sd_ctrls[] = { | |||
112 | 112 | ||
113 | static struct v4l2_pix_format vga_mode[] = { | 113 | static struct v4l2_pix_format vga_mode[] = { |
114 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 114 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
115 | .bytesperline = 160 * 3, | 115 | .bytesperline = 160, |
116 | .sizeimage = 160 * 120 * 3 / 2, | 116 | .sizeimage = 160 * 120 * 3 / 2, |
117 | .colorspace = V4L2_COLORSPACE_SRGB, | 117 | .colorspace = V4L2_COLORSPACE_SRGB, |
118 | .priv = 5}, | 118 | .priv = 5}, |
119 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 119 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
120 | .bytesperline = 176 * 3, | 120 | .bytesperline = 176, |
121 | .sizeimage = 176 * 144 * 3 / 2, | 121 | .sizeimage = 176 * 144 * 3 / 2, |
122 | .colorspace = V4L2_COLORSPACE_SRGB, | 122 | .colorspace = V4L2_COLORSPACE_SRGB, |
123 | .priv = 4}, | 123 | .priv = 4}, |
124 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 124 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
125 | .bytesperline = 320 * 3, | 125 | .bytesperline = 320, |
126 | .sizeimage = 320 * 240 * 3 / 2, | 126 | .sizeimage = 320 * 240 * 3 / 2, |
127 | .colorspace = V4L2_COLORSPACE_SRGB, | 127 | .colorspace = V4L2_COLORSPACE_SRGB, |
128 | .priv = 2}, | 128 | .priv = 2}, |
129 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 129 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
130 | .bytesperline = 352 * 3, | 130 | .bytesperline = 352, |
131 | .sizeimage = 352 * 288 * 3 / 2, | 131 | .sizeimage = 352 * 288 * 3 / 2, |
132 | .colorspace = V4L2_COLORSPACE_SRGB, | 132 | .colorspace = V4L2_COLORSPACE_SRGB, |
133 | .priv = 1}, | 133 | .priv = 1}, |
134 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 134 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
135 | .bytesperline = 640 * 3, | 135 | .bytesperline = 640, |
136 | .sizeimage = 640 * 480 * 3 / 2, | 136 | .sizeimage = 640 * 480 * 3 / 2, |
137 | .colorspace = V4L2_COLORSPACE_SRGB, | 137 | .colorspace = V4L2_COLORSPACE_SRGB, |
138 | .priv = 0}, | 138 | .priv = 0}, |
@@ -588,7 +588,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
588 | default: | 588 | default: |
589 | data += 1; | 589 | data += 1; |
590 | len -= 1; | 590 | len -= 1; |
591 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 591 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
592 | data, len); | 592 | data, len); |
593 | break; | 593 | break; |
594 | } | 594 | } |
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index b608a27ad115..699340c17dea 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -63,23 +63,23 @@ static struct ctrl sd_ctrls[] = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct v4l2_pix_format sif_mode[] = { | 65 | static struct v4l2_pix_format sif_mode[] = { |
66 | {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 66 | {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
67 | .bytesperline = 160 * 3, | 67 | .bytesperline = 160, |
68 | .sizeimage = 160 * 120 * 3 / 2, | 68 | .sizeimage = 160 * 120 * 3 / 2, |
69 | .colorspace = V4L2_COLORSPACE_SRGB, | 69 | .colorspace = V4L2_COLORSPACE_SRGB, |
70 | .priv = 3}, | 70 | .priv = 3}, |
71 | {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 71 | {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
72 | .bytesperline = 176 * 3, | 72 | .bytesperline = 176, |
73 | .sizeimage = 176 * 144 * 3 / 2, | 73 | .sizeimage = 176 * 144 * 3 / 2, |
74 | .colorspace = V4L2_COLORSPACE_SRGB, | 74 | .colorspace = V4L2_COLORSPACE_SRGB, |
75 | .priv = 2}, | 75 | .priv = 2}, |
76 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 76 | {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
77 | .bytesperline = 320 * 3, | 77 | .bytesperline = 320, |
78 | .sizeimage = 320 * 240 * 3 / 2, | 78 | .sizeimage = 320 * 240 * 3 / 2, |
79 | .colorspace = V4L2_COLORSPACE_SRGB, | 79 | .colorspace = V4L2_COLORSPACE_SRGB, |
80 | .priv = 1}, | 80 | .priv = 1}, |
81 | {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 81 | {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
82 | .bytesperline = 352 * 3, | 82 | .bytesperline = 352, |
83 | .sizeimage = 352 * 288 * 3 / 2, | 83 | .sizeimage = 352 * 288 * 3 / 2, |
84 | .colorspace = V4L2_COLORSPACE_SRGB, | 84 | .colorspace = V4L2_COLORSPACE_SRGB, |
85 | .priv = 0}, | 85 | .priv = 0}, |
@@ -1583,7 +1583,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1583 | default: | 1583 | default: |
1584 | data += 1; | 1584 | data += 1; |
1585 | len -= 1; | 1585 | len -= 1; |
1586 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 1586 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
1587 | data, len); | 1587 | data, len); |
1588 | break; | 1588 | break; |
1589 | } | 1589 | } |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index a26174508cb9..1073ac3d2ec6 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
644 | } | 644 | } |
645 | } | 645 | } |
646 | 646 | ||
647 | static void setautogain(struct gspca_dev *gspca_dev) | ||
648 | { | ||
649 | struct sd *sd = (struct sd *) gspca_dev; | ||
650 | |||
651 | if (sd->chip_revision == Rev072A) { | ||
652 | if (sd->autogain) | ||
653 | sd->ag_cnt = AG_CNT_START; | ||
654 | else | ||
655 | sd->ag_cnt = -1; | ||
656 | } | ||
657 | } | ||
658 | |||
647 | static void sd_start(struct gspca_dev *gspca_dev) | 659 | static void sd_start(struct gspca_dev *gspca_dev) |
648 | { | 660 | { |
649 | struct sd *sd = (struct sd *) gspca_dev; | 661 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
671 | reg_w_val(dev, 0x8500, mode); /* mode */ | 683 | reg_w_val(dev, 0x8500, mode); /* mode */ |
672 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | 684 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ |
673 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | 685 | reg_w_val(dev, 0x8112, 0x10 | 0x20); |
686 | setautogain(gspca_dev); | ||
674 | break; | 687 | break; |
675 | default: | 688 | default: |
676 | /* case Rev012A: */ | 689 | /* case Rev012A: */ |
@@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
720 | reg_w_val(gspca_dev->dev, 0x8114, 0); | 733 | reg_w_val(gspca_dev->dev, 0x8114, 0); |
721 | } | 734 | } |
722 | 735 | ||
723 | static void setautogain(struct gspca_dev *gspca_dev) | 736 | static void do_autogain(struct gspca_dev *gspca_dev) |
724 | { | 737 | { |
725 | struct sd *sd = (struct sd *) gspca_dev; | 738 | struct sd *sd = (struct sd *) gspca_dev; |
726 | int expotimes = 0; | 739 | int expotimes; |
727 | int pixelclk = 0; | 740 | int pixelclk; |
728 | int gainG = 0; | 741 | int gainG; |
729 | __u8 R, Gr, Gb, B; | 742 | __u8 R, Gr, Gb, B; |
730 | int y; | 743 | int y; |
731 | __u8 luma_mean = 110; | 744 | __u8 luma_mean = 110; |
732 | __u8 luma_delta = 20; | 745 | __u8 luma_delta = 20; |
733 | __u8 spring = 4; | 746 | __u8 spring = 4; |
734 | 747 | ||
748 | if (sd->ag_cnt < 0) | ||
749 | return; | ||
750 | if (--sd->ag_cnt >= 0) | ||
751 | return; | ||
752 | sd->ag_cnt = AG_CNT_START; | ||
753 | |||
735 | switch (sd->chip_revision) { | 754 | switch (sd->chip_revision) { |
736 | case Rev072A: | 755 | case Rev072A: |
737 | reg_r(gspca_dev, 0x8621, 1); | 756 | reg_r(gspca_dev, 0x8621, 1); |
@@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
795 | __u8 *data, /* isoc packet */ | 814 | __u8 *data, /* isoc packet */ |
796 | int len) /* iso packet length */ | 815 | int len) /* iso packet length */ |
797 | { | 816 | { |
798 | struct sd *sd = (struct sd *) gspca_dev; | ||
799 | |||
800 | switch (data[0]) { | 817 | switch (data[0]) { |
801 | case 0: /* start of frame */ | 818 | case 0: /* start of frame */ |
802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 819 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
803 | data, 0); | 820 | data, 0); |
804 | if (sd->ag_cnt >= 0) { | ||
805 | if (--sd->ag_cnt < 0) { | ||
806 | sd->ag_cnt = AG_CNT_START; | ||
807 | setautogain(gspca_dev); | ||
808 | } | ||
809 | } | ||
810 | data += SPCA561_OFFSET_DATA; | 821 | data += SPCA561_OFFSET_DATA; |
811 | len -= SPCA561_OFFSET_DATA; | 822 | len -= SPCA561_OFFSET_DATA; |
812 | if (data[1] & 0x10) { | 823 | if (data[1] & 0x10) { |
@@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
944 | struct sd *sd = (struct sd *) gspca_dev; | 955 | struct sd *sd = (struct sd *) gspca_dev; |
945 | 956 | ||
946 | sd->autogain = val; | 957 | sd->autogain = val; |
947 | if (val) | 958 | if (gspca_dev->streaming) |
948 | sd->ag_cnt = AG_CNT_START; | 959 | setautogain(gspca_dev); |
949 | else | ||
950 | sd->ag_cnt = -1; | ||
951 | return 0; | 960 | return 0; |
952 | } | 961 | } |
953 | 962 | ||
@@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = { | |||
971 | .stop0 = sd_stop0, | 980 | .stop0 = sd_stop0, |
972 | .close = sd_close, | 981 | .close = sd_close, |
973 | .pkt_scan = sd_pkt_scan, | 982 | .pkt_scan = sd_pkt_scan, |
983 | .dq_callback = do_autogain, | ||
974 | }; | 984 | }; |
975 | 985 | ||
976 | /* -- module initialisation -- */ | 986 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index a4221753e1bf..f4a52956e0d9 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -88,12 +88,12 @@ static struct ctrl sd_ctrls[] = { | |||
88 | 88 | ||
89 | static struct v4l2_pix_format vc0321_mode[] = { | 89 | static struct v4l2_pix_format vc0321_mode[] = { |
90 | {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, | 90 | {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, |
91 | .bytesperline = 320 * 2, | 91 | .bytesperline = 320, |
92 | .sizeimage = 320 * 240 * 2, | 92 | .sizeimage = 320 * 240 * 2, |
93 | .colorspace = V4L2_COLORSPACE_SRGB, | 93 | .colorspace = V4L2_COLORSPACE_SRGB, |
94 | .priv = 1}, | 94 | .priv = 1}, |
95 | {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, | 95 | {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, |
96 | .bytesperline = 640 * 2, | 96 | .bytesperline = 640, |
97 | .sizeimage = 640 * 480 * 2, | 97 | .sizeimage = 640 * 480 * 2, |
98 | .colorspace = V4L2_COLORSPACE_SRGB, | 98 | .colorspace = V4L2_COLORSPACE_SRGB, |
99 | .priv = 0}, | 99 | .priv = 0}, |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 22a994ccb1d5..bc7d0eedcd81 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -6469,7 +6469,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6469 | NULL, Tgradient_1, Tgradient_2, | 6469 | NULL, Tgradient_1, Tgradient_2, |
6470 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 | 6470 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 |
6471 | }; | 6471 | }; |
6472 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 6472 | #ifdef GSPCA_DEBUG |
6473 | __u8 v[16]; | 6473 | __u8 v[16]; |
6474 | #endif | 6474 | #endif |
6475 | 6475 | ||
@@ -6487,7 +6487,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6487 | else if (g <= 0) | 6487 | else if (g <= 0) |
6488 | g = 1; | 6488 | g = 1; |
6489 | reg_w(dev, g, 0x0120 + i); /* gamma */ | 6489 | reg_w(dev, g, 0x0120 + i); /* gamma */ |
6490 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 6490 | #ifdef GSPCA_DEBUG |
6491 | if (gspca_debug & D_CONF) | 6491 | if (gspca_debug & D_CONF) |
6492 | v[i] = g; | 6492 | v[i] = g; |
6493 | #endif | 6493 | #endif |
@@ -6507,7 +6507,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6507 | g = 1; | 6507 | g = 1; |
6508 | } | 6508 | } |
6509 | reg_w(dev, g, 0x0130 + i); /* gradient */ | 6509 | reg_w(dev, g, 0x0130 + i); /* gradient */ |
6510 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 6510 | #ifdef GSPCA_DEBUG |
6511 | if (gspca_debug & D_CONF) | 6511 | if (gspca_debug & D_CONF) |
6512 | v[i] = g; | 6512 | v[i] = g; |
6513 | #endif | 6513 | #endif |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 5e7ebca1968e..388cf94055d3 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -128,6 +128,8 @@ struct pxa_camera_dev { | |||
128 | 128 | ||
129 | struct pxa_buffer *active; | 129 | struct pxa_buffer *active; |
130 | struct pxa_dma_desc *sg_tail[3]; | 130 | struct pxa_dma_desc *sg_tail[3]; |
131 | |||
132 | u32 save_cicr[5]; | ||
131 | }; | 133 | }; |
132 | 134 | ||
133 | static const char *pxa_cam_driver_description = "PXA_Camera"; | 135 | static const char *pxa_cam_driver_description = "PXA_Camera"; |
@@ -997,10 +999,64 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, | |||
997 | return 0; | 999 | return 0; |
998 | } | 1000 | } |
999 | 1001 | ||
1002 | static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state) | ||
1003 | { | ||
1004 | struct soc_camera_host *ici = | ||
1005 | to_soc_camera_host(icd->dev.parent); | ||
1006 | struct pxa_camera_dev *pcdev = ici->priv; | ||
1007 | int i = 0, ret = 0; | ||
1008 | |||
1009 | pcdev->save_cicr[i++] = CICR0; | ||
1010 | pcdev->save_cicr[i++] = CICR1; | ||
1011 | pcdev->save_cicr[i++] = CICR2; | ||
1012 | pcdev->save_cicr[i++] = CICR3; | ||
1013 | pcdev->save_cicr[i++] = CICR4; | ||
1014 | |||
1015 | if ((pcdev->icd) && (pcdev->icd->ops->suspend)) | ||
1016 | ret = pcdev->icd->ops->suspend(pcdev->icd, state); | ||
1017 | |||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | static int pxa_camera_resume(struct soc_camera_device *icd) | ||
1022 | { | ||
1023 | struct soc_camera_host *ici = | ||
1024 | to_soc_camera_host(icd->dev.parent); | ||
1025 | struct pxa_camera_dev *pcdev = ici->priv; | ||
1026 | int i = 0, ret = 0; | ||
1027 | |||
1028 | DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD; | ||
1029 | DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD; | ||
1030 | DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD; | ||
1031 | |||
1032 | CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB; | ||
1033 | CICR1 = pcdev->save_cicr[i++]; | ||
1034 | CICR2 = pcdev->save_cicr[i++]; | ||
1035 | CICR3 = pcdev->save_cicr[i++]; | ||
1036 | CICR4 = pcdev->save_cicr[i++]; | ||
1037 | |||
1038 | if ((pcdev->icd) && (pcdev->icd->ops->resume)) | ||
1039 | ret = pcdev->icd->ops->resume(pcdev->icd); | ||
1040 | |||
1041 | /* Restart frame capture if active buffer exists */ | ||
1042 | if (!ret && pcdev->active) { | ||
1043 | /* Reset the FIFOs */ | ||
1044 | CIFR |= CIFR_RESET_F; | ||
1045 | /* Enable End-Of-Frame Interrupt */ | ||
1046 | CICR0 &= ~CICR0_EOFM; | ||
1047 | /* Restart the Capture Interface */ | ||
1048 | CICR0 |= CICR0_ENB; | ||
1049 | } | ||
1050 | |||
1051 | return ret; | ||
1052 | } | ||
1053 | |||
1000 | static struct soc_camera_host_ops pxa_soc_camera_host_ops = { | 1054 | static struct soc_camera_host_ops pxa_soc_camera_host_ops = { |
1001 | .owner = THIS_MODULE, | 1055 | .owner = THIS_MODULE, |
1002 | .add = pxa_camera_add_device, | 1056 | .add = pxa_camera_add_device, |
1003 | .remove = pxa_camera_remove_device, | 1057 | .remove = pxa_camera_remove_device, |
1058 | .suspend = pxa_camera_suspend, | ||
1059 | .resume = pxa_camera_resume, | ||
1004 | .set_fmt_cap = pxa_camera_set_fmt_cap, | 1060 | .set_fmt_cap = pxa_camera_set_fmt_cap, |
1005 | .try_fmt_cap = pxa_camera_try_fmt_cap, | 1061 | .try_fmt_cap = pxa_camera_try_fmt_cap, |
1006 | .init_videobuf = pxa_camera_init_videobuf, | 1062 | .init_videobuf = pxa_camera_init_videobuf, |
@@ -1198,7 +1254,7 @@ static int __devinit pxa_camera_init(void) | |||
1198 | 1254 | ||
1199 | static void __exit pxa_camera_exit(void) | 1255 | static void __exit pxa_camera_exit(void) |
1200 | { | 1256 | { |
1201 | return platform_driver_unregister(&pxa_camera_driver); | 1257 | platform_driver_unregister(&pxa_camera_driver); |
1202 | } | 1258 | } |
1203 | 1259 | ||
1204 | module_init(pxa_camera_init); | 1260 | module_init(pxa_camera_init); |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index f7ca3cb9340a..318754e73132 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -647,7 +647,7 @@ static int __init sh_mobile_ceu_init(void) | |||
647 | 647 | ||
648 | static void __exit sh_mobile_ceu_exit(void) | 648 | static void __exit sh_mobile_ceu_exit(void) |
649 | { | 649 | { |
650 | return platform_driver_unregister(&sh_mobile_ceu_driver); | 650 | platform_driver_unregister(&sh_mobile_ceu_driver); |
651 | } | 651 | } |
652 | 652 | ||
653 | module_init(sh_mobile_ceu_init); | 653 | module_init(sh_mobile_ceu_init); |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b6be5ee678b6..66ebe5956a87 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -732,10 +732,36 @@ static int soc_camera_remove(struct device *dev) | |||
732 | return 0; | 732 | return 0; |
733 | } | 733 | } |
734 | 734 | ||
735 | static int soc_camera_suspend(struct device *dev, pm_message_t state) | ||
736 | { | ||
737 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | ||
738 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
739 | int ret = 0; | ||
740 | |||
741 | if (ici->ops->suspend) | ||
742 | ret = ici->ops->suspend(icd, state); | ||
743 | |||
744 | return ret; | ||
745 | } | ||
746 | |||
747 | static int soc_camera_resume(struct device *dev) | ||
748 | { | ||
749 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | ||
750 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
751 | int ret = 0; | ||
752 | |||
753 | if (ici->ops->resume) | ||
754 | ret = ici->ops->resume(icd); | ||
755 | |||
756 | return ret; | ||
757 | } | ||
758 | |||
735 | static struct bus_type soc_camera_bus_type = { | 759 | static struct bus_type soc_camera_bus_type = { |
736 | .name = "soc-camera", | 760 | .name = "soc-camera", |
737 | .probe = soc_camera_probe, | 761 | .probe = soc_camera_probe, |
738 | .remove = soc_camera_remove, | 762 | .remove = soc_camera_remove, |
763 | .suspend = soc_camera_suspend, | ||
764 | .resume = soc_camera_resume, | ||
739 | }; | 765 | }; |
740 | 766 | ||
741 | static struct device_driver ic_drv = { | 767 | static struct device_driver ic_drv = { |
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index eefb0327ebb6..1adc257ebdb9 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c | |||
@@ -187,7 +187,7 @@ static int __init soc_camera_platform_module_init(void) | |||
187 | 187 | ||
188 | static void __exit soc_camera_platform_module_exit(void) | 188 | static void __exit soc_camera_platform_module_exit(void) |
189 | { | 189 | { |
190 | return platform_driver_unregister(&soc_camera_platform_driver); | 190 | platform_driver_unregister(&soc_camera_platform_driver); |
191 | } | 191 | } |
192 | 192 | ||
193 | module_init(soc_camera_platform_module_init); | 193 | module_init(soc_camera_platform_module_init); |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 626f4ad7e876..6ef3e5297de8 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
585 | struct uvc_control_mapping *mapping; | 585 | struct uvc_control_mapping *mapping; |
586 | struct uvc_menu_info *menu; | 586 | struct uvc_menu_info *menu; |
587 | unsigned int i; | 587 | unsigned int i; |
588 | __u8 data[8]; | 588 | __u8 *data; |
589 | int ret; | 589 | int ret; |
590 | 590 | ||
591 | ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); | 591 | ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); |
592 | if (ctrl == NULL) | 592 | if (ctrl == NULL) |
593 | return -EINVAL; | 593 | return -EINVAL; |
594 | 594 | ||
595 | data = kmalloc(8, GFP_KERNEL); | ||
596 | if (data == NULL) | ||
597 | return -ENOMEM; | ||
598 | |||
595 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 599 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); |
596 | v4l2_ctrl->id = mapping->id; | 600 | v4l2_ctrl->id = mapping->id; |
597 | v4l2_ctrl->type = mapping->v4l2_type; | 601 | v4l2_ctrl->type = mapping->v4l2_type; |
@@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
604 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 608 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { |
605 | if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, | 609 | if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, |
606 | video->dev->intfnum, ctrl->info->selector, | 610 | video->dev->intfnum, ctrl->info->selector, |
607 | &data, ctrl->info->size)) < 0) | 611 | data, ctrl->info->size)) < 0) |
608 | return ret; | 612 | goto out; |
609 | v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); | 613 | v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); |
610 | } | 614 | } |
611 | 615 | ||
@@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
623 | } | 627 | } |
624 | } | 628 | } |
625 | 629 | ||
626 | return 0; | 630 | ret = 0; |
631 | goto out; | ||
627 | 632 | ||
628 | case V4L2_CTRL_TYPE_BOOLEAN: | 633 | case V4L2_CTRL_TYPE_BOOLEAN: |
629 | v4l2_ctrl->minimum = 0; | 634 | v4l2_ctrl->minimum = 0; |
630 | v4l2_ctrl->maximum = 1; | 635 | v4l2_ctrl->maximum = 1; |
631 | v4l2_ctrl->step = 1; | 636 | v4l2_ctrl->step = 1; |
632 | return 0; | 637 | ret = 0; |
638 | goto out; | ||
633 | 639 | ||
634 | default: | 640 | default: |
635 | break; | 641 | break; |
@@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
638 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { | 644 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { |
639 | if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, | 645 | if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, |
640 | video->dev->intfnum, ctrl->info->selector, | 646 | video->dev->intfnum, ctrl->info->selector, |
641 | &data, ctrl->info->size)) < 0) | 647 | data, ctrl->info->size)) < 0) |
642 | return ret; | 648 | goto out; |
643 | v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); | 649 | v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); |
644 | } | 650 | } |
645 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { | 651 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { |
646 | if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, | 652 | if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, |
647 | video->dev->intfnum, ctrl->info->selector, | 653 | video->dev->intfnum, ctrl->info->selector, |
648 | &data, ctrl->info->size)) < 0) | 654 | data, ctrl->info->size)) < 0) |
649 | return ret; | 655 | goto out; |
650 | v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); | 656 | v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); |
651 | } | 657 | } |
652 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { | 658 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { |
653 | if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, | 659 | if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, |
654 | video->dev->intfnum, ctrl->info->selector, | 660 | video->dev->intfnum, ctrl->info->selector, |
655 | &data, ctrl->info->size)) < 0) | 661 | data, ctrl->info->size)) < 0) |
656 | return ret; | 662 | goto out; |
657 | v4l2_ctrl->step = uvc_get_le_value(data, mapping); | 663 | v4l2_ctrl->step = uvc_get_le_value(data, mapping); |
658 | } | 664 | } |
659 | 665 | ||
660 | return 0; | 666 | ret = 0; |
667 | out: | ||
668 | kfree(data); | ||
669 | return ret; | ||
661 | } | 670 | } |
662 | 671 | ||
663 | 672 | ||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index b3c4d75e8490..7e102034d38d 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -1884,7 +1884,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1884 | .bInterfaceSubClass = 1, | 1884 | .bInterfaceSubClass = 1, |
1885 | .bInterfaceProtocol = 0, | 1885 | .bInterfaceProtocol = 0, |
1886 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1886 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
1887 | /* Packard Bell OEM Webcam */ | 1887 | /* Packard Bell OEM Webcam - Bison Electronics */ |
1888 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1888 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1889 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1889 | | USB_DEVICE_ID_MATCH_INT_INFO, |
1890 | .idVendor = 0x5986, | 1890 | .idVendor = 0x5986, |
@@ -1893,7 +1893,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1893 | .bInterfaceSubClass = 1, | 1893 | .bInterfaceSubClass = 1, |
1894 | .bInterfaceProtocol = 0, | 1894 | .bInterfaceProtocol = 0, |
1895 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1895 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
1896 | /* Acer Crystal Eye webcam */ | 1896 | /* Acer Crystal Eye webcam - Bison Electronics */ |
1897 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1897 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1898 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1898 | | USB_DEVICE_ID_MATCH_INT_INFO, |
1899 | .idVendor = 0x5986, | 1899 | .idVendor = 0x5986, |
@@ -1902,7 +1902,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1902 | .bInterfaceSubClass = 1, | 1902 | .bInterfaceSubClass = 1, |
1903 | .bInterfaceProtocol = 0, | 1903 | .bInterfaceProtocol = 0, |
1904 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1904 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
1905 | /* Medion Akoya Mini E1210 */ | 1905 | /* Medion Akoya Mini E1210 - Bison Electronics */ |
1906 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1906 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1907 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1907 | | USB_DEVICE_ID_MATCH_INT_INFO, |
1908 | .idVendor = 0x5986, | 1908 | .idVendor = 0x5986, |
@@ -1911,7 +1911,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1911 | .bInterfaceSubClass = 1, | 1911 | .bInterfaceSubClass = 1, |
1912 | .bInterfaceProtocol = 0, | 1912 | .bInterfaceProtocol = 0, |
1913 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1913 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
1914 | /* Acer OrbiCam - Unknown vendor */ | 1914 | /* Acer OrbiCam - Bison Electronics */ |
1915 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1915 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1916 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1916 | | USB_DEVICE_ID_MATCH_INT_INFO, |
1917 | .idVendor = 0x5986, | 1917 | .idVendor = 0x5986, |
@@ -1920,6 +1920,24 @@ static struct usb_device_id uvc_ids[] = { | |||
1920 | .bInterfaceSubClass = 1, | 1920 | .bInterfaceSubClass = 1, |
1921 | .bInterfaceProtocol = 0, | 1921 | .bInterfaceProtocol = 0, |
1922 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1922 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
1923 | /* Bison Electronics */ | ||
1924 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
1925 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1926 | .idVendor = 0x5986, | ||
1927 | .idProduct = 0x0300, | ||
1928 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1929 | .bInterfaceSubClass = 1, | ||
1930 | .bInterfaceProtocol = 0, | ||
1931 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
1932 | /* Clevo M570TU - Bison Electronics */ | ||
1933 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
1934 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1935 | .idVendor = 0x5986, | ||
1936 | .idProduct = 0x0303, | ||
1937 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1938 | .bInterfaceSubClass = 1, | ||
1939 | .bInterfaceProtocol = 0, | ||
1940 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
1923 | /* Generic USB Video Class */ | 1941 | /* Generic USB Video Class */ |
1924 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, | 1942 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, |
1925 | {} | 1943 | {} |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index ad63794fda77..6854ac78a161 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video, | |||
90 | static int uvc_get_video_ctrl(struct uvc_video_device *video, | 90 | static int uvc_get_video_ctrl(struct uvc_video_device *video, |
91 | struct uvc_streaming_control *ctrl, int probe, __u8 query) | 91 | struct uvc_streaming_control *ctrl, int probe, __u8 query) |
92 | { | 92 | { |
93 | __u8 data[34]; | 93 | __u8 *data; |
94 | __u8 size; | 94 | __u16 size; |
95 | int ret; | 95 | int ret; |
96 | 96 | ||
97 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; | 97 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; |
98 | data = kmalloc(size, GFP_KERNEL); | ||
99 | if (data == NULL) | ||
100 | return -ENOMEM; | ||
101 | |||
98 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, | 102 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, |
99 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, | 103 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, |
100 | UVC_CTRL_STREAMING_TIMEOUT); | 104 | UVC_CTRL_STREAMING_TIMEOUT); |
101 | |||
102 | if (ret < 0) | 105 | if (ret < 0) |
103 | return ret; | 106 | goto out; |
104 | 107 | ||
105 | ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); | 108 | ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); |
106 | ctrl->bFormatIndex = data[2]; | 109 | ctrl->bFormatIndex = data[2]; |
@@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
136 | */ | 139 | */ |
137 | uvc_fixup_buffer_size(video, ctrl); | 140 | uvc_fixup_buffer_size(video, ctrl); |
138 | 141 | ||
139 | return 0; | 142 | out: |
143 | kfree(data); | ||
144 | return ret; | ||
140 | } | 145 | } |
141 | 146 | ||
142 | int uvc_set_video_ctrl(struct uvc_video_device *video, | 147 | int uvc_set_video_ctrl(struct uvc_video_device *video, |
143 | struct uvc_streaming_control *ctrl, int probe) | 148 | struct uvc_streaming_control *ctrl, int probe) |
144 | { | 149 | { |
145 | __u8 data[34]; | 150 | __u8 *data; |
146 | __u8 size; | 151 | __u16 size; |
152 | int ret; | ||
147 | 153 | ||
148 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; | 154 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; |
149 | memset(data, 0, sizeof data); | 155 | data = kzalloc(size, GFP_KERNEL); |
156 | if (data == NULL) | ||
157 | return -ENOMEM; | ||
150 | 158 | ||
151 | *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); | 159 | *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); |
152 | data[2] = ctrl->bFormatIndex; | 160 | data[2] = ctrl->bFormatIndex; |
@@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video, | |||
174 | data[33] = ctrl->bMaxVersion; | 182 | data[33] = ctrl->bMaxVersion; |
175 | } | 183 | } |
176 | 184 | ||
177 | return __uvc_query_ctrl(video->dev, SET_CUR, 0, | 185 | ret = __uvc_query_ctrl(video->dev, SET_CUR, 0, |
178 | video->streaming->intfnum, | 186 | video->streaming->intfnum, |
179 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, | 187 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, |
180 | UVC_CTRL_STREAMING_TIMEOUT); | 188 | UVC_CTRL_STREAMING_TIMEOUT); |
189 | |||
190 | kfree(data); | ||
191 | return ret; | ||
181 | } | 192 | } |
182 | 193 | ||
183 | int uvc_probe_video(struct uvc_video_device *video, | 194 | int uvc_probe_video(struct uvc_video_device *video, |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 556615fe93de..6f36006aecda 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -222,11 +222,13 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
222 | EXPORT_SYMBOL(video_register_device); | 222 | EXPORT_SYMBOL(video_register_device); |
223 | 223 | ||
224 | /** | 224 | /** |
225 | * video_register_device - register video4linux devices | 225 | * video_register_device_index - register video4linux devices |
226 | * @vfd: video device structure we want to register | 226 | * @vfd: video device structure we want to register |
227 | * @type: type of device to register | 227 | * @type: type of device to register |
228 | * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... | 228 | * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... |
229 | * -1 == first free) | 229 | * -1 == first free) |
230 | * @index: stream number based on parent device; | ||
231 | * -1 if auto assign, requested number otherwise | ||
230 | * | 232 | * |
231 | * The registration code assigns minor numbers based on the type | 233 | * The registration code assigns minor numbers based on the type |
232 | * requested. -ENFILE is returned in all the device slots for this | 234 | * requested. -ENFILE is returned in all the device slots for this |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index ef7572cbc4ab..1edda456fc64 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/videodev2.h> | 41 | #include <linux/videodev2.h> |
42 | #include <media/v4l2-ioctl.h> | 42 | #include <media/v4l2-ioctl.h> |
43 | #include <media/v4l2-common.h> | 43 | #include <media/v4l2-common.h> |
44 | #include <media/v4l2-ioctl.h> | ||
44 | #include <linux/video_decoder.h> | 45 | #include <linux/video_decoder.h> |
45 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
46 | 47 | ||