diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:47:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:47:44 -0400 |
commit | 8762541f067d371320731510669e27f5cc40af38 (patch) | |
tree | fa2890094858614a947ba70612854acde9888940 /drivers/media/video/gspca | |
parent | 6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (diff) | |
parent | adfe1560de1c696324554fba70c92f2d7c947ff7 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull second set of media updates from Mauro Carvalho Chehab:
- radio API: add support to work with radio frequency bands
- new AM/FM radio drivers: radio-shark, radio-shark2
- new Remote Controller USB driver: iguanair
- conversion of several drivers to the v4l2 core control framework
- new board additions at existing drivers
- the remaining (and vast majority of the patches) are due to
drivers/DocBook fixes/cleanups.
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (154 commits)
[media] radio-tea5777: use library for 64bits div
[media] tlg2300: Declare MODULE_FIRMWARE usage
[media] lgs8gxx: Declare MODULE_FIRMWARE usage
[media] xc5000: Add MODULE_FIRMWARE statements
[media] s2255drv: Add MODULE_FIRMWARE statement
[media] dib8000: move dereference after check for NULL
[media] Documentation: Update cardlists
[media] bttv: add support for Aposonic W-DVR
[media] cx25821: Remove bad strcpy to read-only char*
[media] pms.c: remove duplicated include
[media] smiapp-core.c: remove duplicated include
[media] via-camera: pass correct format settings to sensor
[media] rtl2832.c: minor cleanup
[media] Add support for the IguanaWorks USB IR Transceiver
[media] Minor cleanups for MCE USB
[media] drivers/media/dvb/siano/smscoreapi.c: use list_for_each_entry
[media] Use a named union in struct v4l2_ioctl_info
[media] mceusb: Add Twisted Melon USB IDs
[media] staging/media/solo6x10: use module_pci_driver macro
[media] staging/media/dt3155v4l: use module_pci_driver macro
...
Conflicts:
Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/media/video/gspca')
45 files changed, 3165 insertions, 6354 deletions
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c index 9769f17915c0..352f32190e68 100644 --- a/drivers/media/video/gspca/benq.c +++ b/drivers/media/video/gspca/benq.c | |||
@@ -33,10 +33,6 @@ 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 | 35 | ||
36 | /* V4L2 controls supported by the driver */ | ||
37 | static const struct ctrl sd_ctrls[] = { | ||
38 | }; | ||
39 | |||
40 | static const struct v4l2_pix_format vga_mode[] = { | 36 | static const struct v4l2_pix_format vga_mode[] = { |
41 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 37 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
42 | .bytesperline = 320, | 38 | .bytesperline = 320, |
@@ -256,8 +252,6 @@ static void sd_isoc_irq(struct urb *urb) | |||
256 | /* sub-driver description */ | 252 | /* sub-driver description */ |
257 | static const struct sd_desc sd_desc = { | 253 | static const struct sd_desc sd_desc = { |
258 | .name = MODULE_NAME, | 254 | .name = MODULE_NAME, |
259 | .ctrls = sd_ctrls, | ||
260 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
261 | .config = sd_config, | 255 | .config = sd_config, |
262 | .init = sd_init, | 256 | .init = sd_init, |
263 | .start = sd_start, | 257 | .start = sd_start, |
@@ -288,6 +282,7 @@ static struct usb_driver sd_driver = { | |||
288 | #ifdef CONFIG_PM | 282 | #ifdef CONFIG_PM |
289 | .suspend = gspca_suspend, | 283 | .suspend = gspca_suspend, |
290 | .resume = gspca_resume, | 284 | .resume = gspca_resume, |
285 | .reset_resume = gspca_resume, | ||
291 | #endif | 286 | #endif |
292 | }; | 287 | }; |
293 | 288 | ||
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index f39fee0fd10f..c9052f20435e 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
@@ -31,74 +31,18 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
31 | MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); | 31 | MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); |
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | 33 | ||
34 | #define QUALITY 50 | ||
35 | |||
34 | /* specific webcam descriptor */ | 36 | /* specific webcam descriptor */ |
35 | struct sd { | 37 | struct sd { |
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 38 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
37 | 39 | struct v4l2_ctrl *brightness; | |
38 | unsigned char brightness; | 40 | struct v4l2_ctrl *contrast; |
39 | unsigned char contrast; | 41 | struct v4l2_ctrl *sat; |
40 | unsigned char colors; | ||
41 | u8 quality; | ||
42 | #define QUALITY_MIN 30 | ||
43 | #define QUALITY_MAX 60 | ||
44 | #define QUALITY_DEF 40 | ||
45 | 42 | ||
46 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 43 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
47 | }; | 44 | }; |
48 | 45 | ||
49 | /* V4L2 controls supported by the driver */ | ||
50 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | |||
57 | static const struct ctrl sd_ctrls[] = { | ||
58 | { | ||
59 | { | ||
60 | .id = V4L2_CID_BRIGHTNESS, | ||
61 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
62 | .name = "Brightness", | ||
63 | .minimum = 0, | ||
64 | .maximum = 255, | ||
65 | .step = 1, | ||
66 | #define BRIGHTNESS_DEF 0xd4 | ||
67 | .default_value = BRIGHTNESS_DEF, | ||
68 | }, | ||
69 | .set = sd_setbrightness, | ||
70 | .get = sd_getbrightness, | ||
71 | }, | ||
72 | { | ||
73 | { | ||
74 | .id = V4L2_CID_CONTRAST, | ||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
76 | .name = "Contrast", | ||
77 | .minimum = 0x0a, | ||
78 | .maximum = 0x1f, | ||
79 | .step = 1, | ||
80 | #define CONTRAST_DEF 0x0c | ||
81 | .default_value = CONTRAST_DEF, | ||
82 | }, | ||
83 | .set = sd_setcontrast, | ||
84 | .get = sd_getcontrast, | ||
85 | }, | ||
86 | { | ||
87 | { | ||
88 | .id = V4L2_CID_SATURATION, | ||
89 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
90 | .name = "Color", | ||
91 | .minimum = 0, | ||
92 | .maximum = 7, | ||
93 | .step = 1, | ||
94 | #define COLOR_DEF 3 | ||
95 | .default_value = COLOR_DEF, | ||
96 | }, | ||
97 | .set = sd_setcolors, | ||
98 | .get = sd_getcolors, | ||
99 | }, | ||
100 | }; | ||
101 | |||
102 | static const struct v4l2_pix_format vga_mode[] = { | 46 | static const struct v4l2_pix_format vga_mode[] = { |
103 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 47 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
104 | .bytesperline = 176, | 48 | .bytesperline = 176, |
@@ -817,17 +761,11 @@ static void cx11646_init1(struct gspca_dev *gspca_dev) | |||
817 | static int sd_config(struct gspca_dev *gspca_dev, | 761 | static int sd_config(struct gspca_dev *gspca_dev, |
818 | const struct usb_device_id *id) | 762 | const struct usb_device_id *id) |
819 | { | 763 | { |
820 | struct sd *sd = (struct sd *) gspca_dev; | ||
821 | struct cam *cam; | 764 | struct cam *cam; |
822 | 765 | ||
823 | cam = &gspca_dev->cam; | 766 | cam = &gspca_dev->cam; |
824 | cam->cam_mode = vga_mode; | 767 | cam->cam_mode = vga_mode; |
825 | cam->nmodes = ARRAY_SIZE(vga_mode); | 768 | cam->nmodes = ARRAY_SIZE(vga_mode); |
826 | |||
827 | sd->brightness = BRIGHTNESS_DEF; | ||
828 | sd->contrast = CONTRAST_DEF; | ||
829 | sd->colors = COLOR_DEF; | ||
830 | sd->quality = QUALITY_DEF; | ||
831 | return 0; | 769 | return 0; |
832 | } | 770 | } |
833 | 771 | ||
@@ -849,7 +787,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
849 | /* create the JPEG header */ | 787 | /* create the JPEG header */ |
850 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 788 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
851 | 0x22); /* JPEG 411 */ | 789 | 0x22); /* JPEG 411 */ |
852 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 790 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
853 | 791 | ||
854 | cx11646_initsize(gspca_dev); | 792 | cx11646_initsize(gspca_dev); |
855 | cx11646_fw(gspca_dev); | 793 | cx11646_fw(gspca_dev); |
@@ -903,142 +841,99 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
903 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 841 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
904 | } | 842 | } |
905 | 843 | ||
906 | static void setbrightness(struct gspca_dev *gspca_dev) | 844 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat) |
907 | { | 845 | { |
908 | struct sd *sd = (struct sd *) gspca_dev; | ||
909 | __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; | 846 | __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; |
910 | __u8 reg51c[2]; | 847 | __u8 reg51c[2]; |
911 | __u8 bright; | ||
912 | __u8 colors; | ||
913 | 848 | ||
914 | bright = sd->brightness; | 849 | regE5cbx[2] = val; |
915 | regE5cbx[2] = bright; | ||
916 | reg_w(gspca_dev, 0x00e5, regE5cbx, 8); | 850 | reg_w(gspca_dev, 0x00e5, regE5cbx, 8); |
917 | reg_r(gspca_dev, 0x00e8, 8); | 851 | reg_r(gspca_dev, 0x00e8, 8); |
918 | reg_w(gspca_dev, 0x00e5, regE5c, 4); | 852 | reg_w(gspca_dev, 0x00e5, regE5c, 4); |
919 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | 853 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ |
920 | 854 | ||
921 | colors = sd->colors; | ||
922 | reg51c[0] = 0x77; | 855 | reg51c[0] = 0x77; |
923 | reg51c[1] = colors; | 856 | reg51c[1] = sat; |
924 | reg_w(gspca_dev, 0x0051, reg51c, 2); | 857 | reg_w(gspca_dev, 0x0051, reg51c, 2); |
925 | reg_w(gspca_dev, 0x0010, reg10, 2); | 858 | reg_w(gspca_dev, 0x0010, reg10, 2); |
926 | reg_w_val(gspca_dev, 0x0070, reg70); | 859 | reg_w_val(gspca_dev, 0x0070, reg70); |
927 | } | 860 | } |
928 | 861 | ||
929 | static void setcontrast(struct gspca_dev *gspca_dev) | 862 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat) |
930 | { | 863 | { |
931 | struct sd *sd = (struct sd *) gspca_dev; | ||
932 | __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ | 864 | __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ |
933 | /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ | 865 | /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ |
934 | __u8 reg51c[2]; | 866 | __u8 reg51c[2]; |
935 | 867 | ||
936 | regE5acx[2] = sd->contrast; | 868 | regE5acx[2] = val; |
937 | reg_w(gspca_dev, 0x00e5, regE5acx, 4); | 869 | reg_w(gspca_dev, 0x00e5, regE5acx, 4); |
938 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | 870 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ |
939 | reg51c[0] = 0x77; | 871 | reg51c[0] = 0x77; |
940 | reg51c[1] = sd->colors; | 872 | reg51c[1] = sat; |
941 | reg_w(gspca_dev, 0x0051, reg51c, 2); | 873 | reg_w(gspca_dev, 0x0051, reg51c, 2); |
942 | reg_w(gspca_dev, 0x0010, reg10, 2); | 874 | reg_w(gspca_dev, 0x0010, reg10, 2); |
943 | reg_w_val(gspca_dev, 0x0070, reg70); | 875 | reg_w_val(gspca_dev, 0x0070, reg70); |
944 | } | 876 | } |
945 | 877 | ||
946 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 878 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
947 | { | ||
948 | struct sd *sd = (struct sd *) gspca_dev; | ||
949 | |||
950 | sd->brightness = val; | ||
951 | if (gspca_dev->streaming) | ||
952 | setbrightness(gspca_dev); | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
957 | { | ||
958 | struct sd *sd = (struct sd *) gspca_dev; | ||
959 | |||
960 | *val = sd->brightness; | ||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
965 | { | ||
966 | struct sd *sd = (struct sd *) gspca_dev; | ||
967 | |||
968 | sd->contrast = val; | ||
969 | if (gspca_dev->streaming) | ||
970 | setcontrast(gspca_dev); | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
975 | { | 879 | { |
976 | struct sd *sd = (struct sd *) gspca_dev; | 880 | struct gspca_dev *gspca_dev = |
881 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
882 | struct sd *sd = (struct sd *)gspca_dev; | ||
977 | 883 | ||
978 | *val = sd->contrast; | 884 | gspca_dev->usb_err = 0; |
979 | return 0; | ||
980 | } | ||
981 | 885 | ||
982 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | 886 | if (!gspca_dev->streaming) |
983 | { | 887 | return 0; |
984 | struct sd *sd = (struct sd *) gspca_dev; | ||
985 | 888 | ||
986 | sd->colors = val; | 889 | switch (ctrl->id) { |
987 | if (gspca_dev->streaming) { | 890 | case V4L2_CID_BRIGHTNESS: |
988 | setbrightness(gspca_dev); | 891 | setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val); |
989 | setcontrast(gspca_dev); | 892 | break; |
893 | case V4L2_CID_CONTRAST: | ||
894 | setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val); | ||
895 | break; | ||
896 | case V4L2_CID_SATURATION: | ||
897 | setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val); | ||
898 | setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val); | ||
899 | break; | ||
990 | } | 900 | } |
991 | return 0; | 901 | return gspca_dev->usb_err; |
992 | } | 902 | } |
993 | 903 | ||
994 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | 904 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
995 | { | 905 | .s_ctrl = sd_s_ctrl, |
996 | struct sd *sd = (struct sd *) gspca_dev; | 906 | }; |
997 | |||
998 | *val = sd->colors; | ||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | ||
1003 | struct v4l2_jpegcompression *jcomp) | ||
1004 | { | ||
1005 | struct sd *sd = (struct sd *) gspca_dev; | ||
1006 | |||
1007 | if (jcomp->quality < QUALITY_MIN) | ||
1008 | sd->quality = QUALITY_MIN; | ||
1009 | else if (jcomp->quality > QUALITY_MAX) | ||
1010 | sd->quality = QUALITY_MAX; | ||
1011 | else | ||
1012 | sd->quality = jcomp->quality; | ||
1013 | if (gspca_dev->streaming) | ||
1014 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | 907 | ||
1018 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 908 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
1019 | struct v4l2_jpegcompression *jcomp) | ||
1020 | { | 909 | { |
1021 | struct sd *sd = (struct sd *) gspca_dev; | 910 | struct sd *sd = (struct sd *)gspca_dev; |
1022 | 911 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | |
1023 | memset(jcomp, 0, sizeof *jcomp); | 912 | |
1024 | jcomp->quality = sd->quality; | 913 | gspca_dev->vdev.ctrl_handler = hdl; |
1025 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 914 | v4l2_ctrl_handler_init(hdl, 3); |
1026 | | V4L2_JPEG_MARKER_DQT; | 915 | sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
916 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4); | ||
917 | sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
918 | V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c); | ||
919 | sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
920 | V4L2_CID_SATURATION, 0, 7, 1, 3); | ||
921 | if (hdl->error) { | ||
922 | pr_err("Could not initialize controls\n"); | ||
923 | return hdl->error; | ||
924 | } | ||
1027 | return 0; | 925 | return 0; |
1028 | } | 926 | } |
1029 | 927 | ||
1030 | /* sub-driver description */ | 928 | /* sub-driver description */ |
1031 | static const struct sd_desc sd_desc = { | 929 | static const struct sd_desc sd_desc = { |
1032 | .name = MODULE_NAME, | 930 | .name = MODULE_NAME, |
1033 | .ctrls = sd_ctrls, | ||
1034 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1035 | .config = sd_config, | 931 | .config = sd_config, |
1036 | .init = sd_init, | 932 | .init = sd_init, |
933 | .init_controls = sd_init_controls, | ||
1037 | .start = sd_start, | 934 | .start = sd_start, |
1038 | .stop0 = sd_stop0, | 935 | .stop0 = sd_stop0, |
1039 | .pkt_scan = sd_pkt_scan, | 936 | .pkt_scan = sd_pkt_scan, |
1040 | .get_jcomp = sd_get_jcomp, | ||
1041 | .set_jcomp = sd_set_jcomp, | ||
1042 | }; | 937 | }; |
1043 | 938 | ||
1044 | /* -- module initialisation -- */ | 939 | /* -- module initialisation -- */ |
@@ -1064,6 +959,7 @@ static struct usb_driver sd_driver = { | |||
1064 | #ifdef CONFIG_PM | 959 | #ifdef CONFIG_PM |
1065 | .suspend = gspca_suspend, | 960 | .suspend = gspca_suspend, |
1066 | .resume = gspca_resume, | 961 | .resume = gspca_resume, |
962 | .reset_resume = gspca_resume, | ||
1067 | #endif | 963 | #endif |
1068 | }; | 964 | }; |
1069 | 965 | ||
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c index 8f33bbd091ad..2499a881d9a3 100644 --- a/drivers/media/video/gspca/cpia1.c +++ b/drivers/media/video/gspca/cpia1.c | |||
@@ -225,6 +225,15 @@ MODULE_LICENSE("GPL"); | |||
225 | #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \ | 225 | #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \ |
226 | sd->params.version.firmwareRevision == (y)) | 226 | sd->params.version.firmwareRevision == (y)) |
227 | 227 | ||
228 | #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000) | ||
229 | #define BRIGHTNESS_DEF 50 | ||
230 | #define CONTRAST_DEF 48 | ||
231 | #define SATURATION_DEF 50 | ||
232 | #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ | ||
233 | #define ILLUMINATORS_1_DEF 0 | ||
234 | #define ILLUMINATORS_2_DEF 0 | ||
235 | #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY | ||
236 | |||
228 | /* Developer's Guide Table 5 p 3-34 | 237 | /* Developer's Guide Table 5 p 3-34 |
229 | * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/ | 238 | * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/ |
230 | static u8 flicker_jumps[2][2][4] = | 239 | static u8 flicker_jumps[2][2][4] = |
@@ -360,135 +369,9 @@ struct sd { | |||
360 | atomic_t fps; | 369 | atomic_t fps; |
361 | int exposure_count; | 370 | int exposure_count; |
362 | u8 exposure_status; | 371 | u8 exposure_status; |
372 | struct v4l2_ctrl *freq; | ||
363 | u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */ | 373 | u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */ |
364 | u8 first_frame; | 374 | u8 first_frame; |
365 | u8 freq; | ||
366 | }; | ||
367 | |||
368 | /* V4L2 controls supported by the driver */ | ||
369 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
370 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
371 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
372 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
373 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); | ||
374 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); | ||
375 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
376 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
377 | static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val); | ||
378 | static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val); | ||
379 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val); | ||
380 | static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val); | ||
381 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val); | ||
382 | static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val); | ||
383 | |||
384 | static const struct ctrl sd_ctrls[] = { | ||
385 | { | ||
386 | #define BRIGHTNESS_IDX 0 | ||
387 | { | ||
388 | .id = V4L2_CID_BRIGHTNESS, | ||
389 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
390 | .name = "Brightness", | ||
391 | .minimum = 0, | ||
392 | .maximum = 100, | ||
393 | .step = 1, | ||
394 | #define BRIGHTNESS_DEF 50 | ||
395 | .default_value = BRIGHTNESS_DEF, | ||
396 | .flags = 0, | ||
397 | }, | ||
398 | .set = sd_setbrightness, | ||
399 | .get = sd_getbrightness, | ||
400 | }, | ||
401 | #define CONTRAST_IDX 1 | ||
402 | { | ||
403 | { | ||
404 | .id = V4L2_CID_CONTRAST, | ||
405 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
406 | .name = "Contrast", | ||
407 | .minimum = 0, | ||
408 | .maximum = 96, | ||
409 | .step = 8, | ||
410 | #define CONTRAST_DEF 48 | ||
411 | .default_value = CONTRAST_DEF, | ||
412 | }, | ||
413 | .set = sd_setcontrast, | ||
414 | .get = sd_getcontrast, | ||
415 | }, | ||
416 | #define SATURATION_IDX 2 | ||
417 | { | ||
418 | { | ||
419 | .id = V4L2_CID_SATURATION, | ||
420 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
421 | .name = "Saturation", | ||
422 | .minimum = 0, | ||
423 | .maximum = 100, | ||
424 | .step = 1, | ||
425 | #define SATURATION_DEF 50 | ||
426 | .default_value = SATURATION_DEF, | ||
427 | }, | ||
428 | .set = sd_setsaturation, | ||
429 | .get = sd_getsaturation, | ||
430 | }, | ||
431 | #define POWER_LINE_FREQUENCY_IDX 3 | ||
432 | { | ||
433 | { | ||
434 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
435 | .type = V4L2_CTRL_TYPE_MENU, | ||
436 | .name = "Light frequency filter", | ||
437 | .minimum = 0, | ||
438 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
439 | .step = 1, | ||
440 | #define FREQ_DEF 1 | ||
441 | .default_value = FREQ_DEF, | ||
442 | }, | ||
443 | .set = sd_setfreq, | ||
444 | .get = sd_getfreq, | ||
445 | }, | ||
446 | #define ILLUMINATORS_1_IDX 4 | ||
447 | { | ||
448 | { | ||
449 | .id = V4L2_CID_ILLUMINATORS_1, | ||
450 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
451 | .name = "Illuminator 1", | ||
452 | .minimum = 0, | ||
453 | .maximum = 1, | ||
454 | .step = 1, | ||
455 | #define ILLUMINATORS_1_DEF 0 | ||
456 | .default_value = ILLUMINATORS_1_DEF, | ||
457 | }, | ||
458 | .set = sd_setilluminator1, | ||
459 | .get = sd_getilluminator1, | ||
460 | }, | ||
461 | #define ILLUMINATORS_2_IDX 5 | ||
462 | { | ||
463 | { | ||
464 | .id = V4L2_CID_ILLUMINATORS_2, | ||
465 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
466 | .name = "Illuminator 2", | ||
467 | .minimum = 0, | ||
468 | .maximum = 1, | ||
469 | .step = 1, | ||
470 | #define ILLUMINATORS_2_DEF 0 | ||
471 | .default_value = ILLUMINATORS_2_DEF, | ||
472 | }, | ||
473 | .set = sd_setilluminator2, | ||
474 | .get = sd_getilluminator2, | ||
475 | }, | ||
476 | #define COMP_TARGET_IDX 6 | ||
477 | { | ||
478 | { | ||
479 | #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE | ||
480 | .id = V4L2_CID_COMP_TARGET, | ||
481 | .type = V4L2_CTRL_TYPE_MENU, | ||
482 | .name = "Compression Target", | ||
483 | .minimum = 0, | ||
484 | .maximum = 1, | ||
485 | .step = 1, | ||
486 | #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY | ||
487 | .default_value = COMP_TARGET_DEF, | ||
488 | }, | ||
489 | .set = sd_setcomptarget, | ||
490 | .get = sd_getcomptarget, | ||
491 | }, | ||
492 | }; | 375 | }; |
493 | 376 | ||
494 | static const struct v4l2_pix_format mode[] = { | 377 | static const struct v4l2_pix_format mode[] = { |
@@ -770,15 +653,6 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) | |||
770 | params->apcor.gain2 = 0x16; | 653 | params->apcor.gain2 = 0x16; |
771 | params->apcor.gain4 = 0x24; | 654 | params->apcor.gain4 = 0x24; |
772 | params->apcor.gain8 = 0x34; | 655 | params->apcor.gain8 = 0x34; |
773 | params->flickerControl.flickerMode = 0; | ||
774 | params->flickerControl.disabled = 1; | ||
775 | |||
776 | params->flickerControl.coarseJump = | ||
777 | flicker_jumps[sd->mainsFreq] | ||
778 | [params->sensorFps.baserate] | ||
779 | [params->sensorFps.divisor]; | ||
780 | params->flickerControl.allowableOverExposure = | ||
781 | find_over_exposure(params->colourParams.brightness); | ||
782 | params->vlOffset.gain1 = 20; | 656 | params->vlOffset.gain1 = 20; |
783 | params->vlOffset.gain2 = 24; | 657 | params->vlOffset.gain2 = 24; |
784 | params->vlOffset.gain4 = 26; | 658 | params->vlOffset.gain4 = 26; |
@@ -798,6 +672,15 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) | |||
798 | params->sensorFps.divisor = 1; | 672 | params->sensorFps.divisor = 1; |
799 | params->sensorFps.baserate = 1; | 673 | params->sensorFps.baserate = 1; |
800 | 674 | ||
675 | params->flickerControl.flickerMode = 0; | ||
676 | params->flickerControl.disabled = 1; | ||
677 | params->flickerControl.coarseJump = | ||
678 | flicker_jumps[sd->mainsFreq] | ||
679 | [params->sensorFps.baserate] | ||
680 | [params->sensorFps.divisor]; | ||
681 | params->flickerControl.allowableOverExposure = | ||
682 | find_over_exposure(params->colourParams.brightness); | ||
683 | |||
801 | params->yuvThreshold.yThreshold = 6; /* From windows driver */ | 684 | params->yuvThreshold.yThreshold = 6; /* From windows driver */ |
802 | params->yuvThreshold.uvThreshold = 6; /* From windows driver */ | 685 | params->yuvThreshold.uvThreshold = 6; /* From windows driver */ |
803 | 686 | ||
@@ -1110,9 +993,6 @@ static int command_setlights(struct gspca_dev *gspca_dev) | |||
1110 | struct sd *sd = (struct sd *) gspca_dev; | 993 | struct sd *sd = (struct sd *) gspca_dev; |
1111 | int ret, p1, p2; | 994 | int ret, p1, p2; |
1112 | 995 | ||
1113 | if (!sd->params.qx3.qx3_detected) | ||
1114 | return 0; | ||
1115 | |||
1116 | p1 = (sd->params.qx3.bottomlight == 0) << 1; | 996 | p1 = (sd->params.qx3.bottomlight == 0) << 1; |
1117 | p2 = (sd->params.qx3.toplight == 0) << 3; | 997 | p2 = (sd->params.qx3.toplight == 0) << 3; |
1118 | 998 | ||
@@ -1551,8 +1431,10 @@ static void restart_flicker(struct gspca_dev *gspca_dev) | |||
1551 | static int sd_config(struct gspca_dev *gspca_dev, | 1431 | static int sd_config(struct gspca_dev *gspca_dev, |
1552 | const struct usb_device_id *id) | 1432 | const struct usb_device_id *id) |
1553 | { | 1433 | { |
1434 | struct sd *sd = (struct sd *) gspca_dev; | ||
1554 | struct cam *cam; | 1435 | struct cam *cam; |
1555 | 1436 | ||
1437 | sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; | ||
1556 | reset_camera_params(gspca_dev); | 1438 | reset_camera_params(gspca_dev); |
1557 | 1439 | ||
1558 | PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)", | 1440 | PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)", |
@@ -1562,8 +1444,25 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1562 | cam->cam_mode = mode; | 1444 | cam->cam_mode = mode; |
1563 | cam->nmodes = ARRAY_SIZE(mode); | 1445 | cam->nmodes = ARRAY_SIZE(mode); |
1564 | 1446 | ||
1565 | sd_setfreq(gspca_dev, FREQ_DEF); | 1447 | goto_low_power(gspca_dev); |
1448 | /* Check the firmware version. */ | ||
1449 | sd->params.version.firmwareVersion = 0; | ||
1450 | get_version_information(gspca_dev); | ||
1451 | if (sd->params.version.firmwareVersion != 1) { | ||
1452 | PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", | ||
1453 | sd->params.version.firmwareVersion); | ||
1454 | return -ENODEV; | ||
1455 | } | ||
1566 | 1456 | ||
1457 | /* A bug in firmware 1-02 limits gainMode to 2 */ | ||
1458 | if (sd->params.version.firmwareRevision <= 2 && | ||
1459 | sd->params.exposure.gainMode > 2) { | ||
1460 | sd->params.exposure.gainMode = 2; | ||
1461 | } | ||
1462 | |||
1463 | /* set QX3 detected flag */ | ||
1464 | sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && | ||
1465 | sd->params.pnpID.product == 0x0001); | ||
1567 | return 0; | 1466 | return 0; |
1568 | } | 1467 | } |
1569 | 1468 | ||
@@ -1602,21 +1501,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1602 | /* Check the firmware version. */ | 1501 | /* Check the firmware version. */ |
1603 | sd->params.version.firmwareVersion = 0; | 1502 | sd->params.version.firmwareVersion = 0; |
1604 | get_version_information(gspca_dev); | 1503 | get_version_information(gspca_dev); |
1605 | if (sd->params.version.firmwareVersion != 1) { | ||
1606 | PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", | ||
1607 | sd->params.version.firmwareVersion); | ||
1608 | return -ENODEV; | ||
1609 | } | ||
1610 | |||
1611 | /* A bug in firmware 1-02 limits gainMode to 2 */ | ||
1612 | if (sd->params.version.firmwareRevision <= 2 && | ||
1613 | sd->params.exposure.gainMode > 2) { | ||
1614 | sd->params.exposure.gainMode = 2; | ||
1615 | } | ||
1616 | |||
1617 | /* set QX3 detected flag */ | ||
1618 | sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && | ||
1619 | sd->params.pnpID.product == 0x0001); | ||
1620 | 1504 | ||
1621 | /* The fatal error checking should be done after | 1505 | /* The fatal error checking should be done after |
1622 | * the camera powers up (developer's guide p 3-38) */ | 1506 | * the camera powers up (developer's guide p 3-38) */ |
@@ -1785,9 +1669,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1785 | or disable the illuminator controls, if this isn't a QX3 */ | 1669 | or disable the illuminator controls, if this isn't a QX3 */ |
1786 | if (sd->params.qx3.qx3_detected) | 1670 | if (sd->params.qx3.qx3_detected) |
1787 | command_setlights(gspca_dev); | 1671 | command_setlights(gspca_dev); |
1788 | else | ||
1789 | gspca_dev->ctrl_dis |= | ||
1790 | ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX)); | ||
1791 | 1672 | ||
1792 | sd_stopN(gspca_dev); | 1673 | sd_stopN(gspca_dev); |
1793 | 1674 | ||
@@ -1871,235 +1752,123 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) | |||
1871 | do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0); | 1752 | do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0); |
1872 | } | 1753 | } |
1873 | 1754 | ||
1874 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1755 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1875 | { | ||
1876 | struct sd *sd = (struct sd *) gspca_dev; | ||
1877 | int ret; | ||
1878 | |||
1879 | sd->params.colourParams.brightness = val; | ||
1880 | sd->params.flickerControl.allowableOverExposure = | ||
1881 | find_over_exposure(sd->params.colourParams.brightness); | ||
1882 | if (gspca_dev->streaming) { | ||
1883 | ret = command_setcolourparams(gspca_dev); | ||
1884 | if (ret) | ||
1885 | return ret; | ||
1886 | return command_setflickerctrl(gspca_dev); | ||
1887 | } | ||
1888 | return 0; | ||
1889 | } | ||
1890 | |||
1891 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1892 | { | 1756 | { |
1893 | struct sd *sd = (struct sd *) gspca_dev; | 1757 | struct gspca_dev *gspca_dev = |
1894 | 1758 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
1895 | *val = sd->params.colourParams.brightness; | 1759 | struct sd *sd = (struct sd *)gspca_dev; |
1896 | return 0; | ||
1897 | } | ||
1898 | 1760 | ||
1899 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | 1761 | gspca_dev->usb_err = 0; |
1900 | { | ||
1901 | struct sd *sd = (struct sd *) gspca_dev; | ||
1902 | 1762 | ||
1903 | sd->params.colourParams.contrast = val; | 1763 | if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) |
1904 | if (gspca_dev->streaming) | 1764 | return 0; |
1905 | return command_setcolourparams(gspca_dev); | ||
1906 | |||
1907 | return 0; | ||
1908 | } | ||
1909 | |||
1910 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1911 | { | ||
1912 | struct sd *sd = (struct sd *) gspca_dev; | ||
1913 | |||
1914 | *val = sd->params.colourParams.contrast; | ||
1915 | return 0; | ||
1916 | } | ||
1917 | |||
1918 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) | ||
1919 | { | ||
1920 | struct sd *sd = (struct sd *) gspca_dev; | ||
1921 | |||
1922 | sd->params.colourParams.saturation = val; | ||
1923 | if (gspca_dev->streaming) | ||
1924 | return command_setcolourparams(gspca_dev); | ||
1925 | |||
1926 | return 0; | ||
1927 | } | ||
1928 | |||
1929 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) | ||
1930 | { | ||
1931 | struct sd *sd = (struct sd *) gspca_dev; | ||
1932 | |||
1933 | *val = sd->params.colourParams.saturation; | ||
1934 | return 0; | ||
1935 | } | ||
1936 | |||
1937 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
1938 | { | ||
1939 | struct sd *sd = (struct sd *) gspca_dev; | ||
1940 | int on; | ||
1941 | 1765 | ||
1942 | switch (val) { | 1766 | switch (ctrl->id) { |
1943 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | 1767 | case V4L2_CID_BRIGHTNESS: |
1944 | on = 0; | 1768 | sd->params.colourParams.brightness = ctrl->val; |
1769 | sd->params.flickerControl.allowableOverExposure = | ||
1770 | find_over_exposure(sd->params.colourParams.brightness); | ||
1771 | gspca_dev->usb_err = command_setcolourparams(gspca_dev); | ||
1772 | if (!gspca_dev->usb_err) | ||
1773 | gspca_dev->usb_err = command_setflickerctrl(gspca_dev); | ||
1945 | break; | 1774 | break; |
1946 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | 1775 | case V4L2_CID_CONTRAST: |
1947 | on = 1; | 1776 | sd->params.colourParams.contrast = ctrl->val; |
1948 | sd->mainsFreq = 0; | 1777 | gspca_dev->usb_err = command_setcolourparams(gspca_dev); |
1949 | break; | 1778 | break; |
1950 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | 1779 | case V4L2_CID_SATURATION: |
1951 | on = 1; | 1780 | sd->params.colourParams.saturation = ctrl->val; |
1952 | sd->mainsFreq = 1; | 1781 | gspca_dev->usb_err = command_setcolourparams(gspca_dev); |
1953 | break; | 1782 | break; |
1954 | default: | 1783 | case V4L2_CID_POWER_LINE_FREQUENCY: |
1955 | return -EINVAL; | 1784 | sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; |
1956 | } | 1785 | sd->params.flickerControl.coarseJump = |
1957 | 1786 | flicker_jumps[sd->mainsFreq] | |
1958 | sd->freq = val; | 1787 | [sd->params.sensorFps.baserate] |
1959 | sd->params.flickerControl.coarseJump = | 1788 | [sd->params.sensorFps.divisor]; |
1960 | flicker_jumps[sd->mainsFreq] | 1789 | |
1961 | [sd->params.sensorFps.baserate] | 1790 | gspca_dev->usb_err = set_flicker(gspca_dev, |
1962 | [sd->params.sensorFps.divisor]; | 1791 | ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, |
1963 | 1792 | gspca_dev->streaming); | |
1964 | return set_flicker(gspca_dev, on, gspca_dev->streaming); | ||
1965 | } | ||
1966 | |||
1967 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
1968 | { | ||
1969 | struct sd *sd = (struct sd *) gspca_dev; | ||
1970 | |||
1971 | *val = sd->freq; | ||
1972 | return 0; | ||
1973 | } | ||
1974 | |||
1975 | static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val) | ||
1976 | { | ||
1977 | struct sd *sd = (struct sd *) gspca_dev; | ||
1978 | |||
1979 | sd->params.compressionTarget.frTargeting = val; | ||
1980 | if (gspca_dev->streaming) | ||
1981 | return command_setcompressiontarget(gspca_dev); | ||
1982 | |||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val) | ||
1987 | { | ||
1988 | struct sd *sd = (struct sd *) gspca_dev; | ||
1989 | |||
1990 | *val = sd->params.compressionTarget.frTargeting; | ||
1991 | return 0; | ||
1992 | } | ||
1993 | |||
1994 | static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n) | ||
1995 | { | ||
1996 | struct sd *sd = (struct sd *) gspca_dev; | ||
1997 | int ret; | ||
1998 | |||
1999 | if (!sd->params.qx3.qx3_detected) | ||
2000 | return -EINVAL; | ||
2001 | |||
2002 | switch (n) { | ||
2003 | case 1: | ||
2004 | sd->params.qx3.bottomlight = val ? 1 : 0; | ||
2005 | break; | 1793 | break; |
2006 | case 2: | 1794 | case V4L2_CID_ILLUMINATORS_1: |
2007 | sd->params.qx3.toplight = val ? 1 : 0; | 1795 | sd->params.qx3.bottomlight = ctrl->val; |
1796 | gspca_dev->usb_err = command_setlights(gspca_dev); | ||
2008 | break; | 1797 | break; |
2009 | default: | 1798 | case V4L2_CID_ILLUMINATORS_2: |
2010 | return -EINVAL; | 1799 | sd->params.qx3.toplight = ctrl->val; |
2011 | } | 1800 | gspca_dev->usb_err = command_setlights(gspca_dev); |
2012 | |||
2013 | ret = command_setlights(gspca_dev); | ||
2014 | if (ret && ret != -EINVAL) | ||
2015 | ret = -EBUSY; | ||
2016 | |||
2017 | return ret; | ||
2018 | } | ||
2019 | |||
2020 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val) | ||
2021 | { | ||
2022 | return sd_setilluminator(gspca_dev, val, 1); | ||
2023 | } | ||
2024 | |||
2025 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val) | ||
2026 | { | ||
2027 | return sd_setilluminator(gspca_dev, val, 2); | ||
2028 | } | ||
2029 | |||
2030 | static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n) | ||
2031 | { | ||
2032 | struct sd *sd = (struct sd *) gspca_dev; | ||
2033 | |||
2034 | if (!sd->params.qx3.qx3_detected) | ||
2035 | return -EINVAL; | ||
2036 | |||
2037 | switch (n) { | ||
2038 | case 1: | ||
2039 | *val = sd->params.qx3.bottomlight; | ||
2040 | break; | 1801 | break; |
2041 | case 2: | 1802 | case CPIA1_CID_COMP_TARGET: |
2042 | *val = sd->params.qx3.toplight; | 1803 | sd->params.compressionTarget.frTargeting = ctrl->val; |
1804 | gspca_dev->usb_err = command_setcompressiontarget(gspca_dev); | ||
2043 | break; | 1805 | break; |
2044 | default: | ||
2045 | return -EINVAL; | ||
2046 | } | 1806 | } |
2047 | return 0; | 1807 | return gspca_dev->usb_err; |
2048 | } | 1808 | } |
2049 | 1809 | ||
2050 | static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val) | 1810 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
2051 | { | 1811 | .s_ctrl = sd_s_ctrl, |
2052 | return sd_getilluminator(gspca_dev, val, 1); | 1812 | }; |
2053 | } | ||
2054 | 1813 | ||
2055 | static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val) | 1814 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
2056 | { | 1815 | { |
2057 | return sd_getilluminator(gspca_dev, val, 2); | 1816 | struct sd *sd = (struct sd *)gspca_dev; |
2058 | } | 1817 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
1818 | static const char * const comp_target_menu[] = { | ||
1819 | "Quality", | ||
1820 | "Framerate", | ||
1821 | NULL | ||
1822 | }; | ||
1823 | static const struct v4l2_ctrl_config comp_target = { | ||
1824 | .ops = &sd_ctrl_ops, | ||
1825 | .id = CPIA1_CID_COMP_TARGET, | ||
1826 | .type = V4L2_CTRL_TYPE_MENU, | ||
1827 | .name = "Compression Target", | ||
1828 | .qmenu = comp_target_menu, | ||
1829 | .max = 1, | ||
1830 | .def = COMP_TARGET_DEF, | ||
1831 | }; | ||
1832 | |||
1833 | gspca_dev->vdev.ctrl_handler = hdl; | ||
1834 | v4l2_ctrl_handler_init(hdl, 7); | ||
1835 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1836 | V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF); | ||
1837 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1838 | V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF); | ||
1839 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1840 | V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF); | ||
1841 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
1842 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
1843 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, | ||
1844 | FREQ_DEF); | ||
1845 | if (sd->params.qx3.qx3_detected) { | ||
1846 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1847 | V4L2_CID_ILLUMINATORS_1, 0, 1, 1, | ||
1848 | ILLUMINATORS_1_DEF); | ||
1849 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1850 | V4L2_CID_ILLUMINATORS_2, 0, 1, 1, | ||
1851 | ILLUMINATORS_2_DEF); | ||
1852 | } | ||
1853 | v4l2_ctrl_new_custom(hdl, &comp_target, NULL); | ||
2059 | 1854 | ||
2060 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 1855 | if (hdl->error) { |
2061 | struct v4l2_querymenu *menu) | 1856 | pr_err("Could not initialize controls\n"); |
2062 | { | 1857 | return hdl->error; |
2063 | switch (menu->id) { | ||
2064 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
2065 | switch (menu->index) { | ||
2066 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
2067 | strcpy((char *) menu->name, "NoFliker"); | ||
2068 | return 0; | ||
2069 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
2070 | strcpy((char *) menu->name, "50 Hz"); | ||
2071 | return 0; | ||
2072 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
2073 | strcpy((char *) menu->name, "60 Hz"); | ||
2074 | return 0; | ||
2075 | } | ||
2076 | break; | ||
2077 | case V4L2_CID_COMP_TARGET: | ||
2078 | switch (menu->index) { | ||
2079 | case CPIA_COMPRESSION_TARGET_QUALITY: | ||
2080 | strcpy((char *) menu->name, "Quality"); | ||
2081 | return 0; | ||
2082 | case CPIA_COMPRESSION_TARGET_FRAMERATE: | ||
2083 | strcpy((char *) menu->name, "Framerate"); | ||
2084 | return 0; | ||
2085 | } | ||
2086 | break; | ||
2087 | } | 1858 | } |
2088 | return -EINVAL; | 1859 | return 0; |
2089 | } | 1860 | } |
2090 | 1861 | ||
2091 | /* sub-driver description */ | 1862 | /* sub-driver description */ |
2092 | static const struct sd_desc sd_desc = { | 1863 | static const struct sd_desc sd_desc = { |
2093 | .name = MODULE_NAME, | 1864 | .name = MODULE_NAME, |
2094 | .ctrls = sd_ctrls, | ||
2095 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2096 | .config = sd_config, | 1865 | .config = sd_config, |
2097 | .init = sd_init, | 1866 | .init = sd_init, |
1867 | .init_controls = sd_init_controls, | ||
2098 | .start = sd_start, | 1868 | .start = sd_start, |
2099 | .stopN = sd_stopN, | 1869 | .stopN = sd_stopN, |
2100 | .dq_callback = sd_dq_callback, | 1870 | .dq_callback = sd_dq_callback, |
2101 | .pkt_scan = sd_pkt_scan, | 1871 | .pkt_scan = sd_pkt_scan, |
2102 | .querymenu = sd_querymenu, | ||
2103 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 1872 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2104 | .other_input = 1, | 1873 | .other_input = 1, |
2105 | #endif | 1874 | #endif |
@@ -2129,6 +1898,7 @@ static struct usb_driver sd_driver = { | |||
2129 | #ifdef CONFIG_PM | 1898 | #ifdef CONFIG_PM |
2130 | .suspend = gspca_suspend, | 1899 | .suspend = gspca_suspend, |
2131 | .resume = gspca_resume, | 1900 | .resume = gspca_resume, |
1901 | .reset_resume = gspca_resume, | ||
2132 | #endif | 1902 | #endif |
2133 | }; | 1903 | }; |
2134 | 1904 | ||
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 81a4adbd9f7c..38f68e11c3a2 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | unsigned char brightness; | ||
36 | unsigned char contrast; | ||
37 | unsigned char colors; | ||
38 | unsigned char autogain; | 35 | unsigned char autogain; |
39 | 36 | ||
40 | char sensor; | 37 | char sensor; |
@@ -44,76 +41,6 @@ struct sd { | |||
44 | #define AG_CNT_START 13 | 41 | #define AG_CNT_START 13 |
45 | }; | 42 | }; |
46 | 43 | ||
47 | /* V4L2 controls supported by the driver */ | ||
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
50 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | |||
57 | static const struct ctrl sd_ctrls[] = { | ||
58 | { | ||
59 | { | ||
60 | .id = V4L2_CID_BRIGHTNESS, | ||
61 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
62 | .name = "Brightness", | ||
63 | .minimum = 1, | ||
64 | .maximum = 127, | ||
65 | .step = 1, | ||
66 | #define BRIGHTNESS_DEF 63 | ||
67 | .default_value = BRIGHTNESS_DEF, | ||
68 | }, | ||
69 | .set = sd_setbrightness, | ||
70 | .get = sd_getbrightness, | ||
71 | }, | ||
72 | { | ||
73 | { | ||
74 | .id = V4L2_CID_CONTRAST, | ||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
76 | .name = "Contrast", | ||
77 | .minimum = 0, | ||
78 | .maximum = 255, | ||
79 | .step = 1, | ||
80 | #define CONTRAST_DEF 127 | ||
81 | .default_value = CONTRAST_DEF, | ||
82 | }, | ||
83 | .set = sd_setcontrast, | ||
84 | .get = sd_getcontrast, | ||
85 | }, | ||
86 | #define COLOR_IDX 2 | ||
87 | { | ||
88 | { | ||
89 | .id = V4L2_CID_SATURATION, | ||
90 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
91 | .name = "Color", | ||
92 | .minimum = 0, | ||
93 | .maximum = 15, | ||
94 | .step = 1, | ||
95 | #define COLOR_DEF 7 | ||
96 | .default_value = COLOR_DEF, | ||
97 | }, | ||
98 | .set = sd_setcolors, | ||
99 | .get = sd_getcolors, | ||
100 | }, | ||
101 | { | ||
102 | { | ||
103 | .id = V4L2_CID_AUTOGAIN, | ||
104 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
105 | .name = "Auto Gain", | ||
106 | .minimum = 0, | ||
107 | .maximum = 1, | ||
108 | .step = 1, | ||
109 | #define AUTOGAIN_DEF 1 | ||
110 | .default_value = AUTOGAIN_DEF, | ||
111 | }, | ||
112 | .set = sd_setautogain, | ||
113 | .get = sd_getautogain, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static const struct v4l2_pix_format vga_mode[] = { | 44 | static const struct v4l2_pix_format vga_mode[] = { |
118 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 45 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
119 | .bytesperline = 320, | 46 | .bytesperline = 320, |
@@ -464,36 +391,31 @@ static void Et_init2(struct gspca_dev *gspca_dev) | |||
464 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ | 391 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ |
465 | } | 392 | } |
466 | 393 | ||
467 | static void setbrightness(struct gspca_dev *gspca_dev) | 394 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
468 | { | 395 | { |
469 | struct sd *sd = (struct sd *) gspca_dev; | ||
470 | int i; | 396 | int i; |
471 | __u8 brightness = sd->brightness; | ||
472 | 397 | ||
473 | for (i = 0; i < 4; i++) | 398 | for (i = 0; i < 4; i++) |
474 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | 399 | reg_w_val(gspca_dev, ET_O_RED + i, val); |
475 | } | 400 | } |
476 | 401 | ||
477 | static void setcontrast(struct gspca_dev *gspca_dev) | 402 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
478 | { | 403 | { |
479 | struct sd *sd = (struct sd *) gspca_dev; | ||
480 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | 404 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; |
481 | __u8 contrast = sd->contrast; | ||
482 | 405 | ||
483 | memset(RGBG, contrast, sizeof(RGBG) - 2); | 406 | memset(RGBG, val, sizeof(RGBG) - 2); |
484 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | 407 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); |
485 | } | 408 | } |
486 | 409 | ||
487 | static void setcolors(struct gspca_dev *gspca_dev) | 410 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
488 | { | 411 | { |
489 | struct sd *sd = (struct sd *) gspca_dev; | 412 | struct sd *sd = (struct sd *) gspca_dev; |
490 | __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; | 413 | __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; |
491 | __u8 i2cflags = 0x01; | 414 | __u8 i2cflags = 0x01; |
492 | /* __u8 green = 0; */ | 415 | /* __u8 green = 0; */ |
493 | __u8 colors = sd->colors; | ||
494 | 416 | ||
495 | I2cc[3] = colors; /* red */ | 417 | I2cc[3] = val; /* red */ |
496 | I2cc[0] = 15 - colors; /* blue */ | 418 | I2cc[0] = 15 - val; /* blue */ |
497 | /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ | 419 | /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ |
498 | /* I2cc[1] = I2cc[2] = green; */ | 420 | /* I2cc[1] = I2cc[2] = green; */ |
499 | if (sd->sensor == SENSOR_PAS106) { | 421 | if (sd->sensor == SENSOR_PAS106) { |
@@ -504,15 +426,16 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
504 | I2cc[3], I2cc[0], green); */ | 426 | I2cc[3], I2cc[0], green); */ |
505 | } | 427 | } |
506 | 428 | ||
507 | static void getcolors(struct gspca_dev *gspca_dev) | 429 | static s32 getcolors(struct gspca_dev *gspca_dev) |
508 | { | 430 | { |
509 | struct sd *sd = (struct sd *) gspca_dev; | 431 | struct sd *sd = (struct sd *) gspca_dev; |
510 | 432 | ||
511 | if (sd->sensor == SENSOR_PAS106) { | 433 | if (sd->sensor == SENSOR_PAS106) { |
512 | /* i2c_r(gspca_dev, PAS106_REG9); * blue */ | 434 | /* i2c_r(gspca_dev, PAS106_REG9); * blue */ |
513 | i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */ | 435 | i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */ |
514 | sd->colors = gspca_dev->usb_buf[0] & 0x0f; | 436 | return gspca_dev->usb_buf[0] & 0x0f; |
515 | } | 437 | } |
438 | return 0; | ||
516 | } | 439 | } |
517 | 440 | ||
518 | static void setautogain(struct gspca_dev *gspca_dev) | 441 | static void setautogain(struct gspca_dev *gspca_dev) |
@@ -622,8 +545,7 @@ static void Et_init1(struct gspca_dev *gspca_dev) | |||
622 | i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1); | 545 | i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1); |
623 | /* now set by fifo the whole colors setting */ | 546 | /* now set by fifo the whole colors setting */ |
624 | reg_w(gspca_dev, ET_G_RED, GainRGBG, 6); | 547 | reg_w(gspca_dev, ET_G_RED, GainRGBG, 6); |
625 | getcolors(gspca_dev); | 548 | setcolors(gspca_dev, getcolors(gspca_dev)); |
626 | setcolors(gspca_dev); | ||
627 | } | 549 | } |
628 | 550 | ||
629 | /* this function is called at probe time */ | 551 | /* this function is called at probe time */ |
@@ -641,12 +563,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
641 | } else { | 563 | } else { |
642 | cam->cam_mode = vga_mode; | 564 | cam->cam_mode = vga_mode; |
643 | cam->nmodes = ARRAY_SIZE(vga_mode); | 565 | cam->nmodes = ARRAY_SIZE(vga_mode); |
644 | gspca_dev->ctrl_dis = (1 << COLOR_IDX); | ||
645 | } | 566 | } |
646 | sd->brightness = BRIGHTNESS_DEF; | ||
647 | sd->contrast = CONTRAST_DEF; | ||
648 | sd->colors = COLOR_DEF; | ||
649 | sd->autogain = AUTOGAIN_DEF; | ||
650 | sd->ag_cnt = -1; | 567 | sd->ag_cnt = -1; |
651 | return 0; | 568 | return 0; |
652 | } | 569 | } |
@@ -780,85 +697,68 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
780 | } | 697 | } |
781 | } | 698 | } |
782 | 699 | ||
783 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 700 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
784 | { | ||
785 | struct sd *sd = (struct sd *) gspca_dev; | ||
786 | |||
787 | sd->brightness = val; | ||
788 | if (gspca_dev->streaming) | ||
789 | setbrightness(gspca_dev); | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
794 | { | ||
795 | struct sd *sd = (struct sd *) gspca_dev; | ||
796 | |||
797 | *val = sd->brightness; | ||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
802 | { | 701 | { |
803 | struct sd *sd = (struct sd *) gspca_dev; | 702 | struct gspca_dev *gspca_dev = |
804 | 703 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
805 | sd->contrast = val; | 704 | struct sd *sd = (struct sd *)gspca_dev; |
806 | if (gspca_dev->streaming) | 705 | |
807 | setcontrast(gspca_dev); | 706 | gspca_dev->usb_err = 0; |
808 | return 0; | 707 | |
809 | } | 708 | if (!gspca_dev->streaming) |
810 | 709 | return 0; | |
811 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 710 | |
812 | { | 711 | switch (ctrl->id) { |
813 | struct sd *sd = (struct sd *) gspca_dev; | 712 | case V4L2_CID_BRIGHTNESS: |
814 | 713 | setbrightness(gspca_dev, ctrl->val); | |
815 | *val = sd->contrast; | 714 | break; |
816 | return 0; | 715 | case V4L2_CID_CONTRAST: |
817 | } | 716 | setcontrast(gspca_dev, ctrl->val); |
818 | 717 | break; | |
819 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | 718 | case V4L2_CID_SATURATION: |
820 | { | 719 | setcolors(gspca_dev, ctrl->val); |
821 | struct sd *sd = (struct sd *) gspca_dev; | 720 | break; |
822 | 721 | case V4L2_CID_AUTOGAIN: | |
823 | sd->colors = val; | 722 | sd->autogain = ctrl->val; |
824 | if (gspca_dev->streaming) | ||
825 | setcolors(gspca_dev); | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
830 | { | ||
831 | struct sd *sd = (struct sd *) gspca_dev; | ||
832 | |||
833 | *val = sd->colors; | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
838 | { | ||
839 | struct sd *sd = (struct sd *) gspca_dev; | ||
840 | |||
841 | sd->autogain = val; | ||
842 | if (gspca_dev->streaming) | ||
843 | setautogain(gspca_dev); | 723 | setautogain(gspca_dev); |
844 | return 0; | 724 | break; |
725 | } | ||
726 | return gspca_dev->usb_err; | ||
845 | } | 727 | } |
846 | 728 | ||
847 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | 729 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
848 | { | 730 | .s_ctrl = sd_s_ctrl, |
849 | struct sd *sd = (struct sd *) gspca_dev; | 731 | }; |
850 | 732 | ||
851 | *val = sd->autogain; | 733 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
734 | { | ||
735 | struct sd *sd = (struct sd *)gspca_dev; | ||
736 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
737 | |||
738 | gspca_dev->vdev.ctrl_handler = hdl; | ||
739 | v4l2_ctrl_handler_init(hdl, 4); | ||
740 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
741 | V4L2_CID_BRIGHTNESS, 1, 127, 1, 63); | ||
742 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
743 | V4L2_CID_CONTRAST, 0, 255, 1, 127); | ||
744 | if (sd->sensor == SENSOR_PAS106) | ||
745 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
746 | V4L2_CID_SATURATION, 0, 15, 1, 7); | ||
747 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
748 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
749 | if (hdl->error) { | ||
750 | pr_err("Could not initialize controls\n"); | ||
751 | return hdl->error; | ||
752 | } | ||
852 | return 0; | 753 | return 0; |
853 | } | 754 | } |
854 | 755 | ||
855 | /* sub-driver description */ | 756 | /* sub-driver description */ |
856 | static const struct sd_desc sd_desc = { | 757 | static const struct sd_desc sd_desc = { |
857 | .name = MODULE_NAME, | 758 | .name = MODULE_NAME, |
858 | .ctrls = sd_ctrls, | ||
859 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
860 | .config = sd_config, | 759 | .config = sd_config, |
861 | .init = sd_init, | 760 | .init = sd_init, |
761 | .init_controls = sd_init_controls, | ||
862 | .start = sd_start, | 762 | .start = sd_start, |
863 | .stopN = sd_stopN, | 763 | .stopN = sd_stopN, |
864 | .pkt_scan = sd_pkt_scan, | 764 | .pkt_scan = sd_pkt_scan, |
@@ -892,6 +792,7 @@ static struct usb_driver sd_driver = { | |||
892 | #ifdef CONFIG_PM | 792 | #ifdef CONFIG_PM |
893 | .suspend = gspca_suspend, | 793 | .suspend = gspca_suspend, |
894 | .resume = gspca_resume, | 794 | .resume = gspca_resume, |
795 | .reset_resume = gspca_resume, | ||
895 | #endif | 796 | #endif |
896 | }; | 797 | }; |
897 | 798 | ||
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 6e26c93b4656..c8f2201cc35a 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c | |||
@@ -299,6 +299,7 @@ static struct usb_driver sd_driver = { | |||
299 | #ifdef CONFIG_PM | 299 | #ifdef CONFIG_PM |
300 | .suspend = gspca_suspend, | 300 | .suspend = gspca_suspend, |
301 | .resume = gspca_resume, | 301 | .resume = gspca_resume, |
302 | .reset_resume = gspca_resume, | ||
302 | #endif | 303 | #endif |
303 | }; | 304 | }; |
304 | 305 | ||
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index c549574c1c7e..ced3b71f14e5 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c | |||
@@ -521,6 +521,7 @@ static struct usb_driver sd_driver = { | |||
521 | #ifdef CONFIG_PM | 521 | #ifdef CONFIG_PM |
522 | .suspend = gspca_suspend, | 522 | .suspend = gspca_suspend, |
523 | .resume = gspca_resume, | 523 | .resume = gspca_resume, |
524 | .reset_resume = gspca_resume, | ||
524 | #endif | 525 | #endif |
525 | }; | 526 | }; |
526 | 527 | ||
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 31721eadc597..d4e8343f5b10 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -930,6 +930,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
930 | goto out; | 930 | goto out; |
931 | } | 931 | } |
932 | gspca_dev->streaming = 1; | 932 | gspca_dev->streaming = 1; |
933 | v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); | ||
933 | 934 | ||
934 | /* some bulk transfers are started by the subdriver */ | 935 | /* some bulk transfers are started by the subdriver */ |
935 | if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0) | 936 | if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0) |
@@ -1049,12 +1050,6 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1049 | { | 1050 | { |
1050 | struct gspca_dev *gspca_dev = video_drvdata(file); | 1051 | struct gspca_dev *gspca_dev = video_drvdata(file); |
1051 | 1052 | ||
1052 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
1053 | return -ENOTTY; | ||
1054 | |||
1055 | if (!gspca_dev->sd_desc->get_register) | ||
1056 | return -ENOTTY; | ||
1057 | |||
1058 | gspca_dev->usb_err = 0; | 1053 | gspca_dev->usb_err = 0; |
1059 | return gspca_dev->sd_desc->get_register(gspca_dev, reg); | 1054 | return gspca_dev->sd_desc->get_register(gspca_dev, reg); |
1060 | } | 1055 | } |
@@ -1064,12 +1059,6 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1064 | { | 1059 | { |
1065 | struct gspca_dev *gspca_dev = video_drvdata(file); | 1060 | struct gspca_dev *gspca_dev = video_drvdata(file); |
1066 | 1061 | ||
1067 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
1068 | return -ENOTTY; | ||
1069 | |||
1070 | if (!gspca_dev->sd_desc->set_register) | ||
1071 | return -ENOTTY; | ||
1072 | |||
1073 | gspca_dev->usb_err = 0; | 1062 | gspca_dev->usb_err = 0; |
1074 | return gspca_dev->sd_desc->set_register(gspca_dev, reg); | 1063 | return gspca_dev->sd_desc->set_register(gspca_dev, reg); |
1075 | } | 1064 | } |
@@ -1080,9 +1069,6 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, | |||
1080 | { | 1069 | { |
1081 | struct gspca_dev *gspca_dev = video_drvdata(file); | 1070 | struct gspca_dev *gspca_dev = video_drvdata(file); |
1082 | 1071 | ||
1083 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
1084 | return -ENOTTY; | ||
1085 | |||
1086 | gspca_dev->usb_err = 0; | 1072 | gspca_dev->usb_err = 0; |
1087 | return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); | 1073 | return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); |
1088 | } | 1074 | } |
@@ -1136,8 +1122,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1136 | int mode; | 1122 | int mode; |
1137 | 1123 | ||
1138 | mode = gspca_dev->curr_mode; | 1124 | mode = gspca_dev->curr_mode; |
1139 | memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], | 1125 | fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; |
1140 | sizeof fmt->fmt.pix); | 1126 | /* some drivers use priv internally, zero it before giving it to |
1127 | userspace */ | ||
1128 | fmt->fmt.pix.priv = 0; | ||
1141 | return 0; | 1129 | return 0; |
1142 | } | 1130 | } |
1143 | 1131 | ||
@@ -1168,8 +1156,10 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, | |||
1168 | /* else | 1156 | /* else |
1169 | ; * no chance, return this mode */ | 1157 | ; * no chance, return this mode */ |
1170 | } | 1158 | } |
1171 | memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], | 1159 | fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; |
1172 | sizeof fmt->fmt.pix); | 1160 | /* some drivers use priv internally, zero it before giving it to |
1161 | userspace */ | ||
1162 | fmt->fmt.pix.priv = 0; | ||
1173 | return mode; /* used when s_fmt */ | 1163 | return mode; /* used when s_fmt */ |
1174 | } | 1164 | } |
1175 | 1165 | ||
@@ -1284,9 +1274,6 @@ static void gspca_release(struct v4l2_device *v4l2_device) | |||
1284 | struct gspca_dev *gspca_dev = | 1274 | struct gspca_dev *gspca_dev = |
1285 | container_of(v4l2_device, struct gspca_dev, v4l2_dev); | 1275 | container_of(v4l2_device, struct gspca_dev, v4l2_dev); |
1286 | 1276 | ||
1287 | PDEBUG(D_PROBE, "%s released", | ||
1288 | video_device_node_name(&gspca_dev->vdev)); | ||
1289 | |||
1290 | v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); | 1277 | v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); |
1291 | v4l2_device_unregister(&gspca_dev->v4l2_dev); | 1278 | v4l2_device_unregister(&gspca_dev->v4l2_dev); |
1292 | kfree(gspca_dev->usb_buf); | 1279 | kfree(gspca_dev->usb_buf); |
@@ -1694,8 +1681,6 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, | |||
1694 | { | 1681 | { |
1695 | struct gspca_dev *gspca_dev = video_drvdata(file); | 1682 | struct gspca_dev *gspca_dev = video_drvdata(file); |
1696 | 1683 | ||
1697 | if (!gspca_dev->sd_desc->get_jcomp) | ||
1698 | return -ENOTTY; | ||
1699 | gspca_dev->usb_err = 0; | 1684 | gspca_dev->usb_err = 0; |
1700 | return gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); | 1685 | return gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); |
1701 | } | 1686 | } |
@@ -1705,8 +1690,6 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
1705 | { | 1690 | { |
1706 | struct gspca_dev *gspca_dev = video_drvdata(file); | 1691 | struct gspca_dev *gspca_dev = video_drvdata(file); |
1707 | 1692 | ||
1708 | if (!gspca_dev->sd_desc->set_jcomp) | ||
1709 | return -ENOTTY; | ||
1710 | gspca_dev->usb_err = 0; | 1693 | gspca_dev->usb_err = 0; |
1711 | return gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); | 1694 | return gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); |
1712 | } | 1695 | } |
@@ -2290,6 +2273,20 @@ int gspca_dev_probe2(struct usb_interface *intf, | |||
2290 | v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF); | 2273 | v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF); |
2291 | v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF); | 2274 | v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF); |
2292 | v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF); | 2275 | v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF); |
2276 | if (!gspca_dev->sd_desc->get_chip_ident) | ||
2277 | v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_CHIP_IDENT); | ||
2278 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2279 | if (!gspca_dev->sd_desc->get_chip_ident || | ||
2280 | !gspca_dev->sd_desc->get_register) | ||
2281 | v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER); | ||
2282 | if (!gspca_dev->sd_desc->get_chip_ident || | ||
2283 | !gspca_dev->sd_desc->set_register) | ||
2284 | v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_S_REGISTER); | ||
2285 | #endif | ||
2286 | if (!gspca_dev->sd_desc->get_jcomp) | ||
2287 | v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_G_JPEGCOMP); | ||
2288 | if (!gspca_dev->sd_desc->set_jcomp) | ||
2289 | v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_S_JPEGCOMP); | ||
2293 | 2290 | ||
2294 | /* init video stuff */ | 2291 | /* init video stuff */ |
2295 | ret = video_register_device(&gspca_dev->vdev, | 2292 | ret = video_register_device(&gspca_dev->vdev, |
@@ -2429,7 +2426,6 @@ int gspca_resume(struct usb_interface *intf) | |||
2429 | */ | 2426 | */ |
2430 | streaming = gspca_dev->streaming; | 2427 | streaming = gspca_dev->streaming; |
2431 | gspca_dev->streaming = 0; | 2428 | gspca_dev->streaming = 0; |
2432 | v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); | ||
2433 | if (streaming) | 2429 | if (streaming) |
2434 | ret = gspca_init_transfer(gspca_dev); | 2430 | ret = gspca_init_transfer(gspca_dev); |
2435 | mutex_unlock(&gspca_dev->usb_lock); | 2431 | mutex_unlock(&gspca_dev->usb_lock); |
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index 5ab3f7e12760..26b99310d628 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c | |||
@@ -54,21 +54,13 @@ enum { | |||
54 | #define CAMQUALITY_MIN 0 /* highest cam quality */ | 54 | #define CAMQUALITY_MIN 0 /* highest cam quality */ |
55 | #define CAMQUALITY_MAX 97 /* lowest cam quality */ | 55 | #define CAMQUALITY_MAX 97 /* lowest cam quality */ |
56 | 56 | ||
57 | enum e_ctrl { | ||
58 | LIGHTFREQ, | ||
59 | AUTOGAIN, | ||
60 | RED, | ||
61 | GREEN, | ||
62 | BLUE, | ||
63 | NCTRLS /* number of controls */ | ||
64 | }; | ||
65 | |||
66 | /* Structure to hold all of our device specific stuff */ | 57 | /* Structure to hold all of our device specific stuff */ |
67 | struct sd { | 58 | struct sd { |
68 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 59 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
69 | struct gspca_ctrl ctrls[NCTRLS]; | ||
70 | int blocks_left; | 60 | int blocks_left; |
71 | const struct v4l2_pix_format *cap_mode; | 61 | const struct v4l2_pix_format *cap_mode; |
62 | struct v4l2_ctrl *freq; | ||
63 | struct v4l2_ctrl *jpegqual; | ||
72 | /* Driver stuff */ | 64 | /* Driver stuff */ |
73 | u8 type; | 65 | u8 type; |
74 | u8 quality; /* image quality */ | 66 | u8 quality; /* image quality */ |
@@ -139,23 +131,21 @@ static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response) | |||
139 | } | 131 | } |
140 | } | 132 | } |
141 | 133 | ||
142 | static void setfreq(struct gspca_dev *gspca_dev) | 134 | static void setfreq(struct gspca_dev *gspca_dev, s32 val) |
143 | { | 135 | { |
144 | struct sd *sd = (struct sd *) gspca_dev; | ||
145 | u8 freq_commands[][2] = { | 136 | u8 freq_commands[][2] = { |
146 | {0x71, 0x80}, | 137 | {0x71, 0x80}, |
147 | {0x70, 0x07} | 138 | {0x70, 0x07} |
148 | }; | 139 | }; |
149 | 140 | ||
150 | freq_commands[0][1] |= (sd->ctrls[LIGHTFREQ].val >> 1); | 141 | freq_commands[0][1] |= val >> 1; |
151 | 142 | ||
152 | jlj_write2(gspca_dev, freq_commands[0]); | 143 | jlj_write2(gspca_dev, freq_commands[0]); |
153 | jlj_write2(gspca_dev, freq_commands[1]); | 144 | jlj_write2(gspca_dev, freq_commands[1]); |
154 | } | 145 | } |
155 | 146 | ||
156 | static void setcamquality(struct gspca_dev *gspca_dev) | 147 | static void setcamquality(struct gspca_dev *gspca_dev, s32 val) |
157 | { | 148 | { |
158 | struct sd *sd = (struct sd *) gspca_dev; | ||
159 | u8 quality_commands[][2] = { | 149 | u8 quality_commands[][2] = { |
160 | {0x71, 0x1E}, | 150 | {0x71, 0x1E}, |
161 | {0x70, 0x06} | 151 | {0x70, 0x06} |
@@ -163,7 +153,7 @@ static void setcamquality(struct gspca_dev *gspca_dev) | |||
163 | u8 camquality; | 153 | u8 camquality; |
164 | 154 | ||
165 | /* adapt camera quality from jpeg quality */ | 155 | /* adapt camera quality from jpeg quality */ |
166 | camquality = ((QUALITY_MAX - sd->quality) * CAMQUALITY_MAX) | 156 | camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX) |
167 | / (QUALITY_MAX - QUALITY_MIN); | 157 | / (QUALITY_MAX - QUALITY_MIN); |
168 | quality_commands[0][1] += camquality; | 158 | quality_commands[0][1] += camquality; |
169 | 159 | ||
@@ -171,130 +161,58 @@ static void setcamquality(struct gspca_dev *gspca_dev) | |||
171 | jlj_write2(gspca_dev, quality_commands[1]); | 161 | jlj_write2(gspca_dev, quality_commands[1]); |
172 | } | 162 | } |
173 | 163 | ||
174 | static void setautogain(struct gspca_dev *gspca_dev) | 164 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
175 | { | 165 | { |
176 | struct sd *sd = (struct sd *) gspca_dev; | ||
177 | u8 autogain_commands[][2] = { | 166 | u8 autogain_commands[][2] = { |
178 | {0x94, 0x02}, | 167 | {0x94, 0x02}, |
179 | {0xcf, 0x00} | 168 | {0xcf, 0x00} |
180 | }; | 169 | }; |
181 | 170 | ||
182 | autogain_commands[1][1] = (sd->ctrls[AUTOGAIN].val << 4); | 171 | autogain_commands[1][1] = val << 4; |
183 | 172 | ||
184 | jlj_write2(gspca_dev, autogain_commands[0]); | 173 | jlj_write2(gspca_dev, autogain_commands[0]); |
185 | jlj_write2(gspca_dev, autogain_commands[1]); | 174 | jlj_write2(gspca_dev, autogain_commands[1]); |
186 | } | 175 | } |
187 | 176 | ||
188 | static void setred(struct gspca_dev *gspca_dev) | 177 | static void setred(struct gspca_dev *gspca_dev, s32 val) |
189 | { | 178 | { |
190 | struct sd *sd = (struct sd *) gspca_dev; | ||
191 | u8 setred_commands[][2] = { | 179 | u8 setred_commands[][2] = { |
192 | {0x94, 0x02}, | 180 | {0x94, 0x02}, |
193 | {0xe6, 0x00} | 181 | {0xe6, 0x00} |
194 | }; | 182 | }; |
195 | 183 | ||
196 | setred_commands[1][1] = sd->ctrls[RED].val; | 184 | setred_commands[1][1] = val; |
197 | 185 | ||
198 | jlj_write2(gspca_dev, setred_commands[0]); | 186 | jlj_write2(gspca_dev, setred_commands[0]); |
199 | jlj_write2(gspca_dev, setred_commands[1]); | 187 | jlj_write2(gspca_dev, setred_commands[1]); |
200 | } | 188 | } |
201 | 189 | ||
202 | static void setgreen(struct gspca_dev *gspca_dev) | 190 | static void setgreen(struct gspca_dev *gspca_dev, s32 val) |
203 | { | 191 | { |
204 | struct sd *sd = (struct sd *) gspca_dev; | ||
205 | u8 setgreen_commands[][2] = { | 192 | u8 setgreen_commands[][2] = { |
206 | {0x94, 0x02}, | 193 | {0x94, 0x02}, |
207 | {0xe7, 0x00} | 194 | {0xe7, 0x00} |
208 | }; | 195 | }; |
209 | 196 | ||
210 | setgreen_commands[1][1] = sd->ctrls[GREEN].val; | 197 | setgreen_commands[1][1] = val; |
211 | 198 | ||
212 | jlj_write2(gspca_dev, setgreen_commands[0]); | 199 | jlj_write2(gspca_dev, setgreen_commands[0]); |
213 | jlj_write2(gspca_dev, setgreen_commands[1]); | 200 | jlj_write2(gspca_dev, setgreen_commands[1]); |
214 | } | 201 | } |
215 | 202 | ||
216 | static void setblue(struct gspca_dev *gspca_dev) | 203 | static void setblue(struct gspca_dev *gspca_dev, s32 val) |
217 | { | 204 | { |
218 | struct sd *sd = (struct sd *) gspca_dev; | ||
219 | u8 setblue_commands[][2] = { | 205 | u8 setblue_commands[][2] = { |
220 | {0x94, 0x02}, | 206 | {0x94, 0x02}, |
221 | {0xe9, 0x00} | 207 | {0xe9, 0x00} |
222 | }; | 208 | }; |
223 | 209 | ||
224 | setblue_commands[1][1] = sd->ctrls[BLUE].val; | 210 | setblue_commands[1][1] = val; |
225 | 211 | ||
226 | jlj_write2(gspca_dev, setblue_commands[0]); | 212 | jlj_write2(gspca_dev, setblue_commands[0]); |
227 | jlj_write2(gspca_dev, setblue_commands[1]); | 213 | jlj_write2(gspca_dev, setblue_commands[1]); |
228 | } | 214 | } |
229 | 215 | ||
230 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
231 | [LIGHTFREQ] = { | ||
232 | { | ||
233 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
234 | .type = V4L2_CTRL_TYPE_MENU, | ||
235 | .name = "Light frequency filter", | ||
236 | .minimum = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, /* 1 */ | ||
237 | .maximum = V4L2_CID_POWER_LINE_FREQUENCY_60HZ, /* 2 */ | ||
238 | .step = 1, | ||
239 | .default_value = V4L2_CID_POWER_LINE_FREQUENCY_60HZ, | ||
240 | }, | ||
241 | .set_control = setfreq | ||
242 | }, | ||
243 | [AUTOGAIN] = { | ||
244 | { | ||
245 | .id = V4L2_CID_AUTOGAIN, | ||
246 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
247 | .name = "Automatic Gain (and Exposure)", | ||
248 | .minimum = 0, | ||
249 | .maximum = 3, | ||
250 | .step = 1, | ||
251 | #define AUTOGAIN_DEF 0 | ||
252 | .default_value = AUTOGAIN_DEF, | ||
253 | }, | ||
254 | .set_control = setautogain | ||
255 | }, | ||
256 | [RED] = { | ||
257 | { | ||
258 | .id = V4L2_CID_RED_BALANCE, | ||
259 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
260 | .name = "red balance", | ||
261 | .minimum = 0, | ||
262 | .maximum = 3, | ||
263 | .step = 1, | ||
264 | #define RED_BALANCE_DEF 2 | ||
265 | .default_value = RED_BALANCE_DEF, | ||
266 | }, | ||
267 | .set_control = setred | ||
268 | }, | ||
269 | |||
270 | [GREEN] = { | ||
271 | { | ||
272 | .id = V4L2_CID_GAIN, | ||
273 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
274 | .name = "green balance", | ||
275 | .minimum = 0, | ||
276 | .maximum = 3, | ||
277 | .step = 1, | ||
278 | #define GREEN_BALANCE_DEF 2 | ||
279 | .default_value = GREEN_BALANCE_DEF, | ||
280 | }, | ||
281 | .set_control = setgreen | ||
282 | }, | ||
283 | [BLUE] = { | ||
284 | { | ||
285 | .id = V4L2_CID_BLUE_BALANCE, | ||
286 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
287 | .name = "blue balance", | ||
288 | .minimum = 0, | ||
289 | .maximum = 3, | ||
290 | .step = 1, | ||
291 | #define BLUE_BALANCE_DEF 2 | ||
292 | .default_value = BLUE_BALANCE_DEF, | ||
293 | }, | ||
294 | .set_control = setblue | ||
295 | }, | ||
296 | }; | ||
297 | |||
298 | static int jlj_start(struct gspca_dev *gspca_dev) | 216 | static int jlj_start(struct gspca_dev *gspca_dev) |
299 | { | 217 | { |
300 | int i; | 218 | int i; |
@@ -344,9 +262,9 @@ static int jlj_start(struct gspca_dev *gspca_dev) | |||
344 | if (start_commands[i].ack_wanted) | 262 | if (start_commands[i].ack_wanted) |
345 | jlj_read1(gspca_dev, response); | 263 | jlj_read1(gspca_dev, response); |
346 | } | 264 | } |
347 | setcamquality(gspca_dev); | 265 | setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); |
348 | msleep(2); | 266 | msleep(2); |
349 | setfreq(gspca_dev); | 267 | setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq)); |
350 | if (gspca_dev->usb_err < 0) | 268 | if (gspca_dev->usb_err < 0) |
351 | PDEBUG(D_ERR, "Start streaming command failed"); | 269 | PDEBUG(D_ERR, "Start streaming command failed"); |
352 | return gspca_dev->usb_err; | 270 | return gspca_dev->usb_err; |
@@ -403,7 +321,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
403 | struct sd *dev = (struct sd *) gspca_dev; | 321 | struct sd *dev = (struct sd *) gspca_dev; |
404 | 322 | ||
405 | dev->type = id->driver_info; | 323 | dev->type = id->driver_info; |
406 | gspca_dev->cam.ctrls = dev->ctrls; | ||
407 | dev->quality = QUALITY_DEF; | 324 | dev->quality = QUALITY_DEF; |
408 | 325 | ||
409 | cam->cam_mode = jlj_mode; | 326 | cam->cam_mode = jlj_mode; |
@@ -479,25 +396,81 @@ static const struct usb_device_id device_table[] = { | |||
479 | 396 | ||
480 | MODULE_DEVICE_TABLE(usb, device_table); | 397 | MODULE_DEVICE_TABLE(usb, device_table); |
481 | 398 | ||
482 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 399 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
483 | struct v4l2_querymenu *menu) | ||
484 | { | 400 | { |
485 | switch (menu->id) { | 401 | struct gspca_dev *gspca_dev = |
402 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
403 | struct sd *sd = (struct sd *)gspca_dev; | ||
404 | |||
405 | gspca_dev->usb_err = 0; | ||
406 | |||
407 | if (!gspca_dev->streaming) | ||
408 | return 0; | ||
409 | |||
410 | switch (ctrl->id) { | ||
486 | case V4L2_CID_POWER_LINE_FREQUENCY: | 411 | case V4L2_CID_POWER_LINE_FREQUENCY: |
487 | switch (menu->index) { | 412 | setfreq(gspca_dev, ctrl->val); |
488 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | 413 | break; |
489 | strcpy((char *) menu->name, "disable"); | 414 | case V4L2_CID_RED_BALANCE: |
490 | return 0; | 415 | setred(gspca_dev, ctrl->val); |
491 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | 416 | break; |
492 | strcpy((char *) menu->name, "50 Hz"); | 417 | case V4L2_CID_GAIN: |
493 | return 0; | 418 | setgreen(gspca_dev, ctrl->val); |
494 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | 419 | break; |
495 | strcpy((char *) menu->name, "60 Hz"); | 420 | case V4L2_CID_BLUE_BALANCE: |
496 | return 0; | 421 | setblue(gspca_dev, ctrl->val); |
497 | } | 422 | break; |
423 | case V4L2_CID_AUTOGAIN: | ||
424 | setautogain(gspca_dev, ctrl->val); | ||
425 | break; | ||
426 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: | ||
427 | jpeg_set_qual(sd->jpeg_hdr, ctrl->val); | ||
428 | setcamquality(gspca_dev, ctrl->val); | ||
498 | break; | 429 | break; |
499 | } | 430 | } |
500 | return -EINVAL; | 431 | return gspca_dev->usb_err; |
432 | } | ||
433 | |||
434 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
435 | .s_ctrl = sd_s_ctrl, | ||
436 | }; | ||
437 | |||
438 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
439 | { | ||
440 | struct sd *sd = (struct sd *)gspca_dev; | ||
441 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
442 | static const struct v4l2_ctrl_config custom_autogain = { | ||
443 | .ops = &sd_ctrl_ops, | ||
444 | .id = V4L2_CID_AUTOGAIN, | ||
445 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
446 | .name = "Automatic Gain (and Exposure)", | ||
447 | .max = 3, | ||
448 | .step = 1, | ||
449 | .def = 0, | ||
450 | }; | ||
451 | |||
452 | gspca_dev->vdev.ctrl_handler = hdl; | ||
453 | v4l2_ctrl_handler_init(hdl, 6); | ||
454 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
455 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
456 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1, | ||
457 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ); | ||
458 | v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL); | ||
459 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
460 | V4L2_CID_RED_BALANCE, 0, 3, 1, 2); | ||
461 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
462 | V4L2_CID_GAIN, 0, 3, 1, 2); | ||
463 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
464 | V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2); | ||
465 | sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
466 | V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
467 | QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); | ||
468 | |||
469 | if (hdl->error) { | ||
470 | pr_err("Could not initialize controls\n"); | ||
471 | return hdl->error; | ||
472 | } | ||
473 | return 0; | ||
501 | } | 474 | } |
502 | 475 | ||
503 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 476 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, |
@@ -505,16 +478,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, | |||
505 | { | 478 | { |
506 | struct sd *sd = (struct sd *) gspca_dev; | 479 | struct sd *sd = (struct sd *) gspca_dev; |
507 | 480 | ||
508 | if (jcomp->quality < QUALITY_MIN) | 481 | v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); |
509 | sd->quality = QUALITY_MIN; | ||
510 | else if (jcomp->quality > QUALITY_MAX) | ||
511 | sd->quality = QUALITY_MAX; | ||
512 | else | ||
513 | sd->quality = jcomp->quality; | ||
514 | if (gspca_dev->streaming) { | ||
515 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
516 | setcamquality(gspca_dev); | ||
517 | } | ||
518 | return 0; | 482 | return 0; |
519 | } | 483 | } |
520 | 484 | ||
@@ -524,7 +488,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
524 | struct sd *sd = (struct sd *) gspca_dev; | 488 | struct sd *sd = (struct sd *) gspca_dev; |
525 | 489 | ||
526 | memset(jcomp, 0, sizeof *jcomp); | 490 | memset(jcomp, 0, sizeof *jcomp); |
527 | jcomp->quality = sd->quality; | 491 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); |
528 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 492 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT |
529 | | V4L2_JPEG_MARKER_DQT; | 493 | | V4L2_JPEG_MARKER_DQT; |
530 | return 0; | 494 | return 0; |
@@ -546,12 +510,10 @@ static const struct sd_desc sd_desc_sportscam_dv15 = { | |||
546 | .name = MODULE_NAME, | 510 | .name = MODULE_NAME, |
547 | .config = sd_config, | 511 | .config = sd_config, |
548 | .init = sd_init, | 512 | .init = sd_init, |
513 | .init_controls = sd_init_controls, | ||
549 | .start = sd_start, | 514 | .start = sd_start, |
550 | .stopN = sd_stopN, | 515 | .stopN = sd_stopN, |
551 | .pkt_scan = sd_pkt_scan, | 516 | .pkt_scan = sd_pkt_scan, |
552 | .ctrls = sd_ctrls, | ||
553 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
554 | .querymenu = sd_querymenu, | ||
555 | .get_jcomp = sd_get_jcomp, | 517 | .get_jcomp = sd_get_jcomp, |
556 | .set_jcomp = sd_set_jcomp, | 518 | .set_jcomp = sd_set_jcomp, |
557 | }; | 519 | }; |
@@ -579,6 +541,7 @@ static struct usb_driver sd_driver = { | |||
579 | #ifdef CONFIG_PM | 541 | #ifdef CONFIG_PM |
580 | .suspend = gspca_suspend, | 542 | .suspend = gspca_suspend, |
581 | .resume = gspca_resume, | 543 | .resume = gspca_resume, |
544 | .reset_resume = gspca_resume, | ||
582 | #endif | 545 | #endif |
583 | }; | 546 | }; |
584 | 547 | ||
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c index 9c591c7c6f54..cf9d9fca5b84 100644 --- a/drivers/media/video/gspca/jl2005bcd.c +++ b/drivers/media/video/gspca/jl2005bcd.c | |||
@@ -505,8 +505,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
505 | /* sub-driver description */ | 505 | /* sub-driver description */ |
506 | static const struct sd_desc sd_desc = { | 506 | static const struct sd_desc sd_desc = { |
507 | .name = MODULE_NAME, | 507 | .name = MODULE_NAME, |
508 | /* .ctrls = none have been detected */ | ||
509 | /* .nctrls = ARRAY_SIZE(sd_ctrls), */ | ||
510 | .config = sd_config, | 508 | .config = sd_config, |
511 | .init = sd_init, | 509 | .init = sd_init, |
512 | .start = sd_start, | 510 | .start = sd_start, |
@@ -536,6 +534,7 @@ static struct usb_driver sd_driver = { | |||
536 | #ifdef CONFIG_PM | 534 | #ifdef CONFIG_PM |
537 | .suspend = gspca_suspend, | 535 | .suspend = gspca_suspend, |
538 | .resume = gspca_resume, | 536 | .resume = gspca_resume, |
537 | .reset_resume = gspca_resume, | ||
539 | #endif | 538 | #endif |
540 | }; | 539 | }; |
541 | 540 | ||
diff --git a/drivers/media/video/gspca/kinect.c b/drivers/media/video/gspca/kinect.c index e8e8f2fe9166..40ad6687ee5d 100644 --- a/drivers/media/video/gspca/kinect.c +++ b/drivers/media/video/gspca/kinect.c | |||
@@ -63,12 +63,6 @@ struct sd { | |||
63 | uint8_t ibuf[0x200]; /* input buffer for control commands */ | 63 | uint8_t ibuf[0x200]; /* input buffer for control commands */ |
64 | }; | 64 | }; |
65 | 65 | ||
66 | /* V4L2 controls supported by the driver */ | ||
67 | /* controls prototypes here */ | ||
68 | |||
69 | static const struct ctrl sd_ctrls[] = { | ||
70 | }; | ||
71 | |||
72 | #define MODE_640x480 0x0001 | 66 | #define MODE_640x480 0x0001 |
73 | #define MODE_640x488 0x0002 | 67 | #define MODE_640x488 0x0002 |
74 | #define MODE_1280x1024 0x0004 | 68 | #define MODE_1280x1024 0x0004 |
@@ -373,15 +367,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len) | |||
373 | /* sub-driver description */ | 367 | /* sub-driver description */ |
374 | static const struct sd_desc sd_desc = { | 368 | static const struct sd_desc sd_desc = { |
375 | .name = MODULE_NAME, | 369 | .name = MODULE_NAME, |
376 | .ctrls = sd_ctrls, | ||
377 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
378 | .config = sd_config, | 370 | .config = sd_config, |
379 | .init = sd_init, | 371 | .init = sd_init, |
380 | .start = sd_start, | 372 | .start = sd_start, |
381 | .stopN = sd_stopN, | 373 | .stopN = sd_stopN, |
382 | .pkt_scan = sd_pkt_scan, | 374 | .pkt_scan = sd_pkt_scan, |
383 | /* | 375 | /* |
384 | .querymenu = sd_querymenu, | ||
385 | .get_streamparm = sd_get_streamparm, | 376 | .get_streamparm = sd_get_streamparm, |
386 | .set_streamparm = sd_set_streamparm, | 377 | .set_streamparm = sd_set_streamparm, |
387 | */ | 378 | */ |
@@ -410,6 +401,7 @@ static struct usb_driver sd_driver = { | |||
410 | #ifdef CONFIG_PM | 401 | #ifdef CONFIG_PM |
411 | .suspend = gspca_suspend, | 402 | .suspend = gspca_suspend, |
412 | .resume = gspca_resume, | 403 | .resume = gspca_resume, |
404 | .reset_resume = gspca_resume, | ||
413 | #endif | 405 | #endif |
414 | }; | 406 | }; |
415 | 407 | ||
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c index f0c0d74dfe92..bbf91e07e38b 100644 --- a/drivers/media/video/gspca/konica.c +++ b/drivers/media/video/gspca/konica.c | |||
@@ -50,107 +50,8 @@ struct sd { | |||
50 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 50 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
51 | struct urb *last_data_urb; | 51 | struct urb *last_data_urb; |
52 | u8 snapshot_pressed; | 52 | u8 snapshot_pressed; |
53 | u8 brightness; | ||
54 | u8 contrast; | ||
55 | u8 saturation; | ||
56 | u8 whitebal; | ||
57 | u8 sharpness; | ||
58 | }; | 53 | }; |
59 | 54 | ||
60 | /* V4L2 controls supported by the driver */ | ||
61 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
63 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
65 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
70 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
71 | |||
72 | static const struct ctrl sd_ctrls[] = { | ||
73 | #define SD_BRIGHTNESS 0 | ||
74 | { | ||
75 | { | ||
76 | .id = V4L2_CID_BRIGHTNESS, | ||
77 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
78 | .name = "Brightness", | ||
79 | .minimum = 0, | ||
80 | .maximum = 9, | ||
81 | .step = 1, | ||
82 | #define BRIGHTNESS_DEFAULT 4 | ||
83 | .default_value = BRIGHTNESS_DEFAULT, | ||
84 | .flags = 0, | ||
85 | }, | ||
86 | .set = sd_setbrightness, | ||
87 | .get = sd_getbrightness, | ||
88 | }, | ||
89 | #define SD_CONTRAST 1 | ||
90 | { | ||
91 | { | ||
92 | .id = V4L2_CID_CONTRAST, | ||
93 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
94 | .name = "Contrast", | ||
95 | .minimum = 0, | ||
96 | .maximum = 9, | ||
97 | .step = 4, | ||
98 | #define CONTRAST_DEFAULT 10 | ||
99 | .default_value = CONTRAST_DEFAULT, | ||
100 | .flags = 0, | ||
101 | }, | ||
102 | .set = sd_setcontrast, | ||
103 | .get = sd_getcontrast, | ||
104 | }, | ||
105 | #define SD_SATURATION 2 | ||
106 | { | ||
107 | { | ||
108 | .id = V4L2_CID_SATURATION, | ||
109 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
110 | .name = "Saturation", | ||
111 | .minimum = 0, | ||
112 | .maximum = 9, | ||
113 | .step = 1, | ||
114 | #define SATURATION_DEFAULT 4 | ||
115 | .default_value = SATURATION_DEFAULT, | ||
116 | .flags = 0, | ||
117 | }, | ||
118 | .set = sd_setsaturation, | ||
119 | .get = sd_getsaturation, | ||
120 | }, | ||
121 | #define SD_WHITEBAL 3 | ||
122 | { | ||
123 | { | ||
124 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
125 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
126 | .name = "White Balance", | ||
127 | .minimum = 0, | ||
128 | .maximum = 33, | ||
129 | .step = 1, | ||
130 | #define WHITEBAL_DEFAULT 25 | ||
131 | .default_value = WHITEBAL_DEFAULT, | ||
132 | .flags = 0, | ||
133 | }, | ||
134 | .set = sd_setwhitebal, | ||
135 | .get = sd_getwhitebal, | ||
136 | }, | ||
137 | #define SD_SHARPNESS 4 | ||
138 | { | ||
139 | { | ||
140 | .id = V4L2_CID_SHARPNESS, | ||
141 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
142 | .name = "Sharpness", | ||
143 | .minimum = 0, | ||
144 | .maximum = 9, | ||
145 | .step = 1, | ||
146 | #define SHARPNESS_DEFAULT 4 | ||
147 | .default_value = SHARPNESS_DEFAULT, | ||
148 | .flags = 0, | ||
149 | }, | ||
150 | .set = sd_setsharpness, | ||
151 | .get = sd_getsharpness, | ||
152 | }, | ||
153 | }; | ||
154 | 55 | ||
155 | /* .priv is what goes to register 8 for this mode, known working values: | 56 | /* .priv is what goes to register 8 for this mode, known working values: |
156 | 0x00 -> 176x144, cropped | 57 | 0x00 -> 176x144, cropped |
@@ -202,7 +103,8 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) | |||
202 | 0, | 103 | 0, |
203 | 1000); | 104 | 1000); |
204 | if (ret < 0) { | 105 | if (ret < 0) { |
205 | pr_err("reg_w err %d\n", ret); | 106 | pr_err("reg_w err writing %02x to %02x: %d\n", |
107 | value, index, ret); | ||
206 | gspca_dev->usb_err = ret; | 108 | gspca_dev->usb_err = ret; |
207 | } | 109 | } |
208 | } | 110 | } |
@@ -223,7 +125,7 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index) | |||
223 | 2, | 125 | 2, |
224 | 1000); | 126 | 1000); |
225 | if (ret < 0) { | 127 | if (ret < 0) { |
226 | pr_err("reg_w err %d\n", ret); | 128 | pr_err("reg_r err %d\n", ret); |
227 | gspca_dev->usb_err = ret; | 129 | gspca_dev->usb_err = ret; |
228 | } | 130 | } |
229 | } | 131 | } |
@@ -242,34 +144,33 @@ static void konica_stream_off(struct gspca_dev *gspca_dev) | |||
242 | static int sd_config(struct gspca_dev *gspca_dev, | 144 | static int sd_config(struct gspca_dev *gspca_dev, |
243 | const struct usb_device_id *id) | 145 | const struct usb_device_id *id) |
244 | { | 146 | { |
245 | struct sd *sd = (struct sd *) gspca_dev; | ||
246 | |||
247 | gspca_dev->cam.cam_mode = vga_mode; | 147 | gspca_dev->cam.cam_mode = vga_mode; |
248 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | 148 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); |
249 | gspca_dev->cam.no_urb_create = 1; | 149 | gspca_dev->cam.no_urb_create = 1; |
250 | 150 | ||
251 | sd->brightness = BRIGHTNESS_DEFAULT; | ||
252 | sd->contrast = CONTRAST_DEFAULT; | ||
253 | sd->saturation = SATURATION_DEFAULT; | ||
254 | sd->whitebal = WHITEBAL_DEFAULT; | ||
255 | sd->sharpness = SHARPNESS_DEFAULT; | ||
256 | |||
257 | return 0; | 151 | return 0; |
258 | } | 152 | } |
259 | 153 | ||
260 | /* this function is called at probe and resume time */ | 154 | /* this function is called at probe and resume time */ |
261 | static int sd_init(struct gspca_dev *gspca_dev) | 155 | static int sd_init(struct gspca_dev *gspca_dev) |
262 | { | 156 | { |
263 | /* HDG not sure if these 2 reads are needed */ | 157 | int i; |
264 | reg_r(gspca_dev, 0, 0x10); | 158 | |
265 | PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x", | 159 | /* |
266 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); | 160 | * The konica needs a freaking large time to "boot" (approx 6.5 sec.), |
267 | reg_r(gspca_dev, 0, 0x10); | 161 | * and does not want to be bothered while doing so :| |
268 | PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x", | 162 | * Register 0x10 counts from 1 - 3, with 3 being "ready" |
269 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); | 163 | */ |
164 | msleep(6000); | ||
165 | for (i = 0; i < 20; i++) { | ||
166 | reg_r(gspca_dev, 0, 0x10); | ||
167 | if (gspca_dev->usb_buf[0] == 3) | ||
168 | break; | ||
169 | msleep(100); | ||
170 | } | ||
270 | reg_w(gspca_dev, 0, 0x0d); | 171 | reg_w(gspca_dev, 0, 0x0d); |
271 | 172 | ||
272 | return 0; | 173 | return gspca_dev->usb_err; |
273 | } | 174 | } |
274 | 175 | ||
275 | static int sd_start(struct gspca_dev *gspca_dev) | 176 | static int sd_start(struct gspca_dev *gspca_dev) |
@@ -289,12 +190,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
289 | 190 | ||
290 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 191 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
291 | 192 | ||
292 | reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG); | ||
293 | reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG); | ||
294 | reg_w(gspca_dev, sd->contrast, CONTRAST_REG); | ||
295 | reg_w(gspca_dev, sd->saturation, SATURATION_REG); | ||
296 | reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG); | ||
297 | |||
298 | n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | 193 | n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
299 | reg_w(gspca_dev, n, 0x08); | 194 | reg_w(gspca_dev, n, 0x08); |
300 | 195 | ||
@@ -479,125 +374,82 @@ resubmit: | |||
479 | pr_err("usb_submit_urb(status_urb) ret %d\n", st); | 374 | pr_err("usb_submit_urb(status_urb) ret %d\n", st); |
480 | } | 375 | } |
481 | 376 | ||
482 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 377 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
483 | { | 378 | { |
484 | struct sd *sd = (struct sd *) gspca_dev; | 379 | struct gspca_dev *gspca_dev = |
485 | 380 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
486 | sd->brightness = val; | ||
487 | if (gspca_dev->streaming) { | ||
488 | konica_stream_off(gspca_dev); | ||
489 | reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG); | ||
490 | konica_stream_on(gspca_dev); | ||
491 | } | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
497 | { | ||
498 | struct sd *sd = (struct sd *) gspca_dev; | ||
499 | |||
500 | *val = sd->brightness; | ||
501 | 381 | ||
502 | return 0; | 382 | gspca_dev->usb_err = 0; |
503 | } | ||
504 | 383 | ||
505 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | 384 | if (!gspca_dev->streaming) |
506 | { | 385 | return 0; |
507 | struct sd *sd = (struct sd *) gspca_dev; | ||
508 | 386 | ||
509 | sd->contrast = val; | 387 | switch (ctrl->id) { |
510 | if (gspca_dev->streaming) { | 388 | case V4L2_CID_BRIGHTNESS: |
511 | konica_stream_off(gspca_dev); | 389 | konica_stream_off(gspca_dev); |
512 | reg_w(gspca_dev, sd->contrast, CONTRAST_REG); | 390 | reg_w(gspca_dev, ctrl->val, BRIGHTNESS_REG); |
513 | konica_stream_on(gspca_dev); | 391 | konica_stream_on(gspca_dev); |
514 | } | 392 | break; |
515 | 393 | case V4L2_CID_CONTRAST: | |
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
520 | { | ||
521 | struct sd *sd = (struct sd *) gspca_dev; | ||
522 | |||
523 | *val = sd->contrast; | ||
524 | |||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) | ||
529 | { | ||
530 | struct sd *sd = (struct sd *) gspca_dev; | ||
531 | |||
532 | sd->saturation = val; | ||
533 | if (gspca_dev->streaming) { | ||
534 | konica_stream_off(gspca_dev); | 394 | konica_stream_off(gspca_dev); |
535 | reg_w(gspca_dev, sd->saturation, SATURATION_REG); | 395 | reg_w(gspca_dev, ctrl->val, CONTRAST_REG); |
536 | konica_stream_on(gspca_dev); | 396 | konica_stream_on(gspca_dev); |
537 | } | 397 | break; |
538 | return 0; | 398 | case V4L2_CID_SATURATION: |
539 | } | ||
540 | |||
541 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) | ||
542 | { | ||
543 | struct sd *sd = (struct sd *) gspca_dev; | ||
544 | |||
545 | *val = sd->saturation; | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val) | ||
551 | { | ||
552 | struct sd *sd = (struct sd *) gspca_dev; | ||
553 | |||
554 | sd->whitebal = val; | ||
555 | if (gspca_dev->streaming) { | ||
556 | konica_stream_off(gspca_dev); | 399 | konica_stream_off(gspca_dev); |
557 | reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG); | 400 | reg_w(gspca_dev, ctrl->val, SATURATION_REG); |
558 | konica_stream_on(gspca_dev); | 401 | konica_stream_on(gspca_dev); |
559 | } | 402 | break; |
560 | return 0; | 403 | case V4L2_CID_WHITE_BALANCE_TEMPERATURE: |
561 | } | ||
562 | |||
563 | static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val) | ||
564 | { | ||
565 | struct sd *sd = (struct sd *) gspca_dev; | ||
566 | |||
567 | *val = sd->whitebal; | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
573 | { | ||
574 | struct sd *sd = (struct sd *) gspca_dev; | ||
575 | |||
576 | sd->sharpness = val; | ||
577 | if (gspca_dev->streaming) { | ||
578 | konica_stream_off(gspca_dev); | 404 | konica_stream_off(gspca_dev); |
579 | reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG); | 405 | reg_w(gspca_dev, ctrl->val, WHITEBAL_REG); |
580 | konica_stream_on(gspca_dev); | 406 | konica_stream_on(gspca_dev); |
407 | break; | ||
408 | case V4L2_CID_SHARPNESS: | ||
409 | konica_stream_off(gspca_dev); | ||
410 | reg_w(gspca_dev, ctrl->val, SHARPNESS_REG); | ||
411 | konica_stream_on(gspca_dev); | ||
412 | break; | ||
581 | } | 413 | } |
582 | return 0; | 414 | return gspca_dev->usb_err; |
583 | } | 415 | } |
584 | 416 | ||
585 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | 417 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
586 | { | 418 | .s_ctrl = sd_s_ctrl, |
587 | struct sd *sd = (struct sd *) gspca_dev; | 419 | }; |
588 | |||
589 | *val = sd->sharpness; | ||
590 | 420 | ||
421 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
422 | { | ||
423 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
424 | |||
425 | gspca_dev->vdev.ctrl_handler = hdl; | ||
426 | v4l2_ctrl_handler_init(hdl, 5); | ||
427 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
428 | V4L2_CID_BRIGHTNESS, 0, 9, 1, 4); | ||
429 | /* Needs to be verified */ | ||
430 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
431 | V4L2_CID_CONTRAST, 0, 9, 1, 4); | ||
432 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
433 | V4L2_CID_SATURATION, 0, 9, 1, 4); | ||
434 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
435 | V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
436 | 0, 33, 1, 25); | ||
437 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
438 | V4L2_CID_SHARPNESS, 0, 9, 1, 4); | ||
439 | |||
440 | if (hdl->error) { | ||
441 | pr_err("Could not initialize controls\n"); | ||
442 | return hdl->error; | ||
443 | } | ||
591 | return 0; | 444 | return 0; |
592 | } | 445 | } |
593 | 446 | ||
594 | /* sub-driver description */ | 447 | /* sub-driver description */ |
595 | static const struct sd_desc sd_desc = { | 448 | static const struct sd_desc sd_desc = { |
596 | .name = MODULE_NAME, | 449 | .name = MODULE_NAME, |
597 | .ctrls = sd_ctrls, | ||
598 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
599 | .config = sd_config, | 450 | .config = sd_config, |
600 | .init = sd_init, | 451 | .init = sd_init, |
452 | .init_controls = sd_init_controls, | ||
601 | .start = sd_start, | 453 | .start = sd_start, |
602 | .stopN = sd_stopN, | 454 | .stopN = sd_stopN, |
603 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 455 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
@@ -628,6 +480,7 @@ static struct usb_driver sd_driver = { | |||
628 | #ifdef CONFIG_PM | 480 | #ifdef CONFIG_PM |
629 | .suspend = gspca_suspend, | 481 | .suspend = gspca_suspend, |
630 | .resume = gspca_resume, | 482 | .resume = gspca_resume, |
483 | .reset_resume = gspca_resume, | ||
631 | #endif | 484 | #endif |
632 | }; | 485 | }; |
633 | 486 | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 0c4493675438..ed22638978ce 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c | |||
@@ -400,6 +400,7 @@ static struct usb_driver sd_driver = { | |||
400 | #ifdef CONFIG_PM | 400 | #ifdef CONFIG_PM |
401 | .suspend = gspca_suspend, | 401 | .suspend = gspca_suspend, |
402 | .resume = gspca_resume, | 402 | .resume = gspca_resume, |
403 | .reset_resume = gspca_resume, | ||
403 | #endif | 404 | #endif |
404 | .disconnect = m5602_disconnect | 405 | .disconnect = m5602_disconnect |
405 | }; | 406 | }; |
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index ec7b21ee79fb..ff2c5abf115b 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
@@ -30,6 +30,8 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
30 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); | 30 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); |
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | 32 | ||
33 | #define QUALITY 50 | ||
34 | |||
33 | /* specific webcam descriptor */ | 35 | /* specific webcam descriptor */ |
34 | struct sd { | 36 | struct sd { |
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 37 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
@@ -42,13 +44,6 @@ struct sd { | |||
42 | struct v4l2_ctrl *illum_top; | 44 | struct v4l2_ctrl *illum_top; |
43 | struct v4l2_ctrl *illum_bottom; | 45 | struct v4l2_ctrl *illum_bottom; |
44 | }; | 46 | }; |
45 | struct v4l2_ctrl *jpegqual; | ||
46 | |||
47 | u8 quality; | ||
48 | #define QUALITY_MIN 40 | ||
49 | #define QUALITY_MAX 70 | ||
50 | #define QUALITY_DEF 50 | ||
51 | |||
52 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 47 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
53 | }; | 48 | }; |
54 | 49 | ||
@@ -194,9 +189,6 @@ static int mars_s_ctrl(struct v4l2_ctrl *ctrl) | |||
194 | case V4L2_CID_SHARPNESS: | 189 | case V4L2_CID_SHARPNESS: |
195 | setsharpness(gspca_dev, ctrl->val); | 190 | setsharpness(gspca_dev, ctrl->val); |
196 | break; | 191 | break; |
197 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: | ||
198 | jpeg_set_qual(sd->jpeg_hdr, ctrl->val); | ||
199 | break; | ||
200 | default: | 192 | default: |
201 | return -EINVAL; | 193 | return -EINVAL; |
202 | } | 194 | } |
@@ -214,7 +206,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) | |||
214 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | 206 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
215 | 207 | ||
216 | gspca_dev->vdev.ctrl_handler = hdl; | 208 | gspca_dev->vdev.ctrl_handler = hdl; |
217 | v4l2_ctrl_handler_init(hdl, 7); | 209 | v4l2_ctrl_handler_init(hdl, 6); |
218 | sd->brightness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | 210 | sd->brightness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, |
219 | V4L2_CID_BRIGHTNESS, 0, 30, 1, 15); | 211 | V4L2_CID_BRIGHTNESS, 0, 30, 1, 15); |
220 | sd->saturation = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | 212 | sd->saturation = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, |
@@ -229,9 +221,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) | |||
229 | sd->illum_bottom = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | 221 | sd->illum_bottom = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, |
230 | V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); | 222 | V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); |
231 | sd->illum_bottom->flags |= V4L2_CTRL_FLAG_UPDATE; | 223 | sd->illum_bottom->flags |= V4L2_CTRL_FLAG_UPDATE; |
232 | sd->jpegqual = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
233 | V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
234 | QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); | ||
235 | if (hdl->error) { | 224 | if (hdl->error) { |
236 | pr_err("Could not initialize controls\n"); | 225 | pr_err("Could not initialize controls\n"); |
237 | return hdl->error; | 226 | return hdl->error; |
@@ -244,13 +233,11 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) | |||
244 | static int sd_config(struct gspca_dev *gspca_dev, | 233 | static int sd_config(struct gspca_dev *gspca_dev, |
245 | const struct usb_device_id *id) | 234 | const struct usb_device_id *id) |
246 | { | 235 | { |
247 | struct sd *sd = (struct sd *) gspca_dev; | ||
248 | struct cam *cam; | 236 | struct cam *cam; |
249 | 237 | ||
250 | cam = &gspca_dev->cam; | 238 | cam = &gspca_dev->cam; |
251 | cam->cam_mode = vga_mode; | 239 | cam->cam_mode = vga_mode; |
252 | cam->nmodes = ARRAY_SIZE(vga_mode); | 240 | cam->nmodes = ARRAY_SIZE(vga_mode); |
253 | sd->quality = QUALITY_DEF; | ||
254 | return 0; | 241 | return 0; |
255 | } | 242 | } |
256 | 243 | ||
@@ -269,7 +256,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
269 | /* create the JPEG header */ | 256 | /* create the JPEG header */ |
270 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 257 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
271 | 0x21); /* JPEG 422 */ | 258 | 0x21); /* JPEG 422 */ |
272 | jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); | 259 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
273 | 260 | ||
274 | data = gspca_dev->usb_buf; | 261 | data = gspca_dev->usb_buf; |
275 | 262 | ||
@@ -411,31 +398,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
411 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 398 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
412 | } | 399 | } |
413 | 400 | ||
414 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | ||
415 | struct v4l2_jpegcompression *jcomp) | ||
416 | { | ||
417 | struct sd *sd = (struct sd *) gspca_dev; | ||
418 | int ret; | ||
419 | |||
420 | ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); | ||
421 | if (ret) | ||
422 | return ret; | ||
423 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | ||
428 | struct v4l2_jpegcompression *jcomp) | ||
429 | { | ||
430 | struct sd *sd = (struct sd *) gspca_dev; | ||
431 | |||
432 | memset(jcomp, 0, sizeof *jcomp); | ||
433 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); | ||
434 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | ||
435 | | V4L2_JPEG_MARKER_DQT; | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | /* sub-driver description */ | 401 | /* sub-driver description */ |
440 | static const struct sd_desc sd_desc = { | 402 | static const struct sd_desc sd_desc = { |
441 | .name = MODULE_NAME, | 403 | .name = MODULE_NAME, |
@@ -445,8 +407,6 @@ static const struct sd_desc sd_desc = { | |||
445 | .start = sd_start, | 407 | .start = sd_start, |
446 | .stopN = sd_stopN, | 408 | .stopN = sd_stopN, |
447 | .pkt_scan = sd_pkt_scan, | 409 | .pkt_scan = sd_pkt_scan, |
448 | .get_jcomp = sd_get_jcomp, | ||
449 | .set_jcomp = sd_set_jcomp, | ||
450 | }; | 410 | }; |
451 | 411 | ||
452 | /* -- module initialisation -- */ | 412 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index d73e5bd3dbf7..8f4714df5990 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #define MR97310A_CS_GAIN_MAX 0x7ff | 67 | #define MR97310A_CS_GAIN_MAX 0x7ff |
68 | #define MR97310A_CS_GAIN_DEFAULT 0x110 | 68 | #define MR97310A_CS_GAIN_DEFAULT 0x110 |
69 | 69 | ||
70 | #define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000) | ||
70 | #define MR97310A_MIN_CLOCKDIV_MIN 3 | 71 | #define MR97310A_MIN_CLOCKDIV_MIN 3 |
71 | #define MR97310A_MIN_CLOCKDIV_MAX 8 | 72 | #define MR97310A_MIN_CLOCKDIV_MAX 8 |
72 | #define MR97310A_MIN_CLOCKDIV_DEFAULT 3 | 73 | #define MR97310A_MIN_CLOCKDIV_DEFAULT 3 |
@@ -84,17 +85,15 @@ MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); | |||
84 | /* specific webcam descriptor */ | 85 | /* specific webcam descriptor */ |
85 | struct sd { | 86 | struct sd { |
86 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 87 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
88 | struct { /* exposure/min_clockdiv control cluster */ | ||
89 | struct v4l2_ctrl *exposure; | ||
90 | struct v4l2_ctrl *min_clockdiv; | ||
91 | }; | ||
87 | u8 sof_read; | 92 | u8 sof_read; |
88 | u8 cam_type; /* 0 is CIF and 1 is VGA */ | 93 | u8 cam_type; /* 0 is CIF and 1 is VGA */ |
89 | u8 sensor_type; /* We use 0 and 1 here, too. */ | 94 | u8 sensor_type; /* We use 0 and 1 here, too. */ |
90 | u8 do_lcd_stop; | 95 | u8 do_lcd_stop; |
91 | u8 adj_colors; | 96 | u8 adj_colors; |
92 | |||
93 | int brightness; | ||
94 | u16 exposure; | ||
95 | u32 gain; | ||
96 | u8 contrast; | ||
97 | u8 min_clockdiv; | ||
98 | }; | 97 | }; |
99 | 98 | ||
100 | struct sensor_w_data { | 99 | struct sensor_w_data { |
@@ -105,132 +104,6 @@ struct sensor_w_data { | |||
105 | }; | 104 | }; |
106 | 105 | ||
107 | static void sd_stopN(struct gspca_dev *gspca_dev); | 106 | static void sd_stopN(struct gspca_dev *gspca_dev); |
108 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
109 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
110 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
111 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
112 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
113 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
114 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
115 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
116 | static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val); | ||
117 | static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val); | ||
118 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
119 | static void setexposure(struct gspca_dev *gspca_dev); | ||
120 | static void setgain(struct gspca_dev *gspca_dev); | ||
121 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
122 | |||
123 | /* V4L2 controls supported by the driver */ | ||
124 | static const struct ctrl sd_ctrls[] = { | ||
125 | /* Separate brightness control description for Argus QuickClix as it has | ||
126 | * different limits from the other mr97310a cameras, and separate gain | ||
127 | * control for Sakar CyberPix camera. */ | ||
128 | { | ||
129 | #define NORM_BRIGHTNESS_IDX 0 | ||
130 | { | ||
131 | .id = V4L2_CID_BRIGHTNESS, | ||
132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
133 | .name = "Brightness", | ||
134 | .minimum = -254, | ||
135 | .maximum = 255, | ||
136 | .step = 1, | ||
137 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, | ||
138 | .flags = 0, | ||
139 | }, | ||
140 | .set = sd_setbrightness, | ||
141 | .get = sd_getbrightness, | ||
142 | }, | ||
143 | { | ||
144 | #define ARGUS_QC_BRIGHTNESS_IDX 1 | ||
145 | { | ||
146 | .id = V4L2_CID_BRIGHTNESS, | ||
147 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
148 | .name = "Brightness", | ||
149 | .minimum = 0, | ||
150 | .maximum = 15, | ||
151 | .step = 1, | ||
152 | .default_value = MR97310A_BRIGHTNESS_DEFAULT, | ||
153 | .flags = 0, | ||
154 | }, | ||
155 | .set = sd_setbrightness, | ||
156 | .get = sd_getbrightness, | ||
157 | }, | ||
158 | { | ||
159 | #define EXPOSURE_IDX 2 | ||
160 | { | ||
161 | .id = V4L2_CID_EXPOSURE, | ||
162 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
163 | .name = "Exposure", | ||
164 | .minimum = MR97310A_EXPOSURE_MIN, | ||
165 | .maximum = MR97310A_EXPOSURE_MAX, | ||
166 | .step = 1, | ||
167 | .default_value = MR97310A_EXPOSURE_DEFAULT, | ||
168 | .flags = 0, | ||
169 | }, | ||
170 | .set = sd_setexposure, | ||
171 | .get = sd_getexposure, | ||
172 | }, | ||
173 | { | ||
174 | #define GAIN_IDX 3 | ||
175 | { | ||
176 | .id = V4L2_CID_GAIN, | ||
177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
178 | .name = "Gain", | ||
179 | .minimum = MR97310A_GAIN_MIN, | ||
180 | .maximum = MR97310A_GAIN_MAX, | ||
181 | .step = 1, | ||
182 | .default_value = MR97310A_GAIN_DEFAULT, | ||
183 | .flags = 0, | ||
184 | }, | ||
185 | .set = sd_setgain, | ||
186 | .get = sd_getgain, | ||
187 | }, | ||
188 | { | ||
189 | #define SAKAR_CS_GAIN_IDX 4 | ||
190 | { | ||
191 | .id = V4L2_CID_GAIN, | ||
192 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
193 | .name = "Gain", | ||
194 | .minimum = MR97310A_CS_GAIN_MIN, | ||
195 | .maximum = MR97310A_CS_GAIN_MAX, | ||
196 | .step = 1, | ||
197 | .default_value = MR97310A_CS_GAIN_DEFAULT, | ||
198 | .flags = 0, | ||
199 | }, | ||
200 | .set = sd_setgain, | ||
201 | .get = sd_getgain, | ||
202 | }, | ||
203 | { | ||
204 | #define CONTRAST_IDX 5 | ||
205 | { | ||
206 | .id = V4L2_CID_CONTRAST, | ||
207 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
208 | .name = "Contrast", | ||
209 | .minimum = MR97310A_CONTRAST_MIN, | ||
210 | .maximum = MR97310A_CONTRAST_MAX, | ||
211 | .step = 1, | ||
212 | .default_value = MR97310A_CONTRAST_DEFAULT, | ||
213 | .flags = 0, | ||
214 | }, | ||
215 | .set = sd_setcontrast, | ||
216 | .get = sd_getcontrast, | ||
217 | }, | ||
218 | { | ||
219 | #define MIN_CLOCKDIV_IDX 6 | ||
220 | { | ||
221 | .id = V4L2_CID_PRIVATE_BASE, | ||
222 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
223 | .name = "Minimum Clock Divider", | ||
224 | .minimum = MR97310A_MIN_CLOCKDIV_MIN, | ||
225 | .maximum = MR97310A_MIN_CLOCKDIV_MAX, | ||
226 | .step = 1, | ||
227 | .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT, | ||
228 | .flags = 0, | ||
229 | }, | ||
230 | .set = sd_setmin_clockdiv, | ||
231 | .get = sd_getmin_clockdiv, | ||
232 | }, | ||
233 | }; | ||
234 | 107 | ||
235 | static const struct v4l2_pix_format vga_mode[] = { | 108 | static const struct v4l2_pix_format vga_mode[] = { |
236 | {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, | 109 | {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, |
@@ -481,7 +354,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
481 | { | 354 | { |
482 | struct sd *sd = (struct sd *) gspca_dev; | 355 | struct sd *sd = (struct sd *) gspca_dev; |
483 | struct cam *cam; | 356 | struct cam *cam; |
484 | int gain_default = MR97310A_GAIN_DEFAULT; | ||
485 | int err_code; | 357 | int err_code; |
486 | 358 | ||
487 | cam = &gspca_dev->cam; | 359 | cam = &gspca_dev->cam; |
@@ -615,52 +487,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
615 | sd->sensor_type); | 487 | sd->sensor_type); |
616 | } | 488 | } |
617 | 489 | ||
618 | /* Setup controls depending on camera type */ | ||
619 | if (sd->cam_type == CAM_TYPE_CIF) { | ||
620 | /* No brightness for sensor_type 0 */ | ||
621 | if (sd->sensor_type == 0) | ||
622 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | | ||
623 | (1 << ARGUS_QC_BRIGHTNESS_IDX) | | ||
624 | (1 << CONTRAST_IDX) | | ||
625 | (1 << SAKAR_CS_GAIN_IDX); | ||
626 | else | ||
627 | gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | | ||
628 | (1 << CONTRAST_IDX) | | ||
629 | (1 << SAKAR_CS_GAIN_IDX) | | ||
630 | (1 << MIN_CLOCKDIV_IDX); | ||
631 | } else { | ||
632 | /* All controls need to be disabled if VGA sensor_type is 0 */ | ||
633 | if (sd->sensor_type == 0) | ||
634 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | | ||
635 | (1 << ARGUS_QC_BRIGHTNESS_IDX) | | ||
636 | (1 << EXPOSURE_IDX) | | ||
637 | (1 << GAIN_IDX) | | ||
638 | (1 << CONTRAST_IDX) | | ||
639 | (1 << SAKAR_CS_GAIN_IDX) | | ||
640 | (1 << MIN_CLOCKDIV_IDX); | ||
641 | else if (sd->sensor_type == 2) { | ||
642 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | | ||
643 | (1 << ARGUS_QC_BRIGHTNESS_IDX) | | ||
644 | (1 << GAIN_IDX) | | ||
645 | (1 << MIN_CLOCKDIV_IDX); | ||
646 | gain_default = MR97310A_CS_GAIN_DEFAULT; | ||
647 | } else if (sd->do_lcd_stop) | ||
648 | /* Argus QuickClix has different brightness limits */ | ||
649 | gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | | ||
650 | (1 << CONTRAST_IDX) | | ||
651 | (1 << SAKAR_CS_GAIN_IDX); | ||
652 | else | ||
653 | gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | | ||
654 | (1 << CONTRAST_IDX) | | ||
655 | (1 << SAKAR_CS_GAIN_IDX); | ||
656 | } | ||
657 | |||
658 | sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; | ||
659 | sd->exposure = MR97310A_EXPOSURE_DEFAULT; | ||
660 | sd->gain = gain_default; | ||
661 | sd->contrast = MR97310A_CONTRAST_DEFAULT; | ||
662 | sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; | ||
663 | |||
664 | return 0; | 490 | return 0; |
665 | } | 491 | } |
666 | 492 | ||
@@ -952,11 +778,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
952 | if (err_code < 0) | 778 | if (err_code < 0) |
953 | return err_code; | 779 | return err_code; |
954 | 780 | ||
955 | setbrightness(gspca_dev); | ||
956 | setcontrast(gspca_dev); | ||
957 | setexposure(gspca_dev); | ||
958 | setgain(gspca_dev); | ||
959 | |||
960 | return isoc_enable(gspca_dev); | 781 | return isoc_enable(gspca_dev); |
961 | } | 782 | } |
962 | 783 | ||
@@ -971,37 +792,25 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
971 | lcd_stop(gspca_dev); | 792 | lcd_stop(gspca_dev); |
972 | } | 793 | } |
973 | 794 | ||
974 | static void setbrightness(struct gspca_dev *gspca_dev) | 795 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
975 | { | 796 | { |
976 | struct sd *sd = (struct sd *) gspca_dev; | 797 | struct sd *sd = (struct sd *) gspca_dev; |
977 | u8 val; | ||
978 | u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ | 798 | u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ |
979 | u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ | 799 | u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ |
980 | static const u8 quick_clix_table[] = | 800 | static const u8 quick_clix_table[] = |
981 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ | 801 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ |
982 | { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; | 802 | { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; |
983 | /* | ||
984 | * This control is disabled for CIF type 1 and VGA type 0 cameras. | ||
985 | * It does not quite act linearly for the Argus QuickClix camera, | ||
986 | * but it does control brightness. The values are 0 - 15 only, and | ||
987 | * the table above makes them act consecutively. | ||
988 | */ | ||
989 | if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) && | ||
990 | (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX))) | ||
991 | return; | ||
992 | |||
993 | if (sd->cam_type == CAM_TYPE_VGA) { | 803 | if (sd->cam_type == CAM_TYPE_VGA) { |
994 | sign_reg += 4; | 804 | sign_reg += 4; |
995 | value_reg += 4; | 805 | value_reg += 4; |
996 | } | 806 | } |
997 | 807 | ||
998 | /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */ | 808 | /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */ |
999 | if (sd->brightness > 0) { | 809 | if (val > 0) { |
1000 | sensor_write1(gspca_dev, sign_reg, 0x00); | 810 | sensor_write1(gspca_dev, sign_reg, 0x00); |
1001 | val = sd->brightness; | ||
1002 | } else { | 811 | } else { |
1003 | sensor_write1(gspca_dev, sign_reg, 0x01); | 812 | sensor_write1(gspca_dev, sign_reg, 0x01); |
1004 | val = (257 - sd->brightness); | 813 | val = 257 - val; |
1005 | } | 814 | } |
1006 | /* Use lookup table for funky Argus QuickClix brightness */ | 815 | /* Use lookup table for funky Argus QuickClix brightness */ |
1007 | if (sd->do_lcd_stop) | 816 | if (sd->do_lcd_stop) |
@@ -1010,23 +819,20 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1010 | sensor_write1(gspca_dev, value_reg, val); | 819 | sensor_write1(gspca_dev, value_reg, val); |
1011 | } | 820 | } |
1012 | 821 | ||
1013 | static void setexposure(struct gspca_dev *gspca_dev) | 822 | static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv) |
1014 | { | 823 | { |
1015 | struct sd *sd = (struct sd *) gspca_dev; | 824 | struct sd *sd = (struct sd *) gspca_dev; |
1016 | int exposure = MR97310A_EXPOSURE_DEFAULT; | 825 | int exposure = MR97310A_EXPOSURE_DEFAULT; |
1017 | u8 buf[2]; | 826 | u8 buf[2]; |
1018 | 827 | ||
1019 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) | ||
1020 | return; | ||
1021 | |||
1022 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { | 828 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { |
1023 | /* This cam does not like exposure settings < 300, | 829 | /* This cam does not like exposure settings < 300, |
1024 | so scale 0 - 4095 to 300 - 4095 */ | 830 | so scale 0 - 4095 to 300 - 4095 */ |
1025 | exposure = (sd->exposure * 9267) / 10000 + 300; | 831 | exposure = (expo * 9267) / 10000 + 300; |
1026 | sensor_write1(gspca_dev, 3, exposure >> 4); | 832 | sensor_write1(gspca_dev, 3, exposure >> 4); |
1027 | sensor_write1(gspca_dev, 4, exposure & 0x0f); | 833 | sensor_write1(gspca_dev, 4, exposure & 0x0f); |
1028 | } else if (sd->sensor_type == 2) { | 834 | } else if (sd->sensor_type == 2) { |
1029 | exposure = sd->exposure; | 835 | exposure = expo; |
1030 | exposure >>= 3; | 836 | exposure >>= 3; |
1031 | sensor_write1(gspca_dev, 3, exposure >> 8); | 837 | sensor_write1(gspca_dev, 3, exposure >> 8); |
1032 | sensor_write1(gspca_dev, 4, exposure & 0xff); | 838 | sensor_write1(gspca_dev, 4, exposure & 0xff); |
@@ -1038,11 +844,11 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1038 | 844 | ||
1039 | Note our 0 - 4095 exposure is mapped to 0 - 511 | 845 | Note our 0 - 4095 exposure is mapped to 0 - 511 |
1040 | milliseconds exposure time */ | 846 | milliseconds exposure time */ |
1041 | u8 clockdiv = (60 * sd->exposure + 7999) / 8000; | 847 | u8 clockdiv = (60 * expo + 7999) / 8000; |
1042 | 848 | ||
1043 | /* Limit framerate to not exceed usb bandwidth */ | 849 | /* Limit framerate to not exceed usb bandwidth */ |
1044 | if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320) | 850 | if (clockdiv < min_clockdiv && gspca_dev->width >= 320) |
1045 | clockdiv = sd->min_clockdiv; | 851 | clockdiv = min_clockdiv; |
1046 | else if (clockdiv < 2) | 852 | else if (clockdiv < 2) |
1047 | clockdiv = 2; | 853 | clockdiv = 2; |
1048 | 854 | ||
@@ -1051,7 +857,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1051 | 857 | ||
1052 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> | 858 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> |
1053 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ | 859 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ |
1054 | exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); | 860 | exposure = (60 * 511 * expo) / (8000 * clockdiv); |
1055 | if (exposure > 511) | 861 | if (exposure > 511) |
1056 | exposure = 511; | 862 | exposure = 511; |
1057 | 863 | ||
@@ -1065,125 +871,148 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1065 | } | 871 | } |
1066 | } | 872 | } |
1067 | 873 | ||
1068 | static void setgain(struct gspca_dev *gspca_dev) | 874 | static void setgain(struct gspca_dev *gspca_dev, s32 val) |
1069 | { | 875 | { |
1070 | struct sd *sd = (struct sd *) gspca_dev; | 876 | struct sd *sd = (struct sd *) gspca_dev; |
1071 | u8 gainreg; | 877 | u8 gainreg; |
1072 | 878 | ||
1073 | if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) && | ||
1074 | (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX))) | ||
1075 | return; | ||
1076 | |||
1077 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) | 879 | if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) |
1078 | sensor_write1(gspca_dev, 0x0e, sd->gain); | 880 | sensor_write1(gspca_dev, 0x0e, val); |
1079 | else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2) | 881 | else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2) |
1080 | for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) { | 882 | for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) { |
1081 | sensor_write1(gspca_dev, gainreg, sd->gain >> 8); | 883 | sensor_write1(gspca_dev, gainreg, val >> 8); |
1082 | sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff); | 884 | sensor_write1(gspca_dev, gainreg + 1, val & 0xff); |
1083 | } | 885 | } |
1084 | else | 886 | else |
1085 | sensor_write1(gspca_dev, 0x10, sd->gain); | 887 | sensor_write1(gspca_dev, 0x10, val); |
1086 | } | ||
1087 | |||
1088 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1089 | { | ||
1090 | struct sd *sd = (struct sd *) gspca_dev; | ||
1091 | |||
1092 | if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX)) | ||
1093 | return; | ||
1094 | |||
1095 | sensor_write1(gspca_dev, 0x1c, sd->contrast); | ||
1096 | } | ||
1097 | |||
1098 | |||
1099 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1100 | { | ||
1101 | struct sd *sd = (struct sd *) gspca_dev; | ||
1102 | |||
1103 | sd->brightness = val; | ||
1104 | if (gspca_dev->streaming) | ||
1105 | setbrightness(gspca_dev); | ||
1106 | return 0; | ||
1107 | } | ||
1108 | |||
1109 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1110 | { | ||
1111 | struct sd *sd = (struct sd *) gspca_dev; | ||
1112 | |||
1113 | *val = sd->brightness; | ||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
1118 | { | ||
1119 | struct sd *sd = (struct sd *) gspca_dev; | ||
1120 | |||
1121 | sd->exposure = val; | ||
1122 | if (gspca_dev->streaming) | ||
1123 | setexposure(gspca_dev); | ||
1124 | return 0; | ||
1125 | } | 888 | } |
1126 | 889 | ||
1127 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | 890 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
1128 | { | 891 | { |
1129 | struct sd *sd = (struct sd *) gspca_dev; | 892 | sensor_write1(gspca_dev, 0x1c, val); |
1130 | |||
1131 | *val = sd->exposure; | ||
1132 | return 0; | ||
1133 | } | 893 | } |
1134 | 894 | ||
1135 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 895 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1136 | { | 896 | { |
1137 | struct sd *sd = (struct sd *) gspca_dev; | 897 | struct gspca_dev *gspca_dev = |
898 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
899 | struct sd *sd = (struct sd *)gspca_dev; | ||
1138 | 900 | ||
1139 | sd->gain = val; | 901 | gspca_dev->usb_err = 0; |
1140 | if (gspca_dev->streaming) | ||
1141 | setgain(gspca_dev); | ||
1142 | return 0; | ||
1143 | } | ||
1144 | 902 | ||
1145 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | 903 | if (!gspca_dev->streaming) |
1146 | { | 904 | return 0; |
1147 | struct sd *sd = (struct sd *) gspca_dev; | ||
1148 | |||
1149 | *val = sd->gain; | ||
1150 | return 0; | ||
1151 | } | ||
1152 | 905 | ||
1153 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | 906 | switch (ctrl->id) { |
1154 | { | 907 | case V4L2_CID_BRIGHTNESS: |
1155 | struct sd *sd = (struct sd *) gspca_dev; | 908 | setbrightness(gspca_dev, ctrl->val); |
1156 | 909 | break; | |
1157 | sd->contrast = val; | 910 | case V4L2_CID_CONTRAST: |
1158 | if (gspca_dev->streaming) | 911 | setcontrast(gspca_dev, ctrl->val); |
1159 | setcontrast(gspca_dev); | 912 | break; |
1160 | return 0; | 913 | case V4L2_CID_EXPOSURE: |
914 | setexposure(gspca_dev, sd->exposure->val, | ||
915 | sd->min_clockdiv ? sd->min_clockdiv->val : 0); | ||
916 | break; | ||
917 | case V4L2_CID_GAIN: | ||
918 | setgain(gspca_dev, ctrl->val); | ||
919 | break; | ||
920 | } | ||
921 | return gspca_dev->usb_err; | ||
1161 | } | 922 | } |
1162 | 923 | ||
924 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
925 | .s_ctrl = sd_s_ctrl, | ||
926 | }; | ||
1163 | 927 | ||
1164 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 928 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
1165 | { | ||
1166 | struct sd *sd = (struct sd *) gspca_dev; | ||
1167 | |||
1168 | *val = sd->contrast; | ||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1172 | static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) | ||
1173 | { | 929 | { |
1174 | struct sd *sd = (struct sd *) gspca_dev; | 930 | struct sd *sd = (struct sd *)gspca_dev; |
931 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
932 | static const struct v4l2_ctrl_config clockdiv = { | ||
933 | .ops = &sd_ctrl_ops, | ||
934 | .id = MR97310A_CID_CLOCKDIV, | ||
935 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
936 | .name = "Minimum Clock Divider", | ||
937 | .min = MR97310A_MIN_CLOCKDIV_MIN, | ||
938 | .max = MR97310A_MIN_CLOCKDIV_MAX, | ||
939 | .step = 1, | ||
940 | .def = MR97310A_MIN_CLOCKDIV_DEFAULT, | ||
941 | }; | ||
942 | bool has_brightness = false; | ||
943 | bool has_argus_brightness = false; | ||
944 | bool has_contrast = false; | ||
945 | bool has_gain = false; | ||
946 | bool has_cs_gain = false; | ||
947 | bool has_exposure = false; | ||
948 | bool has_clockdiv = false; | ||
1175 | 949 | ||
1176 | sd->min_clockdiv = val; | 950 | gspca_dev->vdev.ctrl_handler = hdl; |
1177 | if (gspca_dev->streaming) | 951 | v4l2_ctrl_handler_init(hdl, 4); |
1178 | setexposure(gspca_dev); | ||
1179 | return 0; | ||
1180 | } | ||
1181 | 952 | ||
1182 | static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val) | 953 | /* Setup controls depending on camera type */ |
1183 | { | 954 | if (sd->cam_type == CAM_TYPE_CIF) { |
1184 | struct sd *sd = (struct sd *) gspca_dev; | 955 | /* No brightness for sensor_type 0 */ |
956 | if (sd->sensor_type == 0) | ||
957 | has_exposure = has_gain = has_clockdiv = true; | ||
958 | else | ||
959 | has_exposure = has_gain = has_brightness = true; | ||
960 | } else { | ||
961 | /* All controls need to be disabled if VGA sensor_type is 0 */ | ||
962 | if (sd->sensor_type == 0) | ||
963 | ; /* no controls! */ | ||
964 | else if (sd->sensor_type == 2) | ||
965 | has_exposure = has_cs_gain = has_contrast = true; | ||
966 | else if (sd->do_lcd_stop) | ||
967 | has_exposure = has_gain = has_argus_brightness = | ||
968 | has_clockdiv = true; | ||
969 | else | ||
970 | has_exposure = has_gain = has_brightness = | ||
971 | has_clockdiv = true; | ||
972 | } | ||
1185 | 973 | ||
1186 | *val = sd->min_clockdiv; | 974 | /* Separate brightness control description for Argus QuickClix as it has |
975 | * different limits from the other mr97310a cameras, and separate gain | ||
976 | * control for Sakar CyberPix camera. */ | ||
977 | /* | ||
978 | * This control is disabled for CIF type 1 and VGA type 0 cameras. | ||
979 | * It does not quite act linearly for the Argus QuickClix camera, | ||
980 | * but it does control brightness. The values are 0 - 15 only, and | ||
981 | * the table above makes them act consecutively. | ||
982 | */ | ||
983 | if (has_brightness) | ||
984 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
985 | V4L2_CID_BRIGHTNESS, -254, 255, 1, | ||
986 | MR97310A_BRIGHTNESS_DEFAULT); | ||
987 | else if (has_argus_brightness) | ||
988 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
989 | V4L2_CID_BRIGHTNESS, 0, 15, 1, | ||
990 | MR97310A_BRIGHTNESS_DEFAULT); | ||
991 | if (has_contrast) | ||
992 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
993 | V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN, | ||
994 | MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT); | ||
995 | if (has_gain) | ||
996 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
997 | V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX, | ||
998 | 1, MR97310A_GAIN_DEFAULT); | ||
999 | else if (has_cs_gain) | ||
1000 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN, | ||
1001 | MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX, | ||
1002 | 1, MR97310A_CS_GAIN_DEFAULT); | ||
1003 | if (has_exposure) | ||
1004 | sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1005 | V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN, | ||
1006 | MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT); | ||
1007 | if (has_clockdiv) | ||
1008 | sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL); | ||
1009 | |||
1010 | if (hdl->error) { | ||
1011 | pr_err("Could not initialize controls\n"); | ||
1012 | return hdl->error; | ||
1013 | } | ||
1014 | if (has_exposure && has_clockdiv) | ||
1015 | v4l2_ctrl_cluster(2, &sd->exposure); | ||
1187 | return 0; | 1016 | return 0; |
1188 | } | 1017 | } |
1189 | 1018 | ||
@@ -1221,10 +1050,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1221 | /* sub-driver description */ | 1050 | /* sub-driver description */ |
1222 | static const struct sd_desc sd_desc = { | 1051 | static const struct sd_desc sd_desc = { |
1223 | .name = MODULE_NAME, | 1052 | .name = MODULE_NAME, |
1224 | .ctrls = sd_ctrls, | ||
1225 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1226 | .config = sd_config, | 1053 | .config = sd_config, |
1227 | .init = sd_init, | 1054 | .init = sd_init, |
1055 | .init_controls = sd_init_controls, | ||
1228 | .start = sd_start, | 1056 | .start = sd_start, |
1229 | .stopN = sd_stopN, | 1057 | .stopN = sd_stopN, |
1230 | .pkt_scan = sd_pkt_scan, | 1058 | .pkt_scan = sd_pkt_scan, |
@@ -1256,6 +1084,7 @@ static struct usb_driver sd_driver = { | |||
1256 | #ifdef CONFIG_PM | 1084 | #ifdef CONFIG_PM |
1257 | .suspend = gspca_suspend, | 1085 | .suspend = gspca_suspend, |
1258 | .resume = gspca_resume, | 1086 | .resume = gspca_resume, |
1087 | .reset_resume = gspca_resume, | ||
1259 | #endif | 1088 | #endif |
1260 | }; | 1089 | }; |
1261 | 1090 | ||
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c index 42e021931e60..44c9964b1b3e 100644 --- a/drivers/media/video/gspca/nw80x.c +++ b/drivers/media/video/gspca/nw80x.c | |||
@@ -32,22 +32,10 @@ MODULE_LICENSE("GPL"); | |||
32 | 32 | ||
33 | static int webcam; | 33 | static int webcam; |
34 | 34 | ||
35 | /* controls */ | ||
36 | enum e_ctrl { | ||
37 | GAIN, | ||
38 | EXPOSURE, | ||
39 | AUTOGAIN, | ||
40 | NCTRLS /* number of controls */ | ||
41 | }; | ||
42 | |||
43 | #define AUTOGAIN_DEF 1 | ||
44 | |||
45 | /* specific webcam descriptor */ | 35 | /* specific webcam descriptor */ |
46 | struct sd { | 36 | struct sd { |
47 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 37 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
48 | 38 | ||
49 | struct gspca_ctrl ctrls[NCTRLS]; | ||
50 | |||
51 | u32 ae_res; | 39 | u32 ae_res; |
52 | s8 ag_cnt; | 40 | s8 ag_cnt; |
53 | #define AG_CNT_START 13 | 41 | #define AG_CNT_START 13 |
@@ -1667,17 +1655,13 @@ static int swap_bits(int v) | |||
1667 | return r; | 1655 | return r; |
1668 | } | 1656 | } |
1669 | 1657 | ||
1670 | static void setgain(struct gspca_dev *gspca_dev) | 1658 | static void setgain(struct gspca_dev *gspca_dev, u8 val) |
1671 | { | 1659 | { |
1672 | struct sd *sd = (struct sd *) gspca_dev; | 1660 | struct sd *sd = (struct sd *) gspca_dev; |
1673 | u8 val, v[2]; | 1661 | u8 v[2]; |
1674 | 1662 | ||
1675 | val = sd->ctrls[GAIN].val; | ||
1676 | switch (sd->webcam) { | 1663 | switch (sd->webcam) { |
1677 | case P35u: | 1664 | case P35u: |
1678 | /* Note the control goes from 0-255 not 0-127, but anything | ||
1679 | above 127 just means amplifying noise */ | ||
1680 | val >>= 1; /* 0 - 255 -> 0 - 127 */ | ||
1681 | reg_w(gspca_dev, 0x1026, &val, 1); | 1665 | reg_w(gspca_dev, 0x1026, &val, 1); |
1682 | break; | 1666 | break; |
1683 | case Kr651us: | 1667 | case Kr651us: |
@@ -1690,13 +1674,11 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
1690 | } | 1674 | } |
1691 | } | 1675 | } |
1692 | 1676 | ||
1693 | static void setexposure(struct gspca_dev *gspca_dev) | 1677 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
1694 | { | 1678 | { |
1695 | struct sd *sd = (struct sd *) gspca_dev; | 1679 | struct sd *sd = (struct sd *) gspca_dev; |
1696 | s16 val; | ||
1697 | u8 v[2]; | 1680 | u8 v[2]; |
1698 | 1681 | ||
1699 | val = sd->ctrls[EXPOSURE].val; | ||
1700 | switch (sd->webcam) { | 1682 | switch (sd->webcam) { |
1701 | case P35u: | 1683 | case P35u: |
1702 | v[0] = ((9 - val) << 3) | 0x01; | 1684 | v[0] = ((9 - val) << 3) | 0x01; |
@@ -1713,14 +1695,12 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1713 | } | 1695 | } |
1714 | } | 1696 | } |
1715 | 1697 | ||
1716 | static void setautogain(struct gspca_dev *gspca_dev) | 1698 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
1717 | { | 1699 | { |
1718 | struct sd *sd = (struct sd *) gspca_dev; | 1700 | struct sd *sd = (struct sd *) gspca_dev; |
1719 | int w, h; | 1701 | int w, h; |
1720 | 1702 | ||
1721 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) | 1703 | if (!val) { |
1722 | return; | ||
1723 | if (!sd->ctrls[AUTOGAIN].val) { | ||
1724 | sd->ag_cnt = -1; | 1704 | sd->ag_cnt = -1; |
1725 | return; | 1705 | return; |
1726 | } | 1706 | } |
@@ -1763,7 +1743,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1763 | if ((unsigned) webcam >= NWEBCAMS) | 1743 | if ((unsigned) webcam >= NWEBCAMS) |
1764 | webcam = 0; | 1744 | webcam = 0; |
1765 | sd->webcam = webcam; | 1745 | sd->webcam = webcam; |
1766 | gspca_dev->cam.ctrls = sd->ctrls; | ||
1767 | gspca_dev->cam.needs_full_bandwidth = 1; | 1746 | gspca_dev->cam.needs_full_bandwidth = 1; |
1768 | sd->ag_cnt = -1; | 1747 | sd->ag_cnt = -1; |
1769 | 1748 | ||
@@ -1834,33 +1813,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1834 | break; | 1813 | break; |
1835 | } | 1814 | } |
1836 | } | 1815 | } |
1837 | switch (sd->webcam) { | ||
1838 | case P35u: | ||
1839 | /* sd->ctrls[EXPOSURE].max = 9; | ||
1840 | * sd->ctrls[EXPOSURE].def = 9; */ | ||
1841 | /* coarse expo auto gain function gain minimum, to avoid | ||
1842 | * a large settings jump the first auto adjustment */ | ||
1843 | sd->ctrls[GAIN].def = 255 / 5 * 2; | ||
1844 | break; | ||
1845 | case Cvideopro: | ||
1846 | case DvcV6: | ||
1847 | case Kritter: | ||
1848 | gspca_dev->ctrl_dis = (1 << GAIN) | (1 << AUTOGAIN); | ||
1849 | /* fall thru */ | ||
1850 | case Kr651us: | ||
1851 | sd->ctrls[EXPOSURE].max = 315; | ||
1852 | sd->ctrls[EXPOSURE].def = 150; | ||
1853 | break; | ||
1854 | default: | ||
1855 | gspca_dev->ctrl_dis = (1 << GAIN) | (1 << EXPOSURE) | ||
1856 | | (1 << AUTOGAIN); | ||
1857 | break; | ||
1858 | } | ||
1859 | 1816 | ||
1860 | #if AUTOGAIN_DEF | ||
1861 | if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN))) | ||
1862 | gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE); | ||
1863 | #endif | ||
1864 | return gspca_dev->usb_err; | 1817 | return gspca_dev->usb_err; |
1865 | } | 1818 | } |
1866 | 1819 | ||
@@ -1925,9 +1878,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1925 | break; | 1878 | break; |
1926 | } | 1879 | } |
1927 | 1880 | ||
1928 | setgain(gspca_dev); | ||
1929 | setexposure(gspca_dev); | ||
1930 | setautogain(gspca_dev); | ||
1931 | sd->exp_too_high_cnt = 0; | 1881 | sd->exp_too_high_cnt = 0; |
1932 | sd->exp_too_low_cnt = 0; | 1882 | sd->exp_too_low_cnt = 0; |
1933 | return gspca_dev->usb_err; | 1883 | return gspca_dev->usb_err; |
@@ -1987,24 +1937,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1987 | } | 1937 | } |
1988 | } | 1938 | } |
1989 | 1939 | ||
1990 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1991 | { | ||
1992 | struct sd *sd = (struct sd *) gspca_dev; | ||
1993 | |||
1994 | sd->ctrls[AUTOGAIN].val = val; | ||
1995 | if (val) | ||
1996 | gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE); | ||
1997 | else | ||
1998 | gspca_dev->ctrl_inac = 0; | ||
1999 | if (gspca_dev->streaming) | ||
2000 | setautogain(gspca_dev); | ||
2001 | return gspca_dev->usb_err; | ||
2002 | } | ||
2003 | |||
2004 | #define WANT_REGULAR_AUTOGAIN | ||
2005 | #define WANT_COARSE_EXPO_AUTOGAIN | ||
2006 | #include "autogain_functions.h" | ||
2007 | |||
2008 | static void do_autogain(struct gspca_dev *gspca_dev) | 1940 | static void do_autogain(struct gspca_dev *gspca_dev) |
2009 | { | 1941 | { |
2010 | struct sd *sd = (struct sd *) gspca_dev; | 1942 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -2024,62 +1956,100 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2024 | 1956 | ||
2025 | switch (sd->webcam) { | 1957 | switch (sd->webcam) { |
2026 | case P35u: | 1958 | case P35u: |
2027 | coarse_grained_expo_autogain(gspca_dev, luma, 100, 5); | 1959 | gspca_coarse_grained_expo_autogain(gspca_dev, luma, 100, 5); |
2028 | break; | 1960 | break; |
2029 | default: | 1961 | default: |
2030 | auto_gain_n_exposure(gspca_dev, luma, 100, 5, 230, 0); | 1962 | gspca_expo_autogain(gspca_dev, luma, 100, 5, 230, 0); |
2031 | break; | 1963 | break; |
2032 | } | 1964 | } |
2033 | } | 1965 | } |
2034 | 1966 | ||
2035 | /* V4L2 controls supported by the driver */ | 1967 | |
2036 | static const struct ctrl sd_ctrls[NCTRLS] = { | 1968 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
2037 | [GAIN] = { | 1969 | { |
2038 | { | 1970 | struct gspca_dev *gspca_dev = |
2039 | .id = V4L2_CID_GAIN, | 1971 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); |
2040 | .type = V4L2_CTRL_TYPE_INTEGER, | 1972 | |
2041 | .name = "Gain", | 1973 | gspca_dev->usb_err = 0; |
2042 | .minimum = 0, | 1974 | |
2043 | .maximum = 253, | 1975 | if (!gspca_dev->streaming) |
2044 | .step = 1, | 1976 | return 0; |
2045 | .default_value = 128 | 1977 | |
2046 | }, | 1978 | switch (ctrl->id) { |
2047 | .set_control = setgain | 1979 | /* autogain/gain/exposure control cluster */ |
2048 | }, | 1980 | case V4L2_CID_AUTOGAIN: |
2049 | [EXPOSURE] = { | 1981 | if (ctrl->is_new) |
2050 | { | 1982 | setautogain(gspca_dev, ctrl->val); |
2051 | .id = V4L2_CID_EXPOSURE, | 1983 | if (!ctrl->val) { |
2052 | .type = V4L2_CTRL_TYPE_INTEGER, | 1984 | if (gspca_dev->gain->is_new) |
2053 | .name = "Exposure", | 1985 | setgain(gspca_dev, gspca_dev->gain->val); |
2054 | .minimum = 0, | 1986 | if (gspca_dev->exposure->is_new) |
2055 | .maximum = 9, | 1987 | setexposure(gspca_dev, |
2056 | .step = 1, | 1988 | gspca_dev->exposure->val); |
2057 | .default_value = 9 | 1989 | } |
2058 | }, | 1990 | break; |
2059 | .set_control = setexposure | 1991 | /* Some webcams only have exposure, so handle that separately from the |
2060 | }, | 1992 | autogain/gain/exposure cluster in the previous case. */ |
2061 | [AUTOGAIN] = { | 1993 | case V4L2_CID_EXPOSURE: |
2062 | { | 1994 | setexposure(gspca_dev, gspca_dev->exposure->val); |
2063 | .id = V4L2_CID_AUTOGAIN, | 1995 | break; |
2064 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 1996 | } |
2065 | .name = "Auto Gain", | 1997 | return gspca_dev->usb_err; |
2066 | .minimum = 0, | 1998 | } |
2067 | .maximum = 1, | 1999 | |
2068 | .step = 1, | 2000 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
2069 | .default_value = AUTOGAIN_DEF, | 2001 | .s_ctrl = sd_s_ctrl, |
2070 | .flags = V4L2_CTRL_FLAG_UPDATE | ||
2071 | }, | ||
2072 | .set = sd_setautogain | ||
2073 | }, | ||
2074 | }; | 2002 | }; |
2075 | 2003 | ||
2004 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
2005 | { | ||
2006 | struct sd *sd = (struct sd *)gspca_dev; | ||
2007 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
2008 | |||
2009 | gspca_dev->vdev.ctrl_handler = hdl; | ||
2010 | v4l2_ctrl_handler_init(hdl, 3); | ||
2011 | switch (sd->webcam) { | ||
2012 | case P35u: | ||
2013 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2014 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
2015 | /* For P35u choose coarse expo auto gain function gain minimum, | ||
2016 | * to avoid a large settings jump the first auto adjustment */ | ||
2017 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2018 | V4L2_CID_GAIN, 0, 127, 1, 127 / 5 * 2); | ||
2019 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2020 | V4L2_CID_EXPOSURE, 0, 9, 1, 9); | ||
2021 | break; | ||
2022 | case Kr651us: | ||
2023 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2024 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
2025 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2026 | V4L2_CID_GAIN, 0, 253, 1, 128); | ||
2027 | /* fall through */ | ||
2028 | case Cvideopro: | ||
2029 | case DvcV6: | ||
2030 | case Kritter: | ||
2031 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2032 | V4L2_CID_EXPOSURE, 0, 315, 1, 150); | ||
2033 | break; | ||
2034 | default: | ||
2035 | break; | ||
2036 | } | ||
2037 | |||
2038 | if (hdl->error) { | ||
2039 | pr_err("Could not initialize controls\n"); | ||
2040 | return hdl->error; | ||
2041 | } | ||
2042 | if (gspca_dev->autogain) | ||
2043 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); | ||
2044 | return 0; | ||
2045 | } | ||
2046 | |||
2076 | /* sub-driver description */ | 2047 | /* sub-driver description */ |
2077 | static const struct sd_desc sd_desc = { | 2048 | static const struct sd_desc sd_desc = { |
2078 | .name = MODULE_NAME, | 2049 | .name = MODULE_NAME, |
2079 | .ctrls = sd_ctrls, | ||
2080 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2081 | .config = sd_config, | 2050 | .config = sd_config, |
2082 | .init = sd_init, | 2051 | .init = sd_init, |
2052 | .init_controls = sd_init_controls, | ||
2083 | .start = sd_start, | 2053 | .start = sd_start, |
2084 | .stopN = sd_stopN, | 2054 | .stopN = sd_stopN, |
2085 | .pkt_scan = sd_pkt_scan, | 2055 | .pkt_scan = sd_pkt_scan, |
@@ -2117,6 +2087,7 @@ static struct usb_driver sd_driver = { | |||
2117 | #ifdef CONFIG_PM | 2087 | #ifdef CONFIG_PM |
2118 | .suspend = gspca_suspend, | 2088 | .suspend = gspca_suspend, |
2119 | .resume = gspca_resume, | 2089 | .resume = gspca_resume, |
2090 | .reset_resume = gspca_resume, | ||
2120 | #endif | 2091 | #endif |
2121 | }; | 2092 | }; |
2122 | 2093 | ||
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 183457c5cfdb..bfc7cefa59f8 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -60,25 +60,20 @@ static int frame_rate; | |||
60 | * are getting "Failed to read sensor ID..." */ | 60 | * are getting "Failed to read sensor ID..." */ |
61 | static int i2c_detect_tries = 10; | 61 | static int i2c_detect_tries = 10; |
62 | 62 | ||
63 | /* controls */ | ||
64 | enum e_ctrl { | ||
65 | BRIGHTNESS, | ||
66 | CONTRAST, | ||
67 | EXPOSURE, | ||
68 | COLORS, | ||
69 | HFLIP, | ||
70 | VFLIP, | ||
71 | AUTOBRIGHT, | ||
72 | AUTOGAIN, | ||
73 | FREQ, | ||
74 | NCTRL /* number of controls */ | ||
75 | }; | ||
76 | |||
77 | /* ov519 device descriptor */ | 63 | /* ov519 device descriptor */ |
78 | struct sd { | 64 | struct sd { |
79 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 65 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
80 | 66 | ||
81 | struct gspca_ctrl ctrls[NCTRL]; | 67 | struct v4l2_ctrl *jpegqual; |
68 | struct v4l2_ctrl *freq; | ||
69 | struct { /* h/vflip control cluster */ | ||
70 | struct v4l2_ctrl *hflip; | ||
71 | struct v4l2_ctrl *vflip; | ||
72 | }; | ||
73 | struct { /* autobrightness/brightness control cluster */ | ||
74 | struct v4l2_ctrl *autobright; | ||
75 | struct v4l2_ctrl *brightness; | ||
76 | }; | ||
82 | 77 | ||
83 | u8 packet_nr; | 78 | u8 packet_nr; |
84 | 79 | ||
@@ -101,7 +96,6 @@ struct sd { | |||
101 | /* Determined by sensor type */ | 96 | /* Determined by sensor type */ |
102 | u8 sif; | 97 | u8 sif; |
103 | 98 | ||
104 | u8 quality; | ||
105 | #define QUALITY_MIN 50 | 99 | #define QUALITY_MIN 50 |
106 | #define QUALITY_MAX 70 | 100 | #define QUALITY_MAX 70 |
107 | #define QUALITY_DEF 50 | 101 | #define QUALITY_DEF 50 |
@@ -145,209 +139,112 @@ enum sensors { | |||
145 | really should move the sensor drivers to v4l2 sub drivers. */ | 139 | really should move the sensor drivers to v4l2 sub drivers. */ |
146 | #include "w996Xcf.c" | 140 | #include "w996Xcf.c" |
147 | 141 | ||
148 | /* V4L2 controls supported by the driver */ | 142 | /* table of the disabled controls */ |
149 | static void setbrightness(struct gspca_dev *gspca_dev); | 143 | struct ctrl_valid { |
150 | static void setcontrast(struct gspca_dev *gspca_dev); | 144 | int has_brightness:1; |
151 | static void setexposure(struct gspca_dev *gspca_dev); | 145 | int has_contrast:1; |
152 | static void setcolors(struct gspca_dev *gspca_dev); | 146 | int has_exposure:1; |
153 | static void sethvflip(struct gspca_dev *gspca_dev); | 147 | int has_autogain:1; |
154 | static void setautobright(struct gspca_dev *gspca_dev); | 148 | int has_sat:1; |
155 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 149 | int has_hvflip:1; |
156 | static void setfreq(struct gspca_dev *gspca_dev); | 150 | int has_autobright:1; |
157 | static void setfreq_i(struct sd *sd); | 151 | int has_freq:1; |
158 | 152 | }; | |
159 | static const struct ctrl sd_ctrls[] = { | 153 | |
160 | [BRIGHTNESS] = { | 154 | static const struct ctrl_valid valid_controls[] = { |
161 | { | 155 | [SEN_OV2610] = { |
162 | .id = V4L2_CID_BRIGHTNESS, | 156 | .has_exposure = 1, |
163 | .type = V4L2_CTRL_TYPE_INTEGER, | 157 | .has_autogain = 1, |
164 | .name = "Brightness", | ||
165 | .minimum = 0, | ||
166 | .maximum = 255, | ||
167 | .step = 1, | ||
168 | .default_value = 127, | ||
169 | }, | ||
170 | .set_control = setbrightness, | ||
171 | }, | 158 | }, |
172 | [CONTRAST] = { | 159 | [SEN_OV2610AE] = { |
173 | { | 160 | .has_exposure = 1, |
174 | .id = V4L2_CID_CONTRAST, | 161 | .has_autogain = 1, |
175 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
176 | .name = "Contrast", | ||
177 | .minimum = 0, | ||
178 | .maximum = 255, | ||
179 | .step = 1, | ||
180 | .default_value = 127, | ||
181 | }, | ||
182 | .set_control = setcontrast, | ||
183 | }, | 162 | }, |
184 | [EXPOSURE] = { | 163 | [SEN_OV3610] = { |
185 | { | 164 | /* No controls */ |
186 | .id = V4L2_CID_EXPOSURE, | ||
187 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
188 | .name = "Exposure", | ||
189 | .minimum = 0, | ||
190 | .maximum = 255, | ||
191 | .step = 1, | ||
192 | .default_value = 127, | ||
193 | }, | ||
194 | .set_control = setexposure, | ||
195 | }, | 165 | }, |
196 | [COLORS] = { | 166 | [SEN_OV6620] = { |
197 | { | 167 | .has_brightness = 1, |
198 | .id = V4L2_CID_SATURATION, | 168 | .has_contrast = 1, |
199 | .type = V4L2_CTRL_TYPE_INTEGER, | 169 | .has_sat = 1, |
200 | .name = "Color", | 170 | .has_autobright = 1, |
201 | .minimum = 0, | 171 | .has_freq = 1, |
202 | .maximum = 255, | ||
203 | .step = 1, | ||
204 | .default_value = 127, | ||
205 | }, | ||
206 | .set_control = setcolors, | ||
207 | }, | 172 | }, |
208 | /* The flip controls work for sensors ov7660 and ov7670 only */ | 173 | [SEN_OV6630] = { |
209 | [HFLIP] = { | 174 | .has_brightness = 1, |
210 | { | 175 | .has_contrast = 1, |
211 | .id = V4L2_CID_HFLIP, | 176 | .has_sat = 1, |
212 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 177 | .has_autobright = 1, |
213 | .name = "Mirror", | 178 | .has_freq = 1, |
214 | .minimum = 0, | ||
215 | .maximum = 1, | ||
216 | .step = 1, | ||
217 | .default_value = 0, | ||
218 | }, | ||
219 | .set_control = sethvflip, | ||
220 | }, | 179 | }, |
221 | [VFLIP] = { | 180 | [SEN_OV66308AF] = { |
222 | { | 181 | .has_brightness = 1, |
223 | .id = V4L2_CID_VFLIP, | 182 | .has_contrast = 1, |
224 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 183 | .has_sat = 1, |
225 | .name = "Vflip", | 184 | .has_autobright = 1, |
226 | .minimum = 0, | 185 | .has_freq = 1, |
227 | .maximum = 1, | ||
228 | .step = 1, | ||
229 | .default_value = 0, | ||
230 | }, | ||
231 | .set_control = sethvflip, | ||
232 | }, | 186 | }, |
233 | [AUTOBRIGHT] = { | 187 | [SEN_OV7610] = { |
234 | { | 188 | .has_brightness = 1, |
235 | .id = V4L2_CID_AUTOBRIGHTNESS, | 189 | .has_contrast = 1, |
236 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 190 | .has_sat = 1, |
237 | .name = "Auto Brightness", | 191 | .has_autobright = 1, |
238 | .minimum = 0, | 192 | .has_freq = 1, |
239 | .maximum = 1, | ||
240 | .step = 1, | ||
241 | .default_value = 1, | ||
242 | }, | ||
243 | .set_control = setautobright, | ||
244 | }, | 193 | }, |
245 | [AUTOGAIN] = { | 194 | [SEN_OV7620] = { |
246 | { | 195 | .has_brightness = 1, |
247 | .id = V4L2_CID_AUTOGAIN, | 196 | .has_contrast = 1, |
248 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 197 | .has_sat = 1, |
249 | .name = "Auto Gain", | 198 | .has_autobright = 1, |
250 | .minimum = 0, | 199 | .has_freq = 1, |
251 | .maximum = 1, | ||
252 | .step = 1, | ||
253 | .default_value = 1, | ||
254 | .flags = V4L2_CTRL_FLAG_UPDATE | ||
255 | }, | ||
256 | .set = sd_setautogain, | ||
257 | }, | 200 | }, |
258 | [FREQ] = { | 201 | [SEN_OV7620AE] = { |
259 | { | 202 | .has_brightness = 1, |
260 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 203 | .has_contrast = 1, |
261 | .type = V4L2_CTRL_TYPE_MENU, | 204 | .has_sat = 1, |
262 | .name = "Light frequency filter", | 205 | .has_autobright = 1, |
263 | .minimum = 0, | 206 | .has_freq = 1, |
264 | .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */ | 207 | }, |
265 | .step = 1, | 208 | [SEN_OV7640] = { |
266 | .default_value = 0, | 209 | .has_brightness = 1, |
267 | }, | 210 | .has_sat = 1, |
268 | .set_control = setfreq, | 211 | .has_freq = 1, |
212 | }, | ||
213 | [SEN_OV7648] = { | ||
214 | .has_brightness = 1, | ||
215 | .has_sat = 1, | ||
216 | .has_freq = 1, | ||
217 | }, | ||
218 | [SEN_OV7660] = { | ||
219 | .has_brightness = 1, | ||
220 | .has_contrast = 1, | ||
221 | .has_sat = 1, | ||
222 | .has_hvflip = 1, | ||
223 | .has_freq = 1, | ||
224 | }, | ||
225 | [SEN_OV7670] = { | ||
226 | .has_brightness = 1, | ||
227 | .has_contrast = 1, | ||
228 | .has_hvflip = 1, | ||
229 | .has_freq = 1, | ||
230 | }, | ||
231 | [SEN_OV76BE] = { | ||
232 | .has_brightness = 1, | ||
233 | .has_contrast = 1, | ||
234 | .has_sat = 1, | ||
235 | .has_autobright = 1, | ||
236 | .has_freq = 1, | ||
237 | }, | ||
238 | [SEN_OV8610] = { | ||
239 | .has_brightness = 1, | ||
240 | .has_contrast = 1, | ||
241 | .has_sat = 1, | ||
242 | .has_autobright = 1, | ||
243 | }, | ||
244 | [SEN_OV9600] = { | ||
245 | .has_exposure = 1, | ||
246 | .has_autogain = 1, | ||
269 | }, | 247 | }, |
270 | }; | ||
271 | |||
272 | /* table of the disabled controls */ | ||
273 | static const unsigned ctrl_dis[] = { | ||
274 | [SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */ | ||
275 | ^ ((1 << EXPOSURE) /* but exposure */ | ||
276 | | (1 << AUTOGAIN)), /* and autogain */ | ||
277 | |||
278 | [SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */ | ||
279 | ^ ((1 << EXPOSURE) /* but exposure */ | ||
280 | | (1 << AUTOGAIN)), /* and autogain */ | ||
281 | |||
282 | [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ | ||
283 | |||
284 | [SEN_OV6620] = (1 << HFLIP) | | ||
285 | (1 << VFLIP) | | ||
286 | (1 << EXPOSURE) | | ||
287 | (1 << AUTOGAIN), | ||
288 | |||
289 | [SEN_OV6630] = (1 << HFLIP) | | ||
290 | (1 << VFLIP) | | ||
291 | (1 << EXPOSURE) | | ||
292 | (1 << AUTOGAIN), | ||
293 | |||
294 | [SEN_OV66308AF] = (1 << HFLIP) | | ||
295 | (1 << VFLIP) | | ||
296 | (1 << EXPOSURE) | | ||
297 | (1 << AUTOGAIN), | ||
298 | |||
299 | [SEN_OV7610] = (1 << HFLIP) | | ||
300 | (1 << VFLIP) | | ||
301 | (1 << EXPOSURE) | | ||
302 | (1 << AUTOGAIN), | ||
303 | |||
304 | [SEN_OV7620] = (1 << HFLIP) | | ||
305 | (1 << VFLIP) | | ||
306 | (1 << EXPOSURE) | | ||
307 | (1 << AUTOGAIN), | ||
308 | |||
309 | [SEN_OV7620AE] = (1 << HFLIP) | | ||
310 | (1 << VFLIP) | | ||
311 | (1 << EXPOSURE) | | ||
312 | (1 << AUTOGAIN), | ||
313 | |||
314 | [SEN_OV7640] = (1 << HFLIP) | | ||
315 | (1 << VFLIP) | | ||
316 | (1 << AUTOBRIGHT) | | ||
317 | (1 << CONTRAST) | | ||
318 | (1 << EXPOSURE) | | ||
319 | (1 << AUTOGAIN), | ||
320 | |||
321 | [SEN_OV7648] = (1 << HFLIP) | | ||
322 | (1 << VFLIP) | | ||
323 | (1 << AUTOBRIGHT) | | ||
324 | (1 << CONTRAST) | | ||
325 | (1 << EXPOSURE) | | ||
326 | (1 << AUTOGAIN), | ||
327 | |||
328 | [SEN_OV7660] = (1 << AUTOBRIGHT) | | ||
329 | (1 << EXPOSURE) | | ||
330 | (1 << AUTOGAIN), | ||
331 | |||
332 | [SEN_OV7670] = (1 << COLORS) | | ||
333 | (1 << AUTOBRIGHT) | | ||
334 | (1 << EXPOSURE) | | ||
335 | (1 << AUTOGAIN), | ||
336 | |||
337 | [SEN_OV76BE] = (1 << HFLIP) | | ||
338 | (1 << VFLIP) | | ||
339 | (1 << EXPOSURE) | | ||
340 | (1 << AUTOGAIN), | ||
341 | |||
342 | [SEN_OV8610] = (1 << HFLIP) | | ||
343 | (1 << VFLIP) | | ||
344 | (1 << EXPOSURE) | | ||
345 | (1 << AUTOGAIN) | | ||
346 | (1 << FREQ), | ||
347 | [SEN_OV9600] = ((1 << NCTRL) - 1) /* no control */ | ||
348 | ^ ((1 << EXPOSURE) /* but exposure */ | ||
349 | | (1 << AUTOGAIN)), /* and autogain */ | ||
350 | |||
351 | }; | 248 | }; |
352 | 249 | ||
353 | static const struct v4l2_pix_format ov519_vga_mode[] = { | 250 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
@@ -3306,11 +3203,11 @@ static void ov519_set_fr(struct sd *sd) | |||
3306 | ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); | 3203 | ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); |
3307 | } | 3204 | } |
3308 | 3205 | ||
3309 | static void setautogain(struct gspca_dev *gspca_dev) | 3206 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
3310 | { | 3207 | { |
3311 | struct sd *sd = (struct sd *) gspca_dev; | 3208 | struct sd *sd = (struct sd *) gspca_dev; |
3312 | 3209 | ||
3313 | i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05); | 3210 | i2c_w_mask(sd, 0x13, val ? 0x05 : 0x00, 0x05); |
3314 | } | 3211 | } |
3315 | 3212 | ||
3316 | /* this function is called at probe time */ | 3213 | /* this function is called at probe time */ |
@@ -3351,8 +3248,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3351 | break; | 3248 | break; |
3352 | } | 3249 | } |
3353 | 3250 | ||
3354 | gspca_dev->cam.ctrls = sd->ctrls; | ||
3355 | sd->quality = QUALITY_DEF; | ||
3356 | sd->frame_rate = 15; | 3251 | sd->frame_rate = 15; |
3357 | 3252 | ||
3358 | return 0; | 3253 | return 0; |
@@ -3467,8 +3362,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3467 | break; | 3362 | break; |
3468 | } | 3363 | } |
3469 | 3364 | ||
3470 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | ||
3471 | |||
3472 | /* initialize the sensor */ | 3365 | /* initialize the sensor */ |
3473 | switch (sd->sensor) { | 3366 | switch (sd->sensor) { |
3474 | case SEN_OV2610: | 3367 | case SEN_OV2610: |
@@ -3494,8 +3387,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3494 | break; | 3387 | break; |
3495 | case SEN_OV6630: | 3388 | case SEN_OV6630: |
3496 | case SEN_OV66308AF: | 3389 | case SEN_OV66308AF: |
3497 | sd->ctrls[CONTRAST].def = 200; | ||
3498 | /* The default is too low for the ov6630 */ | ||
3499 | write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); | 3390 | write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); |
3500 | break; | 3391 | break; |
3501 | default: | 3392 | default: |
@@ -3522,26 +3413,12 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3522 | sd->gspca_dev.curr_mode = 1; /* 640x480 */ | 3413 | sd->gspca_dev.curr_mode = 1; /* 640x480 */ |
3523 | ov519_set_mode(sd); | 3414 | ov519_set_mode(sd); |
3524 | ov519_set_fr(sd); | 3415 | ov519_set_fr(sd); |
3525 | sd->ctrls[COLORS].max = 4; /* 0..4 */ | ||
3526 | sd->ctrls[COLORS].val = | ||
3527 | sd->ctrls[COLORS].def = 2; | ||
3528 | setcolors(gspca_dev); | ||
3529 | sd->ctrls[CONTRAST].max = 6; /* 0..6 */ | ||
3530 | sd->ctrls[CONTRAST].val = | ||
3531 | sd->ctrls[CONTRAST].def = 3; | ||
3532 | setcontrast(gspca_dev); | ||
3533 | sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */ | ||
3534 | sd->ctrls[BRIGHTNESS].val = | ||
3535 | sd->ctrls[BRIGHTNESS].def = 3; | ||
3536 | setbrightness(gspca_dev); | ||
3537 | sd_reset_snapshot(gspca_dev); | 3416 | sd_reset_snapshot(gspca_dev); |
3538 | ov51x_restart(sd); | 3417 | ov51x_restart(sd); |
3539 | ov51x_stop(sd); /* not in win traces */ | 3418 | ov51x_stop(sd); /* not in win traces */ |
3540 | ov51x_led_control(sd, 0); | 3419 | ov51x_led_control(sd, 0); |
3541 | break; | 3420 | break; |
3542 | case SEN_OV7670: | 3421 | case SEN_OV7670: |
3543 | sd->ctrls[FREQ].max = 3; /* auto */ | ||
3544 | sd->ctrls[FREQ].def = 3; | ||
3545 | write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); | 3422 | write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); |
3546 | break; | 3423 | break; |
3547 | case SEN_OV8610: | 3424 | case SEN_OV8610: |
@@ -4177,15 +4054,14 @@ static void mode_init_ov_sensor_regs(struct sd *sd) | |||
4177 | } | 4054 | } |
4178 | 4055 | ||
4179 | /* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ | 4056 | /* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ |
4180 | static void sethvflip(struct gspca_dev *gspca_dev) | 4057 | static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) |
4181 | { | 4058 | { |
4182 | struct sd *sd = (struct sd *) gspca_dev; | 4059 | struct sd *sd = (struct sd *) gspca_dev; |
4183 | 4060 | ||
4184 | if (sd->gspca_dev.streaming) | 4061 | if (sd->gspca_dev.streaming) |
4185 | reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ | 4062 | reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ |
4186 | i2c_w_mask(sd, OV7670_R1E_MVFP, | 4063 | i2c_w_mask(sd, OV7670_R1E_MVFP, |
4187 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val | 4064 | OV7670_MVFP_MIRROR * hflip | OV7670_MVFP_VFLIP * vflip, |
4188 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, | ||
4189 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | 4065 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); |
4190 | if (sd->gspca_dev.streaming) | 4066 | if (sd->gspca_dev.streaming) |
4191 | reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ | 4067 | reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ |
@@ -4333,23 +4209,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
4333 | 4209 | ||
4334 | set_ov_sensor_window(sd); | 4210 | set_ov_sensor_window(sd); |
4335 | 4211 | ||
4336 | if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST))) | ||
4337 | setcontrast(gspca_dev); | ||
4338 | if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) | ||
4339 | setbrightness(gspca_dev); | ||
4340 | if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE))) | ||
4341 | setexposure(gspca_dev); | ||
4342 | if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) | ||
4343 | setcolors(gspca_dev); | ||
4344 | if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) | ||
4345 | sethvflip(gspca_dev); | ||
4346 | if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) | ||
4347 | setautobright(gspca_dev); | ||
4348 | if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN))) | ||
4349 | setautogain(gspca_dev); | ||
4350 | if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) | ||
4351 | setfreq_i(sd); | ||
4352 | |||
4353 | /* Force clear snapshot state in case the snapshot button was | 4212 | /* Force clear snapshot state in case the snapshot button was |
4354 | pressed while we weren't streaming */ | 4213 | pressed while we weren't streaming */ |
4355 | sd->snapshot_needs_reset = 1; | 4214 | sd->snapshot_needs_reset = 1; |
@@ -4605,10 +4464,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
4605 | 4464 | ||
4606 | /* -- management routines -- */ | 4465 | /* -- management routines -- */ |
4607 | 4466 | ||
4608 | static void setbrightness(struct gspca_dev *gspca_dev) | 4467 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
4609 | { | 4468 | { |
4610 | struct sd *sd = (struct sd *) gspca_dev; | 4469 | struct sd *sd = (struct sd *) gspca_dev; |
4611 | int val; | ||
4612 | static const struct ov_i2c_regvals brit_7660[][7] = { | 4470 | static const struct ov_i2c_regvals brit_7660[][7] = { |
4613 | {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, | 4471 | {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, |
4614 | {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, | 4472 | {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, |
@@ -4626,7 +4484,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4626 | {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} | 4484 | {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} |
4627 | }; | 4485 | }; |
4628 | 4486 | ||
4629 | val = sd->ctrls[BRIGHTNESS].val; | ||
4630 | switch (sd->sensor) { | 4487 | switch (sd->sensor) { |
4631 | case SEN_OV8610: | 4488 | case SEN_OV8610: |
4632 | case SEN_OV7610: | 4489 | case SEN_OV7610: |
@@ -4640,9 +4497,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4640 | break; | 4497 | break; |
4641 | case SEN_OV7620: | 4498 | case SEN_OV7620: |
4642 | case SEN_OV7620AE: | 4499 | case SEN_OV7620AE: |
4643 | /* 7620 doesn't like manual changes when in auto mode */ | 4500 | i2c_w(sd, OV7610_REG_BRT, val); |
4644 | if (!sd->ctrls[AUTOBRIGHT].val) | ||
4645 | i2c_w(sd, OV7610_REG_BRT, val); | ||
4646 | break; | 4501 | break; |
4647 | case SEN_OV7660: | 4502 | case SEN_OV7660: |
4648 | write_i2c_regvals(sd, brit_7660[val], | 4503 | write_i2c_regvals(sd, brit_7660[val], |
@@ -4656,10 +4511,9 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4656 | } | 4511 | } |
4657 | } | 4512 | } |
4658 | 4513 | ||
4659 | static void setcontrast(struct gspca_dev *gspca_dev) | 4514 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
4660 | { | 4515 | { |
4661 | struct sd *sd = (struct sd *) gspca_dev; | 4516 | struct sd *sd = (struct sd *) gspca_dev; |
4662 | int val; | ||
4663 | static const struct ov_i2c_regvals contrast_7660[][31] = { | 4517 | static const struct ov_i2c_regvals contrast_7660[][31] = { |
4664 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, | 4518 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, |
4665 | {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, | 4519 | {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, |
@@ -4719,7 +4573,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4719 | {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, | 4573 | {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, |
4720 | }; | 4574 | }; |
4721 | 4575 | ||
4722 | val = sd->ctrls[CONTRAST].val; | ||
4723 | switch (sd->sensor) { | 4576 | switch (sd->sensor) { |
4724 | case SEN_OV7610: | 4577 | case SEN_OV7610: |
4725 | case SEN_OV6620: | 4578 | case SEN_OV6620: |
@@ -4760,18 +4613,16 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4760 | } | 4613 | } |
4761 | } | 4614 | } |
4762 | 4615 | ||
4763 | static void setexposure(struct gspca_dev *gspca_dev) | 4616 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
4764 | { | 4617 | { |
4765 | struct sd *sd = (struct sd *) gspca_dev; | 4618 | struct sd *sd = (struct sd *) gspca_dev; |
4766 | 4619 | ||
4767 | if (!sd->ctrls[AUTOGAIN].val) | 4620 | i2c_w(sd, 0x10, val); |
4768 | i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val); | ||
4769 | } | 4621 | } |
4770 | 4622 | ||
4771 | static void setcolors(struct gspca_dev *gspca_dev) | 4623 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
4772 | { | 4624 | { |
4773 | struct sd *sd = (struct sd *) gspca_dev; | 4625 | struct sd *sd = (struct sd *) gspca_dev; |
4774 | int val; | ||
4775 | static const struct ov_i2c_regvals colors_7660[][6] = { | 4626 | static const struct ov_i2c_regvals colors_7660[][6] = { |
4776 | {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, | 4627 | {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, |
4777 | {0x53, 0x19}, {0x54, 0x23}}, | 4628 | {0x53, 0x19}, {0x54, 0x23}}, |
@@ -4785,7 +4636,6 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4785 | {0x53, 0x66}, {0x54, 0x8e}}, | 4636 | {0x53, 0x66}, {0x54, 0x8e}}, |
4786 | }; | 4637 | }; |
4787 | 4638 | ||
4788 | val = sd->ctrls[COLORS].val; | ||
4789 | switch (sd->sensor) { | 4639 | switch (sd->sensor) { |
4790 | case SEN_OV8610: | 4640 | case SEN_OV8610: |
4791 | case SEN_OV7610: | 4641 | case SEN_OV7610: |
@@ -4819,34 +4669,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4819 | } | 4669 | } |
4820 | } | 4670 | } |
4821 | 4671 | ||
4822 | static void setautobright(struct gspca_dev *gspca_dev) | 4672 | static void setautobright(struct gspca_dev *gspca_dev, s32 val) |
4823 | { | 4673 | { |
4824 | struct sd *sd = (struct sd *) gspca_dev; | 4674 | struct sd *sd = (struct sd *) gspca_dev; |
4825 | 4675 | ||
4826 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); | 4676 | i2c_w_mask(sd, 0x2d, val ? 0x10 : 0x00, 0x10); |
4827 | } | 4677 | } |
4828 | 4678 | ||
4829 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 4679 | static void setfreq_i(struct sd *sd, s32 val) |
4830 | { | ||
4831 | struct sd *sd = (struct sd *) gspca_dev; | ||
4832 | |||
4833 | sd->ctrls[AUTOGAIN].val = val; | ||
4834 | if (val) { | ||
4835 | gspca_dev->ctrl_inac |= (1 << EXPOSURE); | ||
4836 | } else { | ||
4837 | gspca_dev->ctrl_inac &= ~(1 << EXPOSURE); | ||
4838 | sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10); | ||
4839 | } | ||
4840 | if (gspca_dev->streaming) | ||
4841 | setautogain(gspca_dev); | ||
4842 | return gspca_dev->usb_err; | ||
4843 | } | ||
4844 | |||
4845 | static void setfreq_i(struct sd *sd) | ||
4846 | { | 4680 | { |
4847 | if (sd->sensor == SEN_OV7660 | 4681 | if (sd->sensor == SEN_OV7660 |
4848 | || sd->sensor == SEN_OV7670) { | 4682 | || sd->sensor == SEN_OV7670) { |
4849 | switch (sd->ctrls[FREQ].val) { | 4683 | switch (val) { |
4850 | case 0: /* Banding filter disabled */ | 4684 | case 0: /* Banding filter disabled */ |
4851 | i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); | 4685 | i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); |
4852 | break; | 4686 | break; |
@@ -4868,7 +4702,7 @@ static void setfreq_i(struct sd *sd) | |||
4868 | break; | 4702 | break; |
4869 | } | 4703 | } |
4870 | } else { | 4704 | } else { |
4871 | switch (sd->ctrls[FREQ].val) { | 4705 | switch (val) { |
4872 | case 0: /* Banding filter disabled */ | 4706 | case 0: /* Banding filter disabled */ |
4873 | i2c_w_mask(sd, 0x2d, 0x00, 0x04); | 4707 | i2c_w_mask(sd, 0x2d, 0x00, 0x04); |
4874 | i2c_w_mask(sd, 0x2a, 0x00, 0x80); | 4708 | i2c_w_mask(sd, 0x2a, 0x00, 0x80); |
@@ -4900,56 +4734,28 @@ static void setfreq_i(struct sd *sd) | |||
4900 | } | 4734 | } |
4901 | } | 4735 | } |
4902 | } | 4736 | } |
4903 | static void setfreq(struct gspca_dev *gspca_dev) | 4737 | |
4738 | static void setfreq(struct gspca_dev *gspca_dev, s32 val) | ||
4904 | { | 4739 | { |
4905 | struct sd *sd = (struct sd *) gspca_dev; | 4740 | struct sd *sd = (struct sd *) gspca_dev; |
4906 | 4741 | ||
4907 | setfreq_i(sd); | 4742 | setfreq_i(sd, val); |
4908 | 4743 | ||
4909 | /* Ugly but necessary */ | 4744 | /* Ugly but necessary */ |
4910 | if (sd->bridge == BRIDGE_W9968CF) | 4745 | if (sd->bridge == BRIDGE_W9968CF) |
4911 | w9968cf_set_crop_window(sd); | 4746 | w9968cf_set_crop_window(sd); |
4912 | } | 4747 | } |
4913 | 4748 | ||
4914 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
4915 | struct v4l2_querymenu *menu) | ||
4916 | { | ||
4917 | struct sd *sd = (struct sd *) gspca_dev; | ||
4918 | |||
4919 | switch (menu->id) { | ||
4920 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
4921 | switch (menu->index) { | ||
4922 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
4923 | strcpy((char *) menu->name, "NoFliker"); | ||
4924 | return 0; | ||
4925 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
4926 | strcpy((char *) menu->name, "50 Hz"); | ||
4927 | return 0; | ||
4928 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
4929 | strcpy((char *) menu->name, "60 Hz"); | ||
4930 | return 0; | ||
4931 | case 3: | ||
4932 | if (sd->sensor != SEN_OV7670) | ||
4933 | return -EINVAL; | ||
4934 | |||
4935 | strcpy((char *) menu->name, "Automatic"); | ||
4936 | return 0; | ||
4937 | } | ||
4938 | break; | ||
4939 | } | ||
4940 | return -EINVAL; | ||
4941 | } | ||
4942 | |||
4943 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 4749 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, |
4944 | struct v4l2_jpegcompression *jcomp) | 4750 | struct v4l2_jpegcompression *jcomp) |
4945 | { | 4751 | { |
4946 | struct sd *sd = (struct sd *) gspca_dev; | 4752 | struct sd *sd = (struct sd *) gspca_dev; |
4947 | 4753 | ||
4948 | if (sd->bridge != BRIDGE_W9968CF) | 4754 | if (sd->bridge != BRIDGE_W9968CF) |
4949 | return -EINVAL; | 4755 | return -ENOTTY; |
4950 | 4756 | ||
4951 | memset(jcomp, 0, sizeof *jcomp); | 4757 | memset(jcomp, 0, sizeof *jcomp); |
4952 | jcomp->quality = sd->quality; | 4758 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); |
4953 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | | 4759 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | |
4954 | V4L2_JPEG_MARKER_DRI; | 4760 | V4L2_JPEG_MARKER_DRI; |
4955 | return 0; | 4761 | return 0; |
@@ -4961,38 +4767,161 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, | |||
4961 | struct sd *sd = (struct sd *) gspca_dev; | 4767 | struct sd *sd = (struct sd *) gspca_dev; |
4962 | 4768 | ||
4963 | if (sd->bridge != BRIDGE_W9968CF) | 4769 | if (sd->bridge != BRIDGE_W9968CF) |
4964 | return -EINVAL; | 4770 | return -ENOTTY; |
4771 | |||
4772 | v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); | ||
4773 | return 0; | ||
4774 | } | ||
4965 | 4775 | ||
4966 | if (gspca_dev->streaming) | 4776 | static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
4967 | return -EBUSY; | 4777 | { |
4778 | struct gspca_dev *gspca_dev = | ||
4779 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
4780 | struct sd *sd = (struct sd *)gspca_dev; | ||
4968 | 4781 | ||
4969 | if (jcomp->quality < QUALITY_MIN) | 4782 | gspca_dev->usb_err = 0; |
4970 | sd->quality = QUALITY_MIN; | 4783 | |
4971 | else if (jcomp->quality > QUALITY_MAX) | 4784 | switch (ctrl->id) { |
4972 | sd->quality = QUALITY_MAX; | 4785 | case V4L2_CID_AUTOGAIN: |
4973 | else | 4786 | gspca_dev->exposure->val = i2c_r(sd, 0x10); |
4974 | sd->quality = jcomp->quality; | 4787 | break; |
4788 | } | ||
4789 | return 0; | ||
4790 | } | ||
4791 | |||
4792 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | ||
4793 | { | ||
4794 | struct gspca_dev *gspca_dev = | ||
4795 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
4796 | struct sd *sd = (struct sd *)gspca_dev; | ||
4797 | |||
4798 | gspca_dev->usb_err = 0; | ||
4799 | |||
4800 | if (!gspca_dev->streaming) | ||
4801 | return 0; | ||
4802 | |||
4803 | switch (ctrl->id) { | ||
4804 | case V4L2_CID_BRIGHTNESS: | ||
4805 | setbrightness(gspca_dev, ctrl->val); | ||
4806 | break; | ||
4807 | case V4L2_CID_CONTRAST: | ||
4808 | setcontrast(gspca_dev, ctrl->val); | ||
4809 | break; | ||
4810 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
4811 | setfreq(gspca_dev, ctrl->val); | ||
4812 | break; | ||
4813 | case V4L2_CID_AUTOBRIGHTNESS: | ||
4814 | if (ctrl->is_new) | ||
4815 | setautobright(gspca_dev, ctrl->val); | ||
4816 | if (!ctrl->val && sd->brightness->is_new) | ||
4817 | setbrightness(gspca_dev, sd->brightness->val); | ||
4818 | break; | ||
4819 | case V4L2_CID_SATURATION: | ||
4820 | setcolors(gspca_dev, ctrl->val); | ||
4821 | break; | ||
4822 | case V4L2_CID_HFLIP: | ||
4823 | sethvflip(gspca_dev, ctrl->val, sd->vflip->val); | ||
4824 | break; | ||
4825 | case V4L2_CID_AUTOGAIN: | ||
4826 | if (ctrl->is_new) | ||
4827 | setautogain(gspca_dev, ctrl->val); | ||
4828 | if (!ctrl->val && gspca_dev->exposure->is_new) | ||
4829 | setexposure(gspca_dev, gspca_dev->exposure->val); | ||
4830 | break; | ||
4831 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: | ||
4832 | return -EBUSY; /* Should never happen, as we grab the ctrl */ | ||
4833 | } | ||
4834 | return gspca_dev->usb_err; | ||
4835 | } | ||
4975 | 4836 | ||
4976 | /* Return resulting jcomp params to app */ | 4837 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
4977 | sd_get_jcomp(gspca_dev, jcomp); | 4838 | .g_volatile_ctrl = sd_g_volatile_ctrl, |
4839 | .s_ctrl = sd_s_ctrl, | ||
4840 | }; | ||
4841 | |||
4842 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
4843 | { | ||
4844 | struct sd *sd = (struct sd *)gspca_dev; | ||
4845 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
4846 | |||
4847 | gspca_dev->vdev.ctrl_handler = hdl; | ||
4848 | v4l2_ctrl_handler_init(hdl, 10); | ||
4849 | if (valid_controls[sd->sensor].has_brightness) | ||
4850 | sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4851 | V4L2_CID_BRIGHTNESS, 0, | ||
4852 | sd->sensor == SEN_OV7660 ? 6 : 255, 1, | ||
4853 | sd->sensor == SEN_OV7660 ? 3 : 127); | ||
4854 | if (valid_controls[sd->sensor].has_contrast) { | ||
4855 | if (sd->sensor == SEN_OV7660) | ||
4856 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4857 | V4L2_CID_CONTRAST, 0, 6, 1, 3); | ||
4858 | else | ||
4859 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4860 | V4L2_CID_CONTRAST, 0, 255, 1, | ||
4861 | (sd->sensor == SEN_OV6630 || | ||
4862 | sd->sensor == SEN_OV66308AF) ? 200 : 127); | ||
4863 | } | ||
4864 | if (valid_controls[sd->sensor].has_sat) | ||
4865 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4866 | V4L2_CID_SATURATION, 0, | ||
4867 | sd->sensor == SEN_OV7660 ? 4 : 255, 1, | ||
4868 | sd->sensor == SEN_OV7660 ? 2 : 127); | ||
4869 | if (valid_controls[sd->sensor].has_exposure) | ||
4870 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4871 | V4L2_CID_EXPOSURE, 0, 255, 1, 127); | ||
4872 | if (valid_controls[sd->sensor].has_hvflip) { | ||
4873 | sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4874 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
4875 | sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4876 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
4877 | } | ||
4878 | if (valid_controls[sd->sensor].has_autobright) | ||
4879 | sd->autobright = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4880 | V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1); | ||
4881 | if (valid_controls[sd->sensor].has_autogain) | ||
4882 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4883 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
4884 | if (valid_controls[sd->sensor].has_freq) { | ||
4885 | if (sd->sensor == SEN_OV7670) | ||
4886 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
4887 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
4888 | V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0, | ||
4889 | V4L2_CID_POWER_LINE_FREQUENCY_AUTO); | ||
4890 | else | ||
4891 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
4892 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
4893 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); | ||
4894 | } | ||
4895 | if (sd->bridge == BRIDGE_W9968CF) | ||
4896 | sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4897 | V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
4898 | QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); | ||
4978 | 4899 | ||
4900 | if (hdl->error) { | ||
4901 | pr_err("Could not initialize controls\n"); | ||
4902 | return hdl->error; | ||
4903 | } | ||
4904 | if (gspca_dev->autogain) | ||
4905 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, true); | ||
4906 | if (sd->autobright) | ||
4907 | v4l2_ctrl_auto_cluster(2, &sd->autobright, 0, false); | ||
4908 | if (sd->hflip) | ||
4909 | v4l2_ctrl_cluster(2, &sd->hflip); | ||
4979 | return 0; | 4910 | return 0; |
4980 | } | 4911 | } |
4981 | 4912 | ||
4982 | /* sub-driver description */ | 4913 | /* sub-driver description */ |
4983 | static const struct sd_desc sd_desc = { | 4914 | static const struct sd_desc sd_desc = { |
4984 | .name = MODULE_NAME, | 4915 | .name = MODULE_NAME, |
4985 | .ctrls = sd_ctrls, | ||
4986 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
4987 | .config = sd_config, | 4916 | .config = sd_config, |
4988 | .init = sd_init, | 4917 | .init = sd_init, |
4918 | .init_controls = sd_init_controls, | ||
4989 | .isoc_init = sd_isoc_init, | 4919 | .isoc_init = sd_isoc_init, |
4990 | .start = sd_start, | 4920 | .start = sd_start, |
4991 | .stopN = sd_stopN, | 4921 | .stopN = sd_stopN, |
4992 | .stop0 = sd_stop0, | 4922 | .stop0 = sd_stop0, |
4993 | .pkt_scan = sd_pkt_scan, | 4923 | .pkt_scan = sd_pkt_scan, |
4994 | .dq_callback = sd_reset_snapshot, | 4924 | .dq_callback = sd_reset_snapshot, |
4995 | .querymenu = sd_querymenu, | ||
4996 | .get_jcomp = sd_get_jcomp, | 4925 | .get_jcomp = sd_get_jcomp, |
4997 | .set_jcomp = sd_set_jcomp, | 4926 | .set_jcomp = sd_set_jcomp, |
4998 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 4927 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
@@ -5052,6 +4981,7 @@ static struct usb_driver sd_driver = { | |||
5052 | #ifdef CONFIG_PM | 4981 | #ifdef CONFIG_PM |
5053 | .suspend = gspca_suspend, | 4982 | .suspend = gspca_suspend, |
5054 | .resume = gspca_resume, | 4983 | .resume = gspca_resume, |
4984 | .reset_resume = gspca_resume, | ||
5055 | #endif | 4985 | #endif |
5056 | }; | 4986 | }; |
5057 | 4987 | ||
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 80c81dd6d68b..bb09d7884b89 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "gspca.h" | 35 | #include "gspca.h" |
36 | 36 | ||
37 | #include <linux/fixp-arith.h> | 37 | #include <linux/fixp-arith.h> |
38 | #include <media/v4l2-ctrls.h> | ||
38 | 39 | ||
39 | #define OV534_REG_ADDRESS 0xf1 /* sensor address */ | 40 | #define OV534_REG_ADDRESS 0xf1 /* sensor address */ |
40 | #define OV534_REG_SUBADDR 0xf2 | 41 | #define OV534_REG_SUBADDR 0xf2 |
@@ -53,29 +54,28 @@ MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); | |||
53 | MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); | 54 | MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); |
54 | MODULE_LICENSE("GPL"); | 55 | MODULE_LICENSE("GPL"); |
55 | 56 | ||
56 | /* controls */ | ||
57 | enum e_ctrl { | ||
58 | HUE, | ||
59 | SATURATION, | ||
60 | BRIGHTNESS, | ||
61 | CONTRAST, | ||
62 | GAIN, | ||
63 | EXPOSURE, | ||
64 | AGC, | ||
65 | AWB, | ||
66 | AEC, | ||
67 | SHARPNESS, | ||
68 | HFLIP, | ||
69 | VFLIP, | ||
70 | LIGHTFREQ, | ||
71 | NCTRLS /* number of controls */ | ||
72 | }; | ||
73 | |||
74 | /* specific webcam descriptor */ | 57 | /* specific webcam descriptor */ |
75 | struct sd { | 58 | struct sd { |
76 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 59 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
77 | 60 | ||
78 | struct gspca_ctrl ctrls[NCTRLS]; | 61 | struct v4l2_ctrl_handler ctrl_handler; |
62 | struct v4l2_ctrl *hue; | ||
63 | struct v4l2_ctrl *saturation; | ||
64 | struct v4l2_ctrl *brightness; | ||
65 | struct v4l2_ctrl *contrast; | ||
66 | struct { /* gain control cluster */ | ||
67 | struct v4l2_ctrl *autogain; | ||
68 | struct v4l2_ctrl *gain; | ||
69 | }; | ||
70 | struct v4l2_ctrl *autowhitebalance; | ||
71 | struct { /* exposure control cluster */ | ||
72 | struct v4l2_ctrl *autoexposure; | ||
73 | struct v4l2_ctrl *exposure; | ||
74 | }; | ||
75 | struct v4l2_ctrl *sharpness; | ||
76 | struct v4l2_ctrl *hflip; | ||
77 | struct v4l2_ctrl *vflip; | ||
78 | struct v4l2_ctrl *plfreq; | ||
79 | 79 | ||
80 | __u32 last_pts; | 80 | __u32 last_pts; |
81 | u16 last_fid; | 81 | u16 last_fid; |
@@ -89,181 +89,9 @@ enum sensors { | |||
89 | NSENSORS | 89 | NSENSORS |
90 | }; | 90 | }; |
91 | 91 | ||
92 | /* V4L2 controls supported by the driver */ | ||
93 | static void sethue(struct gspca_dev *gspca_dev); | ||
94 | static void setsaturation(struct gspca_dev *gspca_dev); | ||
95 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
96 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
97 | static void setgain(struct gspca_dev *gspca_dev); | ||
98 | static void setexposure(struct gspca_dev *gspca_dev); | ||
99 | static void setagc(struct gspca_dev *gspca_dev); | ||
100 | static void setawb(struct gspca_dev *gspca_dev); | ||
101 | static void setaec(struct gspca_dev *gspca_dev); | ||
102 | static void setsharpness(struct gspca_dev *gspca_dev); | ||
103 | static void sethvflip(struct gspca_dev *gspca_dev); | ||
104 | static void setlightfreq(struct gspca_dev *gspca_dev); | ||
105 | |||
106 | static int sd_start(struct gspca_dev *gspca_dev); | 92 | static int sd_start(struct gspca_dev *gspca_dev); |
107 | static void sd_stopN(struct gspca_dev *gspca_dev); | 93 | static void sd_stopN(struct gspca_dev *gspca_dev); |
108 | 94 | ||
109 | static const struct ctrl sd_ctrls[] = { | ||
110 | [HUE] = { | ||
111 | { | ||
112 | .id = V4L2_CID_HUE, | ||
113 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
114 | .name = "Hue", | ||
115 | .minimum = -90, | ||
116 | .maximum = 90, | ||
117 | .step = 1, | ||
118 | .default_value = 0, | ||
119 | }, | ||
120 | .set_control = sethue | ||
121 | }, | ||
122 | [SATURATION] = { | ||
123 | { | ||
124 | .id = V4L2_CID_SATURATION, | ||
125 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
126 | .name = "Saturation", | ||
127 | .minimum = 0, | ||
128 | .maximum = 255, | ||
129 | .step = 1, | ||
130 | .default_value = 64, | ||
131 | }, | ||
132 | .set_control = setsaturation | ||
133 | }, | ||
134 | [BRIGHTNESS] = { | ||
135 | { | ||
136 | .id = V4L2_CID_BRIGHTNESS, | ||
137 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
138 | .name = "Brightness", | ||
139 | .minimum = 0, | ||
140 | .maximum = 255, | ||
141 | .step = 1, | ||
142 | .default_value = 0, | ||
143 | }, | ||
144 | .set_control = setbrightness | ||
145 | }, | ||
146 | [CONTRAST] = { | ||
147 | { | ||
148 | .id = V4L2_CID_CONTRAST, | ||
149 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
150 | .name = "Contrast", | ||
151 | .minimum = 0, | ||
152 | .maximum = 255, | ||
153 | .step = 1, | ||
154 | .default_value = 32, | ||
155 | }, | ||
156 | .set_control = setcontrast | ||
157 | }, | ||
158 | [GAIN] = { | ||
159 | { | ||
160 | .id = V4L2_CID_GAIN, | ||
161 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
162 | .name = "Main Gain", | ||
163 | .minimum = 0, | ||
164 | .maximum = 63, | ||
165 | .step = 1, | ||
166 | .default_value = 20, | ||
167 | }, | ||
168 | .set_control = setgain | ||
169 | }, | ||
170 | [EXPOSURE] = { | ||
171 | { | ||
172 | .id = V4L2_CID_EXPOSURE, | ||
173 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
174 | .name = "Exposure", | ||
175 | .minimum = 0, | ||
176 | .maximum = 255, | ||
177 | .step = 1, | ||
178 | .default_value = 120, | ||
179 | }, | ||
180 | .set_control = setexposure | ||
181 | }, | ||
182 | [AGC] = { | ||
183 | { | ||
184 | .id = V4L2_CID_AUTOGAIN, | ||
185 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
186 | .name = "Auto Gain", | ||
187 | .minimum = 0, | ||
188 | .maximum = 1, | ||
189 | .step = 1, | ||
190 | .default_value = 1, | ||
191 | }, | ||
192 | .set_control = setagc | ||
193 | }, | ||
194 | [AWB] = { | ||
195 | { | ||
196 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
197 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
198 | .name = "Auto White Balance", | ||
199 | .minimum = 0, | ||
200 | .maximum = 1, | ||
201 | .step = 1, | ||
202 | .default_value = 1, | ||
203 | }, | ||
204 | .set_control = setawb | ||
205 | }, | ||
206 | [AEC] = { | ||
207 | { | ||
208 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
209 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
210 | .name = "Auto Exposure", | ||
211 | .minimum = 0, | ||
212 | .maximum = 1, | ||
213 | .step = 1, | ||
214 | .default_value = 1, | ||
215 | }, | ||
216 | .set_control = setaec | ||
217 | }, | ||
218 | [SHARPNESS] = { | ||
219 | { | ||
220 | .id = V4L2_CID_SHARPNESS, | ||
221 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
222 | .name = "Sharpness", | ||
223 | .minimum = 0, | ||
224 | .maximum = 63, | ||
225 | .step = 1, | ||
226 | .default_value = 0, | ||
227 | }, | ||
228 | .set_control = setsharpness | ||
229 | }, | ||
230 | [HFLIP] = { | ||
231 | { | ||
232 | .id = V4L2_CID_HFLIP, | ||
233 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
234 | .name = "HFlip", | ||
235 | .minimum = 0, | ||
236 | .maximum = 1, | ||
237 | .step = 1, | ||
238 | .default_value = 0, | ||
239 | }, | ||
240 | .set_control = sethvflip | ||
241 | }, | ||
242 | [VFLIP] = { | ||
243 | { | ||
244 | .id = V4L2_CID_VFLIP, | ||
245 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
246 | .name = "VFlip", | ||
247 | .minimum = 0, | ||
248 | .maximum = 1, | ||
249 | .step = 1, | ||
250 | .default_value = 0, | ||
251 | }, | ||
252 | .set_control = sethvflip | ||
253 | }, | ||
254 | [LIGHTFREQ] = { | ||
255 | { | ||
256 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
257 | .type = V4L2_CTRL_TYPE_MENU, | ||
258 | .name = "Light Frequency Filter", | ||
259 | .minimum = 0, | ||
260 | .maximum = 1, | ||
261 | .step = 1, | ||
262 | .default_value = 0, | ||
263 | }, | ||
264 | .set_control = setlightfreq | ||
265 | }, | ||
266 | }; | ||
267 | 95 | ||
268 | static const struct v4l2_pix_format ov772x_mode[] = { | 96 | static const struct v4l2_pix_format ov772x_mode[] = { |
269 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 97 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
@@ -972,12 +800,10 @@ static void set_frame_rate(struct gspca_dev *gspca_dev) | |||
972 | PDEBUG(D_PROBE, "frame_rate: %d", r->fps); | 800 | PDEBUG(D_PROBE, "frame_rate: %d", r->fps); |
973 | } | 801 | } |
974 | 802 | ||
975 | static void sethue(struct gspca_dev *gspca_dev) | 803 | static void sethue(struct gspca_dev *gspca_dev, s32 val) |
976 | { | 804 | { |
977 | struct sd *sd = (struct sd *) gspca_dev; | 805 | struct sd *sd = (struct sd *) gspca_dev; |
978 | int val; | ||
979 | 806 | ||
980 | val = sd->ctrls[HUE].val; | ||
981 | if (sd->sensor == SENSOR_OV767x) { | 807 | if (sd->sensor == SENSOR_OV767x) { |
982 | /* TBD */ | 808 | /* TBD */ |
983 | } else { | 809 | } else { |
@@ -1014,12 +840,10 @@ static void sethue(struct gspca_dev *gspca_dev) | |||
1014 | } | 840 | } |
1015 | } | 841 | } |
1016 | 842 | ||
1017 | static void setsaturation(struct gspca_dev *gspca_dev) | 843 | static void setsaturation(struct gspca_dev *gspca_dev, s32 val) |
1018 | { | 844 | { |
1019 | struct sd *sd = (struct sd *) gspca_dev; | 845 | struct sd *sd = (struct sd *) gspca_dev; |
1020 | int val; | ||
1021 | 846 | ||
1022 | val = sd->ctrls[SATURATION].val; | ||
1023 | if (sd->sensor == SENSOR_OV767x) { | 847 | if (sd->sensor == SENSOR_OV767x) { |
1024 | int i; | 848 | int i; |
1025 | static u8 color_tb[][6] = { | 849 | static u8 color_tb[][6] = { |
@@ -1040,12 +864,10 @@ static void setsaturation(struct gspca_dev *gspca_dev) | |||
1040 | } | 864 | } |
1041 | } | 865 | } |
1042 | 866 | ||
1043 | static void setbrightness(struct gspca_dev *gspca_dev) | 867 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
1044 | { | 868 | { |
1045 | struct sd *sd = (struct sd *) gspca_dev; | 869 | struct sd *sd = (struct sd *) gspca_dev; |
1046 | int val; | ||
1047 | 870 | ||
1048 | val = sd->ctrls[BRIGHTNESS].val; | ||
1049 | if (sd->sensor == SENSOR_OV767x) { | 871 | if (sd->sensor == SENSOR_OV767x) { |
1050 | if (val < 0) | 872 | if (val < 0) |
1051 | val = 0x80 - val; | 873 | val = 0x80 - val; |
@@ -1055,27 +877,18 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1055 | } | 877 | } |
1056 | } | 878 | } |
1057 | 879 | ||
1058 | static void setcontrast(struct gspca_dev *gspca_dev) | 880 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
1059 | { | 881 | { |
1060 | struct sd *sd = (struct sd *) gspca_dev; | 882 | struct sd *sd = (struct sd *) gspca_dev; |
1061 | u8 val; | ||
1062 | 883 | ||
1063 | val = sd->ctrls[CONTRAST].val; | ||
1064 | if (sd->sensor == SENSOR_OV767x) | 884 | if (sd->sensor == SENSOR_OV767x) |
1065 | sccb_reg_write(gspca_dev, 0x56, val); /* contras */ | 885 | sccb_reg_write(gspca_dev, 0x56, val); /* contras */ |
1066 | else | 886 | else |
1067 | sccb_reg_write(gspca_dev, 0x9c, val); | 887 | sccb_reg_write(gspca_dev, 0x9c, val); |
1068 | } | 888 | } |
1069 | 889 | ||
1070 | static void setgain(struct gspca_dev *gspca_dev) | 890 | static void setgain(struct gspca_dev *gspca_dev, s32 val) |
1071 | { | 891 | { |
1072 | struct sd *sd = (struct sd *) gspca_dev; | ||
1073 | u8 val; | ||
1074 | |||
1075 | if (sd->ctrls[AGC].val) | ||
1076 | return; | ||
1077 | |||
1078 | val = sd->ctrls[GAIN].val; | ||
1079 | switch (val & 0x30) { | 892 | switch (val & 0x30) { |
1080 | case 0x00: | 893 | case 0x00: |
1081 | val &= 0x0f; | 894 | val &= 0x0f; |
@@ -1097,15 +910,15 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
1097 | sccb_reg_write(gspca_dev, 0x00, val); | 910 | sccb_reg_write(gspca_dev, 0x00, val); |
1098 | } | 911 | } |
1099 | 912 | ||
1100 | static void setexposure(struct gspca_dev *gspca_dev) | 913 | static s32 getgain(struct gspca_dev *gspca_dev) |
1101 | { | 914 | { |
1102 | struct sd *sd = (struct sd *) gspca_dev; | 915 | return sccb_reg_read(gspca_dev, 0x00); |
1103 | u8 val; | 916 | } |
1104 | 917 | ||
1105 | if (sd->ctrls[AEC].val) | 918 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
1106 | return; | 919 | { |
920 | struct sd *sd = (struct sd *) gspca_dev; | ||
1107 | 921 | ||
1108 | val = sd->ctrls[EXPOSURE].val; | ||
1109 | if (sd->sensor == SENSOR_OV767x) { | 922 | if (sd->sensor == SENSOR_OV767x) { |
1110 | 923 | ||
1111 | /* set only aec[9:2] */ | 924 | /* set only aec[9:2] */ |
@@ -1123,11 +936,23 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1123 | } | 936 | } |
1124 | } | 937 | } |
1125 | 938 | ||
1126 | static void setagc(struct gspca_dev *gspca_dev) | 939 | static s32 getexposure(struct gspca_dev *gspca_dev) |
1127 | { | 940 | { |
1128 | struct sd *sd = (struct sd *) gspca_dev; | 941 | struct sd *sd = (struct sd *) gspca_dev; |
1129 | 942 | ||
1130 | if (sd->ctrls[AGC].val) { | 943 | if (sd->sensor == SENSOR_OV767x) { |
944 | /* get only aec[9:2] */ | ||
945 | return sccb_reg_read(gspca_dev, 0x10); /* aech */ | ||
946 | } else { | ||
947 | u8 hi = sccb_reg_read(gspca_dev, 0x08); | ||
948 | u8 lo = sccb_reg_read(gspca_dev, 0x10); | ||
949 | return (hi << 8 | lo) >> 1; | ||
950 | } | ||
951 | } | ||
952 | |||
953 | static void setagc(struct gspca_dev *gspca_dev, s32 val) | ||
954 | { | ||
955 | if (val) { | ||
1131 | sccb_reg_write(gspca_dev, 0x13, | 956 | sccb_reg_write(gspca_dev, 0x13, |
1132 | sccb_reg_read(gspca_dev, 0x13) | 0x04); | 957 | sccb_reg_read(gspca_dev, 0x13) | 0x04); |
1133 | sccb_reg_write(gspca_dev, 0x64, | 958 | sccb_reg_write(gspca_dev, 0x64, |
@@ -1137,16 +962,14 @@ static void setagc(struct gspca_dev *gspca_dev) | |||
1137 | sccb_reg_read(gspca_dev, 0x13) & ~0x04); | 962 | sccb_reg_read(gspca_dev, 0x13) & ~0x04); |
1138 | sccb_reg_write(gspca_dev, 0x64, | 963 | sccb_reg_write(gspca_dev, 0x64, |
1139 | sccb_reg_read(gspca_dev, 0x64) & ~0x03); | 964 | sccb_reg_read(gspca_dev, 0x64) & ~0x03); |
1140 | |||
1141 | setgain(gspca_dev); | ||
1142 | } | 965 | } |
1143 | } | 966 | } |
1144 | 967 | ||
1145 | static void setawb(struct gspca_dev *gspca_dev) | 968 | static void setawb(struct gspca_dev *gspca_dev, s32 val) |
1146 | { | 969 | { |
1147 | struct sd *sd = (struct sd *) gspca_dev; | 970 | struct sd *sd = (struct sd *) gspca_dev; |
1148 | 971 | ||
1149 | if (sd->ctrls[AWB].val) { | 972 | if (val) { |
1150 | sccb_reg_write(gspca_dev, 0x13, | 973 | sccb_reg_write(gspca_dev, 0x13, |
1151 | sccb_reg_read(gspca_dev, 0x13) | 0x02); | 974 | sccb_reg_read(gspca_dev, 0x13) | 0x02); |
1152 | if (sd->sensor == SENSOR_OV772x) | 975 | if (sd->sensor == SENSOR_OV772x) |
@@ -1161,7 +984,7 @@ static void setawb(struct gspca_dev *gspca_dev) | |||
1161 | } | 984 | } |
1162 | } | 985 | } |
1163 | 986 | ||
1164 | static void setaec(struct gspca_dev *gspca_dev) | 987 | static void setaec(struct gspca_dev *gspca_dev, s32 val) |
1165 | { | 988 | { |
1166 | struct sd *sd = (struct sd *) gspca_dev; | 989 | struct sd *sd = (struct sd *) gspca_dev; |
1167 | u8 data; | 990 | u8 data; |
@@ -1169,31 +992,25 @@ static void setaec(struct gspca_dev *gspca_dev) | |||
1169 | data = sd->sensor == SENSOR_OV767x ? | 992 | data = sd->sensor == SENSOR_OV767x ? |
1170 | 0x05 : /* agc + aec */ | 993 | 0x05 : /* agc + aec */ |
1171 | 0x01; /* agc */ | 994 | 0x01; /* agc */ |
1172 | if (sd->ctrls[AEC].val) | 995 | switch (val) { |
996 | case V4L2_EXPOSURE_AUTO: | ||
1173 | sccb_reg_write(gspca_dev, 0x13, | 997 | sccb_reg_write(gspca_dev, 0x13, |
1174 | sccb_reg_read(gspca_dev, 0x13) | data); | 998 | sccb_reg_read(gspca_dev, 0x13) | data); |
1175 | else { | 999 | break; |
1000 | case V4L2_EXPOSURE_MANUAL: | ||
1176 | sccb_reg_write(gspca_dev, 0x13, | 1001 | sccb_reg_write(gspca_dev, 0x13, |
1177 | sccb_reg_read(gspca_dev, 0x13) & ~data); | 1002 | sccb_reg_read(gspca_dev, 0x13) & ~data); |
1178 | if (sd->sensor == SENSOR_OV767x) | 1003 | break; |
1179 | sd->ctrls[EXPOSURE].val = | ||
1180 | sccb_reg_read(gspca_dev, 10); /* aech */ | ||
1181 | else | ||
1182 | setexposure(gspca_dev); | ||
1183 | } | 1004 | } |
1184 | } | 1005 | } |
1185 | 1006 | ||
1186 | static void setsharpness(struct gspca_dev *gspca_dev) | 1007 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
1187 | { | 1008 | { |
1188 | struct sd *sd = (struct sd *) gspca_dev; | ||
1189 | u8 val; | ||
1190 | |||
1191 | val = sd->ctrls[SHARPNESS].val; | ||
1192 | sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */ | 1009 | sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */ |
1193 | sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */ | 1010 | sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */ |
1194 | } | 1011 | } |
1195 | 1012 | ||
1196 | static void sethvflip(struct gspca_dev *gspca_dev) | 1013 | static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) |
1197 | { | 1014 | { |
1198 | struct sd *sd = (struct sd *) gspca_dev; | 1015 | struct sd *sd = (struct sd *) gspca_dev; |
1199 | u8 val; | 1016 | u8 val; |
@@ -1201,28 +1018,27 @@ static void sethvflip(struct gspca_dev *gspca_dev) | |||
1201 | if (sd->sensor == SENSOR_OV767x) { | 1018 | if (sd->sensor == SENSOR_OV767x) { |
1202 | val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */ | 1019 | val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */ |
1203 | val &= ~0x30; | 1020 | val &= ~0x30; |
1204 | if (sd->ctrls[HFLIP].val) | 1021 | if (hflip) |
1205 | val |= 0x20; | 1022 | val |= 0x20; |
1206 | if (sd->ctrls[VFLIP].val) | 1023 | if (vflip) |
1207 | val |= 0x10; | 1024 | val |= 0x10; |
1208 | sccb_reg_write(gspca_dev, 0x1e, val); | 1025 | sccb_reg_write(gspca_dev, 0x1e, val); |
1209 | } else { | 1026 | } else { |
1210 | val = sccb_reg_read(gspca_dev, 0x0c); | 1027 | val = sccb_reg_read(gspca_dev, 0x0c); |
1211 | val &= ~0xc0; | 1028 | val &= ~0xc0; |
1212 | if (sd->ctrls[HFLIP].val == 0) | 1029 | if (hflip == 0) |
1213 | val |= 0x40; | 1030 | val |= 0x40; |
1214 | if (sd->ctrls[VFLIP].val == 0) | 1031 | if (vflip == 0) |
1215 | val |= 0x80; | 1032 | val |= 0x80; |
1216 | sccb_reg_write(gspca_dev, 0x0c, val); | 1033 | sccb_reg_write(gspca_dev, 0x0c, val); |
1217 | } | 1034 | } |
1218 | } | 1035 | } |
1219 | 1036 | ||
1220 | static void setlightfreq(struct gspca_dev *gspca_dev) | 1037 | static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) |
1221 | { | 1038 | { |
1222 | struct sd *sd = (struct sd *) gspca_dev; | 1039 | struct sd *sd = (struct sd *) gspca_dev; |
1223 | u8 val; | ||
1224 | 1040 | ||
1225 | val = sd->ctrls[LIGHTFREQ].val ? 0x9e : 0x00; | 1041 | val = val ? 0x9e : 0x00; |
1226 | if (sd->sensor == SENSOR_OV767x) { | 1042 | if (sd->sensor == SENSOR_OV767x) { |
1227 | sccb_reg_write(gspca_dev, 0x2a, 0x00); | 1043 | sccb_reg_write(gspca_dev, 0x2a, 0x00); |
1228 | if (val) | 1044 | if (val) |
@@ -1241,8 +1057,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1241 | 1057 | ||
1242 | cam = &gspca_dev->cam; | 1058 | cam = &gspca_dev->cam; |
1243 | 1059 | ||
1244 | cam->ctrls = sd->ctrls; | ||
1245 | |||
1246 | cam->cam_mode = ov772x_mode; | 1060 | cam->cam_mode = ov772x_mode; |
1247 | cam->nmodes = ARRAY_SIZE(ov772x_mode); | 1061 | cam->nmodes = ARRAY_SIZE(ov772x_mode); |
1248 | 1062 | ||
@@ -1251,6 +1065,195 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1251 | return 0; | 1065 | return 0; |
1252 | } | 1066 | } |
1253 | 1067 | ||
1068 | static int ov534_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
1069 | { | ||
1070 | struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler); | ||
1071 | struct gspca_dev *gspca_dev = &sd->gspca_dev; | ||
1072 | |||
1073 | switch (ctrl->id) { | ||
1074 | case V4L2_CID_AUTOGAIN: | ||
1075 | gspca_dev->usb_err = 0; | ||
1076 | if (ctrl->val && sd->gain && gspca_dev->streaming) | ||
1077 | sd->gain->val = getgain(gspca_dev); | ||
1078 | return gspca_dev->usb_err; | ||
1079 | |||
1080 | case V4L2_CID_EXPOSURE_AUTO: | ||
1081 | gspca_dev->usb_err = 0; | ||
1082 | if (ctrl->val == V4L2_EXPOSURE_AUTO && sd->exposure && | ||
1083 | gspca_dev->streaming) | ||
1084 | sd->exposure->val = getexposure(gspca_dev); | ||
1085 | return gspca_dev->usb_err; | ||
1086 | } | ||
1087 | return -EINVAL; | ||
1088 | } | ||
1089 | |||
1090 | static int ov534_s_ctrl(struct v4l2_ctrl *ctrl) | ||
1091 | { | ||
1092 | struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler); | ||
1093 | struct gspca_dev *gspca_dev = &sd->gspca_dev; | ||
1094 | |||
1095 | gspca_dev->usb_err = 0; | ||
1096 | if (!gspca_dev->streaming) | ||
1097 | return 0; | ||
1098 | |||
1099 | switch (ctrl->id) { | ||
1100 | case V4L2_CID_HUE: | ||
1101 | sethue(gspca_dev, ctrl->val); | ||
1102 | break; | ||
1103 | case V4L2_CID_SATURATION: | ||
1104 | setsaturation(gspca_dev, ctrl->val); | ||
1105 | break; | ||
1106 | case V4L2_CID_BRIGHTNESS: | ||
1107 | setbrightness(gspca_dev, ctrl->val); | ||
1108 | break; | ||
1109 | case V4L2_CID_CONTRAST: | ||
1110 | setcontrast(gspca_dev, ctrl->val); | ||
1111 | break; | ||
1112 | case V4L2_CID_AUTOGAIN: | ||
1113 | /* case V4L2_CID_GAIN: */ | ||
1114 | setagc(gspca_dev, ctrl->val); | ||
1115 | if (!gspca_dev->usb_err && !ctrl->val && sd->gain) | ||
1116 | setgain(gspca_dev, sd->gain->val); | ||
1117 | break; | ||
1118 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
1119 | setawb(gspca_dev, ctrl->val); | ||
1120 | break; | ||
1121 | case V4L2_CID_EXPOSURE_AUTO: | ||
1122 | /* case V4L2_CID_EXPOSURE: */ | ||
1123 | setaec(gspca_dev, ctrl->val); | ||
1124 | if (!gspca_dev->usb_err && ctrl->val == V4L2_EXPOSURE_MANUAL && | ||
1125 | sd->exposure) | ||
1126 | setexposure(gspca_dev, sd->exposure->val); | ||
1127 | break; | ||
1128 | case V4L2_CID_SHARPNESS: | ||
1129 | setsharpness(gspca_dev, ctrl->val); | ||
1130 | break; | ||
1131 | case V4L2_CID_HFLIP: | ||
1132 | sethvflip(gspca_dev, ctrl->val, sd->vflip->val); | ||
1133 | break; | ||
1134 | case V4L2_CID_VFLIP: | ||
1135 | sethvflip(gspca_dev, sd->hflip->val, ctrl->val); | ||
1136 | break; | ||
1137 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
1138 | setlightfreq(gspca_dev, ctrl->val); | ||
1139 | break; | ||
1140 | } | ||
1141 | return gspca_dev->usb_err; | ||
1142 | } | ||
1143 | |||
1144 | static const struct v4l2_ctrl_ops ov534_ctrl_ops = { | ||
1145 | .g_volatile_ctrl = ov534_g_volatile_ctrl, | ||
1146 | .s_ctrl = ov534_s_ctrl, | ||
1147 | }; | ||
1148 | |||
1149 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
1150 | { | ||
1151 | struct sd *sd = (struct sd *) gspca_dev; | ||
1152 | struct v4l2_ctrl_handler *hdl = &sd->ctrl_handler; | ||
1153 | /* parameters with different values between the supported sensors */ | ||
1154 | int saturation_min; | ||
1155 | int saturation_max; | ||
1156 | int saturation_def; | ||
1157 | int brightness_min; | ||
1158 | int brightness_max; | ||
1159 | int brightness_def; | ||
1160 | int contrast_max; | ||
1161 | int contrast_def; | ||
1162 | int exposure_min; | ||
1163 | int exposure_max; | ||
1164 | int exposure_def; | ||
1165 | int hflip_def; | ||
1166 | |||
1167 | if (sd->sensor == SENSOR_OV767x) { | ||
1168 | saturation_min = 0, | ||
1169 | saturation_max = 6, | ||
1170 | saturation_def = 3, | ||
1171 | brightness_min = -127; | ||
1172 | brightness_max = 127; | ||
1173 | brightness_def = 0; | ||
1174 | contrast_max = 0x80; | ||
1175 | contrast_def = 0x40; | ||
1176 | exposure_min = 0x08; | ||
1177 | exposure_max = 0x60; | ||
1178 | exposure_def = 0x13; | ||
1179 | hflip_def = 1; | ||
1180 | } else { | ||
1181 | saturation_min = 0, | ||
1182 | saturation_max = 255, | ||
1183 | saturation_def = 64, | ||
1184 | brightness_min = 0; | ||
1185 | brightness_max = 255; | ||
1186 | brightness_def = 0; | ||
1187 | contrast_max = 255; | ||
1188 | contrast_def = 32; | ||
1189 | exposure_min = 0; | ||
1190 | exposure_max = 255; | ||
1191 | exposure_def = 120; | ||
1192 | hflip_def = 0; | ||
1193 | } | ||
1194 | |||
1195 | gspca_dev->vdev.ctrl_handler = hdl; | ||
1196 | |||
1197 | v4l2_ctrl_handler_init(hdl, 13); | ||
1198 | |||
1199 | if (sd->sensor == SENSOR_OV772x) | ||
1200 | sd->hue = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1201 | V4L2_CID_HUE, -90, 90, 1, 0); | ||
1202 | |||
1203 | sd->saturation = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1204 | V4L2_CID_SATURATION, saturation_min, saturation_max, 1, | ||
1205 | saturation_def); | ||
1206 | sd->brightness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1207 | V4L2_CID_BRIGHTNESS, brightness_min, brightness_max, 1, | ||
1208 | brightness_def); | ||
1209 | sd->contrast = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1210 | V4L2_CID_CONTRAST, 0, contrast_max, 1, contrast_def); | ||
1211 | |||
1212 | if (sd->sensor == SENSOR_OV772x) { | ||
1213 | sd->autogain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1214 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
1215 | sd->gain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1216 | V4L2_CID_GAIN, 0, 63, 1, 20); | ||
1217 | } | ||
1218 | |||
1219 | sd->autoexposure = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops, | ||
1220 | V4L2_CID_EXPOSURE_AUTO, | ||
1221 | V4L2_EXPOSURE_MANUAL, 0, | ||
1222 | V4L2_EXPOSURE_AUTO); | ||
1223 | sd->exposure = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1224 | V4L2_CID_EXPOSURE, exposure_min, exposure_max, 1, | ||
1225 | exposure_def); | ||
1226 | |||
1227 | sd->autowhitebalance = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1228 | V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); | ||
1229 | |||
1230 | if (sd->sensor == SENSOR_OV772x) | ||
1231 | sd->sharpness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1232 | V4L2_CID_SHARPNESS, 0, 63, 1, 0); | ||
1233 | |||
1234 | sd->hflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1235 | V4L2_CID_HFLIP, 0, 1, 1, hflip_def); | ||
1236 | sd->vflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, | ||
1237 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
1238 | sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops, | ||
1239 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
1240 | V4L2_CID_POWER_LINE_FREQUENCY_50HZ, 0, | ||
1241 | V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); | ||
1242 | |||
1243 | if (hdl->error) { | ||
1244 | pr_err("Could not initialize controls\n"); | ||
1245 | return hdl->error; | ||
1246 | } | ||
1247 | |||
1248 | if (sd->sensor == SENSOR_OV772x) | ||
1249 | v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true); | ||
1250 | |||
1251 | v4l2_ctrl_auto_cluster(2, &sd->autoexposure, V4L2_EXPOSURE_MANUAL, | ||
1252 | true); | ||
1253 | |||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1254 | /* this function is called at probe and resume time */ | 1257 | /* this function is called at probe and resume time */ |
1255 | static int sd_init(struct gspca_dev *gspca_dev) | 1258 | static int sd_init(struct gspca_dev *gspca_dev) |
1256 | { | 1259 | { |
@@ -1286,24 +1289,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1286 | 1289 | ||
1287 | if ((sensor_id & 0xfff0) == 0x7670) { | 1290 | if ((sensor_id & 0xfff0) == 0x7670) { |
1288 | sd->sensor = SENSOR_OV767x; | 1291 | sd->sensor = SENSOR_OV767x; |
1289 | gspca_dev->ctrl_dis = (1 << HUE) | | ||
1290 | (1 << GAIN) | | ||
1291 | (1 << AGC) | | ||
1292 | (1 << SHARPNESS); /* auto */ | ||
1293 | sd->ctrls[SATURATION].min = 0, | ||
1294 | sd->ctrls[SATURATION].max = 6, | ||
1295 | sd->ctrls[SATURATION].def = 3, | ||
1296 | sd->ctrls[BRIGHTNESS].min = -127; | ||
1297 | sd->ctrls[BRIGHTNESS].max = 127; | ||
1298 | sd->ctrls[BRIGHTNESS].def = 0; | ||
1299 | sd->ctrls[CONTRAST].max = 0x80; | ||
1300 | sd->ctrls[CONTRAST].def = 0x40; | ||
1301 | sd->ctrls[EXPOSURE].min = 0x08; | ||
1302 | sd->ctrls[EXPOSURE].max = 0x60; | ||
1303 | sd->ctrls[EXPOSURE].def = 0x13; | ||
1304 | sd->ctrls[SHARPNESS].max = 9; | ||
1305 | sd->ctrls[SHARPNESS].def = 4; | ||
1306 | sd->ctrls[HFLIP].def = 1; | ||
1307 | gspca_dev->cam.cam_mode = ov767x_mode; | 1292 | gspca_dev->cam.cam_mode = ov767x_mode; |
1308 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode); | 1293 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode); |
1309 | } else { | 1294 | } else { |
@@ -1366,22 +1351,23 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1366 | 1351 | ||
1367 | set_frame_rate(gspca_dev); | 1352 | set_frame_rate(gspca_dev); |
1368 | 1353 | ||
1369 | if (!(gspca_dev->ctrl_dis & (1 << HUE))) | 1354 | if (sd->hue) |
1370 | sethue(gspca_dev); | 1355 | sethue(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue)); |
1371 | setsaturation(gspca_dev); | 1356 | setsaturation(gspca_dev, v4l2_ctrl_g_ctrl(sd->saturation)); |
1372 | if (!(gspca_dev->ctrl_dis & (1 << AGC))) | 1357 | if (sd->autogain) |
1373 | setagc(gspca_dev); | 1358 | setagc(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); |
1374 | setawb(gspca_dev); | 1359 | setawb(gspca_dev, v4l2_ctrl_g_ctrl(sd->autowhitebalance)); |
1375 | setaec(gspca_dev); | 1360 | setaec(gspca_dev, v4l2_ctrl_g_ctrl(sd->autoexposure)); |
1376 | if (!(gspca_dev->ctrl_dis & (1 << GAIN))) | 1361 | if (sd->gain) |
1377 | setgain(gspca_dev); | 1362 | setgain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); |
1378 | setexposure(gspca_dev); | 1363 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); |
1379 | setbrightness(gspca_dev); | 1364 | setbrightness(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness)); |
1380 | setcontrast(gspca_dev); | 1365 | setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast)); |
1381 | if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS))) | 1366 | if (sd->sharpness) |
1382 | setsharpness(gspca_dev); | 1367 | setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); |
1383 | sethvflip(gspca_dev); | 1368 | sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), |
1384 | setlightfreq(gspca_dev); | 1369 | v4l2_ctrl_g_ctrl(sd->vflip)); |
1370 | setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq)); | ||
1385 | 1371 | ||
1386 | ov534_set_led(gspca_dev, 1); | 1372 | ov534_set_led(gspca_dev, 1); |
1387 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | 1373 | ov534_reg_write(gspca_dev, 0xe0, 0x00); |
@@ -1483,25 +1469,6 @@ scan_next: | |||
1483 | } while (remaining_len > 0); | 1469 | } while (remaining_len > 0); |
1484 | } | 1470 | } |
1485 | 1471 | ||
1486 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
1487 | struct v4l2_querymenu *menu) | ||
1488 | { | ||
1489 | switch (menu->id) { | ||
1490 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
1491 | switch (menu->index) { | ||
1492 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
1493 | strcpy((char *) menu->name, "Disabled"); | ||
1494 | return 0; | ||
1495 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
1496 | strcpy((char *) menu->name, "50 Hz"); | ||
1497 | return 0; | ||
1498 | } | ||
1499 | break; | ||
1500 | } | ||
1501 | |||
1502 | return -EINVAL; | ||
1503 | } | ||
1504 | |||
1505 | /* get stream parameters (framerate) */ | 1472 | /* get stream parameters (framerate) */ |
1506 | static void sd_get_streamparm(struct gspca_dev *gspca_dev, | 1473 | static void sd_get_streamparm(struct gspca_dev *gspca_dev, |
1507 | struct v4l2_streamparm *parm) | 1474 | struct v4l2_streamparm *parm) |
@@ -1536,14 +1503,12 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev, | |||
1536 | /* sub-driver description */ | 1503 | /* sub-driver description */ |
1537 | static const struct sd_desc sd_desc = { | 1504 | static const struct sd_desc sd_desc = { |
1538 | .name = MODULE_NAME, | 1505 | .name = MODULE_NAME, |
1539 | .ctrls = sd_ctrls, | ||
1540 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1541 | .config = sd_config, | 1506 | .config = sd_config, |
1542 | .init = sd_init, | 1507 | .init = sd_init, |
1508 | .init_controls = sd_init_controls, | ||
1543 | .start = sd_start, | 1509 | .start = sd_start, |
1544 | .stopN = sd_stopN, | 1510 | .stopN = sd_stopN, |
1545 | .pkt_scan = sd_pkt_scan, | 1511 | .pkt_scan = sd_pkt_scan, |
1546 | .querymenu = sd_querymenu, | ||
1547 | .get_streamparm = sd_get_streamparm, | 1512 | .get_streamparm = sd_get_streamparm, |
1548 | .set_streamparm = sd_set_streamparm, | 1513 | .set_streamparm = sd_set_streamparm, |
1549 | }; | 1514 | }; |
@@ -1572,6 +1537,7 @@ static struct usb_driver sd_driver = { | |||
1572 | #ifdef CONFIG_PM | 1537 | #ifdef CONFIG_PM |
1573 | .suspend = gspca_suspend, | 1538 | .suspend = gspca_suspend, |
1574 | .resume = gspca_resume, | 1539 | .resume = gspca_resume, |
1540 | .reset_resume = gspca_resume, | ||
1575 | #endif | 1541 | #endif |
1576 | }; | 1542 | }; |
1577 | 1543 | ||
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index 1fd41f0d2e95..c4cd028fe0b4 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c | |||
@@ -47,22 +47,9 @@ MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>"); | |||
47 | MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); | 47 | MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | /* controls */ | ||
51 | enum e_ctrl { | ||
52 | BRIGHTNESS, | ||
53 | CONTRAST, | ||
54 | AUTOGAIN, | ||
55 | EXPOSURE, | ||
56 | SHARPNESS, | ||
57 | SATUR, | ||
58 | LIGHTFREQ, | ||
59 | NCTRLS /* number of controls */ | ||
60 | }; | ||
61 | |||
62 | /* specific webcam descriptor */ | 50 | /* specific webcam descriptor */ |
63 | struct sd { | 51 | struct sd { |
64 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 52 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
65 | struct gspca_ctrl ctrls[NCTRLS]; | ||
66 | __u32 last_pts; | 53 | __u32 last_pts; |
67 | u8 last_fid; | 54 | u8 last_fid; |
68 | 55 | ||
@@ -75,103 +62,6 @@ enum sensors { | |||
75 | NSENSORS | 62 | NSENSORS |
76 | }; | 63 | }; |
77 | 64 | ||
78 | /* V4L2 controls supported by the driver */ | ||
79 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
80 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
81 | static void setautogain(struct gspca_dev *gspca_dev); | ||
82 | static void setexposure(struct gspca_dev *gspca_dev); | ||
83 | static void setsharpness(struct gspca_dev *gspca_dev); | ||
84 | static void setsatur(struct gspca_dev *gspca_dev); | ||
85 | static void setlightfreq(struct gspca_dev *gspca_dev); | ||
86 | |||
87 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
88 | [BRIGHTNESS] = { | ||
89 | { | ||
90 | .id = V4L2_CID_BRIGHTNESS, | ||
91 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
92 | .name = "Brightness", | ||
93 | .minimum = 0, | ||
94 | .maximum = 15, | ||
95 | .step = 1, | ||
96 | .default_value = 7 | ||
97 | }, | ||
98 | .set_control = setbrightness | ||
99 | }, | ||
100 | [CONTRAST] = { | ||
101 | { | ||
102 | .id = V4L2_CID_CONTRAST, | ||
103 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
104 | .name = "Contrast", | ||
105 | .minimum = 0, | ||
106 | .maximum = 15, | ||
107 | .step = 1, | ||
108 | .default_value = 3 | ||
109 | }, | ||
110 | .set_control = setcontrast | ||
111 | }, | ||
112 | [AUTOGAIN] = { | ||
113 | { | ||
114 | .id = V4L2_CID_AUTOGAIN, | ||
115 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
116 | .name = "Autogain", | ||
117 | .minimum = 0, | ||
118 | .maximum = 1, | ||
119 | .step = 1, | ||
120 | #define AUTOGAIN_DEF 1 | ||
121 | .default_value = AUTOGAIN_DEF, | ||
122 | }, | ||
123 | .set_control = setautogain | ||
124 | }, | ||
125 | [EXPOSURE] = { | ||
126 | { | ||
127 | .id = V4L2_CID_EXPOSURE, | ||
128 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
129 | .name = "Exposure", | ||
130 | .minimum = 0, | ||
131 | .maximum = 3, | ||
132 | .step = 1, | ||
133 | .default_value = 0 | ||
134 | }, | ||
135 | .set_control = setexposure | ||
136 | }, | ||
137 | [SHARPNESS] = { | ||
138 | { | ||
139 | .id = V4L2_CID_SHARPNESS, | ||
140 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
141 | .name = "Sharpness", | ||
142 | .minimum = -1, /* -1 = auto */ | ||
143 | .maximum = 4, | ||
144 | .step = 1, | ||
145 | .default_value = -1 | ||
146 | }, | ||
147 | .set_control = setsharpness | ||
148 | }, | ||
149 | [SATUR] = { | ||
150 | { | ||
151 | .id = V4L2_CID_SATURATION, | ||
152 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
153 | .name = "Saturation", | ||
154 | .minimum = 0, | ||
155 | .maximum = 4, | ||
156 | .step = 1, | ||
157 | .default_value = 2 | ||
158 | }, | ||
159 | .set_control = setsatur | ||
160 | }, | ||
161 | [LIGHTFREQ] = { | ||
162 | { | ||
163 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
164 | .type = V4L2_CTRL_TYPE_MENU, | ||
165 | .name = "Light frequency filter", | ||
166 | .minimum = 0, | ||
167 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
168 | .step = 1, | ||
169 | .default_value = 0 | ||
170 | }, | ||
171 | .set_control = setlightfreq | ||
172 | }, | ||
173 | }; | ||
174 | |||
175 | static const struct v4l2_pix_format ov965x_mode[] = { | 65 | static const struct v4l2_pix_format ov965x_mode[] = { |
176 | #define QVGA_MODE 0 | 66 | #define QVGA_MODE 0 |
177 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 67 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
@@ -1104,16 +994,14 @@ static void set_led(struct gspca_dev *gspca_dev, int status) | |||
1104 | } | 994 | } |
1105 | } | 995 | } |
1106 | 996 | ||
1107 | static void setbrightness(struct gspca_dev *gspca_dev) | 997 | static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) |
1108 | { | 998 | { |
1109 | struct sd *sd = (struct sd *) gspca_dev; | 999 | struct sd *sd = (struct sd *) gspca_dev; |
1110 | u8 val; | 1000 | u8 val; |
1111 | s8 sval; | 1001 | s8 sval; |
1112 | 1002 | ||
1113 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS)) | ||
1114 | return; | ||
1115 | if (sd->sensor == SENSOR_OV562x) { | 1003 | if (sd->sensor == SENSOR_OV562x) { |
1116 | sval = sd->ctrls[BRIGHTNESS].val; | 1004 | sval = brightness; |
1117 | val = 0x76; | 1005 | val = 0x76; |
1118 | val += sval; | 1006 | val += sval; |
1119 | sccb_write(gspca_dev, 0x24, val); | 1007 | sccb_write(gspca_dev, 0x24, val); |
@@ -1128,7 +1016,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1128 | val = 0xe6; | 1016 | val = 0xe6; |
1129 | sccb_write(gspca_dev, 0x26, val); | 1017 | sccb_write(gspca_dev, 0x26, val); |
1130 | } else { | 1018 | } else { |
1131 | val = sd->ctrls[BRIGHTNESS].val; | 1019 | val = brightness; |
1132 | if (val < 8) | 1020 | if (val < 8) |
1133 | val = 15 - val; /* f .. 8 */ | 1021 | val = 15 - val; /* f .. 8 */ |
1134 | else | 1022 | else |
@@ -1138,43 +1026,32 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1138 | } | 1026 | } |
1139 | } | 1027 | } |
1140 | 1028 | ||
1141 | static void setcontrast(struct gspca_dev *gspca_dev) | 1029 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
1142 | { | 1030 | { |
1143 | struct sd *sd = (struct sd *) gspca_dev; | ||
1144 | |||
1145 | if (gspca_dev->ctrl_dis & (1 << CONTRAST)) | ||
1146 | return; | ||
1147 | sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ | 1031 | sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ |
1148 | sd->ctrls[CONTRAST].val << 4); | 1032 | val << 4); |
1149 | } | 1033 | } |
1150 | 1034 | ||
1151 | static void setautogain(struct gspca_dev *gspca_dev) | 1035 | static void setautogain(struct gspca_dev *gspca_dev, s32 autogain) |
1152 | { | 1036 | { |
1153 | struct sd *sd = (struct sd *) gspca_dev; | ||
1154 | u8 val; | 1037 | u8 val; |
1155 | 1038 | ||
1156 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) | ||
1157 | return; | ||
1158 | /*fixme: should adjust agc/awb/aec by different controls */ | 1039 | /*fixme: should adjust agc/awb/aec by different controls */ |
1159 | val = sccb_read(gspca_dev, 0x13); /* com8 */ | 1040 | val = sccb_read(gspca_dev, 0x13); /* com8 */ |
1160 | sccb_write(gspca_dev, 0xff, 0x00); | 1041 | sccb_write(gspca_dev, 0xff, 0x00); |
1161 | if (sd->ctrls[AUTOGAIN].val) | 1042 | if (autogain) |
1162 | val |= 0x05; /* agc & aec */ | 1043 | val |= 0x05; /* agc & aec */ |
1163 | else | 1044 | else |
1164 | val &= 0xfa; | 1045 | val &= 0xfa; |
1165 | sccb_write(gspca_dev, 0x13, val); | 1046 | sccb_write(gspca_dev, 0x13, val); |
1166 | } | 1047 | } |
1167 | 1048 | ||
1168 | static void setexposure(struct gspca_dev *gspca_dev) | 1049 | static void setexposure(struct gspca_dev *gspca_dev, s32 exposure) |
1169 | { | 1050 | { |
1170 | struct sd *sd = (struct sd *) gspca_dev; | ||
1171 | u8 val; | ||
1172 | static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; | 1051 | static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; |
1052 | u8 val; | ||
1173 | 1053 | ||
1174 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE)) | 1054 | sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */ |
1175 | return; | ||
1176 | sccb_write(gspca_dev, 0x10, /* aec[9:2] */ | ||
1177 | expo[sd->ctrls[EXPOSURE].val]); | ||
1178 | 1055 | ||
1179 | val = sccb_read(gspca_dev, 0x13); /* com8 */ | 1056 | val = sccb_read(gspca_dev, 0x13); /* com8 */ |
1180 | sccb_write(gspca_dev, 0xff, 0x00); | 1057 | sccb_write(gspca_dev, 0xff, 0x00); |
@@ -1185,14 +1062,8 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1185 | sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ | 1062 | sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ |
1186 | } | 1063 | } |
1187 | 1064 | ||
1188 | static void setsharpness(struct gspca_dev *gspca_dev) | 1065 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
1189 | { | 1066 | { |
1190 | struct sd *sd = (struct sd *) gspca_dev; | ||
1191 | s8 val; | ||
1192 | |||
1193 | if (gspca_dev->ctrl_dis & (1 << SHARPNESS)) | ||
1194 | return; | ||
1195 | val = sd->ctrls[SHARPNESS].val; | ||
1196 | if (val < 0) { /* auto */ | 1067 | if (val < 0) { /* auto */ |
1197 | val = sccb_read(gspca_dev, 0x42); /* com17 */ | 1068 | val = sccb_read(gspca_dev, 0x42); /* com17 */ |
1198 | sccb_write(gspca_dev, 0xff, 0x00); | 1069 | sccb_write(gspca_dev, 0xff, 0x00); |
@@ -1209,9 +1080,8 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
1209 | sccb_write(gspca_dev, 0x42, val & 0xbf); | 1080 | sccb_write(gspca_dev, 0x42, val & 0xbf); |
1210 | } | 1081 | } |
1211 | 1082 | ||
1212 | static void setsatur(struct gspca_dev *gspca_dev) | 1083 | static void setsatur(struct gspca_dev *gspca_dev, s32 val) |
1213 | { | 1084 | { |
1214 | struct sd *sd = (struct sd *) gspca_dev; | ||
1215 | u8 val1, val2, val3; | 1085 | u8 val1, val2, val3; |
1216 | static const u8 matrix[5][2] = { | 1086 | static const u8 matrix[5][2] = { |
1217 | {0x14, 0x38}, | 1087 | {0x14, 0x38}, |
@@ -1221,10 +1091,8 @@ static void setsatur(struct gspca_dev *gspca_dev) | |||
1221 | {0x48, 0x90} | 1091 | {0x48, 0x90} |
1222 | }; | 1092 | }; |
1223 | 1093 | ||
1224 | if (gspca_dev->ctrl_dis & (1 << SATUR)) | 1094 | val1 = matrix[val][0]; |
1225 | return; | 1095 | val2 = matrix[val][1]; |
1226 | val1 = matrix[sd->ctrls[SATUR].val][0]; | ||
1227 | val2 = matrix[sd->ctrls[SATUR].val][1]; | ||
1228 | val3 = val1 + val2; | 1096 | val3 = val1 + val2; |
1229 | sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ | 1097 | sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ |
1230 | sccb_write(gspca_dev, 0x50, val3); | 1098 | sccb_write(gspca_dev, 0x50, val3); |
@@ -1239,16 +1107,13 @@ static void setsatur(struct gspca_dev *gspca_dev) | |||
1239 | sccb_write(gspca_dev, 0x41, val1); | 1107 | sccb_write(gspca_dev, 0x41, val1); |
1240 | } | 1108 | } |
1241 | 1109 | ||
1242 | static void setlightfreq(struct gspca_dev *gspca_dev) | 1110 | static void setlightfreq(struct gspca_dev *gspca_dev, s32 freq) |
1243 | { | 1111 | { |
1244 | struct sd *sd = (struct sd *) gspca_dev; | ||
1245 | u8 val; | 1112 | u8 val; |
1246 | 1113 | ||
1247 | if (gspca_dev->ctrl_dis & (1 << LIGHTFREQ)) | ||
1248 | return; | ||
1249 | val = sccb_read(gspca_dev, 0x13); /* com8 */ | 1114 | val = sccb_read(gspca_dev, 0x13); /* com8 */ |
1250 | sccb_write(gspca_dev, 0xff, 0x00); | 1115 | sccb_write(gspca_dev, 0xff, 0x00); |
1251 | if (sd->ctrls[LIGHTFREQ].val == 0) { | 1116 | if (freq == 0) { |
1252 | sccb_write(gspca_dev, 0x13, val & 0xdf); | 1117 | sccb_write(gspca_dev, 0x13, val & 0xdf); |
1253 | return; | 1118 | return; |
1254 | } | 1119 | } |
@@ -1256,7 +1121,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
1256 | 1121 | ||
1257 | val = sccb_read(gspca_dev, 0x42); /* com17 */ | 1122 | val = sccb_read(gspca_dev, 0x42); /* com17 */ |
1258 | sccb_write(gspca_dev, 0xff, 0x00); | 1123 | sccb_write(gspca_dev, 0xff, 0x00); |
1259 | if (sd->ctrls[LIGHTFREQ].val == 1) | 1124 | if (freq == 1) |
1260 | val |= 0x01; | 1125 | val |= 0x01; |
1261 | else | 1126 | else |
1262 | val &= 0xfe; | 1127 | val &= 0xfe; |
@@ -1267,13 +1132,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
1267 | static int sd_config(struct gspca_dev *gspca_dev, | 1132 | static int sd_config(struct gspca_dev *gspca_dev, |
1268 | const struct usb_device_id *id) | 1133 | const struct usb_device_id *id) |
1269 | { | 1134 | { |
1270 | struct sd *sd = (struct sd *) gspca_dev; | ||
1271 | |||
1272 | gspca_dev->cam.ctrls = sd->ctrls; | ||
1273 | |||
1274 | #if AUTOGAIN_DEF != 0 | ||
1275 | gspca_dev->ctrl_inac |= (1 << EXPOSURE); | ||
1276 | #endif | ||
1277 | return 0; | 1135 | return 0; |
1278 | } | 1136 | } |
1279 | 1137 | ||
@@ -1330,9 +1188,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1330 | gspca_dev->cam.cam_mode = ov971x_mode; | 1188 | gspca_dev->cam.cam_mode = ov971x_mode; |
1331 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); | 1189 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); |
1332 | 1190 | ||
1333 | /* no control yet */ | ||
1334 | gspca_dev->ctrl_dis = (1 << NCTRLS) - 1; | ||
1335 | |||
1336 | gspca_dev->cam.bulk = 1; | 1191 | gspca_dev->cam.bulk = 1; |
1337 | gspca_dev->cam.bulk_size = 16384; | 1192 | gspca_dev->cam.bulk_size = 16384; |
1338 | gspca_dev->cam.bulk_nurbs = 2; | 1193 | gspca_dev->cam.bulk_nurbs = 2; |
@@ -1358,16 +1213,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1358 | reg_w(gspca_dev, 0x56, 0x17); | 1213 | reg_w(gspca_dev, 0x56, 0x17); |
1359 | } else if ((sensor_id & 0xfff0) == 0x5620) { | 1214 | } else if ((sensor_id & 0xfff0) == 0x5620) { |
1360 | sd->sensor = SENSOR_OV562x; | 1215 | sd->sensor = SENSOR_OV562x; |
1361 | gspca_dev->ctrl_dis = (1 << CONTRAST) | | ||
1362 | (1 << AUTOGAIN) | | ||
1363 | (1 << EXPOSURE) | | ||
1364 | (1 << SHARPNESS) | | ||
1365 | (1 << SATUR) | | ||
1366 | (1 << LIGHTFREQ); | ||
1367 | |||
1368 | sd->ctrls[BRIGHTNESS].min = -90; | ||
1369 | sd->ctrls[BRIGHTNESS].max = 90; | ||
1370 | sd->ctrls[BRIGHTNESS].def = 0; | ||
1371 | gspca_dev->cam.cam_mode = ov562x_mode; | 1216 | gspca_dev->cam.cam_mode = ov562x_mode; |
1372 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); | 1217 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); |
1373 | 1218 | ||
@@ -1390,10 +1235,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1390 | 1235 | ||
1391 | if (sd->sensor == SENSOR_OV971x) | 1236 | if (sd->sensor == SENSOR_OV971x) |
1392 | return gspca_dev->usb_err; | 1237 | return gspca_dev->usb_err; |
1393 | else if (sd->sensor == SENSOR_OV562x) { | 1238 | if (sd->sensor == SENSOR_OV562x) |
1394 | setbrightness(gspca_dev); | ||
1395 | return gspca_dev->usb_err; | 1239 | return gspca_dev->usb_err; |
1396 | } | 1240 | |
1397 | switch (gspca_dev->curr_mode) { | 1241 | switch (gspca_dev->curr_mode) { |
1398 | case QVGA_MODE: /* 320x240 */ | 1242 | case QVGA_MODE: /* 320x240 */ |
1399 | sccb_w_array(gspca_dev, ov965x_start_1_vga, | 1243 | sccb_w_array(gspca_dev, ov965x_start_1_vga, |
@@ -1437,13 +1281,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1437 | ARRAY_SIZE(ov965x_start_2_sxga)); | 1281 | ARRAY_SIZE(ov965x_start_2_sxga)); |
1438 | break; | 1282 | break; |
1439 | } | 1283 | } |
1440 | setlightfreq(gspca_dev); | ||
1441 | setautogain(gspca_dev); | ||
1442 | setbrightness(gspca_dev); | ||
1443 | setcontrast(gspca_dev); | ||
1444 | setexposure(gspca_dev); | ||
1445 | setsharpness(gspca_dev); | ||
1446 | setsatur(gspca_dev); | ||
1447 | 1284 | ||
1448 | reg_w(gspca_dev, 0xe0, 0x00); | 1285 | reg_w(gspca_dev, 0xe0, 0x00); |
1449 | reg_w(gspca_dev, 0xe0, 0x00); | 1286 | reg_w(gspca_dev, 0xe0, 0x00); |
@@ -1541,38 +1378,94 @@ scan_next: | |||
1541 | } while (remaining_len > 0); | 1378 | } while (remaining_len > 0); |
1542 | } | 1379 | } |
1543 | 1380 | ||
1544 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 1381 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1545 | struct v4l2_querymenu *menu) | ||
1546 | { | 1382 | { |
1547 | switch (menu->id) { | 1383 | struct gspca_dev *gspca_dev = |
1384 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
1385 | |||
1386 | gspca_dev->usb_err = 0; | ||
1387 | |||
1388 | if (!gspca_dev->streaming) | ||
1389 | return 0; | ||
1390 | |||
1391 | switch (ctrl->id) { | ||
1392 | case V4L2_CID_BRIGHTNESS: | ||
1393 | setbrightness(gspca_dev, ctrl->val); | ||
1394 | break; | ||
1395 | case V4L2_CID_CONTRAST: | ||
1396 | setcontrast(gspca_dev, ctrl->val); | ||
1397 | break; | ||
1398 | case V4L2_CID_SATURATION: | ||
1399 | setsatur(gspca_dev, ctrl->val); | ||
1400 | break; | ||
1548 | case V4L2_CID_POWER_LINE_FREQUENCY: | 1401 | case V4L2_CID_POWER_LINE_FREQUENCY: |
1549 | switch (menu->index) { | 1402 | setlightfreq(gspca_dev, ctrl->val); |
1550 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
1551 | strcpy((char *) menu->name, "NoFliker"); | ||
1552 | return 0; | ||
1553 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
1554 | strcpy((char *) menu->name, "50 Hz"); | ||
1555 | return 0; | ||
1556 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
1557 | strcpy((char *) menu->name, "60 Hz"); | ||
1558 | return 0; | ||
1559 | } | ||
1560 | break; | 1403 | break; |
1404 | case V4L2_CID_SHARPNESS: | ||
1405 | setsharpness(gspca_dev, ctrl->val); | ||
1406 | break; | ||
1407 | case V4L2_CID_AUTOGAIN: | ||
1408 | if (ctrl->is_new) | ||
1409 | setautogain(gspca_dev, ctrl->val); | ||
1410 | if (!ctrl->val && gspca_dev->exposure->is_new) | ||
1411 | setexposure(gspca_dev, gspca_dev->exposure->val); | ||
1412 | break; | ||
1413 | } | ||
1414 | return gspca_dev->usb_err; | ||
1415 | } | ||
1416 | |||
1417 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
1418 | .s_ctrl = sd_s_ctrl, | ||
1419 | }; | ||
1420 | |||
1421 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
1422 | { | ||
1423 | struct sd *sd = (struct sd *)gspca_dev; | ||
1424 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
1425 | |||
1426 | if (sd->sensor == SENSOR_OV971x) | ||
1427 | return 0; | ||
1428 | gspca_dev->vdev.ctrl_handler = hdl; | ||
1429 | v4l2_ctrl_handler_init(hdl, 7); | ||
1430 | if (sd->sensor == SENSOR_OV562x) { | ||
1431 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1432 | V4L2_CID_BRIGHTNESS, -90, 90, 1, 0); | ||
1433 | } else { | ||
1434 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1435 | V4L2_CID_BRIGHTNESS, 0, 15, 1, 7); | ||
1436 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1437 | V4L2_CID_CONTRAST, 0, 15, 1, 3); | ||
1438 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1439 | V4L2_CID_SATURATION, 0, 4, 1, 2); | ||
1440 | /* -1 = auto */ | ||
1441 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1442 | V4L2_CID_SHARPNESS, -1, 4, 1, -1); | ||
1443 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1444 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
1445 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1446 | V4L2_CID_EXPOSURE, 0, 3, 1, 0); | ||
1447 | v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
1448 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
1449 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); | ||
1450 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); | ||
1561 | } | 1451 | } |
1562 | return -EINVAL; | 1452 | |
1453 | if (hdl->error) { | ||
1454 | pr_err("Could not initialize controls\n"); | ||
1455 | return hdl->error; | ||
1456 | } | ||
1457 | return 0; | ||
1563 | } | 1458 | } |
1564 | 1459 | ||
1565 | /* sub-driver description */ | 1460 | /* sub-driver description */ |
1566 | static const struct sd_desc sd_desc = { | 1461 | static const struct sd_desc sd_desc = { |
1567 | .name = MODULE_NAME, | 1462 | .name = MODULE_NAME, |
1568 | .ctrls = sd_ctrls, | ||
1569 | .nctrls = NCTRLS, | ||
1570 | .config = sd_config, | 1463 | .config = sd_config, |
1571 | .init = sd_init, | 1464 | .init = sd_init, |
1465 | .init_controls = sd_init_controls, | ||
1572 | .start = sd_start, | 1466 | .start = sd_start, |
1573 | .stopN = sd_stopN, | 1467 | .stopN = sd_stopN, |
1574 | .pkt_scan = sd_pkt_scan, | 1468 | .pkt_scan = sd_pkt_scan, |
1575 | .querymenu = sd_querymenu, | ||
1576 | }; | 1469 | }; |
1577 | 1470 | ||
1578 | /* -- module initialisation -- */ | 1471 | /* -- module initialisation -- */ |
@@ -1600,6 +1493,7 @@ static struct usb_driver sd_driver = { | |||
1600 | #ifdef CONFIG_PM | 1493 | #ifdef CONFIG_PM |
1601 | .suspend = gspca_suspend, | 1494 | .suspend = gspca_suspend, |
1602 | .resume = gspca_resume, | 1495 | .resume = gspca_resume, |
1496 | .reset_resume = gspca_resume, | ||
1603 | #endif | 1497 | #endif |
1604 | }; | 1498 | }; |
1605 | 1499 | ||
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index fa661c6d6d55..d236d1791f78 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c | |||
@@ -462,6 +462,7 @@ static struct usb_driver sd_driver = { | |||
462 | #ifdef CONFIG_PM | 462 | #ifdef CONFIG_PM |
463 | .suspend = gspca_suspend, | 463 | .suspend = gspca_suspend, |
464 | .resume = gspca_resume, | 464 | .resume = gspca_resume, |
465 | .reset_resume = gspca_resume, | ||
465 | #endif | 466 | #endif |
466 | }; | 467 | }; |
467 | 468 | ||
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index a0369a58c4bb..4877f7ab3d59 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c | |||
@@ -84,31 +84,31 @@ | |||
84 | /* Include pac common sof detection functions */ | 84 | /* Include pac common sof detection functions */ |
85 | #include "pac_common.h" | 85 | #include "pac_common.h" |
86 | 86 | ||
87 | #define PAC7302_GAIN_DEFAULT 15 | ||
88 | #define PAC7302_GAIN_KNEE 42 | ||
89 | #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */ | ||
90 | #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ | ||
91 | |||
87 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " | 92 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " |
88 | "Thomas Kaiser thomas@kaiser-linux.li"); | 93 | "Thomas Kaiser thomas@kaiser-linux.li"); |
89 | MODULE_DESCRIPTION("Pixart PAC7302"); | 94 | MODULE_DESCRIPTION("Pixart PAC7302"); |
90 | MODULE_LICENSE("GPL"); | 95 | MODULE_LICENSE("GPL"); |
91 | 96 | ||
92 | enum e_ctrl { | ||
93 | BRIGHTNESS, | ||
94 | CONTRAST, | ||
95 | COLORS, | ||
96 | WHITE_BALANCE, | ||
97 | RED_BALANCE, | ||
98 | BLUE_BALANCE, | ||
99 | GAIN, | ||
100 | AUTOGAIN, | ||
101 | EXPOSURE, | ||
102 | VFLIP, | ||
103 | HFLIP, | ||
104 | NCTRLS /* number of controls */ | ||
105 | }; | ||
106 | |||
107 | struct sd { | 97 | struct sd { |
108 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 98 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
109 | 99 | ||
110 | struct gspca_ctrl ctrls[NCTRLS]; | 100 | struct { /* brightness / contrast cluster */ |
111 | 101 | struct v4l2_ctrl *brightness; | |
102 | struct v4l2_ctrl *contrast; | ||
103 | }; | ||
104 | struct v4l2_ctrl *saturation; | ||
105 | struct v4l2_ctrl *white_balance; | ||
106 | struct v4l2_ctrl *red_balance; | ||
107 | struct v4l2_ctrl *blue_balance; | ||
108 | struct { /* flip cluster */ | ||
109 | struct v4l2_ctrl *hflip; | ||
110 | struct v4l2_ctrl *vflip; | ||
111 | }; | ||
112 | u8 flags; | 112 | u8 flags; |
113 | #define FL_HFLIP 0x01 /* mirrored by default */ | 113 | #define FL_HFLIP 0x01 /* mirrored by default */ |
114 | #define FL_VFLIP 0x02 /* vertical flipped by default */ | 114 | #define FL_VFLIP 0x02 /* vertical flipped by default */ |
@@ -119,160 +119,6 @@ struct sd { | |||
119 | atomic_t avg_lum; | 119 | atomic_t avg_lum; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | /* V4L2 controls supported by the driver */ | ||
123 | static void setbrightcont(struct gspca_dev *gspca_dev); | ||
124 | static void setcolors(struct gspca_dev *gspca_dev); | ||
125 | static void setwhitebalance(struct gspca_dev *gspca_dev); | ||
126 | static void setredbalance(struct gspca_dev *gspca_dev); | ||
127 | static void setbluebalance(struct gspca_dev *gspca_dev); | ||
128 | static void setgain(struct gspca_dev *gspca_dev); | ||
129 | static void setexposure(struct gspca_dev *gspca_dev); | ||
130 | static void setautogain(struct gspca_dev *gspca_dev); | ||
131 | static void sethvflip(struct gspca_dev *gspca_dev); | ||
132 | |||
133 | static const struct ctrl sd_ctrls[] = { | ||
134 | [BRIGHTNESS] = { | ||
135 | { | ||
136 | .id = V4L2_CID_BRIGHTNESS, | ||
137 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
138 | .name = "Brightness", | ||
139 | .minimum = 0, | ||
140 | #define BRIGHTNESS_MAX 0x20 | ||
141 | .maximum = BRIGHTNESS_MAX, | ||
142 | .step = 1, | ||
143 | .default_value = 0x10, | ||
144 | }, | ||
145 | .set_control = setbrightcont | ||
146 | }, | ||
147 | [CONTRAST] = { | ||
148 | { | ||
149 | .id = V4L2_CID_CONTRAST, | ||
150 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
151 | .name = "Contrast", | ||
152 | .minimum = 0, | ||
153 | #define CONTRAST_MAX 255 | ||
154 | .maximum = CONTRAST_MAX, | ||
155 | .step = 1, | ||
156 | .default_value = 127, | ||
157 | }, | ||
158 | .set_control = setbrightcont | ||
159 | }, | ||
160 | [COLORS] = { | ||
161 | { | ||
162 | .id = V4L2_CID_SATURATION, | ||
163 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
164 | .name = "Saturation", | ||
165 | .minimum = 0, | ||
166 | #define COLOR_MAX 255 | ||
167 | .maximum = COLOR_MAX, | ||
168 | .step = 1, | ||
169 | .default_value = 127 | ||
170 | }, | ||
171 | .set_control = setcolors | ||
172 | }, | ||
173 | [WHITE_BALANCE] = { | ||
174 | { | ||
175 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
176 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
177 | .name = "White Balance", | ||
178 | .minimum = 0, | ||
179 | .maximum = 255, | ||
180 | .step = 1, | ||
181 | .default_value = 4, | ||
182 | }, | ||
183 | .set_control = setwhitebalance | ||
184 | }, | ||
185 | [RED_BALANCE] = { | ||
186 | { | ||
187 | .id = V4L2_CID_RED_BALANCE, | ||
188 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
189 | .name = "Red", | ||
190 | .minimum = 0, | ||
191 | .maximum = 3, | ||
192 | .step = 1, | ||
193 | .default_value = 1, | ||
194 | }, | ||
195 | .set_control = setredbalance | ||
196 | }, | ||
197 | [BLUE_BALANCE] = { | ||
198 | { | ||
199 | .id = V4L2_CID_BLUE_BALANCE, | ||
200 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
201 | .name = "Blue", | ||
202 | .minimum = 0, | ||
203 | .maximum = 3, | ||
204 | .step = 1, | ||
205 | .default_value = 1, | ||
206 | }, | ||
207 | .set_control = setbluebalance | ||
208 | }, | ||
209 | [GAIN] = { | ||
210 | { | ||
211 | .id = V4L2_CID_GAIN, | ||
212 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
213 | .name = "Gain", | ||
214 | .minimum = 0, | ||
215 | .maximum = 62, | ||
216 | .step = 1, | ||
217 | #define GAIN_DEF 15 | ||
218 | #define GAIN_KNEE 46 | ||
219 | .default_value = GAIN_DEF, | ||
220 | }, | ||
221 | .set_control = setgain | ||
222 | }, | ||
223 | [EXPOSURE] = { | ||
224 | { | ||
225 | .id = V4L2_CID_EXPOSURE, | ||
226 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
227 | .name = "Exposure", | ||
228 | .minimum = 0, | ||
229 | .maximum = 1023, | ||
230 | .step = 1, | ||
231 | #define EXPOSURE_DEF 66 /* 33 ms / 30 fps */ | ||
232 | #define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ | ||
233 | .default_value = EXPOSURE_DEF, | ||
234 | }, | ||
235 | .set_control = setexposure | ||
236 | }, | ||
237 | [AUTOGAIN] = { | ||
238 | { | ||
239 | .id = V4L2_CID_AUTOGAIN, | ||
240 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
241 | .name = "Auto Gain", | ||
242 | .minimum = 0, | ||
243 | .maximum = 1, | ||
244 | .step = 1, | ||
245 | #define AUTOGAIN_DEF 1 | ||
246 | .default_value = AUTOGAIN_DEF, | ||
247 | }, | ||
248 | .set_control = setautogain, | ||
249 | }, | ||
250 | [HFLIP] = { | ||
251 | { | ||
252 | .id = V4L2_CID_HFLIP, | ||
253 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
254 | .name = "Mirror", | ||
255 | .minimum = 0, | ||
256 | .maximum = 1, | ||
257 | .step = 1, | ||
258 | .default_value = 0, | ||
259 | }, | ||
260 | .set_control = sethvflip, | ||
261 | }, | ||
262 | [VFLIP] = { | ||
263 | { | ||
264 | .id = V4L2_CID_VFLIP, | ||
265 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
266 | .name = "Vflip", | ||
267 | .minimum = 0, | ||
268 | .maximum = 1, | ||
269 | .step = 1, | ||
270 | .default_value = 0, | ||
271 | }, | ||
272 | .set_control = sethvflip | ||
273 | }, | ||
274 | }; | ||
275 | |||
276 | static const struct v4l2_pix_format vga_mode[] = { | 122 | static const struct v4l2_pix_format vga_mode[] = { |
277 | {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, | 123 | {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, |
278 | .bytesperline = 640, | 124 | .bytesperline = 640, |
@@ -516,8 +362,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
516 | cam->cam_mode = vga_mode; /* only 640x480 */ | 362 | cam->cam_mode = vga_mode; /* only 640x480 */ |
517 | cam->nmodes = ARRAY_SIZE(vga_mode); | 363 | cam->nmodes = ARRAY_SIZE(vga_mode); |
518 | 364 | ||
519 | gspca_dev->cam.ctrls = sd->ctrls; | ||
520 | |||
521 | sd->flags = id->driver_info; | 365 | sd->flags = id->driver_info; |
522 | return 0; | 366 | return 0; |
523 | } | 367 | } |
@@ -536,9 +380,9 @@ static void setbrightcont(struct gspca_dev *gspca_dev) | |||
536 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 380 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
537 | for (i = 0; i < 10; i++) { | 381 | for (i = 0; i < 10; i++) { |
538 | v = max[i]; | 382 | v = max[i]; |
539 | v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX) | 383 | v += (sd->brightness->val - sd->brightness->maximum) |
540 | * 150 / BRIGHTNESS_MAX; /* 200 ? */ | 384 | * 150 / sd->brightness->maximum; /* 200 ? */ |
541 | v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX; | 385 | v -= delta[i] * sd->contrast->val / sd->contrast->maximum; |
542 | if (v < 0) | 386 | if (v < 0) |
543 | v = 0; | 387 | v = 0; |
544 | else if (v > 0xff) | 388 | else if (v > 0xff) |
@@ -561,7 +405,8 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
561 | reg_w(gspca_dev, 0x11, 0x01); | 405 | reg_w(gspca_dev, 0x11, 0x01); |
562 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 406 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
563 | for (i = 0; i < 9; i++) { | 407 | for (i = 0; i < 9; i++) { |
564 | v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i]; | 408 | v = a[i] * sd->saturation->val / sd->saturation->maximum; |
409 | v += b[i]; | ||
565 | reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); | 410 | reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); |
566 | reg_w(gspca_dev, 0x0f + 2 * i + 1, v); | 411 | reg_w(gspca_dev, 0x0f + 2 * i + 1, v); |
567 | } | 412 | } |
@@ -573,7 +418,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) | |||
573 | struct sd *sd = (struct sd *) gspca_dev; | 418 | struct sd *sd = (struct sd *) gspca_dev; |
574 | 419 | ||
575 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 420 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
576 | reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val); | 421 | reg_w(gspca_dev, 0xc6, sd->white_balance->val); |
577 | 422 | ||
578 | reg_w(gspca_dev, 0xdc, 0x01); | 423 | reg_w(gspca_dev, 0xdc, 0x01); |
579 | } | 424 | } |
@@ -583,7 +428,7 @@ static void setredbalance(struct gspca_dev *gspca_dev) | |||
583 | struct sd *sd = (struct sd *) gspca_dev; | 428 | struct sd *sd = (struct sd *) gspca_dev; |
584 | 429 | ||
585 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 430 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
586 | reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val); | 431 | reg_w(gspca_dev, 0xc5, sd->red_balance->val); |
587 | 432 | ||
588 | reg_w(gspca_dev, 0xdc, 0x01); | 433 | reg_w(gspca_dev, 0xdc, 0x01); |
589 | } | 434 | } |
@@ -593,22 +438,21 @@ static void setbluebalance(struct gspca_dev *gspca_dev) | |||
593 | struct sd *sd = (struct sd *) gspca_dev; | 438 | struct sd *sd = (struct sd *) gspca_dev; |
594 | 439 | ||
595 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 440 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
596 | reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val); | 441 | reg_w(gspca_dev, 0xc7, sd->blue_balance->val); |
597 | 442 | ||
598 | reg_w(gspca_dev, 0xdc, 0x01); | 443 | reg_w(gspca_dev, 0xdc, 0x01); |
599 | } | 444 | } |
600 | 445 | ||
601 | static void setgain(struct gspca_dev *gspca_dev) | 446 | static void setgain(struct gspca_dev *gspca_dev) |
602 | { | 447 | { |
603 | struct sd *sd = (struct sd *) gspca_dev; | ||
604 | u8 reg10, reg12; | 448 | u8 reg10, reg12; |
605 | 449 | ||
606 | if (sd->ctrls[GAIN].val < 32) { | 450 | if (gspca_dev->gain->val < 32) { |
607 | reg10 = sd->ctrls[GAIN].val; | 451 | reg10 = gspca_dev->gain->val; |
608 | reg12 = 0; | 452 | reg12 = 0; |
609 | } else { | 453 | } else { |
610 | reg10 = 31; | 454 | reg10 = 31; |
611 | reg12 = sd->ctrls[GAIN].val - 31; | 455 | reg12 = gspca_dev->gain->val - 31; |
612 | } | 456 | } |
613 | 457 | ||
614 | reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ | 458 | reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ |
@@ -621,7 +465,6 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
621 | 465 | ||
622 | static void setexposure(struct gspca_dev *gspca_dev) | 466 | static void setexposure(struct gspca_dev *gspca_dev) |
623 | { | 467 | { |
624 | struct sd *sd = (struct sd *) gspca_dev; | ||
625 | u8 clockdiv; | 468 | u8 clockdiv; |
626 | u16 exposure; | 469 | u16 exposure; |
627 | 470 | ||
@@ -630,7 +473,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
630 | * no fps according to the formula: 90 / reg. sd->exposure is the | 473 | * no fps according to the formula: 90 / reg. sd->exposure is the |
631 | * desired exposure time in 0.5 ms. | 474 | * desired exposure time in 0.5 ms. |
632 | */ | 475 | */ |
633 | clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000; | 476 | clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000; |
634 | 477 | ||
635 | /* | 478 | /* |
636 | * Note clockdiv = 3 also works, but when running at 30 fps, depending | 479 | * Note clockdiv = 3 also works, but when running at 30 fps, depending |
@@ -655,7 +498,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
655 | * frame exposure time in ms = 1000 * clockdiv / 90 -> | 498 | * frame exposure time in ms = 1000 * clockdiv / 90 -> |
656 | * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) | 499 | * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) |
657 | */ | 500 | */ |
658 | exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv); | 501 | exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv); |
659 | /* 0 = use full frametime, 448 = no exposure, reverse it */ | 502 | /* 0 = use full frametime, 448 = no exposure, reverse it */ |
660 | exposure = 448 - exposure; | 503 | exposure = 448 - exposure; |
661 | 504 | ||
@@ -668,37 +511,15 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
668 | reg_w(gspca_dev, 0x11, 0x01); | 511 | reg_w(gspca_dev, 0x11, 0x01); |
669 | } | 512 | } |
670 | 513 | ||
671 | static void setautogain(struct gspca_dev *gspca_dev) | ||
672 | { | ||
673 | struct sd *sd = (struct sd *) gspca_dev; | ||
674 | |||
675 | /* | ||
676 | * When switching to autogain set defaults to make sure | ||
677 | * we are on a valid point of the autogain gain / | ||
678 | * exposure knee graph, and give this change time to | ||
679 | * take effect before doing autogain. | ||
680 | */ | ||
681 | if (sd->ctrls[AUTOGAIN].val) { | ||
682 | sd->ctrls[EXPOSURE].val = EXPOSURE_DEF; | ||
683 | sd->ctrls[GAIN].val = GAIN_DEF; | ||
684 | sd->autogain_ignore_frames = | ||
685 | PAC_AUTOGAIN_IGNORE_FRAMES; | ||
686 | } else { | ||
687 | sd->autogain_ignore_frames = -1; | ||
688 | } | ||
689 | setexposure(gspca_dev); | ||
690 | setgain(gspca_dev); | ||
691 | } | ||
692 | |||
693 | static void sethvflip(struct gspca_dev *gspca_dev) | 514 | static void sethvflip(struct gspca_dev *gspca_dev) |
694 | { | 515 | { |
695 | struct sd *sd = (struct sd *) gspca_dev; | 516 | struct sd *sd = (struct sd *) gspca_dev; |
696 | u8 data, hflip, vflip; | 517 | u8 data, hflip, vflip; |
697 | 518 | ||
698 | hflip = sd->ctrls[HFLIP].val; | 519 | hflip = sd->hflip->val; |
699 | if (sd->flags & FL_HFLIP) | 520 | if (sd->flags & FL_HFLIP) |
700 | hflip = !hflip; | 521 | hflip = !hflip; |
701 | vflip = sd->ctrls[VFLIP].val; | 522 | vflip = sd->vflip->val; |
702 | if (sd->flags & FL_VFLIP) | 523 | if (sd->flags & FL_VFLIP) |
703 | vflip = !vflip; | 524 | vflip = !vflip; |
704 | 525 | ||
@@ -717,6 +538,112 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
717 | return gspca_dev->usb_err; | 538 | return gspca_dev->usb_err; |
718 | } | 539 | } |
719 | 540 | ||
541 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | ||
542 | { | ||
543 | struct gspca_dev *gspca_dev = | ||
544 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
545 | struct sd *sd = (struct sd *)gspca_dev; | ||
546 | |||
547 | gspca_dev->usb_err = 0; | ||
548 | |||
549 | if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) { | ||
550 | /* when switching to autogain set defaults to make sure | ||
551 | we are on a valid point of the autogain gain / | ||
552 | exposure knee graph, and give this change time to | ||
553 | take effect before doing autogain. */ | ||
554 | gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT; | ||
555 | gspca_dev->gain->val = PAC7302_GAIN_DEFAULT; | ||
556 | sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; | ||
557 | } | ||
558 | |||
559 | if (!gspca_dev->streaming) | ||
560 | return 0; | ||
561 | |||
562 | switch (ctrl->id) { | ||
563 | case V4L2_CID_BRIGHTNESS: | ||
564 | setbrightcont(gspca_dev); | ||
565 | break; | ||
566 | case V4L2_CID_SATURATION: | ||
567 | setcolors(gspca_dev); | ||
568 | break; | ||
569 | case V4L2_CID_WHITE_BALANCE_TEMPERATURE: | ||
570 | setwhitebalance(gspca_dev); | ||
571 | break; | ||
572 | case V4L2_CID_RED_BALANCE: | ||
573 | setredbalance(gspca_dev); | ||
574 | break; | ||
575 | case V4L2_CID_BLUE_BALANCE: | ||
576 | setbluebalance(gspca_dev); | ||
577 | break; | ||
578 | case V4L2_CID_AUTOGAIN: | ||
579 | if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val)) | ||
580 | setexposure(gspca_dev); | ||
581 | if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val)) | ||
582 | setgain(gspca_dev); | ||
583 | break; | ||
584 | case V4L2_CID_HFLIP: | ||
585 | sethvflip(gspca_dev); | ||
586 | break; | ||
587 | default: | ||
588 | return -EINVAL; | ||
589 | } | ||
590 | return gspca_dev->usb_err; | ||
591 | } | ||
592 | |||
593 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
594 | .s_ctrl = sd_s_ctrl, | ||
595 | }; | ||
596 | |||
597 | /* this function is called at probe time */ | ||
598 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
599 | { | ||
600 | struct sd *sd = (struct sd *) gspca_dev; | ||
601 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
602 | |||
603 | gspca_dev->vdev.ctrl_handler = hdl; | ||
604 | v4l2_ctrl_handler_init(hdl, 11); | ||
605 | |||
606 | sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
607 | V4L2_CID_BRIGHTNESS, 0, 32, 1, 16); | ||
608 | sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
609 | V4L2_CID_CONTRAST, 0, 255, 1, 127); | ||
610 | |||
611 | sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
612 | V4L2_CID_SATURATION, 0, 255, 1, 127); | ||
613 | sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
614 | V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
615 | 0, 255, 1, 4); | ||
616 | sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
617 | V4L2_CID_RED_BALANCE, 0, 3, 1, 1); | ||
618 | sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
619 | V4L2_CID_RED_BALANCE, 0, 3, 1, 1); | ||
620 | |||
621 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
622 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
623 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
624 | V4L2_CID_EXPOSURE, 0, 1023, 1, | ||
625 | PAC7302_EXPOSURE_DEFAULT); | ||
626 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
627 | V4L2_CID_GAIN, 0, 62, 1, | ||
628 | PAC7302_GAIN_DEFAULT); | ||
629 | |||
630 | sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
631 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
632 | sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
633 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
634 | |||
635 | if (hdl->error) { | ||
636 | pr_err("Could not initialize controls\n"); | ||
637 | return hdl->error; | ||
638 | } | ||
639 | |||
640 | v4l2_ctrl_cluster(2, &sd->brightness); | ||
641 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); | ||
642 | v4l2_ctrl_cluster(2, &sd->hflip); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | /* -- start the camera -- */ | ||
720 | static int sd_start(struct gspca_dev *gspca_dev) | 647 | static int sd_start(struct gspca_dev *gspca_dev) |
721 | { | 648 | { |
722 | struct sd *sd = (struct sd *) gspca_dev; | 649 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -728,11 +655,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
728 | setwhitebalance(gspca_dev); | 655 | setwhitebalance(gspca_dev); |
729 | setredbalance(gspca_dev); | 656 | setredbalance(gspca_dev); |
730 | setbluebalance(gspca_dev); | 657 | setbluebalance(gspca_dev); |
731 | setautogain(gspca_dev); | 658 | setexposure(gspca_dev); |
659 | setgain(gspca_dev); | ||
732 | sethvflip(gspca_dev); | 660 | sethvflip(gspca_dev); |
733 | 661 | ||
734 | sd->sof_read = 0; | 662 | sd->sof_read = 0; |
735 | atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val); | 663 | sd->autogain_ignore_frames = 0; |
664 | atomic_set(&sd->avg_lum, 270 + sd->brightness->val); | ||
736 | 665 | ||
737 | /* start stream */ | 666 | /* start stream */ |
738 | reg_w(gspca_dev, 0xff, 0x01); | 667 | reg_w(gspca_dev, 0xff, 0x01); |
@@ -758,9 +687,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
758 | reg_w(gspca_dev, 0x78, 0x40); | 687 | reg_w(gspca_dev, 0x78, 0x40); |
759 | } | 688 | } |
760 | 689 | ||
761 | #define WANT_REGULAR_AUTOGAIN | ||
762 | #include "autogain_functions.h" | ||
763 | |||
764 | static void do_autogain(struct gspca_dev *gspca_dev) | 690 | static void do_autogain(struct gspca_dev *gspca_dev) |
765 | { | 691 | { |
766 | struct sd *sd = (struct sd *) gspca_dev; | 692 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -774,11 +700,13 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
774 | if (sd->autogain_ignore_frames > 0) { | 700 | if (sd->autogain_ignore_frames > 0) { |
775 | sd->autogain_ignore_frames--; | 701 | sd->autogain_ignore_frames--; |
776 | } else { | 702 | } else { |
777 | desired_lum = 270 + sd->ctrls[BRIGHTNESS].val; | 703 | desired_lum = 270 + sd->brightness->val; |
778 | 704 | ||
779 | auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, | 705 | if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum, |
780 | deadzone, GAIN_KNEE, EXPOSURE_KNEE); | 706 | deadzone, PAC7302_GAIN_KNEE, |
781 | sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; | 707 | PAC7302_EXPOSURE_KNEE)) |
708 | sd->autogain_ignore_frames = | ||
709 | PAC_AUTOGAIN_IGNORE_FRAMES; | ||
782 | } | 710 | } |
783 | } | 711 | } |
784 | 712 | ||
@@ -944,10 +872,9 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | |||
944 | /* sub-driver description for pac7302 */ | 872 | /* sub-driver description for pac7302 */ |
945 | static const struct sd_desc sd_desc = { | 873 | static const struct sd_desc sd_desc = { |
946 | .name = KBUILD_MODNAME, | 874 | .name = KBUILD_MODNAME, |
947 | .ctrls = sd_ctrls, | ||
948 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
949 | .config = sd_config, | 875 | .config = sd_config, |
950 | .init = sd_init, | 876 | .init = sd_init, |
877 | .init_controls = sd_init_controls, | ||
951 | .start = sd_start, | 878 | .start = sd_start, |
952 | .stopN = sd_stopN, | 879 | .stopN = sd_stopN, |
953 | .stop0 = sd_stop0, | 880 | .stop0 = sd_stop0, |
@@ -998,6 +925,7 @@ static struct usb_driver sd_driver = { | |||
998 | #ifdef CONFIG_PM | 925 | #ifdef CONFIG_PM |
999 | .suspend = gspca_suspend, | 926 | .suspend = gspca_suspend, |
1000 | .resume = gspca_resume, | 927 | .resume = gspca_resume, |
928 | .reset_resume = gspca_resume, | ||
1001 | #endif | 929 | #endif |
1002 | }; | 930 | }; |
1003 | 931 | ||
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 115da169f32a..ba3558d3f017 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -694,6 +694,7 @@ static struct usb_driver sd_driver = { | |||
694 | #ifdef CONFIG_PM | 694 | #ifdef CONFIG_PM |
695 | .suspend = gspca_suspend, | 695 | .suspend = gspca_suspend, |
696 | .resume = gspca_resume, | 696 | .resume = gspca_resume, |
697 | .reset_resume = gspca_resume, | ||
697 | #endif | 698 | #endif |
698 | }; | 699 | }; |
699 | 700 | ||
diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c index bb70092c2229..a33cb78a839c 100644 --- a/drivers/media/video/gspca/se401.c +++ b/drivers/media/video/gspca/se401.c | |||
@@ -45,15 +45,6 @@ MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | |||
45 | MODULE_DESCRIPTION("Endpoints se401"); | 45 | MODULE_DESCRIPTION("Endpoints se401"); |
46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
47 | 47 | ||
48 | /* controls */ | ||
49 | enum e_ctrl { | ||
50 | BRIGHTNESS, | ||
51 | GAIN, | ||
52 | EXPOSURE, | ||
53 | FREQ, | ||
54 | NCTRL /* number of controls */ | ||
55 | }; | ||
56 | |||
57 | /* exposure change state machine states */ | 48 | /* exposure change state machine states */ |
58 | enum { | 49 | enum { |
59 | EXPO_CHANGED, | 50 | EXPO_CHANGED, |
@@ -64,7 +55,11 @@ enum { | |||
64 | /* specific webcam descriptor */ | 55 | /* specific webcam descriptor */ |
65 | struct sd { | 56 | struct sd { |
66 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 57 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
67 | struct gspca_ctrl ctrls[NCTRL]; | 58 | struct { /* exposure/freq control cluster */ |
59 | struct v4l2_ctrl *exposure; | ||
60 | struct v4l2_ctrl *freq; | ||
61 | }; | ||
62 | bool has_brightness; | ||
68 | struct v4l2_pix_format fmts[MAX_MODES]; | 63 | struct v4l2_pix_format fmts[MAX_MODES]; |
69 | int pixels_read; | 64 | int pixels_read; |
70 | int packet_read; | 65 | int packet_read; |
@@ -77,60 +72,6 @@ struct sd { | |||
77 | int expo_change_state; | 72 | int expo_change_state; |
78 | }; | 73 | }; |
79 | 74 | ||
80 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
81 | static void setgain(struct gspca_dev *gspca_dev); | ||
82 | static void setexposure(struct gspca_dev *gspca_dev); | ||
83 | |||
84 | static const struct ctrl sd_ctrls[NCTRL] = { | ||
85 | [BRIGHTNESS] = { | ||
86 | { | ||
87 | .id = V4L2_CID_BRIGHTNESS, | ||
88 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
89 | .name = "Brightness", | ||
90 | .minimum = 0, | ||
91 | .maximum = 255, | ||
92 | .step = 1, | ||
93 | .default_value = 15, | ||
94 | }, | ||
95 | .set_control = setbrightness | ||
96 | }, | ||
97 | [GAIN] = { | ||
98 | { | ||
99 | .id = V4L2_CID_GAIN, | ||
100 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
101 | .name = "Gain", | ||
102 | .minimum = 0, | ||
103 | .maximum = 50, /* Really 63 but > 50 is not pretty */ | ||
104 | .step = 1, | ||
105 | .default_value = 25, | ||
106 | }, | ||
107 | .set_control = setgain | ||
108 | }, | ||
109 | [EXPOSURE] = { | ||
110 | { | ||
111 | .id = V4L2_CID_EXPOSURE, | ||
112 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
113 | .name = "Exposure", | ||
114 | .minimum = 0, | ||
115 | .maximum = 32767, | ||
116 | .step = 1, | ||
117 | .default_value = 15000, | ||
118 | }, | ||
119 | .set_control = setexposure | ||
120 | }, | ||
121 | [FREQ] = { | ||
122 | { | ||
123 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
124 | .type = V4L2_CTRL_TYPE_MENU, | ||
125 | .name = "Light frequency filter", | ||
126 | .minimum = 0, | ||
127 | .maximum = 2, | ||
128 | .step = 1, | ||
129 | .default_value = 0, | ||
130 | }, | ||
131 | .set_control = setexposure | ||
132 | }, | ||
133 | }; | ||
134 | 75 | ||
135 | static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value, | 76 | static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value, |
136 | int silent) | 77 | int silent) |
@@ -224,22 +165,15 @@ static int se401_get_feature(struct gspca_dev *gspca_dev, u16 selector) | |||
224 | return gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8); | 165 | return gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8); |
225 | } | 166 | } |
226 | 167 | ||
227 | static void setbrightness(struct gspca_dev *gspca_dev) | 168 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
228 | { | 169 | { |
229 | struct sd *sd = (struct sd *) gspca_dev; | ||
230 | |||
231 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS)) | ||
232 | return; | ||
233 | |||
234 | /* HDG: this does not seem to do anything on my cam */ | 170 | /* HDG: this does not seem to do anything on my cam */ |
235 | se401_write_req(gspca_dev, SE401_REQ_SET_BRT, | 171 | se401_write_req(gspca_dev, SE401_REQ_SET_BRT, val, 0); |
236 | sd->ctrls[BRIGHTNESS].val, 0); | ||
237 | } | 172 | } |
238 | 173 | ||
239 | static void setgain(struct gspca_dev *gspca_dev) | 174 | static void setgain(struct gspca_dev *gspca_dev, s32 val) |
240 | { | 175 | { |
241 | struct sd *sd = (struct sd *) gspca_dev; | 176 | u16 gain = 63 - val; |
242 | u16 gain = 63 - sd->ctrls[GAIN].val; | ||
243 | 177 | ||
244 | /* red color gain */ | 178 | /* red color gain */ |
245 | se401_set_feature(gspca_dev, HV7131_REG_ARCG, gain); | 179 | se401_set_feature(gspca_dev, HV7131_REG_ARCG, gain); |
@@ -249,10 +183,10 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
249 | se401_set_feature(gspca_dev, HV7131_REG_ABCG, gain); | 183 | se401_set_feature(gspca_dev, HV7131_REG_ABCG, gain); |
250 | } | 184 | } |
251 | 185 | ||
252 | static void setexposure(struct gspca_dev *gspca_dev) | 186 | static void setexposure(struct gspca_dev *gspca_dev, s32 val, s32 freq) |
253 | { | 187 | { |
254 | struct sd *sd = (struct sd *) gspca_dev; | 188 | struct sd *sd = (struct sd *) gspca_dev; |
255 | int integration = sd->ctrls[EXPOSURE].val << 6; | 189 | int integration = val << 6; |
256 | u8 expose_h, expose_m, expose_l; | 190 | u8 expose_h, expose_m, expose_l; |
257 | 191 | ||
258 | /* Do this before the set_feature calls, for proper timing wrt | 192 | /* Do this before the set_feature calls, for proper timing wrt |
@@ -262,9 +196,9 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
262 | through so be it */ | 196 | through so be it */ |
263 | sd->expo_change_state = EXPO_CHANGED; | 197 | sd->expo_change_state = EXPO_CHANGED; |
264 | 198 | ||
265 | if (sd->ctrls[FREQ].val == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) | 199 | if (freq == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) |
266 | integration = integration - integration % 106667; | 200 | integration = integration - integration % 106667; |
267 | if (sd->ctrls[FREQ].val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ) | 201 | if (freq == V4L2_CID_POWER_LINE_FREQUENCY_60HZ) |
268 | integration = integration - integration % 88889; | 202 | integration = integration - integration % 88889; |
269 | 203 | ||
270 | expose_h = (integration >> 16); | 204 | expose_h = (integration >> 16); |
@@ -375,15 +309,12 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
375 | cam->bulk = 1; | 309 | cam->bulk = 1; |
376 | cam->bulk_size = BULK_SIZE; | 310 | cam->bulk_size = BULK_SIZE; |
377 | cam->bulk_nurbs = 4; | 311 | cam->bulk_nurbs = 4; |
378 | cam->ctrls = sd->ctrls; | ||
379 | sd->resetlevel = 0x2d; /* Set initial resetlevel */ | 312 | sd->resetlevel = 0x2d; /* Set initial resetlevel */ |
380 | 313 | ||
381 | /* See if the camera supports brightness */ | 314 | /* See if the camera supports brightness */ |
382 | se401_read_req(gspca_dev, SE401_REQ_GET_BRT, 1); | 315 | se401_read_req(gspca_dev, SE401_REQ_GET_BRT, 1); |
383 | if (gspca_dev->usb_err) { | 316 | sd->has_brightness = !!gspca_dev->usb_err; |
384 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS); | 317 | gspca_dev->usb_err = 0; |
385 | gspca_dev->usb_err = 0; | ||
386 | } | ||
387 | 318 | ||
388 | return 0; | 319 | return 0; |
389 | } | 320 | } |
@@ -442,9 +373,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
442 | } | 373 | } |
443 | se401_set_feature(gspca_dev, SE401_OPERATINGMODE, mode); | 374 | se401_set_feature(gspca_dev, SE401_OPERATINGMODE, mode); |
444 | 375 | ||
445 | setbrightness(gspca_dev); | ||
446 | setgain(gspca_dev); | ||
447 | setexposure(gspca_dev); | ||
448 | se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel); | 376 | se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel); |
449 | 377 | ||
450 | sd->packet_read = 0; | 378 | sd->packet_read = 0; |
@@ -666,27 +594,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
666 | sd_pkt_scan_janggu(gspca_dev, data, len); | 594 | sd_pkt_scan_janggu(gspca_dev, data, len); |
667 | } | 595 | } |
668 | 596 | ||
669 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
670 | struct v4l2_querymenu *menu) | ||
671 | { | ||
672 | switch (menu->id) { | ||
673 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
674 | switch (menu->index) { | ||
675 | case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED: | ||
676 | strcpy((char *) menu->name, "NoFliker"); | ||
677 | return 0; | ||
678 | case V4L2_CID_POWER_LINE_FREQUENCY_50HZ: | ||
679 | strcpy((char *) menu->name, "50 Hz"); | ||
680 | return 0; | ||
681 | case V4L2_CID_POWER_LINE_FREQUENCY_60HZ: | ||
682 | strcpy((char *) menu->name, "60 Hz"); | ||
683 | return 0; | ||
684 | } | ||
685 | break; | ||
686 | } | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | |||
690 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 597 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
691 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) | 598 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) |
692 | { | 599 | { |
@@ -714,19 +621,73 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
714 | } | 621 | } |
715 | #endif | 622 | #endif |
716 | 623 | ||
624 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | ||
625 | { | ||
626 | struct gspca_dev *gspca_dev = | ||
627 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
628 | struct sd *sd = (struct sd *)gspca_dev; | ||
629 | |||
630 | gspca_dev->usb_err = 0; | ||
631 | |||
632 | if (!gspca_dev->streaming) | ||
633 | return 0; | ||
634 | |||
635 | switch (ctrl->id) { | ||
636 | case V4L2_CID_BRIGHTNESS: | ||
637 | setbrightness(gspca_dev, ctrl->val); | ||
638 | break; | ||
639 | case V4L2_CID_GAIN: | ||
640 | setgain(gspca_dev, ctrl->val); | ||
641 | break; | ||
642 | case V4L2_CID_EXPOSURE: | ||
643 | setexposure(gspca_dev, ctrl->val, sd->freq->val); | ||
644 | break; | ||
645 | } | ||
646 | return gspca_dev->usb_err; | ||
647 | } | ||
648 | |||
649 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
650 | .s_ctrl = sd_s_ctrl, | ||
651 | }; | ||
652 | |||
653 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
654 | { | ||
655 | struct sd *sd = (struct sd *)gspca_dev; | ||
656 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
657 | |||
658 | gspca_dev->vdev.ctrl_handler = hdl; | ||
659 | v4l2_ctrl_handler_init(hdl, 4); | ||
660 | if (sd->has_brightness) | ||
661 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
662 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 15); | ||
663 | /* max is really 63 but > 50 is not pretty */ | ||
664 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
665 | V4L2_CID_GAIN, 0, 50, 1, 25); | ||
666 | sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
667 | V4L2_CID_EXPOSURE, 0, 32767, 1, 15000); | ||
668 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
669 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
670 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); | ||
671 | |||
672 | if (hdl->error) { | ||
673 | pr_err("Could not initialize controls\n"); | ||
674 | return hdl->error; | ||
675 | } | ||
676 | v4l2_ctrl_cluster(2, &sd->exposure); | ||
677 | return 0; | ||
678 | } | ||
679 | |||
717 | /* sub-driver description */ | 680 | /* sub-driver description */ |
718 | static const struct sd_desc sd_desc = { | 681 | static const struct sd_desc sd_desc = { |
719 | .name = MODULE_NAME, | 682 | .name = MODULE_NAME, |
720 | .ctrls = sd_ctrls, | ||
721 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
722 | .config = sd_config, | 683 | .config = sd_config, |
723 | .init = sd_init, | 684 | .init = sd_init, |
685 | .init_controls = sd_init_controls, | ||
724 | .isoc_init = sd_isoc_init, | 686 | .isoc_init = sd_isoc_init, |
725 | .start = sd_start, | 687 | .start = sd_start, |
726 | .stopN = sd_stopN, | 688 | .stopN = sd_stopN, |
727 | .dq_callback = sd_dq_callback, | 689 | .dq_callback = sd_dq_callback, |
728 | .pkt_scan = sd_pkt_scan, | 690 | .pkt_scan = sd_pkt_scan, |
729 | .querymenu = sd_querymenu, | ||
730 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 691 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
731 | .int_pkt_scan = sd_int_pkt_scan, | 692 | .int_pkt_scan = sd_int_pkt_scan, |
732 | #endif | 693 | #endif |
@@ -769,6 +730,7 @@ static struct usb_driver sd_driver = { | |||
769 | #ifdef CONFIG_PM | 730 | #ifdef CONFIG_PM |
770 | .suspend = gspca_suspend, | 731 | .suspend = gspca_suspend, |
771 | .resume = gspca_resume, | 732 | .resume = gspca_resume, |
733 | .reset_resume = gspca_resume, | ||
772 | #endif | 734 | #endif |
773 | .pre_reset = sd_pre_reset, | 735 | .pre_reset = sd_pre_reset, |
774 | .post_reset = sd_post_reset, | 736 | .post_reset = sd_post_reset, |
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c index 478533cb1152..03fa3fd940b4 100644 --- a/drivers/media/video/gspca/sn9c2028.c +++ b/drivers/media/video/gspca/sn9c2028.c | |||
@@ -40,10 +40,6 @@ struct init_command { | |||
40 | unsigned char to_read; /* length to read. 0 means no reply requested */ | 40 | unsigned char to_read; /* length to read. 0 means no reply requested */ |
41 | }; | 41 | }; |
42 | 42 | ||
43 | /* V4L2 controls supported by the driver */ | ||
44 | static const struct ctrl sd_ctrls[] = { | ||
45 | }; | ||
46 | |||
47 | /* How to change the resolution of any of the VGA cams is unknown */ | 43 | /* How to change the resolution of any of the VGA cams is unknown */ |
48 | static const struct v4l2_pix_format vga_mode[] = { | 44 | static const struct v4l2_pix_format vga_mode[] = { |
49 | {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE, | 45 | {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE, |
@@ -695,8 +691,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
695 | /* sub-driver description */ | 691 | /* sub-driver description */ |
696 | static const struct sd_desc sd_desc = { | 692 | static const struct sd_desc sd_desc = { |
697 | .name = MODULE_NAME, | 693 | .name = MODULE_NAME, |
698 | .ctrls = sd_ctrls, | ||
699 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
700 | .config = sd_config, | 694 | .config = sd_config, |
701 | .init = sd_init, | 695 | .init = sd_init, |
702 | .start = sd_start, | 696 | .start = sd_start, |
@@ -734,6 +728,7 @@ static struct usb_driver sd_driver = { | |||
734 | #ifdef CONFIG_PM | 728 | #ifdef CONFIG_PM |
735 | .suspend = gspca_suspend, | 729 | .suspend = gspca_suspend, |
736 | .resume = gspca_resume, | 730 | .resume = gspca_resume, |
731 | .reset_resume = gspca_resume, | ||
737 | #endif | 732 | #endif |
738 | }; | 733 | }; |
739 | 734 | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index e2bdf8f632f4..fd1f8d2d3b0b 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -56,26 +56,16 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); | |||
56 | MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); | 56 | MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); |
57 | MODULE_LICENSE("GPL"); | 57 | MODULE_LICENSE("GPL"); |
58 | 58 | ||
59 | /* controls */ | ||
60 | enum e_ctrl { | ||
61 | BRIGHTNESS, | ||
62 | GAIN, | ||
63 | EXPOSURE, | ||
64 | AUTOGAIN, | ||
65 | FREQ, | ||
66 | NCTRLS /* number of controls */ | ||
67 | }; | ||
68 | |||
69 | /* specific webcam descriptor */ | 59 | /* specific webcam descriptor */ |
70 | struct sd { | 60 | struct sd { |
71 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 61 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
72 | 62 | ||
73 | struct gspca_ctrl ctrls[NCTRLS]; | 63 | struct v4l2_ctrl *brightness; |
64 | struct v4l2_ctrl *plfreq; | ||
74 | 65 | ||
75 | atomic_t avg_lum; | 66 | atomic_t avg_lum; |
76 | int prev_avg_lum; | 67 | int prev_avg_lum; |
77 | int exp_too_low_cnt; | 68 | int exposure_knee; |
78 | int exp_too_high_cnt; | ||
79 | int header_read; | 69 | int header_read; |
80 | u8 header[12]; /* Header without sof marker */ | 70 | u8 header[12]; /* Header without sof marker */ |
81 | 71 | ||
@@ -107,24 +97,16 @@ struct sensor_data { | |||
107 | sensor_init_t *sensor_init; | 97 | sensor_init_t *sensor_init; |
108 | int sensor_init_size; | 98 | int sensor_init_size; |
109 | int flags; | 99 | int flags; |
110 | unsigned ctrl_dis; | ||
111 | __u8 sensor_addr; | 100 | __u8 sensor_addr; |
112 | }; | 101 | }; |
113 | 102 | ||
114 | /* sensor_data flags */ | 103 | /* sensor_data flags */ |
115 | #define F_GAIN 0x01 /* has gain */ | 104 | #define F_SIF 0x01 /* sif or vga */ |
116 | #define F_SIF 0x02 /* sif or vga */ | ||
117 | #define F_COARSE_EXPO 0x04 /* exposure control is coarse */ | ||
118 | 105 | ||
119 | /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ | 106 | /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ |
120 | #define MODE_RAW 0x10 /* raw bayer mode */ | 107 | #define MODE_RAW 0x10 /* raw bayer mode */ |
121 | #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ | 108 | #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ |
122 | 109 | ||
123 | /* ctrl_dis helper macros */ | ||
124 | #define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN)) | ||
125 | #define NO_FREQ (1 << FREQ) | ||
126 | #define NO_BRIGHTNESS (1 << BRIGHTNESS) | ||
127 | |||
128 | #define COMP 0xc7 /* 0x87 //0x07 */ | 110 | #define COMP 0xc7 /* 0x87 //0x07 */ |
129 | #define COMP1 0xc9 /* 0x89 //0x09 */ | 111 | #define COMP1 0xc9 /* 0x89 //0x09 */ |
130 | 112 | ||
@@ -133,12 +115,12 @@ struct sensor_data { | |||
133 | 115 | ||
134 | #define SYS_CLK 0x04 | 116 | #define SYS_CLK 0x04 |
135 | 117 | ||
136 | #define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \ | 118 | #define SENS(bridge, sensor, _flags, _sensor_addr) \ |
137 | { \ | 119 | { \ |
138 | .bridge_init = bridge, \ | 120 | .bridge_init = bridge, \ |
139 | .sensor_init = sensor, \ | 121 | .sensor_init = sensor, \ |
140 | .sensor_init_size = sizeof(sensor), \ | 122 | .sensor_init_size = sizeof(sensor), \ |
141 | .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ | 123 | .flags = _flags, .sensor_addr = _sensor_addr \ |
142 | } | 124 | } |
143 | 125 | ||
144 | /* We calculate the autogain at the end of the transfer of a frame, at this | 126 | /* We calculate the autogain at the end of the transfer of a frame, at this |
@@ -147,87 +129,6 @@ struct sensor_data { | |||
147 | the new settings to come into effect before doing any other adjustments. */ | 129 | the new settings to come into effect before doing any other adjustments. */ |
148 | #define AUTOGAIN_IGNORE_FRAMES 1 | 130 | #define AUTOGAIN_IGNORE_FRAMES 1 |
149 | 131 | ||
150 | /* V4L2 controls supported by the driver */ | ||
151 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
152 | static void setgain(struct gspca_dev *gspca_dev); | ||
153 | static void setexposure(struct gspca_dev *gspca_dev); | ||
154 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
155 | static void setfreq(struct gspca_dev *gspca_dev); | ||
156 | |||
157 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
158 | [BRIGHTNESS] = { | ||
159 | { | ||
160 | .id = V4L2_CID_BRIGHTNESS, | ||
161 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
162 | .name = "Brightness", | ||
163 | .minimum = 0, | ||
164 | .maximum = 255, | ||
165 | .step = 1, | ||
166 | .default_value = 127, | ||
167 | }, | ||
168 | .set_control = setbrightness | ||
169 | }, | ||
170 | [GAIN] = { | ||
171 | { | ||
172 | .id = V4L2_CID_GAIN, | ||
173 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
174 | .name = "Gain", | ||
175 | .minimum = 0, | ||
176 | .maximum = 255, | ||
177 | .step = 1, | ||
178 | #define GAIN_KNEE 230 | ||
179 | .default_value = 127, | ||
180 | }, | ||
181 | .set_control = setgain | ||
182 | }, | ||
183 | [EXPOSURE] = { | ||
184 | { | ||
185 | .id = V4L2_CID_EXPOSURE, | ||
186 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
187 | .name = "Exposure", | ||
188 | .minimum = 0, | ||
189 | .maximum = 1023, | ||
190 | .step = 1, | ||
191 | .default_value = 66, | ||
192 | /* 33 ms / 30 fps (except on PASXXX) */ | ||
193 | #define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */ | ||
194 | .flags = 0, | ||
195 | }, | ||
196 | .set_control = setexposure | ||
197 | }, | ||
198 | /* for coarse exposure */ | ||
199 | #define COARSE_EXPOSURE_MIN 2 | ||
200 | #define COARSE_EXPOSURE_MAX 15 | ||
201 | #define COARSE_EXPOSURE_DEF 2 /* 30 fps */ | ||
202 | [AUTOGAIN] = { | ||
203 | { | ||
204 | .id = V4L2_CID_AUTOGAIN, | ||
205 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
206 | .name = "Automatic Gain (and Exposure)", | ||
207 | .minimum = 0, | ||
208 | .maximum = 1, | ||
209 | .step = 1, | ||
210 | #define AUTOGAIN_DEF 1 | ||
211 | .default_value = AUTOGAIN_DEF, | ||
212 | .flags = V4L2_CTRL_FLAG_UPDATE | ||
213 | }, | ||
214 | .set = sd_setautogain, | ||
215 | }, | ||
216 | [FREQ] = { | ||
217 | { | ||
218 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
219 | .type = V4L2_CTRL_TYPE_MENU, | ||
220 | .name = "Light frequency filter", | ||
221 | .minimum = 0, | ||
222 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
223 | .step = 1, | ||
224 | #define FREQ_DEF 0 | ||
225 | .default_value = FREQ_DEF, | ||
226 | }, | ||
227 | .set_control = setfreq | ||
228 | }, | ||
229 | }; | ||
230 | |||
231 | static const struct v4l2_pix_format vga_mode[] = { | 132 | static const struct v4l2_pix_format vga_mode[] = { |
232 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 133 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
233 | .bytesperline = 160, | 134 | .bytesperline = 160, |
@@ -532,25 +433,27 @@ static const __u8 tas5130_sensor_init[][8] = { | |||
532 | }; | 433 | }; |
533 | 434 | ||
534 | static const struct sensor_data sensor_data[] = { | 435 | static const struct sensor_data sensor_data[] = { |
535 | SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), | 436 | SENS(initHv7131d, hv7131d_sensor_init, 0, 0), |
536 | SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), | 437 | SENS(initHv7131r, hv7131r_sensor_init, 0, 0), |
537 | SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), | 438 | SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60), |
538 | SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21), | 439 | SENS(initOv7630, ov7630_sensor_init, 0, 0x21), |
539 | SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0), | 440 | SENS(initPas106, pas106_sensor_init, F_SIF, 0), |
540 | SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0), | 441 | SENS(initPas202, pas202_sensor_init, 0, 0), |
541 | SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, | 442 | SENS(initTas5110c, tas5110c_sensor_init, F_SIF, 0), |
542 | NO_BRIGHTNESS|NO_FREQ, 0), | 443 | SENS(initTas5110d, tas5110d_sensor_init, F_SIF, 0), |
543 | SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, | 444 | SENS(initTas5130, tas5130_sensor_init, 0, 0), |
544 | NO_BRIGHTNESS|NO_FREQ, 0), | ||
545 | SENS(initTas5130, tas5130_sensor_init, F_GAIN, | ||
546 | NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), | ||
547 | }; | 445 | }; |
548 | 446 | ||
549 | /* get one byte in gspca_dev->usb_buf */ | 447 | /* get one byte in gspca_dev->usb_buf */ |
550 | static void reg_r(struct gspca_dev *gspca_dev, | 448 | static void reg_r(struct gspca_dev *gspca_dev, |
551 | __u16 value) | 449 | __u16 value) |
552 | { | 450 | { |
553 | usb_control_msg(gspca_dev->dev, | 451 | int res; |
452 | |||
453 | if (gspca_dev->usb_err < 0) | ||
454 | return; | ||
455 | |||
456 | res = usb_control_msg(gspca_dev->dev, | ||
554 | usb_rcvctrlpipe(gspca_dev->dev, 0), | 457 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
555 | 0, /* request */ | 458 | 0, /* request */ |
556 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 459 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -558,6 +461,12 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
558 | 0, /* index */ | 461 | 0, /* index */ |
559 | gspca_dev->usb_buf, 1, | 462 | gspca_dev->usb_buf, 1, |
560 | 500); | 463 | 500); |
464 | |||
465 | if (res < 0) { | ||
466 | dev_err(gspca_dev->v4l2_dev.dev, | ||
467 | "Error reading register %02x: %d\n", value, res); | ||
468 | gspca_dev->usb_err = res; | ||
469 | } | ||
561 | } | 470 | } |
562 | 471 | ||
563 | static void reg_w(struct gspca_dev *gspca_dev, | 472 | static void reg_w(struct gspca_dev *gspca_dev, |
@@ -565,14 +474,13 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
565 | const __u8 *buffer, | 474 | const __u8 *buffer, |
566 | int len) | 475 | int len) |
567 | { | 476 | { |
568 | #ifdef GSPCA_DEBUG | 477 | int res; |
569 | if (len > USB_BUF_SZ) { | 478 | |
570 | PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); | 479 | if (gspca_dev->usb_err < 0) |
571 | return; | 480 | return; |
572 | } | 481 | |
573 | #endif | ||
574 | memcpy(gspca_dev->usb_buf, buffer, len); | 482 | memcpy(gspca_dev->usb_buf, buffer, len); |
575 | usb_control_msg(gspca_dev->dev, | 483 | res = usb_control_msg(gspca_dev->dev, |
576 | usb_sndctrlpipe(gspca_dev->dev, 0), | 484 | usb_sndctrlpipe(gspca_dev->dev, 0), |
577 | 0x08, /* request */ | 485 | 0x08, /* request */ |
578 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 486 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -580,30 +488,48 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
580 | 0, /* index */ | 488 | 0, /* index */ |
581 | gspca_dev->usb_buf, len, | 489 | gspca_dev->usb_buf, len, |
582 | 500); | 490 | 500); |
491 | |||
492 | if (res < 0) { | ||
493 | dev_err(gspca_dev->v4l2_dev.dev, | ||
494 | "Error writing register %02x: %d\n", value, res); | ||
495 | gspca_dev->usb_err = res; | ||
496 | } | ||
583 | } | 497 | } |
584 | 498 | ||
585 | static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) | 499 | static void i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) |
586 | { | 500 | { |
587 | int retry = 60; | 501 | int retry = 60; |
588 | 502 | ||
503 | if (gspca_dev->usb_err < 0) | ||
504 | return; | ||
505 | |||
589 | /* is i2c ready */ | 506 | /* is i2c ready */ |
590 | reg_w(gspca_dev, 0x08, buffer, 8); | 507 | reg_w(gspca_dev, 0x08, buffer, 8); |
591 | while (retry--) { | 508 | while (retry--) { |
509 | if (gspca_dev->usb_err < 0) | ||
510 | return; | ||
592 | msleep(10); | 511 | msleep(10); |
593 | reg_r(gspca_dev, 0x08); | 512 | reg_r(gspca_dev, 0x08); |
594 | if (gspca_dev->usb_buf[0] & 0x04) { | 513 | if (gspca_dev->usb_buf[0] & 0x04) { |
595 | if (gspca_dev->usb_buf[0] & 0x08) | 514 | if (gspca_dev->usb_buf[0] & 0x08) { |
596 | return -1; | 515 | dev_err(gspca_dev->v4l2_dev.dev, |
597 | return 0; | 516 | "i2c write error\n"); |
517 | gspca_dev->usb_err = -EIO; | ||
518 | } | ||
519 | return; | ||
598 | } | 520 | } |
599 | } | 521 | } |
600 | return -1; | 522 | |
523 | dev_err(gspca_dev->v4l2_dev.dev, "i2c write timeout\n"); | ||
524 | gspca_dev->usb_err = -EIO; | ||
601 | } | 525 | } |
602 | 526 | ||
603 | static void i2c_w_vector(struct gspca_dev *gspca_dev, | 527 | static void i2c_w_vector(struct gspca_dev *gspca_dev, |
604 | const __u8 buffer[][8], int len) | 528 | const __u8 buffer[][8], int len) |
605 | { | 529 | { |
606 | for (;;) { | 530 | for (;;) { |
531 | if (gspca_dev->usb_err < 0) | ||
532 | return; | ||
607 | reg_w(gspca_dev, 0x08, *buffer, 8); | 533 | reg_w(gspca_dev, 0x08, *buffer, 8); |
608 | len -= 8; | 534 | len -= 8; |
609 | if (len <= 0) | 535 | if (len <= 0) |
@@ -624,11 +550,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
624 | 550 | ||
625 | /* change reg 0x06 */ | 551 | /* change reg 0x06 */ |
626 | i2cOV[1] = sensor_data[sd->sensor].sensor_addr; | 552 | i2cOV[1] = sensor_data[sd->sensor].sensor_addr; |
627 | i2cOV[3] = sd->ctrls[BRIGHTNESS].val; | 553 | i2cOV[3] = sd->brightness->val; |
628 | if (i2c_w(gspca_dev, i2cOV) < 0) | 554 | i2c_w(gspca_dev, i2cOV); |
629 | goto err; | ||
630 | break; | 555 | break; |
631 | } | 556 | } |
632 | case SENSOR_PAS106: | 557 | case SENSOR_PAS106: |
633 | case SENSOR_PAS202: { | 558 | case SENSOR_PAS202: { |
634 | __u8 i2cpbright[] = | 559 | __u8 i2cpbright[] = |
@@ -642,54 +567,49 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
642 | i2cpdoit[2] = 0x13; | 567 | i2cpdoit[2] = 0x13; |
643 | } | 568 | } |
644 | 569 | ||
645 | if (sd->ctrls[BRIGHTNESS].val < 127) { | 570 | if (sd->brightness->val < 127) { |
646 | /* change reg 0x0b, signreg */ | 571 | /* change reg 0x0b, signreg */ |
647 | i2cpbright[3] = 0x01; | 572 | i2cpbright[3] = 0x01; |
648 | /* set reg 0x0c, offset */ | 573 | /* set reg 0x0c, offset */ |
649 | i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val; | 574 | i2cpbright[4] = 127 - sd->brightness->val; |
650 | } else | 575 | } else |
651 | i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127; | 576 | i2cpbright[4] = sd->brightness->val - 127; |
652 | 577 | ||
653 | if (i2c_w(gspca_dev, i2cpbright) < 0) | 578 | i2c_w(gspca_dev, i2cpbright); |
654 | goto err; | 579 | i2c_w(gspca_dev, i2cpdoit); |
655 | if (i2c_w(gspca_dev, i2cpdoit) < 0) | 580 | break; |
656 | goto err; | 581 | } |
582 | default: | ||
657 | break; | 583 | break; |
658 | } | ||
659 | } | 584 | } |
660 | return; | ||
661 | err: | ||
662 | PDEBUG(D_ERR, "i2c error brightness"); | ||
663 | } | 585 | } |
664 | 586 | ||
665 | static void setsensorgain(struct gspca_dev *gspca_dev) | 587 | static void setgain(struct gspca_dev *gspca_dev) |
666 | { | 588 | { |
667 | struct sd *sd = (struct sd *) gspca_dev; | 589 | struct sd *sd = (struct sd *) gspca_dev; |
668 | u8 gain = sd->ctrls[GAIN].val; | 590 | u8 gain = gspca_dev->gain->val; |
669 | 591 | ||
670 | switch (sd->sensor) { | 592 | switch (sd->sensor) { |
671 | case SENSOR_HV7131D: { | 593 | case SENSOR_HV7131D: { |
672 | __u8 i2c[] = | 594 | __u8 i2c[] = |
673 | {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; | 595 | {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; |
674 | 596 | ||
675 | i2c[3] = 0x3f - (gain / 4); | 597 | i2c[3] = 0x3f - gain; |
676 | i2c[4] = 0x3f - (gain / 4); | 598 | i2c[4] = 0x3f - gain; |
677 | i2c[5] = 0x3f - (gain / 4); | 599 | i2c[5] = 0x3f - gain; |
678 | 600 | ||
679 | if (i2c_w(gspca_dev, i2c) < 0) | 601 | i2c_w(gspca_dev, i2c); |
680 | goto err; | ||
681 | break; | 602 | break; |
682 | } | 603 | } |
683 | case SENSOR_TAS5110C: | 604 | case SENSOR_TAS5110C: |
684 | case SENSOR_TAS5130CXX: { | 605 | case SENSOR_TAS5130CXX: { |
685 | __u8 i2c[] = | 606 | __u8 i2c[] = |
686 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; | 607 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; |
687 | 608 | ||
688 | i2c[4] = 255 - gain; | 609 | i2c[4] = 255 - gain; |
689 | if (i2c_w(gspca_dev, i2c) < 0) | 610 | i2c_w(gspca_dev, i2c); |
690 | goto err; | ||
691 | break; | 611 | break; |
692 | } | 612 | } |
693 | case SENSOR_TAS5110D: { | 613 | case SENSOR_TAS5110D: { |
694 | __u8 i2c[] = { | 614 | __u8 i2c[] = { |
695 | 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 }; | 615 | 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 }; |
@@ -703,23 +623,25 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
703 | i2c[3] |= (gain & 0x04) << 3; | 623 | i2c[3] |= (gain & 0x04) << 3; |
704 | i2c[3] |= (gain & 0x02) << 5; | 624 | i2c[3] |= (gain & 0x02) << 5; |
705 | i2c[3] |= (gain & 0x01) << 7; | 625 | i2c[3] |= (gain & 0x01) << 7; |
706 | if (i2c_w(gspca_dev, i2c) < 0) | 626 | i2c_w(gspca_dev, i2c); |
707 | goto err; | ||
708 | break; | 627 | break; |
709 | } | 628 | } |
710 | |||
711 | case SENSOR_OV6650: | 629 | case SENSOR_OV6650: |
712 | gain >>= 1; | ||
713 | /* fall thru */ | ||
714 | case SENSOR_OV7630: { | 630 | case SENSOR_OV7630: { |
715 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; | 631 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; |
716 | 632 | ||
633 | /* | ||
634 | * The ov7630's gain is weird, at 32 the gain drops to the | ||
635 | * same level as at 16, so skip 32-47 (of the 0-63 scale). | ||
636 | */ | ||
637 | if (sd->sensor == SENSOR_OV7630 && gain >= 32) | ||
638 | gain += 16; | ||
639 | |||
717 | i2c[1] = sensor_data[sd->sensor].sensor_addr; | 640 | i2c[1] = sensor_data[sd->sensor].sensor_addr; |
718 | i2c[3] = gain >> 2; | 641 | i2c[3] = gain; |
719 | if (i2c_w(gspca_dev, i2c) < 0) | 642 | i2c_w(gspca_dev, i2c); |
720 | goto err; | ||
721 | break; | 643 | break; |
722 | } | 644 | } |
723 | case SENSOR_PAS106: | 645 | case SENSOR_PAS106: |
724 | case SENSOR_PAS202: { | 646 | case SENSOR_PAS202: { |
725 | __u8 i2cpgain[] = | 647 | __u8 i2cpgain[] = |
@@ -737,49 +659,27 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
737 | i2cpdoit[2] = 0x13; | 659 | i2cpdoit[2] = 0x13; |
738 | } | 660 | } |
739 | 661 | ||
740 | i2cpgain[3] = gain >> 3; | 662 | i2cpgain[3] = gain; |
741 | i2cpcolorgain[3] = gain >> 4; | 663 | i2cpcolorgain[3] = gain >> 1; |
742 | i2cpcolorgain[4] = gain >> 4; | 664 | i2cpcolorgain[4] = gain >> 1; |
743 | i2cpcolorgain[5] = gain >> 4; | 665 | i2cpcolorgain[5] = gain >> 1; |
744 | i2cpcolorgain[6] = gain >> 4; | 666 | i2cpcolorgain[6] = gain >> 1; |
745 | |||
746 | if (i2c_w(gspca_dev, i2cpgain) < 0) | ||
747 | goto err; | ||
748 | if (i2c_w(gspca_dev, i2cpcolorgain) < 0) | ||
749 | goto err; | ||
750 | if (i2c_w(gspca_dev, i2cpdoit) < 0) | ||
751 | goto err; | ||
752 | break; | ||
753 | } | ||
754 | } | ||
755 | return; | ||
756 | err: | ||
757 | PDEBUG(D_ERR, "i2c error gain"); | ||
758 | } | ||
759 | |||
760 | static void setgain(struct gspca_dev *gspca_dev) | ||
761 | { | ||
762 | struct sd *sd = (struct sd *) gspca_dev; | ||
763 | __u8 gain; | ||
764 | __u8 buf[3] = { 0, 0, 0 }; | ||
765 | 667 | ||
766 | if (sensor_data[sd->sensor].flags & F_GAIN) { | 668 | i2c_w(gspca_dev, i2cpgain); |
767 | /* Use the sensor gain to do the actual gain */ | 669 | i2c_w(gspca_dev, i2cpcolorgain); |
768 | setsensorgain(gspca_dev); | 670 | i2c_w(gspca_dev, i2cpdoit); |
769 | return; | 671 | break; |
770 | } | 672 | } |
771 | 673 | default: | |
772 | if (sd->bridge == BRIDGE_103) { | 674 | if (sd->bridge == BRIDGE_103) { |
773 | gain = sd->ctrls[GAIN].val >> 1; | 675 | u8 buf[3] = { gain, gain, gain }; /* R, G, B */ |
774 | buf[0] = gain; /* Red */ | 676 | reg_w(gspca_dev, 0x05, buf, 3); |
775 | buf[1] = gain; /* Green */ | 677 | } else { |
776 | buf[2] = gain; /* Blue */ | 678 | u8 buf[2]; |
777 | reg_w(gspca_dev, 0x05, buf, 3); | 679 | buf[0] = gain << 4 | gain; /* Red and blue */ |
778 | } else { | 680 | buf[1] = gain; /* Green */ |
779 | gain = sd->ctrls[GAIN].val >> 4; | 681 | reg_w(gspca_dev, 0x10, buf, 2); |
780 | buf[0] = gain << 4 | gain; /* Red and blue */ | 682 | } |
781 | buf[1] = gain; /* Green */ | ||
782 | reg_w(gspca_dev, 0x10, buf, 2); | ||
783 | } | 683 | } |
784 | } | 684 | } |
785 | 685 | ||
@@ -792,31 +692,24 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
792 | /* Note the datasheet wrongly says line mode exposure uses reg | 692 | /* Note the datasheet wrongly says line mode exposure uses reg |
793 | 0x26 and 0x27, testing has shown 0x25 + 0x26 */ | 693 | 0x26 and 0x27, testing has shown 0x25 + 0x26 */ |
794 | __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17}; | 694 | __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17}; |
795 | /* The HV7131D's exposure goes from 0 - 65535, we scale our | 695 | u16 reg = gspca_dev->exposure->val; |
796 | exposure of 0-1023 to 0-6138. There are 2 reasons for this: | ||
797 | 1) This puts our exposure knee of 200 at approx the point | ||
798 | where the framerate starts dropping | ||
799 | 2) At 6138 the framerate has already dropped to 2 fps, | ||
800 | going any lower makes little sense */ | ||
801 | u16 reg = sd->ctrls[EXPOSURE].val * 6; | ||
802 | 696 | ||
803 | i2c[3] = reg >> 8; | 697 | i2c[3] = reg >> 8; |
804 | i2c[4] = reg & 0xff; | 698 | i2c[4] = reg & 0xff; |
805 | if (i2c_w(gspca_dev, i2c) != 0) | 699 | i2c_w(gspca_dev, i2c); |
806 | goto err; | ||
807 | break; | 700 | break; |
808 | } | 701 | } |
809 | case SENSOR_TAS5110C: | 702 | case SENSOR_TAS5110C: |
810 | case SENSOR_TAS5110D: { | 703 | case SENSOR_TAS5110D: { |
811 | /* register 19's high nibble contains the sn9c10x clock divider | 704 | /* register 19's high nibble contains the sn9c10x clock divider |
812 | The high nibble configures the no fps according to the | 705 | The high nibble configures the no fps according to the |
813 | formula: 60 / high_nibble. With a maximum of 30 fps */ | 706 | formula: 60 / high_nibble. With a maximum of 30 fps */ |
814 | u8 reg = sd->ctrls[EXPOSURE].val; | 707 | u8 reg = gspca_dev->exposure->val; |
815 | 708 | ||
816 | reg = (reg << 4) | 0x0b; | 709 | reg = (reg << 4) | 0x0b; |
817 | reg_w(gspca_dev, 0x19, ®, 1); | 710 | reg_w(gspca_dev, 0x19, ®, 1); |
818 | break; | 711 | break; |
819 | } | 712 | } |
820 | case SENSOR_OV6650: | 713 | case SENSOR_OV6650: |
821 | case SENSOR_OV7630: { | 714 | case SENSOR_OV7630: { |
822 | /* The ov6650 / ov7630 have 2 registers which both influence | 715 | /* The ov6650 / ov7630 have 2 registers which both influence |
@@ -848,7 +741,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
848 | } else | 741 | } else |
849 | reg10_max = 0x41; | 742 | reg10_max = 0x41; |
850 | 743 | ||
851 | reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000; | 744 | reg11 = (15 * gspca_dev->exposure->val + 999) / 1000; |
852 | if (reg11 < 1) | 745 | if (reg11 < 1) |
853 | reg11 = 1; | 746 | reg11 = 1; |
854 | else if (reg11 > 16) | 747 | else if (reg11 > 16) |
@@ -861,16 +754,16 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
861 | reg11 = 4; | 754 | reg11 = 4; |
862 | 755 | ||
863 | /* frame exposure time in ms = 1000 * reg11 / 30 -> | 756 | /* frame exposure time in ms = 1000 * reg11 / 30 -> |
864 | reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max | 757 | reg10 = (gspca_dev->exposure->val / 2) * reg10_max |
865 | / (1000 * reg11 / 30) */ | 758 | / (1000 * reg11 / 30) */ |
866 | reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max) | 759 | reg10 = (gspca_dev->exposure->val * 15 * reg10_max) |
867 | / (1000 * reg11); | 760 | / (1000 * reg11); |
868 | 761 | ||
869 | /* Don't allow this to get below 10 when using autogain, the | 762 | /* Don't allow this to get below 10 when using autogain, the |
870 | steps become very large (relatively) when below 10 causing | 763 | steps become very large (relatively) when below 10 causing |
871 | the image to oscilate from much too dark, to much too bright | 764 | the image to oscilate from much too dark, to much too bright |
872 | and back again. */ | 765 | and back again. */ |
873 | if (sd->ctrls[AUTOGAIN].val && reg10 < 10) | 766 | if (gspca_dev->autogain->val && reg10 < 10) |
874 | reg10 = 10; | 767 | reg10 = 10; |
875 | else if (reg10 > reg10_max) | 768 | else if (reg10 > reg10_max) |
876 | reg10 = reg10_max; | 769 | reg10 = reg10_max; |
@@ -884,12 +777,11 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
884 | if (sd->reg11 == reg11) | 777 | if (sd->reg11 == reg11) |
885 | i2c[0] = 0xa0; | 778 | i2c[0] = 0xa0; |
886 | 779 | ||
887 | if (i2c_w(gspca_dev, i2c) == 0) | 780 | i2c_w(gspca_dev, i2c); |
781 | if (gspca_dev->usb_err == 0) | ||
888 | sd->reg11 = reg11; | 782 | sd->reg11 = reg11; |
889 | else | ||
890 | goto err; | ||
891 | break; | 783 | break; |
892 | } | 784 | } |
893 | case SENSOR_PAS202: { | 785 | case SENSOR_PAS202: { |
894 | __u8 i2cpframerate[] = | 786 | __u8 i2cpframerate[] = |
895 | {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16}; | 787 | {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16}; |
@@ -909,28 +801,25 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
909 | frame exposure times (like we are doing with the ov chips), | 801 | frame exposure times (like we are doing with the ov chips), |
910 | as that sometimes leads to jumps in the exposure control, | 802 | as that sometimes leads to jumps in the exposure control, |
911 | which are bad for auto exposure. */ | 803 | which are bad for auto exposure. */ |
912 | if (sd->ctrls[EXPOSURE].val < 200) { | 804 | if (gspca_dev->exposure->val < 200) { |
913 | i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255) | 805 | i2cpexpo[3] = 255 - (gspca_dev->exposure->val * 255) |
914 | / 200; | 806 | / 200; |
915 | framerate_ctrl = 500; | 807 | framerate_ctrl = 500; |
916 | } else { | 808 | } else { |
917 | /* The PAS202's exposure control goes from 0 - 4095, | 809 | /* The PAS202's exposure control goes from 0 - 4095, |
918 | but anything below 500 causes vsync issues, so scale | 810 | but anything below 500 causes vsync issues, so scale |
919 | our 200-1023 to 500-4095 */ | 811 | our 200-1023 to 500-4095 */ |
920 | framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200) | 812 | framerate_ctrl = (gspca_dev->exposure->val - 200) |
921 | * 1000 / 229 + 500; | 813 | * 1000 / 229 + 500; |
922 | } | 814 | } |
923 | 815 | ||
924 | i2cpframerate[3] = framerate_ctrl >> 6; | 816 | i2cpframerate[3] = framerate_ctrl >> 6; |
925 | i2cpframerate[4] = framerate_ctrl & 0x3f; | 817 | i2cpframerate[4] = framerate_ctrl & 0x3f; |
926 | if (i2c_w(gspca_dev, i2cpframerate) < 0) | 818 | i2c_w(gspca_dev, i2cpframerate); |
927 | goto err; | 819 | i2c_w(gspca_dev, i2cpexpo); |
928 | if (i2c_w(gspca_dev, i2cpexpo) < 0) | 820 | i2c_w(gspca_dev, i2cpdoit); |
929 | goto err; | ||
930 | if (i2c_w(gspca_dev, i2cpdoit) < 0) | ||
931 | goto err; | ||
932 | break; | 821 | break; |
933 | } | 822 | } |
934 | case SENSOR_PAS106: { | 823 | case SENSOR_PAS106: { |
935 | __u8 i2cpframerate[] = | 824 | __u8 i2cpframerate[] = |
936 | {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14}; | 825 | {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14}; |
@@ -942,46 +831,40 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
942 | 831 | ||
943 | /* For values below 150 use partial frame exposure, above | 832 | /* For values below 150 use partial frame exposure, above |
944 | that use framerate ctrl */ | 833 | that use framerate ctrl */ |
945 | if (sd->ctrls[EXPOSURE].val < 150) { | 834 | if (gspca_dev->exposure->val < 150) { |
946 | i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val; | 835 | i2cpexpo[3] = 150 - gspca_dev->exposure->val; |
947 | framerate_ctrl = 300; | 836 | framerate_ctrl = 300; |
948 | } else { | 837 | } else { |
949 | /* The PAS106's exposure control goes from 0 - 4095, | 838 | /* The PAS106's exposure control goes from 0 - 4095, |
950 | but anything below 300 causes vsync issues, so scale | 839 | but anything below 300 causes vsync issues, so scale |
951 | our 150-1023 to 300-4095 */ | 840 | our 150-1023 to 300-4095 */ |
952 | framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150) | 841 | framerate_ctrl = (gspca_dev->exposure->val - 150) |
953 | * 1000 / 230 + 300; | 842 | * 1000 / 230 + 300; |
954 | } | 843 | } |
955 | 844 | ||
956 | i2cpframerate[3] = framerate_ctrl >> 4; | 845 | i2cpframerate[3] = framerate_ctrl >> 4; |
957 | i2cpframerate[4] = framerate_ctrl & 0x0f; | 846 | i2cpframerate[4] = framerate_ctrl & 0x0f; |
958 | if (i2c_w(gspca_dev, i2cpframerate) < 0) | 847 | i2c_w(gspca_dev, i2cpframerate); |
959 | goto err; | 848 | i2c_w(gspca_dev, i2cpexpo); |
960 | if (i2c_w(gspca_dev, i2cpexpo) < 0) | 849 | i2c_w(gspca_dev, i2cpdoit); |
961 | goto err; | 850 | break; |
962 | if (i2c_w(gspca_dev, i2cpdoit) < 0) | 851 | } |
963 | goto err; | 852 | default: |
964 | break; | 853 | break; |
965 | } | ||
966 | } | 854 | } |
967 | return; | ||
968 | err: | ||
969 | PDEBUG(D_ERR, "i2c error exposure"); | ||
970 | } | 855 | } |
971 | 856 | ||
972 | static void setfreq(struct gspca_dev *gspca_dev) | 857 | static void setfreq(struct gspca_dev *gspca_dev) |
973 | { | 858 | { |
974 | struct sd *sd = (struct sd *) gspca_dev; | 859 | struct sd *sd = (struct sd *) gspca_dev; |
975 | 860 | ||
976 | switch (sd->sensor) { | 861 | if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) { |
977 | case SENSOR_OV6650: | ||
978 | case SENSOR_OV7630: { | ||
979 | /* Framerate adjust register for artificial light 50 hz flicker | 862 | /* Framerate adjust register for artificial light 50 hz flicker |
980 | compensation, for the ov6650 this is identical to ov6630 | 863 | compensation, for the ov6650 this is identical to ov6630 |
981 | 0x2b register, see ov6630 datasheet. | 864 | 0x2b register, see ov6630 datasheet. |
982 | 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ | 865 | 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ |
983 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; | 866 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; |
984 | switch (sd->ctrls[FREQ].val) { | 867 | switch (sd->plfreq->val) { |
985 | default: | 868 | default: |
986 | /* case 0: * no filter*/ | 869 | /* case 0: * no filter*/ |
987 | /* case 2: * 60 hz */ | 870 | /* case 2: * 60 hz */ |
@@ -993,25 +876,17 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
993 | break; | 876 | break; |
994 | } | 877 | } |
995 | i2c[1] = sensor_data[sd->sensor].sensor_addr; | 878 | i2c[1] = sensor_data[sd->sensor].sensor_addr; |
996 | if (i2c_w(gspca_dev, i2c) < 0) | 879 | i2c_w(gspca_dev, i2c); |
997 | PDEBUG(D_ERR, "i2c error setfreq"); | ||
998 | break; | ||
999 | } | ||
1000 | } | 880 | } |
1001 | } | 881 | } |
1002 | 882 | ||
1003 | #define WANT_REGULAR_AUTOGAIN | ||
1004 | #define WANT_COARSE_EXPO_AUTOGAIN | ||
1005 | #include "autogain_functions.h" | ||
1006 | |||
1007 | static void do_autogain(struct gspca_dev *gspca_dev) | 883 | static void do_autogain(struct gspca_dev *gspca_dev) |
1008 | { | 884 | { |
1009 | int deadzone, desired_avg_lum, result; | ||
1010 | struct sd *sd = (struct sd *) gspca_dev; | 885 | struct sd *sd = (struct sd *) gspca_dev; |
1011 | int avg_lum = atomic_read(&sd->avg_lum); | 886 | int deadzone, desired_avg_lum, avg_lum; |
1012 | 887 | ||
1013 | if ((gspca_dev->ctrl_dis & (1 << AUTOGAIN)) || | 888 | avg_lum = atomic_read(&sd->avg_lum); |
1014 | avg_lum == -1 || !sd->ctrls[AUTOGAIN].val) | 889 | if (avg_lum == -1) |
1015 | return; | 890 | return; |
1016 | 891 | ||
1017 | if (sd->autogain_ignore_frames > 0) { | 892 | if (sd->autogain_ignore_frames > 0) { |
@@ -1030,22 +905,18 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1030 | desired_avg_lum = 13000; | 905 | desired_avg_lum = 13000; |
1031 | } | 906 | } |
1032 | 907 | ||
1033 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) | 908 | if (sd->brightness) |
1034 | result = coarse_grained_expo_autogain(gspca_dev, avg_lum, | 909 | desired_avg_lum = sd->brightness->val * desired_avg_lum / 127; |
1035 | sd->ctrls[BRIGHTNESS].val | 910 | |
1036 | * desired_avg_lum / 127, | 911 | if (gspca_dev->exposure->maximum < 500) { |
1037 | deadzone); | 912 | if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, |
1038 | else | 913 | desired_avg_lum, deadzone)) |
1039 | result = auto_gain_n_exposure(gspca_dev, avg_lum, | 914 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; |
1040 | sd->ctrls[BRIGHTNESS].val | 915 | } else { |
1041 | * desired_avg_lum / 127, | 916 | int gain_knee = gspca_dev->gain->maximum * 9 / 10; |
1042 | deadzone, GAIN_KNEE, EXPOSURE_KNEE); | 917 | if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum, |
1043 | 918 | deadzone, gain_knee, sd->exposure_knee)) | |
1044 | if (result) { | 919 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; |
1045 | PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", | ||
1046 | (int) sd->ctrls[GAIN].val, | ||
1047 | (int) sd->ctrls[EXPOSURE].val); | ||
1048 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | ||
1049 | } | 920 | } |
1050 | } | 921 | } |
1051 | 922 | ||
@@ -1064,14 +935,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1064 | sd->sensor = id->driver_info >> 8; | 935 | sd->sensor = id->driver_info >> 8; |
1065 | sd->bridge = id->driver_info & 0xff; | 936 | sd->bridge = id->driver_info & 0xff; |
1066 | 937 | ||
1067 | gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; | ||
1068 | #if AUTOGAIN_DEF | ||
1069 | if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN))) | ||
1070 | gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE); | ||
1071 | #endif | ||
1072 | |||
1073 | cam = &gspca_dev->cam; | 938 | cam = &gspca_dev->cam; |
1074 | cam->ctrls = sd->ctrls; | ||
1075 | if (!(sensor_data[sd->sensor].flags & F_SIF)) { | 939 | if (!(sensor_data[sd->sensor].flags & F_SIF)) { |
1076 | cam->cam_mode = vga_mode; | 940 | cam->cam_mode = vga_mode; |
1077 | cam->nmodes = ARRAY_SIZE(vga_mode); | 941 | cam->nmodes = ARRAY_SIZE(vga_mode); |
@@ -1087,18 +951,143 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1087 | /* this function is called at probe and resume time */ | 951 | /* this function is called at probe and resume time */ |
1088 | static int sd_init(struct gspca_dev *gspca_dev) | 952 | static int sd_init(struct gspca_dev *gspca_dev) |
1089 | { | 953 | { |
1090 | struct sd *sd = (struct sd *) gspca_dev; | ||
1091 | const __u8 stop = 0x09; /* Disable stream turn of LED */ | 954 | const __u8 stop = 0x09; /* Disable stream turn of LED */ |
1092 | 955 | ||
1093 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { | 956 | reg_w(gspca_dev, 0x01, &stop, 1); |
1094 | sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN; | 957 | |
1095 | sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX; | 958 | return gspca_dev->usb_err; |
1096 | sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF; | 959 | } |
1097 | if (sd->ctrls[EXPOSURE].val > COARSE_EXPOSURE_MAX) | 960 | |
1098 | sd->ctrls[EXPOSURE].val = COARSE_EXPOSURE_DEF; | 961 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
962 | { | ||
963 | struct gspca_dev *gspca_dev = | ||
964 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
965 | struct sd *sd = (struct sd *)gspca_dev; | ||
966 | |||
967 | gspca_dev->usb_err = 0; | ||
968 | |||
969 | if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) { | ||
970 | /* when switching to autogain set defaults to make sure | ||
971 | we are on a valid point of the autogain gain / | ||
972 | exposure knee graph, and give this change time to | ||
973 | take effect before doing autogain. */ | ||
974 | gspca_dev->gain->val = gspca_dev->gain->default_value; | ||
975 | gspca_dev->exposure->val = gspca_dev->exposure->default_value; | ||
976 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | ||
1099 | } | 977 | } |
1100 | 978 | ||
1101 | reg_w(gspca_dev, 0x01, &stop, 1); | 979 | if (!gspca_dev->streaming) |
980 | return 0; | ||
981 | |||
982 | switch (ctrl->id) { | ||
983 | case V4L2_CID_BRIGHTNESS: | ||
984 | setbrightness(gspca_dev); | ||
985 | break; | ||
986 | case V4L2_CID_AUTOGAIN: | ||
987 | if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val)) | ||
988 | setexposure(gspca_dev); | ||
989 | if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val)) | ||
990 | setgain(gspca_dev); | ||
991 | break; | ||
992 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
993 | setfreq(gspca_dev); | ||
994 | break; | ||
995 | default: | ||
996 | return -EINVAL; | ||
997 | } | ||
998 | return gspca_dev->usb_err; | ||
999 | } | ||
1000 | |||
1001 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
1002 | .s_ctrl = sd_s_ctrl, | ||
1003 | }; | ||
1004 | |||
1005 | /* this function is called at probe time */ | ||
1006 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
1007 | { | ||
1008 | struct sd *sd = (struct sd *) gspca_dev; | ||
1009 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
1010 | |||
1011 | gspca_dev->vdev.ctrl_handler = hdl; | ||
1012 | v4l2_ctrl_handler_init(hdl, 5); | ||
1013 | |||
1014 | if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630 || | ||
1015 | sd->sensor == SENSOR_PAS106 || sd->sensor == SENSOR_PAS202) | ||
1016 | sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1017 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); | ||
1018 | |||
1019 | /* Gain range is sensor dependent */ | ||
1020 | switch (sd->sensor) { | ||
1021 | case SENSOR_OV6650: | ||
1022 | case SENSOR_PAS106: | ||
1023 | case SENSOR_PAS202: | ||
1024 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1025 | V4L2_CID_GAIN, 0, 31, 1, 15); | ||
1026 | break; | ||
1027 | case SENSOR_OV7630: | ||
1028 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1029 | V4L2_CID_GAIN, 0, 47, 1, 31); | ||
1030 | break; | ||
1031 | case SENSOR_HV7131D: | ||
1032 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1033 | V4L2_CID_GAIN, 0, 63, 1, 31); | ||
1034 | break; | ||
1035 | case SENSOR_TAS5110C: | ||
1036 | case SENSOR_TAS5110D: | ||
1037 | case SENSOR_TAS5130CXX: | ||
1038 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1039 | V4L2_CID_GAIN, 0, 255, 1, 127); | ||
1040 | break; | ||
1041 | default: | ||
1042 | if (sd->bridge == BRIDGE_103) { | ||
1043 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1044 | V4L2_CID_GAIN, 0, 127, 1, 63); | ||
1045 | } else { | ||
1046 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1047 | V4L2_CID_GAIN, 0, 15, 1, 7); | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | /* Exposure range is sensor dependent, and not all have exposure */ | ||
1052 | switch (sd->sensor) { | ||
1053 | case SENSOR_HV7131D: | ||
1054 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1055 | V4L2_CID_EXPOSURE, 0, 8191, 1, 482); | ||
1056 | sd->exposure_knee = 964; | ||
1057 | break; | ||
1058 | case SENSOR_OV6650: | ||
1059 | case SENSOR_OV7630: | ||
1060 | case SENSOR_PAS106: | ||
1061 | case SENSOR_PAS202: | ||
1062 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1063 | V4L2_CID_EXPOSURE, 0, 1023, 1, 66); | ||
1064 | sd->exposure_knee = 200; | ||
1065 | break; | ||
1066 | case SENSOR_TAS5110C: | ||
1067 | case SENSOR_TAS5110D: | ||
1068 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1069 | V4L2_CID_EXPOSURE, 2, 15, 1, 2); | ||
1070 | break; | ||
1071 | } | ||
1072 | |||
1073 | if (gspca_dev->exposure) { | ||
1074 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1075 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
1076 | } | ||
1077 | |||
1078 | if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) | ||
1079 | sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
1080 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
1081 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, | ||
1082 | V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); | ||
1083 | |||
1084 | if (hdl->error) { | ||
1085 | pr_err("Could not initialize controls\n"); | ||
1086 | return hdl->error; | ||
1087 | } | ||
1088 | |||
1089 | if (gspca_dev->autogain) | ||
1090 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); | ||
1102 | 1091 | ||
1103 | return 0; | 1092 | return 0; |
1104 | } | 1093 | } |
@@ -1242,10 +1231,10 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1242 | 1231 | ||
1243 | sd->frames_to_drop = 0; | 1232 | sd->frames_to_drop = 0; |
1244 | sd->autogain_ignore_frames = 0; | 1233 | sd->autogain_ignore_frames = 0; |
1245 | sd->exp_too_high_cnt = 0; | 1234 | gspca_dev->exp_too_high_cnt = 0; |
1246 | sd->exp_too_low_cnt = 0; | 1235 | gspca_dev->exp_too_low_cnt = 0; |
1247 | atomic_set(&sd->avg_lum, -1); | 1236 | atomic_set(&sd->avg_lum, -1); |
1248 | return 0; | 1237 | return gspca_dev->usb_err; |
1249 | } | 1238 | } |
1250 | 1239 | ||
1251 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1240 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -1387,37 +1376,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1387 | } | 1376 | } |
1388 | } | 1377 | } |
1389 | 1378 | ||
1390 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1391 | { | ||
1392 | struct sd *sd = (struct sd *) gspca_dev; | ||
1393 | |||
1394 | sd->ctrls[AUTOGAIN].val = val; | ||
1395 | sd->exp_too_high_cnt = 0; | ||
1396 | sd->exp_too_low_cnt = 0; | ||
1397 | |||
1398 | /* when switching to autogain set defaults to make sure | ||
1399 | we are on a valid point of the autogain gain / | ||
1400 | exposure knee graph, and give this change time to | ||
1401 | take effect before doing autogain. */ | ||
1402 | if (sd->ctrls[AUTOGAIN].val | ||
1403 | && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { | ||
1404 | sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def; | ||
1405 | sd->ctrls[GAIN].val = sd->ctrls[GAIN].def; | ||
1406 | if (gspca_dev->streaming) { | ||
1407 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | ||
1408 | setexposure(gspca_dev); | ||
1409 | setgain(gspca_dev); | ||
1410 | } | ||
1411 | } | ||
1412 | |||
1413 | if (sd->ctrls[AUTOGAIN].val) | ||
1414 | gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE); | ||
1415 | else | ||
1416 | gspca_dev->ctrl_inac = 0; | ||
1417 | |||
1418 | return 0; | ||
1419 | } | ||
1420 | |||
1421 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 1379 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
1422 | struct v4l2_querymenu *menu) | 1380 | struct v4l2_querymenu *menu) |
1423 | { | 1381 | { |
@@ -1461,10 +1419,9 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | |||
1461 | /* sub-driver description */ | 1419 | /* sub-driver description */ |
1462 | static const struct sd_desc sd_desc = { | 1420 | static const struct sd_desc sd_desc = { |
1463 | .name = MODULE_NAME, | 1421 | .name = MODULE_NAME, |
1464 | .ctrls = sd_ctrls, | ||
1465 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1466 | .config = sd_config, | 1422 | .config = sd_config, |
1467 | .init = sd_init, | 1423 | .init = sd_init, |
1424 | .init_controls = sd_init_controls, | ||
1468 | .start = sd_start, | 1425 | .start = sd_start, |
1469 | .stopN = sd_stopN, | 1426 | .stopN = sd_stopN, |
1470 | .pkt_scan = sd_pkt_scan, | 1427 | .pkt_scan = sd_pkt_scan, |
@@ -1529,6 +1486,7 @@ static struct usb_driver sd_driver = { | |||
1529 | #ifdef CONFIG_PM | 1486 | #ifdef CONFIG_PM |
1530 | .suspend = gspca_suspend, | 1487 | .suspend = gspca_suspend, |
1531 | .resume = gspca_resume, | 1488 | .resume = gspca_resume, |
1489 | .reset_resume = gspca_resume, | ||
1532 | #endif | 1490 | #endif |
1533 | }; | 1491 | }; |
1534 | 1492 | ||
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index f38faa9b37c3..150b2df40f7f 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -3199,6 +3199,7 @@ static struct usb_driver sd_driver = { | |||
3199 | #ifdef CONFIG_PM | 3199 | #ifdef CONFIG_PM |
3200 | .suspend = gspca_suspend, | 3200 | .suspend = gspca_suspend, |
3201 | .resume = gspca_resume, | 3201 | .resume = gspca_resume, |
3202 | .reset_resume = gspca_resume, | ||
3202 | #endif | 3203 | #endif |
3203 | }; | 3204 | }; |
3204 | 3205 | ||
diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/video/gspca/spca1528.c index 070b9c33b517..14d635277d71 100644 --- a/drivers/media/video/gspca/spca1528.c +++ b/drivers/media/video/gspca/spca1528.c | |||
@@ -33,102 +33,11 @@ MODULE_LICENSE("GPL"); | |||
33 | struct sd { | 33 | struct sd { |
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 34 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
35 | 35 | ||
36 | u8 brightness; | ||
37 | u8 contrast; | ||
38 | u8 hue; | ||
39 | u8 color; | ||
40 | u8 sharpness; | ||
41 | |||
42 | u8 pkt_seq; | 36 | u8 pkt_seq; |
43 | 37 | ||
44 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 38 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
45 | }; | 39 | }; |
46 | 40 | ||
47 | /* V4L2 controls supported by the driver */ | ||
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
50 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
57 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
58 | |||
59 | static const struct ctrl sd_ctrls[] = { | ||
60 | { | ||
61 | { | ||
62 | .id = V4L2_CID_BRIGHTNESS, | ||
63 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
64 | .name = "Brightness", | ||
65 | .minimum = 0, | ||
66 | .maximum = 255, | ||
67 | .step = 1, | ||
68 | #define BRIGHTNESS_DEF 128 | ||
69 | .default_value = BRIGHTNESS_DEF, | ||
70 | }, | ||
71 | .set = sd_setbrightness, | ||
72 | .get = sd_getbrightness, | ||
73 | }, | ||
74 | { | ||
75 | { | ||
76 | .id = V4L2_CID_CONTRAST, | ||
77 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
78 | .name = "Contrast", | ||
79 | .minimum = 0, | ||
80 | .maximum = 8, | ||
81 | .step = 1, | ||
82 | #define CONTRAST_DEF 1 | ||
83 | .default_value = CONTRAST_DEF, | ||
84 | }, | ||
85 | .set = sd_setcontrast, | ||
86 | .get = sd_getcontrast, | ||
87 | }, | ||
88 | { | ||
89 | { | ||
90 | .id = V4L2_CID_HUE, | ||
91 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
92 | .name = "Hue", | ||
93 | .minimum = 0, | ||
94 | .maximum = 255, | ||
95 | .step = 1, | ||
96 | #define HUE_DEF 0 | ||
97 | .default_value = HUE_DEF, | ||
98 | }, | ||
99 | .set = sd_sethue, | ||
100 | .get = sd_gethue, | ||
101 | }, | ||
102 | { | ||
103 | { | ||
104 | .id = V4L2_CID_SATURATION, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Saturation", | ||
107 | .minimum = 0, | ||
108 | .maximum = 8, | ||
109 | .step = 1, | ||
110 | #define COLOR_DEF 1 | ||
111 | .default_value = COLOR_DEF, | ||
112 | }, | ||
113 | .set = sd_setcolor, | ||
114 | .get = sd_getcolor, | ||
115 | }, | ||
116 | { | ||
117 | { | ||
118 | .id = V4L2_CID_SHARPNESS, | ||
119 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
120 | .name = "Sharpness", | ||
121 | .minimum = 0, | ||
122 | .maximum = 255, | ||
123 | .step = 1, | ||
124 | #define SHARPNESS_DEF 0 | ||
125 | .default_value = SHARPNESS_DEF, | ||
126 | }, | ||
127 | .set = sd_setsharpness, | ||
128 | .get = sd_getsharpness, | ||
129 | }, | ||
130 | }; | ||
131 | |||
132 | static const struct v4l2_pix_format vga_mode[] = { | 41 | static const struct v4l2_pix_format vga_mode[] = { |
133 | /* (does not work correctly) | 42 | /* (does not work correctly) |
134 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 43 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
@@ -259,58 +168,40 @@ static void wait_status_1(struct gspca_dev *gspca_dev) | |||
259 | gspca_dev->usb_err = -ETIME; | 168 | gspca_dev->usb_err = -ETIME; |
260 | } | 169 | } |
261 | 170 | ||
262 | static void setbrightness(struct gspca_dev *gspca_dev) | 171 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
263 | { | 172 | { |
264 | struct sd *sd = (struct sd *) gspca_dev; | 173 | reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val); |
265 | |||
266 | reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, sd->brightness); | ||
267 | } | 174 | } |
268 | 175 | ||
269 | static void setcontrast(struct gspca_dev *gspca_dev) | 176 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
270 | { | 177 | { |
271 | struct sd *sd = (struct sd *) gspca_dev; | 178 | reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val); |
272 | |||
273 | reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, sd->contrast); | ||
274 | } | 179 | } |
275 | 180 | ||
276 | static void sethue(struct gspca_dev *gspca_dev) | 181 | static void sethue(struct gspca_dev *gspca_dev, s32 val) |
277 | { | 182 | { |
278 | struct sd *sd = (struct sd *) gspca_dev; | 183 | reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val); |
279 | |||
280 | reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, sd->hue); | ||
281 | } | 184 | } |
282 | 185 | ||
283 | static void setcolor(struct gspca_dev *gspca_dev) | 186 | static void setcolor(struct gspca_dev *gspca_dev, s32 val) |
284 | { | 187 | { |
285 | struct sd *sd = (struct sd *) gspca_dev; | 188 | reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val); |
286 | |||
287 | reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, sd->color); | ||
288 | } | 189 | } |
289 | 190 | ||
290 | static void setsharpness(struct gspca_dev *gspca_dev) | 191 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
291 | { | 192 | { |
292 | struct sd *sd = (struct sd *) gspca_dev; | 193 | reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val); |
293 | |||
294 | reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, sd->sharpness); | ||
295 | } | 194 | } |
296 | 195 | ||
297 | /* this function is called at probe time */ | 196 | /* this function is called at probe time */ |
298 | static int sd_config(struct gspca_dev *gspca_dev, | 197 | static int sd_config(struct gspca_dev *gspca_dev, |
299 | const struct usb_device_id *id) | 198 | const struct usb_device_id *id) |
300 | { | 199 | { |
301 | struct sd *sd = (struct sd *) gspca_dev; | ||
302 | |||
303 | gspca_dev->cam.cam_mode = vga_mode; | 200 | gspca_dev->cam.cam_mode = vga_mode; |
304 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | 201 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); |
305 | gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */ | 202 | gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */ |
306 | /*fixme: 256 in ms-win traces*/ | 203 | /*fixme: 256 in ms-win traces*/ |
307 | 204 | ||
308 | sd->brightness = BRIGHTNESS_DEF; | ||
309 | sd->contrast = CONTRAST_DEF; | ||
310 | sd->hue = HUE_DEF; | ||
311 | sd->color = COLOR_DEF; | ||
312 | sd->sharpness = SHARPNESS_DEF; | ||
313 | |||
314 | return 0; | 205 | return 0; |
315 | } | 206 | } |
316 | 207 | ||
@@ -370,14 +261,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
370 | /* the JPEG quality shall be 85% */ | 261 | /* the JPEG quality shall be 85% */ |
371 | jpeg_set_qual(sd->jpeg_hdr, 85); | 262 | jpeg_set_qual(sd->jpeg_hdr, 85); |
372 | 263 | ||
373 | /* set the controls */ | ||
374 | setbrightness(gspca_dev); | ||
375 | setcontrast(gspca_dev); | ||
376 | sethue(gspca_dev); | ||
377 | setcolor(gspca_dev); | ||
378 | setsharpness(gspca_dev); | ||
379 | |||
380 | msleep(5); | ||
381 | reg_r(gspca_dev, 0x00, 0x2520, 1); | 264 | reg_r(gspca_dev, 0x00, 0x2520, 1); |
382 | msleep(8); | 265 | msleep(8); |
383 | 266 | ||
@@ -457,103 +340,70 @@ err: | |||
457 | gspca_dev->last_packet_type = DISCARD_PACKET; | 340 | gspca_dev->last_packet_type = DISCARD_PACKET; |
458 | } | 341 | } |
459 | 342 | ||
460 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 343 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
461 | { | ||
462 | struct sd *sd = (struct sd *) gspca_dev; | ||
463 | |||
464 | sd->brightness = val; | ||
465 | if (gspca_dev->streaming) | ||
466 | setbrightness(gspca_dev); | ||
467 | return gspca_dev->usb_err; | ||
468 | } | ||
469 | |||
470 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
471 | { | ||
472 | struct sd *sd = (struct sd *) gspca_dev; | ||
473 | |||
474 | *val = sd->brightness; | ||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
479 | { | 344 | { |
480 | struct sd *sd = (struct sd *) gspca_dev; | 345 | struct gspca_dev *gspca_dev = |
481 | 346 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
482 | sd->contrast = val; | 347 | |
483 | if (gspca_dev->streaming) | 348 | gspca_dev->usb_err = 0; |
484 | setcontrast(gspca_dev); | 349 | |
485 | return gspca_dev->usb_err; | 350 | if (!gspca_dev->streaming) |
486 | } | 351 | return 0; |
487 | 352 | ||
488 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 353 | switch (ctrl->id) { |
489 | { | 354 | case V4L2_CID_BRIGHTNESS: |
490 | struct sd *sd = (struct sd *) gspca_dev; | 355 | setbrightness(gspca_dev, ctrl->val); |
491 | 356 | break; | |
492 | *val = sd->contrast; | 357 | case V4L2_CID_CONTRAST: |
493 | return 0; | 358 | setcontrast(gspca_dev, ctrl->val); |
494 | } | 359 | break; |
495 | 360 | case V4L2_CID_HUE: | |
496 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | 361 | sethue(gspca_dev, ctrl->val); |
497 | { | 362 | break; |
498 | struct sd *sd = (struct sd *) gspca_dev; | 363 | case V4L2_CID_SATURATION: |
499 | 364 | setcolor(gspca_dev, ctrl->val); | |
500 | sd->hue = val; | 365 | break; |
501 | if (gspca_dev->streaming) | 366 | case V4L2_CID_SHARPNESS: |
502 | sethue(gspca_dev); | 367 | setsharpness(gspca_dev, ctrl->val); |
503 | return gspca_dev->usb_err; | 368 | break; |
504 | } | 369 | } |
505 | |||
506 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
507 | { | ||
508 | struct sd *sd = (struct sd *) gspca_dev; | ||
509 | |||
510 | *val = sd->hue; | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val) | ||
515 | { | ||
516 | struct sd *sd = (struct sd *) gspca_dev; | ||
517 | |||
518 | sd->color = val; | ||
519 | if (gspca_dev->streaming) | ||
520 | setcolor(gspca_dev); | ||
521 | return gspca_dev->usb_err; | 370 | return gspca_dev->usb_err; |
522 | } | 371 | } |
523 | 372 | ||
524 | static int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val) | 373 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
525 | { | 374 | .s_ctrl = sd_s_ctrl, |
526 | struct sd *sd = (struct sd *) gspca_dev; | 375 | }; |
527 | |||
528 | *val = sd->color; | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
533 | { | ||
534 | struct sd *sd = (struct sd *) gspca_dev; | ||
535 | |||
536 | sd->sharpness = val; | ||
537 | if (gspca_dev->streaming) | ||
538 | setsharpness(gspca_dev); | ||
539 | return gspca_dev->usb_err; | ||
540 | } | ||
541 | 376 | ||
542 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | 377 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
543 | { | 378 | { |
544 | struct sd *sd = (struct sd *) gspca_dev; | 379 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
545 | 380 | ||
546 | *val = sd->sharpness; | 381 | gspca_dev->vdev.ctrl_handler = hdl; |
382 | v4l2_ctrl_handler_init(hdl, 5); | ||
383 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
384 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); | ||
385 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
386 | V4L2_CID_CONTRAST, 0, 8, 1, 1); | ||
387 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
388 | V4L2_CID_HUE, 0, 255, 1, 0); | ||
389 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
390 | V4L2_CID_SATURATION, 0, 8, 1, 1); | ||
391 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
392 | V4L2_CID_SHARPNESS, 0, 255, 1, 0); | ||
393 | |||
394 | if (hdl->error) { | ||
395 | pr_err("Could not initialize controls\n"); | ||
396 | return hdl->error; | ||
397 | } | ||
547 | return 0; | 398 | return 0; |
548 | } | 399 | } |
549 | 400 | ||
550 | /* sub-driver description */ | 401 | /* sub-driver description */ |
551 | static const struct sd_desc sd_desc = { | 402 | static const struct sd_desc sd_desc = { |
552 | .name = MODULE_NAME, | 403 | .name = MODULE_NAME, |
553 | .ctrls = sd_ctrls, | ||
554 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
555 | .config = sd_config, | 404 | .config = sd_config, |
556 | .init = sd_init, | 405 | .init = sd_init, |
406 | .init_controls = sd_init_controls, | ||
557 | .isoc_init = sd_isoc_init, | 407 | .isoc_init = sd_isoc_init, |
558 | .start = sd_start, | 408 | .start = sd_start, |
559 | .stopN = sd_stopN, | 409 | .stopN = sd_stopN, |
@@ -587,6 +437,7 @@ static struct usb_driver sd_driver = { | |||
587 | #ifdef CONFIG_PM | 437 | #ifdef CONFIG_PM |
588 | .suspend = gspca_suspend, | 438 | .suspend = gspca_suspend, |
589 | .resume = gspca_resume, | 439 | .resume = gspca_resume, |
440 | .reset_resume = gspca_resume, | ||
590 | #endif | 441 | #endif |
591 | }; | 442 | }; |
592 | 443 | ||
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 103984708c77..25cb68d0556d 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -30,18 +30,12 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
30 | MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); | 30 | MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); |
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | 32 | ||
33 | #define QUALITY 85 | ||
34 | |||
33 | /* specific webcam descriptor */ | 35 | /* specific webcam descriptor */ |
34 | struct sd { | 36 | struct sd { |
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 37 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
36 | 38 | ||
37 | unsigned char brightness; | ||
38 | unsigned char contrast; | ||
39 | unsigned char colors; | ||
40 | u8 quality; | ||
41 | #define QUALITY_MIN 70 | ||
42 | #define QUALITY_MAX 95 | ||
43 | #define QUALITY_DEF 85 | ||
44 | |||
45 | char subtype; | 39 | char subtype; |
46 | #define AgfaCl20 0 | 40 | #define AgfaCl20 0 |
47 | #define AiptekPocketDV 1 | 41 | #define AiptekPocketDV 1 |
@@ -62,59 +56,6 @@ struct sd { | |||
62 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 56 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
63 | }; | 57 | }; |
64 | 58 | ||
65 | /* V4L2 controls supported by the driver */ | ||
66 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
67 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
68 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
69 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
70 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
71 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | |||
73 | static const struct ctrl sd_ctrls[] = { | ||
74 | { | ||
75 | { | ||
76 | .id = V4L2_CID_BRIGHTNESS, | ||
77 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
78 | .name = "Brightness", | ||
79 | .minimum = 0, | ||
80 | .maximum = 255, | ||
81 | .step = 1, | ||
82 | #define BRIGHTNESS_DEF 127 | ||
83 | .default_value = BRIGHTNESS_DEF, | ||
84 | }, | ||
85 | .set = sd_setbrightness, | ||
86 | .get = sd_getbrightness, | ||
87 | }, | ||
88 | { | ||
89 | { | ||
90 | .id = V4L2_CID_CONTRAST, | ||
91 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
92 | .name = "Contrast", | ||
93 | .minimum = 0, | ||
94 | .maximum = 63, | ||
95 | .step = 1, | ||
96 | #define CONTRAST_DEF 31 | ||
97 | .default_value = CONTRAST_DEF, | ||
98 | }, | ||
99 | .set = sd_setcontrast, | ||
100 | .get = sd_getcontrast, | ||
101 | }, | ||
102 | { | ||
103 | { | ||
104 | .id = V4L2_CID_SATURATION, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Color", | ||
107 | .minimum = 0, | ||
108 | .maximum = 63, | ||
109 | .step = 1, | ||
110 | #define COLOR_DEF 31 | ||
111 | .default_value = COLOR_DEF, | ||
112 | }, | ||
113 | .set = sd_setcolors, | ||
114 | .get = sd_getcolors, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static const struct v4l2_pix_format vga_mode[] = { | 59 | static const struct v4l2_pix_format vga_mode[] = { |
119 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 60 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
120 | .bytesperline = 320, | 61 | .bytesperline = 320, |
@@ -641,10 +582,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
641 | cam->cam_mode = sif_mode; | 582 | cam->cam_mode = sif_mode; |
642 | cam->nmodes = ARRAY_SIZE(sif_mode); | 583 | cam->nmodes = ARRAY_SIZE(sif_mode); |
643 | } | 584 | } |
644 | sd->brightness = BRIGHTNESS_DEF; | ||
645 | sd->contrast = CONTRAST_DEF; | ||
646 | sd->colors = COLOR_DEF; | ||
647 | sd->quality = QUALITY_DEF; | ||
648 | return 0; | 585 | return 0; |
649 | } | 586 | } |
650 | 587 | ||
@@ -673,7 +610,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
673 | /* create the JPEG header */ | 610 | /* create the JPEG header */ |
674 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 611 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
675 | 0x22); /* JPEG 411 */ | 612 | 0x22); /* JPEG 411 */ |
676 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 613 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
677 | 614 | ||
678 | if (sd->subtype == LogitechClickSmart310) { | 615 | if (sd->subtype == LogitechClickSmart310) { |
679 | xmult = 0x16; | 616 | xmult = 0x16; |
@@ -934,122 +871,79 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
934 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 871 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
935 | } | 872 | } |
936 | 873 | ||
937 | static void setbrightness(struct gspca_dev *gspca_dev) | 874 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
938 | { | 875 | { |
939 | struct sd *sd = (struct sd *) gspca_dev; | ||
940 | |||
941 | reg_w(gspca_dev, 0x00, 0x8167, | 876 | reg_w(gspca_dev, 0x00, 0x8167, |
942 | (__u8) (sd->brightness - 128)); | 877 | (__u8) (val - 128)); |
943 | } | 878 | } |
944 | 879 | ||
945 | static void setcontrast(struct gspca_dev *gspca_dev) | 880 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
946 | { | 881 | { |
947 | struct sd *sd = (struct sd *) gspca_dev; | 882 | reg_w(gspca_dev, 0x00, 0x8168, val); |
948 | |||
949 | reg_w(gspca_dev, 0x00, 0x8168, sd->contrast); | ||
950 | } | 883 | } |
951 | 884 | ||
952 | static void setcolors(struct gspca_dev *gspca_dev) | 885 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
953 | { | 886 | { |
954 | struct sd *sd = (struct sd *) gspca_dev; | 887 | reg_w(gspca_dev, 0x00, 0x8169, val); |
955 | |||
956 | reg_w(gspca_dev, 0x00, 0x8169, sd->colors); | ||
957 | } | 888 | } |
958 | 889 | ||
959 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 890 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
960 | { | 891 | { |
961 | struct sd *sd = (struct sd *) gspca_dev; | 892 | struct gspca_dev *gspca_dev = |
893 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
962 | 894 | ||
963 | sd->brightness = val; | 895 | gspca_dev->usb_err = 0; |
964 | if (gspca_dev->streaming) | ||
965 | setbrightness(gspca_dev); | ||
966 | return 0; | ||
967 | } | ||
968 | 896 | ||
969 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | 897 | if (!gspca_dev->streaming) |
970 | { | 898 | return 0; |
971 | struct sd *sd = (struct sd *) gspca_dev; | ||
972 | |||
973 | *val = sd->brightness; | ||
974 | return 0; | ||
975 | } | ||
976 | |||
977 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
978 | { | ||
979 | struct sd *sd = (struct sd *) gspca_dev; | ||
980 | |||
981 | sd->contrast = val; | ||
982 | if (gspca_dev->streaming) | ||
983 | setcontrast(gspca_dev); | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
988 | { | ||
989 | struct sd *sd = (struct sd *) gspca_dev; | ||
990 | 899 | ||
991 | *val = sd->contrast; | 900 | switch (ctrl->id) { |
992 | return 0; | 901 | case V4L2_CID_BRIGHTNESS: |
993 | } | 902 | setbrightness(gspca_dev, ctrl->val); |
994 | 903 | break; | |
995 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | 904 | case V4L2_CID_CONTRAST: |
996 | { | 905 | setcontrast(gspca_dev, ctrl->val); |
997 | struct sd *sd = (struct sd *) gspca_dev; | 906 | break; |
998 | 907 | case V4L2_CID_SATURATION: | |
999 | sd->colors = val; | 908 | setcolors(gspca_dev, ctrl->val); |
1000 | if (gspca_dev->streaming) | 909 | break; |
1001 | setcolors(gspca_dev); | 910 | } |
1002 | return 0; | 911 | return gspca_dev->usb_err; |
1003 | } | ||
1004 | |||
1005 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1006 | { | ||
1007 | struct sd *sd = (struct sd *) gspca_dev; | ||
1008 | |||
1009 | *val = sd->colors; | ||
1010 | return 0; | ||
1011 | } | 912 | } |
1012 | 913 | ||
1013 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 914 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
1014 | struct v4l2_jpegcompression *jcomp) | 915 | .s_ctrl = sd_s_ctrl, |
1015 | { | 916 | }; |
1016 | struct sd *sd = (struct sd *) gspca_dev; | ||
1017 | |||
1018 | if (jcomp->quality < QUALITY_MIN) | ||
1019 | sd->quality = QUALITY_MIN; | ||
1020 | else if (jcomp->quality > QUALITY_MAX) | ||
1021 | sd->quality = QUALITY_MAX; | ||
1022 | else | ||
1023 | sd->quality = jcomp->quality; | ||
1024 | if (gspca_dev->streaming) | ||
1025 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
1026 | return 0; | ||
1027 | } | ||
1028 | 917 | ||
1029 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 918 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
1030 | struct v4l2_jpegcompression *jcomp) | ||
1031 | { | 919 | { |
1032 | struct sd *sd = (struct sd *) gspca_dev; | 920 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
1033 | 921 | ||
1034 | memset(jcomp, 0, sizeof *jcomp); | 922 | gspca_dev->vdev.ctrl_handler = hdl; |
1035 | jcomp->quality = sd->quality; | 923 | v4l2_ctrl_handler_init(hdl, 3); |
1036 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 924 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
1037 | | V4L2_JPEG_MARKER_DQT; | 925 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); |
926 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
927 | V4L2_CID_CONTRAST, 0, 63, 1, 31); | ||
928 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
929 | V4L2_CID_SATURATION, 0, 63, 1, 31); | ||
930 | |||
931 | if (hdl->error) { | ||
932 | pr_err("Could not initialize controls\n"); | ||
933 | return hdl->error; | ||
934 | } | ||
1038 | return 0; | 935 | return 0; |
1039 | } | 936 | } |
1040 | 937 | ||
1041 | /* sub-driver description */ | 938 | /* sub-driver description */ |
1042 | static const struct sd_desc sd_desc = { | 939 | static const struct sd_desc sd_desc = { |
1043 | .name = MODULE_NAME, | 940 | .name = MODULE_NAME, |
1044 | .ctrls = sd_ctrls, | ||
1045 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1046 | .config = sd_config, | 941 | .config = sd_config, |
1047 | .init = sd_init, | 942 | .init = sd_init, |
943 | .init_controls = sd_init_controls, | ||
1048 | .start = sd_start, | 944 | .start = sd_start, |
1049 | .stopN = sd_stopN, | 945 | .stopN = sd_stopN, |
1050 | .pkt_scan = sd_pkt_scan, | 946 | .pkt_scan = sd_pkt_scan, |
1051 | .get_jcomp = sd_get_jcomp, | ||
1052 | .set_jcomp = sd_set_jcomp, | ||
1053 | }; | 947 | }; |
1054 | 948 | ||
1055 | /* -- module initialisation -- */ | 949 | /* -- module initialisation -- */ |
@@ -1089,6 +983,7 @@ static struct usb_driver sd_driver = { | |||
1089 | #ifdef CONFIG_PM | 983 | #ifdef CONFIG_PM |
1090 | .suspend = gspca_suspend, | 984 | .suspend = gspca_suspend, |
1091 | .resume = gspca_resume, | 985 | .resume = gspca_resume, |
986 | .reset_resume = gspca_resume, | ||
1092 | #endif | 987 | #endif |
1093 | }; | 988 | }; |
1094 | 989 | ||
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 9c16821addd4..3b7f777785b4 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c | |||
@@ -49,91 +49,6 @@ struct sd { | |||
49 | #define ViewQuestM318B 6 | 49 | #define ViewQuestM318B 6 |
50 | }; | 50 | }; |
51 | 51 | ||
52 | /* V4L2 controls supported by the driver */ | ||
53 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
60 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
61 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
63 | |||
64 | static const struct ctrl sd_ctrls[] = { | ||
65 | #define MY_BRIGHTNESS 0 | ||
66 | { | ||
67 | { | ||
68 | .id = V4L2_CID_BRIGHTNESS, | ||
69 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
70 | .name = "Brightness", | ||
71 | .minimum = 0, | ||
72 | .maximum = 127, | ||
73 | .step = 1, | ||
74 | .default_value = 0, | ||
75 | }, | ||
76 | .set = sd_setbrightness, | ||
77 | .get = sd_getbrightness, | ||
78 | }, | ||
79 | #define MY_CONTRAST 1 | ||
80 | { | ||
81 | { | ||
82 | .id = V4L2_CID_CONTRAST, | ||
83 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
84 | .name = "Contrast", | ||
85 | .minimum = 0, | ||
86 | .maximum = 64725, | ||
87 | .step = 1, | ||
88 | .default_value = 64725, | ||
89 | }, | ||
90 | .set = sd_setcontrast, | ||
91 | .get = sd_getcontrast, | ||
92 | }, | ||
93 | #define MY_COLOR 2 | ||
94 | { | ||
95 | { | ||
96 | .id = V4L2_CID_SATURATION, | ||
97 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
98 | .name = "Color", | ||
99 | .minimum = 0, | ||
100 | .maximum = 63, | ||
101 | .step = 1, | ||
102 | .default_value = 20, | ||
103 | }, | ||
104 | .set = sd_setcolors, | ||
105 | .get = sd_getcolors, | ||
106 | }, | ||
107 | #define MY_BLUE_BALANCE 3 | ||
108 | { | ||
109 | { | ||
110 | .id = V4L2_CID_BLUE_BALANCE, | ||
111 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
112 | .name = "Blue Balance", | ||
113 | .minimum = 0, | ||
114 | .maximum = 127, | ||
115 | .step = 1, | ||
116 | .default_value = 0, | ||
117 | }, | ||
118 | .set = sd_setblue_balance, | ||
119 | .get = sd_getblue_balance, | ||
120 | }, | ||
121 | #define MY_RED_BALANCE 4 | ||
122 | { | ||
123 | { | ||
124 | .id = V4L2_CID_RED_BALANCE, | ||
125 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
126 | .name = "Red Balance", | ||
127 | .minimum = 0, | ||
128 | .maximum = 127, | ||
129 | .step = 1, | ||
130 | .default_value = 0, | ||
131 | }, | ||
132 | .set = sd_setred_balance, | ||
133 | .get = sd_getred_balance, | ||
134 | }, | ||
135 | }; | ||
136 | |||
137 | static const struct v4l2_pix_format vga_mode[] = { | 52 | static const struct v4l2_pix_format vga_mode[] = { |
138 | {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, | 53 | {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, |
139 | .bytesperline = 160, | 54 | .bytesperline = 160, |
@@ -1878,42 +1793,32 @@ static int write_vector(struct gspca_dev *gspca_dev, | |||
1878 | return 0; | 1793 | return 0; |
1879 | } | 1794 | } |
1880 | 1795 | ||
1881 | static void setbrightness(struct gspca_dev *gspca_dev) | 1796 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
1882 | { | 1797 | { |
1883 | struct sd *sd = (struct sd *) gspca_dev; | 1798 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, val); |
1884 | |||
1885 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); | ||
1886 | } | 1799 | } |
1887 | 1800 | ||
1888 | static void setcontrast(struct gspca_dev *gspca_dev) | 1801 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
1889 | { | 1802 | { |
1890 | struct sd *sd = (struct sd *) gspca_dev; | ||
1891 | |||
1892 | reg_write(gspca_dev->dev, 0x00, 0x00, | 1803 | reg_write(gspca_dev->dev, 0x00, 0x00, |
1893 | (sd->contrast >> 8) & 0xff); | 1804 | (val >> 8) & 0xff); |
1894 | reg_write(gspca_dev->dev, 0x00, 0x01, | 1805 | reg_write(gspca_dev->dev, 0x00, 0x01, |
1895 | sd->contrast & 0xff); | 1806 | val & 0xff); |
1896 | } | 1807 | } |
1897 | 1808 | ||
1898 | static void setcolors(struct gspca_dev *gspca_dev) | 1809 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
1899 | { | 1810 | { |
1900 | struct sd *sd = (struct sd *) gspca_dev; | 1811 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, val); |
1901 | |||
1902 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors); | ||
1903 | } | 1812 | } |
1904 | 1813 | ||
1905 | static void setblue_balance(struct gspca_dev *gspca_dev) | 1814 | static void setblue_balance(struct gspca_dev *gspca_dev, s32 val) |
1906 | { | 1815 | { |
1907 | struct sd *sd = (struct sd *) gspca_dev; | 1816 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, val); |
1908 | |||
1909 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->blue_balance); | ||
1910 | } | 1817 | } |
1911 | 1818 | ||
1912 | static void setred_balance(struct gspca_dev *gspca_dev) | 1819 | static void setred_balance(struct gspca_dev *gspca_dev, s32 val) |
1913 | { | 1820 | { |
1914 | struct sd *sd = (struct sd *) gspca_dev; | 1821 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, val); |
1915 | |||
1916 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->red_balance); | ||
1917 | } | 1822 | } |
1918 | 1823 | ||
1919 | /* this function is called at probe time */ | 1824 | /* this function is called at probe time */ |
@@ -1927,9 +1832,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1927 | cam->cam_mode = vga_mode; | 1832 | cam->cam_mode = vga_mode; |
1928 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1833 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1929 | sd->subtype = id->driver_info; | 1834 | sd->subtype = id->driver_info; |
1930 | sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; | ||
1931 | sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; | ||
1932 | sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; | ||
1933 | 1835 | ||
1934 | return 0; | 1836 | return 0; |
1935 | } | 1837 | } |
@@ -2008,13 +1910,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2008 | } | 1910 | } |
2009 | reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); | 1911 | reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); |
2010 | 1912 | ||
2011 | /* HDG atleast the Intel CreateAndShare needs to have one of its | ||
2012 | * brightness / contrast / color set otherwise it assumes what seems | ||
2013 | * max contrast. Note that strange enough setting any of these is | ||
2014 | * enough to fix the max contrast problem, to be sure we set all 3 */ | ||
2015 | setbrightness(gspca_dev); | ||
2016 | setcontrast(gspca_dev); | ||
2017 | setcolors(gspca_dev); | ||
2018 | return 0; | 1913 | return 0; |
2019 | } | 1914 | } |
2020 | 1915 | ||
@@ -2053,103 +1948,70 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
2053 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 1948 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
2054 | } | 1949 | } |
2055 | 1950 | ||
2056 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1951 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
2057 | { | 1952 | { |
2058 | struct sd *sd = (struct sd *) gspca_dev; | 1953 | struct gspca_dev *gspca_dev = |
1954 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
2059 | 1955 | ||
2060 | sd->brightness = val; | 1956 | gspca_dev->usb_err = 0; |
2061 | if (gspca_dev->streaming) | ||
2062 | setbrightness(gspca_dev); | ||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
2066 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2067 | { | ||
2068 | struct sd *sd = (struct sd *) gspca_dev; | ||
2069 | 1957 | ||
2070 | *val = sd->brightness; | 1958 | if (!gspca_dev->streaming) |
2071 | return 0; | 1959 | return 0; |
2072 | } | ||
2073 | |||
2074 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2075 | { | ||
2076 | struct sd *sd = (struct sd *) gspca_dev; | ||
2077 | |||
2078 | sd->contrast = val; | ||
2079 | if (gspca_dev->streaming) | ||
2080 | setcontrast(gspca_dev); | ||
2081 | return 0; | ||
2082 | } | ||
2083 | |||
2084 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2085 | { | ||
2086 | struct sd *sd = (struct sd *) gspca_dev; | ||
2087 | |||
2088 | *val = sd->contrast; | ||
2089 | return 0; | ||
2090 | } | ||
2091 | |||
2092 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
2093 | { | ||
2094 | struct sd *sd = (struct sd *) gspca_dev; | ||
2095 | 1960 | ||
2096 | sd->colors = val; | 1961 | switch (ctrl->id) { |
2097 | if (gspca_dev->streaming) | 1962 | case V4L2_CID_BRIGHTNESS: |
2098 | setcolors(gspca_dev); | 1963 | setbrightness(gspca_dev, ctrl->val); |
2099 | return 0; | 1964 | break; |
2100 | } | 1965 | case V4L2_CID_CONTRAST: |
2101 | 1966 | setcontrast(gspca_dev, ctrl->val); | |
2102 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | 1967 | break; |
2103 | { | 1968 | case V4L2_CID_SATURATION: |
2104 | struct sd *sd = (struct sd *) gspca_dev; | 1969 | setcolors(gspca_dev, ctrl->val); |
2105 | 1970 | break; | |
2106 | *val = sd->colors; | 1971 | case V4L2_CID_BLUE_BALANCE: |
2107 | return 0; | 1972 | setblue_balance(gspca_dev, ctrl->val); |
2108 | } | 1973 | break; |
2109 | 1974 | case V4L2_CID_RED_BALANCE: | |
2110 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val) | 1975 | setred_balance(gspca_dev, ctrl->val); |
2111 | { | 1976 | break; |
2112 | struct sd *sd = (struct sd *) gspca_dev; | 1977 | } |
2113 | 1978 | return gspca_dev->usb_err; | |
2114 | sd->blue_balance = val; | ||
2115 | if (gspca_dev->streaming) | ||
2116 | setblue_balance(gspca_dev); | ||
2117 | return 0; | ||
2118 | } | ||
2119 | |||
2120 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
2121 | { | ||
2122 | struct sd *sd = (struct sd *) gspca_dev; | ||
2123 | |||
2124 | *val = sd->blue_balance; | ||
2125 | return 0; | ||
2126 | } | 1979 | } |
2127 | 1980 | ||
2128 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) | 1981 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
2129 | { | 1982 | .s_ctrl = sd_s_ctrl, |
2130 | struct sd *sd = (struct sd *) gspca_dev; | 1983 | }; |
2131 | |||
2132 | sd->red_balance = val; | ||
2133 | if (gspca_dev->streaming) | ||
2134 | setred_balance(gspca_dev); | ||
2135 | return 0; | ||
2136 | } | ||
2137 | 1984 | ||
2138 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) | 1985 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
2139 | { | 1986 | { |
2140 | struct sd *sd = (struct sd *) gspca_dev; | 1987 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
2141 | 1988 | ||
2142 | *val = sd->red_balance; | 1989 | gspca_dev->vdev.ctrl_handler = hdl; |
1990 | v4l2_ctrl_handler_init(hdl, 5); | ||
1991 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1992 | V4L2_CID_BRIGHTNESS, 0, 127, 1, 0); | ||
1993 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1994 | V4L2_CID_CONTRAST, 0, 64725, 1, 64725); | ||
1995 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1996 | V4L2_CID_SATURATION, 0, 63, 1, 20); | ||
1997 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1998 | V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0); | ||
1999 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
2000 | V4L2_CID_RED_BALANCE, 0, 127, 1, 0); | ||
2001 | |||
2002 | if (hdl->error) { | ||
2003 | pr_err("Could not initialize controls\n"); | ||
2004 | return hdl->error; | ||
2005 | } | ||
2143 | return 0; | 2006 | return 0; |
2144 | } | 2007 | } |
2145 | 2008 | ||
2146 | /* sub-driver description */ | 2009 | /* sub-driver description */ |
2147 | static const struct sd_desc sd_desc = { | 2010 | static const struct sd_desc sd_desc = { |
2148 | .name = MODULE_NAME, | 2011 | .name = MODULE_NAME, |
2149 | .ctrls = sd_ctrls, | ||
2150 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2151 | .config = sd_config, | 2012 | .config = sd_config, |
2152 | .init = sd_init, | 2013 | .init = sd_init, |
2014 | .init_controls = sd_init_controls, | ||
2153 | .start = sd_start, | 2015 | .start = sd_start, |
2154 | .stopN = sd_stopN, | 2016 | .stopN = sd_stopN, |
2155 | .stop0 = sd_stop0, | 2017 | .stop0 = sd_stop0, |
@@ -2185,6 +2047,7 @@ static struct usb_driver sd_driver = { | |||
2185 | #ifdef CONFIG_PM | 2047 | #ifdef CONFIG_PM |
2186 | .suspend = gspca_suspend, | 2048 | .suspend = gspca_suspend, |
2187 | .resume = gspca_resume, | 2049 | .resume = gspca_resume, |
2050 | .reset_resume = gspca_resume, | ||
2188 | #endif | 2051 | #endif |
2189 | }; | 2052 | }; |
2190 | 2053 | ||
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 1320f35e39f2..bc7d67c3cb04 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -33,34 +33,11 @@ MODULE_LICENSE("GPL"); | |||
33 | struct sd { | 33 | struct sd { |
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 34 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
35 | 35 | ||
36 | u8 brightness; | ||
37 | |||
38 | u8 subtype; | 36 | u8 subtype; |
39 | #define IntelPCCameraPro 0 | 37 | #define IntelPCCameraPro 0 |
40 | #define Nxultra 1 | 38 | #define Nxultra 1 |
41 | }; | 39 | }; |
42 | 40 | ||
43 | /* V4L2 controls supported by the driver */ | ||
44 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
45 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
46 | |||
47 | static const struct ctrl sd_ctrls[] = { | ||
48 | { | ||
49 | { | ||
50 | .id = V4L2_CID_BRIGHTNESS, | ||
51 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
52 | .name = "Brightness", | ||
53 | .minimum = 0, | ||
54 | .maximum = 255, | ||
55 | .step = 1, | ||
56 | #define BRIGHTNESS_DEF 127 | ||
57 | .default_value = BRIGHTNESS_DEF, | ||
58 | }, | ||
59 | .set = sd_setbrightness, | ||
60 | .get = sd_getbrightness, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static const struct v4l2_pix_format vga_mode[] = { | 41 | static const struct v4l2_pix_format vga_mode[] = { |
65 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 42 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
66 | .bytesperline = 160, | 43 | .bytesperline = 160, |
@@ -633,7 +610,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
633 | cam->nmodes = ARRAY_SIZE(vga_mode); | 610 | cam->nmodes = ARRAY_SIZE(vga_mode); |
634 | else /* no 640x480 for IntelPCCameraPro */ | 611 | else /* no 640x480 for IntelPCCameraPro */ |
635 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; | 612 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; |
636 | sd->brightness = BRIGHTNESS_DEF; | ||
637 | 613 | ||
638 | return 0; | 614 | return 0; |
639 | } | 615 | } |
@@ -651,11 +627,8 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
651 | return 0; | 627 | return 0; |
652 | } | 628 | } |
653 | 629 | ||
654 | static void setbrightness(struct gspca_dev *gspca_dev) | 630 | static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) |
655 | { | 631 | { |
656 | struct sd *sd = (struct sd *) gspca_dev; | ||
657 | u8 brightness = sd->brightness; | ||
658 | |||
659 | reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); | 632 | reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); |
660 | reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); | 633 | reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); |
661 | } | 634 | } |
@@ -706,13 +679,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
706 | reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); | 679 | reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); |
707 | reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); | 680 | reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); |
708 | 681 | ||
709 | ret = reg_write(dev, SPCA50X_REG_USB, | 682 | return reg_write(dev, SPCA50X_REG_USB, |
710 | SPCA50X_USB_CTRL, | 683 | SPCA50X_USB_CTRL, |
711 | SPCA50X_CUSB_ENABLE); | 684 | SPCA50X_CUSB_ENABLE); |
712 | |||
713 | setbrightness(gspca_dev); | ||
714 | |||
715 | return ret; | ||
716 | } | 685 | } |
717 | 686 | ||
718 | static void sd_stopN(struct gspca_dev *gspca_dev) | 687 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -756,30 +725,49 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
756 | } | 725 | } |
757 | } | 726 | } |
758 | 727 | ||
759 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 728 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
760 | { | 729 | { |
761 | struct sd *sd = (struct sd *) gspca_dev; | 730 | struct gspca_dev *gspca_dev = |
731 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
762 | 732 | ||
763 | sd->brightness = val; | 733 | gspca_dev->usb_err = 0; |
764 | if (gspca_dev->streaming) | 734 | |
765 | setbrightness(gspca_dev); | 735 | if (!gspca_dev->streaming) |
766 | return 0; | 736 | return 0; |
737 | |||
738 | switch (ctrl->id) { | ||
739 | case V4L2_CID_BRIGHTNESS: | ||
740 | setbrightness(gspca_dev, ctrl->val); | ||
741 | break; | ||
742 | } | ||
743 | return gspca_dev->usb_err; | ||
767 | } | 744 | } |
768 | 745 | ||
769 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | 746 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
747 | .s_ctrl = sd_s_ctrl, | ||
748 | }; | ||
749 | |||
750 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
770 | { | 751 | { |
771 | struct sd *sd = (struct sd *) gspca_dev; | 752 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
772 | 753 | ||
773 | *val = sd->brightness; | 754 | gspca_dev->vdev.ctrl_handler = hdl; |
755 | v4l2_ctrl_handler_init(hdl, 5); | ||
756 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
757 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); | ||
758 | |||
759 | if (hdl->error) { | ||
760 | pr_err("Could not initialize controls\n"); | ||
761 | return hdl->error; | ||
762 | } | ||
774 | return 0; | 763 | return 0; |
775 | } | 764 | } |
776 | 765 | ||
777 | /* sub-driver description */ | 766 | /* sub-driver description */ |
778 | static const struct sd_desc sd_desc = { | 767 | static const struct sd_desc sd_desc = { |
779 | .name = MODULE_NAME, | 768 | .name = MODULE_NAME, |
780 | .ctrls = sd_ctrls, | ||
781 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
782 | .config = sd_config, | 769 | .config = sd_config, |
770 | .init_controls = sd_init_controls, | ||
783 | .init = sd_init, | 771 | .init = sd_init, |
784 | .start = sd_start, | 772 | .start = sd_start, |
785 | .stopN = sd_stopN, | 773 | .stopN = sd_stopN, |
@@ -812,6 +800,7 @@ static struct usb_driver sd_driver = { | |||
812 | #ifdef CONFIG_PM | 800 | #ifdef CONFIG_PM |
813 | .suspend = gspca_suspend, | 801 | .suspend = gspca_suspend, |
814 | .resume = gspca_resume, | 802 | .resume = gspca_resume, |
803 | .reset_resume = gspca_resume, | ||
815 | #endif | 804 | #endif |
816 | }; | 805 | }; |
817 | 806 | ||
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 54eed87672d2..969bb5a4cd93 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -33,83 +33,10 @@ MODULE_LICENSE("GPL"); | |||
33 | struct sd { | 33 | struct sd { |
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 34 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
35 | 35 | ||
36 | unsigned char brightness; | ||
37 | unsigned char contrast; | ||
38 | unsigned char colors; | ||
39 | unsigned char hue; | ||
40 | char norme; | 36 | char norme; |
41 | char channel; | 37 | char channel; |
42 | }; | 38 | }; |
43 | 39 | ||
44 | /* V4L2 controls supported by the driver */ | ||
45 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
46 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
47 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | |||
54 | static const struct ctrl sd_ctrls[] = { | ||
55 | #define SD_BRIGHTNESS 0 | ||
56 | { | ||
57 | { | ||
58 | .id = V4L2_CID_BRIGHTNESS, | ||
59 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
60 | .name = "Brightness", | ||
61 | .minimum = 0, | ||
62 | .maximum = 0xff, | ||
63 | .step = 1, | ||
64 | .default_value = 0x80, | ||
65 | }, | ||
66 | .set = sd_setbrightness, | ||
67 | .get = sd_getbrightness, | ||
68 | }, | ||
69 | #define SD_CONTRAST 1 | ||
70 | { | ||
71 | { | ||
72 | .id = V4L2_CID_CONTRAST, | ||
73 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
74 | .name = "Contrast", | ||
75 | .minimum = 0, | ||
76 | .maximum = 0xff, | ||
77 | .step = 1, | ||
78 | .default_value = 0x47, | ||
79 | }, | ||
80 | .set = sd_setcontrast, | ||
81 | .get = sd_getcontrast, | ||
82 | }, | ||
83 | #define SD_COLOR 2 | ||
84 | { | ||
85 | { | ||
86 | .id = V4L2_CID_SATURATION, | ||
87 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
88 | .name = "Saturation", | ||
89 | .minimum = 0, | ||
90 | .maximum = 0xff, | ||
91 | .step = 1, | ||
92 | .default_value = 0x40, | ||
93 | }, | ||
94 | .set = sd_setcolors, | ||
95 | .get = sd_getcolors, | ||
96 | }, | ||
97 | #define SD_HUE 3 | ||
98 | { | ||
99 | { | ||
100 | .id = V4L2_CID_HUE, | ||
101 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
102 | .name = "Hue", | ||
103 | .minimum = 0, | ||
104 | .maximum = 0xff, | ||
105 | .step = 1, | ||
106 | .default_value = 0, | ||
107 | }, | ||
108 | .set = sd_sethue, | ||
109 | .get = sd_gethue, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | static const struct v4l2_pix_format vga_mode[] = { | 40 | static const struct v4l2_pix_format vga_mode[] = { |
114 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 41 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
115 | .bytesperline = 160, | 42 | .bytesperline = 160, |
@@ -281,16 +208,11 @@ static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code, | |||
281 | static int sd_config(struct gspca_dev *gspca_dev, | 208 | static int sd_config(struct gspca_dev *gspca_dev, |
282 | const struct usb_device_id *id) | 209 | const struct usb_device_id *id) |
283 | { | 210 | { |
284 | struct sd *sd = (struct sd *) gspca_dev; | ||
285 | struct cam *cam; | 211 | struct cam *cam; |
286 | 212 | ||
287 | cam = &gspca_dev->cam; | 213 | cam = &gspca_dev->cam; |
288 | cam->cam_mode = vga_mode; | 214 | cam->cam_mode = vga_mode; |
289 | cam->nmodes = ARRAY_SIZE(vga_mode); | 215 | cam->nmodes = ARRAY_SIZE(vga_mode); |
290 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
291 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
292 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
293 | sd->hue = sd_ctrls[SD_HUE].qctrl.default_value; | ||
294 | return 0; | 216 | return 0; |
295 | } | 217 | } |
296 | 218 | ||
@@ -564,121 +486,93 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
564 | } | 486 | } |
565 | } | 487 | } |
566 | 488 | ||
567 | static void setbrightness(struct gspca_dev *gspca_dev) | 489 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
568 | { | 490 | { |
569 | struct sd *sd = (struct sd *) gspca_dev; | ||
570 | |||
571 | spca506_Initi2c(gspca_dev); | 491 | spca506_Initi2c(gspca_dev); |
572 | spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright); | 492 | spca506_WriteI2c(gspca_dev, val, SAA7113_bright); |
573 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | 493 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); |
574 | } | 494 | } |
575 | 495 | ||
576 | static void setcontrast(struct gspca_dev *gspca_dev) | 496 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
577 | { | 497 | { |
578 | struct sd *sd = (struct sd *) gspca_dev; | ||
579 | |||
580 | spca506_Initi2c(gspca_dev); | 498 | spca506_Initi2c(gspca_dev); |
581 | spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast); | 499 | spca506_WriteI2c(gspca_dev, val, SAA7113_contrast); |
582 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | 500 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); |
583 | } | 501 | } |
584 | 502 | ||
585 | static void setcolors(struct gspca_dev *gspca_dev) | 503 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
586 | { | 504 | { |
587 | struct sd *sd = (struct sd *) gspca_dev; | ||
588 | |||
589 | spca506_Initi2c(gspca_dev); | 505 | spca506_Initi2c(gspca_dev); |
590 | spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation); | 506 | spca506_WriteI2c(gspca_dev, val, SAA7113_saturation); |
591 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | 507 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); |
592 | } | 508 | } |
593 | 509 | ||
594 | static void sethue(struct gspca_dev *gspca_dev) | 510 | static void sethue(struct gspca_dev *gspca_dev, s32 val) |
595 | { | 511 | { |
596 | struct sd *sd = (struct sd *) gspca_dev; | ||
597 | |||
598 | spca506_Initi2c(gspca_dev); | 512 | spca506_Initi2c(gspca_dev); |
599 | spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue); | 513 | spca506_WriteI2c(gspca_dev, val, SAA7113_hue); |
600 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | 514 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); |
601 | } | 515 | } |
602 | 516 | ||
603 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 517 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
604 | { | ||
605 | struct sd *sd = (struct sd *) gspca_dev; | ||
606 | |||
607 | sd->brightness = val; | ||
608 | if (gspca_dev->streaming) | ||
609 | setbrightness(gspca_dev); | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
614 | { | ||
615 | struct sd *sd = (struct sd *) gspca_dev; | ||
616 | |||
617 | *val = sd->brightness; | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
622 | { | 518 | { |
623 | struct sd *sd = (struct sd *) gspca_dev; | 519 | struct gspca_dev *gspca_dev = |
520 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
624 | 521 | ||
625 | sd->contrast = val; | 522 | gspca_dev->usb_err = 0; |
626 | if (gspca_dev->streaming) | ||
627 | setcontrast(gspca_dev); | ||
628 | return 0; | ||
629 | } | ||
630 | 523 | ||
631 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 524 | if (!gspca_dev->streaming) |
632 | { | 525 | return 0; |
633 | struct sd *sd = (struct sd *) gspca_dev; | ||
634 | 526 | ||
635 | *val = sd->contrast; | 527 | switch (ctrl->id) { |
636 | return 0; | 528 | case V4L2_CID_BRIGHTNESS: |
637 | } | 529 | setbrightness(gspca_dev, ctrl->val); |
638 | 530 | break; | |
639 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | 531 | case V4L2_CID_CONTRAST: |
640 | { | 532 | setcontrast(gspca_dev, ctrl->val); |
641 | struct sd *sd = (struct sd *) gspca_dev; | 533 | break; |
642 | 534 | case V4L2_CID_SATURATION: | |
643 | sd->colors = val; | 535 | setcolors(gspca_dev, ctrl->val); |
644 | if (gspca_dev->streaming) | 536 | break; |
645 | setcolors(gspca_dev); | 537 | case V4L2_CID_HUE: |
646 | return 0; | 538 | sethue(gspca_dev, ctrl->val); |
647 | } | 539 | break; |
648 | 540 | } | |
649 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | 541 | return gspca_dev->usb_err; |
650 | { | ||
651 | struct sd *sd = (struct sd *) gspca_dev; | ||
652 | |||
653 | *val = sd->colors; | ||
654 | return 0; | ||
655 | } | 542 | } |
656 | 543 | ||
657 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | 544 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
658 | { | 545 | .s_ctrl = sd_s_ctrl, |
659 | struct sd *sd = (struct sd *) gspca_dev; | 546 | }; |
660 | |||
661 | sd->hue = val; | ||
662 | if (gspca_dev->streaming) | ||
663 | sethue(gspca_dev); | ||
664 | return 0; | ||
665 | } | ||
666 | 547 | ||
667 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | 548 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
668 | { | 549 | { |
669 | struct sd *sd = (struct sd *) gspca_dev; | 550 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
670 | 551 | ||
671 | *val = sd->hue; | 552 | gspca_dev->vdev.ctrl_handler = hdl; |
553 | v4l2_ctrl_handler_init(hdl, 4); | ||
554 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
555 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); | ||
556 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
557 | V4L2_CID_CONTRAST, 0, 255, 1, 0x47); | ||
558 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
559 | V4L2_CID_SATURATION, 0, 255, 1, 0x40); | ||
560 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
561 | V4L2_CID_HUE, 0, 255, 1, 0); | ||
562 | |||
563 | if (hdl->error) { | ||
564 | pr_err("Could not initialize controls\n"); | ||
565 | return hdl->error; | ||
566 | } | ||
672 | return 0; | 567 | return 0; |
673 | } | 568 | } |
674 | 569 | ||
675 | /* sub-driver description */ | 570 | /* sub-driver description */ |
676 | static const struct sd_desc sd_desc = { | 571 | static const struct sd_desc sd_desc = { |
677 | .name = MODULE_NAME, | 572 | .name = MODULE_NAME, |
678 | .ctrls = sd_ctrls, | ||
679 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
680 | .config = sd_config, | 573 | .config = sd_config, |
681 | .init = sd_init, | 574 | .init = sd_init, |
575 | .init_controls = sd_init_controls, | ||
682 | .start = sd_start, | 576 | .start = sd_start, |
683 | .stopN = sd_stopN, | 577 | .stopN = sd_stopN, |
684 | .pkt_scan = sd_pkt_scan, | 578 | .pkt_scan = sd_pkt_scan, |
@@ -711,6 +605,7 @@ static struct usb_driver sd_driver = { | |||
711 | #ifdef CONFIG_PM | 605 | #ifdef CONFIG_PM |
712 | .suspend = gspca_suspend, | 606 | .suspend = gspca_suspend, |
713 | .resume = gspca_resume, | 607 | .resume = gspca_resume, |
608 | .reset_resume = gspca_resume, | ||
714 | #endif | 609 | #endif |
715 | }; | 610 | }; |
716 | 611 | ||
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index df4e16996461..1286b4170b88 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -32,8 +32,6 @@ 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 | u8 brightness; | ||
36 | |||
37 | u8 subtype; | 35 | u8 subtype; |
38 | #define CreativeVista 0 | 36 | #define CreativeVista 0 |
39 | #define HamaUSBSightcam 1 | 37 | #define HamaUSBSightcam 1 |
@@ -43,27 +41,6 @@ struct sd { | |||
43 | #define ViewQuestVQ110 5 | 41 | #define ViewQuestVQ110 5 |
44 | }; | 42 | }; |
45 | 43 | ||
46 | /* V4L2 controls supported by the driver */ | ||
47 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | |||
50 | static const struct ctrl sd_ctrls[] = { | ||
51 | { | ||
52 | { | ||
53 | .id = V4L2_CID_BRIGHTNESS, | ||
54 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
55 | .name = "Brightness", | ||
56 | .minimum = 0, | ||
57 | .maximum = 255, | ||
58 | .step = 1, | ||
59 | #define BRIGHTNESS_DEF 128 | ||
60 | .default_value = BRIGHTNESS_DEF, | ||
61 | }, | ||
62 | .set = sd_setbrightness, | ||
63 | .get = sd_getbrightness, | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | static const struct v4l2_pix_format sif_mode[] = { | 44 | static const struct v4l2_pix_format sif_mode[] = { |
68 | {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, | 45 | {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
69 | .bytesperline = 160, | 46 | .bytesperline = 160, |
@@ -1411,7 +1388,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1411 | cam->nmodes = ARRAY_SIZE(sif_mode); | 1388 | cam->nmodes = ARRAY_SIZE(sif_mode); |
1412 | 1389 | ||
1413 | sd->subtype = id->driver_info; | 1390 | sd->subtype = id->driver_info; |
1414 | sd->brightness = BRIGHTNESS_DEF; | ||
1415 | 1391 | ||
1416 | init_data = init_data_tb[sd->subtype]; | 1392 | init_data = init_data_tb[sd->subtype]; |
1417 | return write_vector(gspca_dev, init_data); | 1393 | return write_vector(gspca_dev, init_data); |
@@ -1471,11 +1447,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1471 | } | 1447 | } |
1472 | } | 1448 | } |
1473 | 1449 | ||
1474 | static void setbrightness(struct gspca_dev *gspca_dev) | 1450 | static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) |
1475 | { | 1451 | { |
1476 | struct sd *sd = (struct sd *) gspca_dev; | ||
1477 | u8 brightness = sd->brightness; | ||
1478 | |||
1479 | /* MX seem contrast */ | 1452 | /* MX seem contrast */ |
1480 | reg_write(gspca_dev->dev, 0x8651, brightness); | 1453 | reg_write(gspca_dev->dev, 0x8651, brightness); |
1481 | reg_write(gspca_dev->dev, 0x8652, brightness); | 1454 | reg_write(gspca_dev->dev, 0x8652, brightness); |
@@ -1483,31 +1456,50 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1483 | reg_write(gspca_dev->dev, 0x8654, brightness); | 1456 | reg_write(gspca_dev->dev, 0x8654, brightness); |
1484 | } | 1457 | } |
1485 | 1458 | ||
1486 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1459 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1487 | { | 1460 | { |
1488 | struct sd *sd = (struct sd *) gspca_dev; | 1461 | struct gspca_dev *gspca_dev = |
1462 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
1489 | 1463 | ||
1490 | sd->brightness = val; | 1464 | gspca_dev->usb_err = 0; |
1491 | if (gspca_dev->streaming) | 1465 | |
1492 | setbrightness(gspca_dev); | 1466 | if (!gspca_dev->streaming) |
1493 | return 0; | 1467 | return 0; |
1468 | |||
1469 | switch (ctrl->id) { | ||
1470 | case V4L2_CID_BRIGHTNESS: | ||
1471 | setbrightness(gspca_dev, ctrl->val); | ||
1472 | break; | ||
1473 | } | ||
1474 | return gspca_dev->usb_err; | ||
1494 | } | 1475 | } |
1495 | 1476 | ||
1496 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | 1477 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
1478 | .s_ctrl = sd_s_ctrl, | ||
1479 | }; | ||
1480 | |||
1481 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
1497 | { | 1482 | { |
1498 | struct sd *sd = (struct sd *) gspca_dev; | 1483 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
1499 | 1484 | ||
1500 | *val = sd->brightness; | 1485 | gspca_dev->vdev.ctrl_handler = hdl; |
1486 | v4l2_ctrl_handler_init(hdl, 5); | ||
1487 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1488 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); | ||
1489 | |||
1490 | if (hdl->error) { | ||
1491 | pr_err("Could not initialize controls\n"); | ||
1492 | return hdl->error; | ||
1493 | } | ||
1501 | return 0; | 1494 | return 0; |
1502 | } | 1495 | } |
1503 | 1496 | ||
1504 | /* sub-driver description */ | 1497 | /* sub-driver description */ |
1505 | static const struct sd_desc sd_desc = { | 1498 | static const struct sd_desc sd_desc = { |
1506 | .name = MODULE_NAME, | 1499 | .name = MODULE_NAME, |
1507 | .ctrls = sd_ctrls, | ||
1508 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1509 | .config = sd_config, | 1500 | .config = sd_config, |
1510 | .init = sd_init, | 1501 | .init = sd_init, |
1502 | .init_controls = sd_init_controls, | ||
1511 | .start = sd_start, | 1503 | .start = sd_start, |
1512 | .stopN = sd_stopN, | 1504 | .stopN = sd_stopN, |
1513 | .pkt_scan = sd_pkt_scan, | 1505 | .pkt_scan = sd_pkt_scan, |
@@ -1541,6 +1533,7 @@ static struct usb_driver sd_driver = { | |||
1541 | #ifdef CONFIG_PM | 1533 | #ifdef CONFIG_PM |
1542 | .suspend = gspca_suspend, | 1534 | .suspend = gspca_suspend, |
1543 | .resume = gspca_resume, | 1535 | .resume = gspca_resume, |
1536 | .reset_resume = gspca_resume, | ||
1544 | #endif | 1537 | #endif |
1545 | }; | 1538 | }; |
1546 | 1539 | ||
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 4a5f209ce719..cfe71dd6747d 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -31,39 +31,17 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
31 | MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); | 31 | MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); |
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | 33 | ||
34 | #define EXPOSURE_MAX (2047 + 325) | ||
35 | |||
34 | /* specific webcam descriptor */ | 36 | /* specific webcam descriptor */ |
35 | struct sd { | 37 | struct sd { |
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 38 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
37 | 39 | ||
38 | __u16 exposure; /* rev12a only */ | 40 | struct { /* hue/contrast control cluster */ |
39 | #define EXPOSURE_MIN 1 | 41 | struct v4l2_ctrl *contrast; |
40 | #define EXPOSURE_DEF 700 /* == 10 fps */ | 42 | struct v4l2_ctrl *hue; |
41 | #define EXPOSURE_MAX (2047 + 325) /* see setexposure */ | 43 | }; |
42 | 44 | struct v4l2_ctrl *autogain; | |
43 | __u8 contrast; /* rev72a only */ | ||
44 | #define CONTRAST_MIN 0x00 | ||
45 | #define CONTRAST_DEF 0x20 | ||
46 | #define CONTRAST_MAX 0x3f | ||
47 | |||
48 | __u8 brightness; /* rev72a only */ | ||
49 | #define BRIGHTNESS_MIN 0 | ||
50 | #define BRIGHTNESS_DEF 0x20 | ||
51 | #define BRIGHTNESS_MAX 0x3f | ||
52 | |||
53 | __u8 white; | ||
54 | #define HUE_MIN 1 | ||
55 | #define HUE_DEF 0x40 | ||
56 | #define HUE_MAX 0x7f | ||
57 | |||
58 | __u8 autogain; | ||
59 | #define AUTOGAIN_MIN 0 | ||
60 | #define AUTOGAIN_DEF 1 | ||
61 | #define AUTOGAIN_MAX 1 | ||
62 | |||
63 | __u8 gain; /* rev12a only */ | ||
64 | #define GAIN_MIN 0 | ||
65 | #define GAIN_DEF 63 | ||
66 | #define GAIN_MAX 255 | ||
67 | 45 | ||
68 | #define EXPO12A_DEF 3 | 46 | #define EXPO12A_DEF 3 |
69 | __u8 expo12a; /* expo/gain? for rev 12a */ | 47 | __u8 expo12a; /* expo/gain? for rev 12a */ |
@@ -461,12 +439,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
461 | cam->cam_mode = sif_072a_mode; | 439 | cam->cam_mode = sif_072a_mode; |
462 | cam->nmodes = ARRAY_SIZE(sif_072a_mode); | 440 | cam->nmodes = ARRAY_SIZE(sif_072a_mode); |
463 | } | 441 | } |
464 | sd->brightness = BRIGHTNESS_DEF; | ||
465 | sd->contrast = CONTRAST_DEF; | ||
466 | sd->white = HUE_DEF; | ||
467 | sd->exposure = EXPOSURE_DEF; | ||
468 | sd->autogain = AUTOGAIN_DEF; | ||
469 | sd->gain = GAIN_DEF; | ||
470 | sd->expo12a = EXPO12A_DEF; | 442 | sd->expo12a = EXPO12A_DEF; |
471 | return 0; | 443 | return 0; |
472 | } | 444 | } |
@@ -491,66 +463,49 @@ static int sd_init_72a(struct gspca_dev *gspca_dev) | |||
491 | return 0; | 463 | return 0; |
492 | } | 464 | } |
493 | 465 | ||
494 | /* rev 72a only */ | 466 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
495 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
496 | { | 467 | { |
497 | struct sd *sd = (struct sd *) gspca_dev; | 468 | struct sd *sd = (struct sd *) gspca_dev; |
498 | struct usb_device *dev = gspca_dev->dev; | 469 | struct usb_device *dev = gspca_dev->dev; |
499 | __u8 value; | 470 | __u16 reg; |
500 | 471 | ||
501 | value = sd->brightness; | 472 | if (sd->chip_revision == Rev012A) |
473 | reg = 0x8610; | ||
474 | else | ||
475 | reg = 0x8611; | ||
502 | 476 | ||
503 | /* offsets for white balance */ | 477 | reg_w_val(dev, reg + 0, val); /* R */ |
504 | reg_w_val(dev, 0x8611, value); /* R */ | 478 | reg_w_val(dev, reg + 1, val); /* Gr */ |
505 | reg_w_val(dev, 0x8612, value); /* Gr */ | 479 | reg_w_val(dev, reg + 2, val); /* B */ |
506 | reg_w_val(dev, 0x8613, value); /* B */ | 480 | reg_w_val(dev, reg + 3, val); /* Gb */ |
507 | reg_w_val(dev, 0x8614, value); /* Gb */ | ||
508 | } | 481 | } |
509 | 482 | ||
510 | static void setwhite(struct gspca_dev *gspca_dev) | 483 | static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast) |
511 | { | 484 | { |
512 | struct sd *sd = (struct sd *) gspca_dev; | 485 | struct sd *sd = (struct sd *) gspca_dev; |
513 | __u16 white; | 486 | struct usb_device *dev = gspca_dev->dev; |
514 | __u8 blue, red; | 487 | __u8 blue, red; |
515 | __u16 reg; | 488 | __u16 reg; |
516 | 489 | ||
517 | /* try to emulate MS-win as possible */ | 490 | /* try to emulate MS-win as possible */ |
518 | white = sd->white; | ||
519 | red = 0x20 + white * 3 / 8; | 491 | red = 0x20 + white * 3 / 8; |
520 | blue = 0x90 - white * 5 / 8; | 492 | blue = 0x90 - white * 5 / 8; |
521 | if (sd->chip_revision == Rev012A) { | 493 | if (sd->chip_revision == Rev012A) { |
522 | reg = 0x8614; | 494 | reg = 0x8614; |
523 | } else { | 495 | } else { |
524 | reg = 0x8651; | 496 | reg = 0x8651; |
525 | red += sd->contrast - 0x20; | 497 | red += contrast - 0x20; |
526 | blue += sd->contrast - 0x20; | 498 | blue += contrast - 0x20; |
499 | reg_w_val(dev, 0x8652, contrast + 0x20); /* Gr */ | ||
500 | reg_w_val(dev, 0x8654, contrast + 0x20); /* Gb */ | ||
527 | } | 501 | } |
528 | reg_w_val(gspca_dev->dev, reg, red); | 502 | reg_w_val(dev, reg, red); |
529 | reg_w_val(gspca_dev->dev, reg + 2, blue); | 503 | reg_w_val(dev, reg + 2, blue); |
530 | } | ||
531 | |||
532 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
533 | { | ||
534 | struct sd *sd = (struct sd *) gspca_dev; | ||
535 | struct usb_device *dev = gspca_dev->dev; | ||
536 | __u8 value; | ||
537 | |||
538 | if (sd->chip_revision != Rev072A) | ||
539 | return; | ||
540 | value = sd->contrast + 0x20; | ||
541 | |||
542 | /* gains for white balance */ | ||
543 | setwhite(gspca_dev); | ||
544 | /* reg_w_val(dev, 0x8651, value); * R - done by setwhite */ | ||
545 | reg_w_val(dev, 0x8652, value); /* Gr */ | ||
546 | /* reg_w_val(dev, 0x8653, value); * B - done by setwhite */ | ||
547 | reg_w_val(dev, 0x8654, value); /* Gb */ | ||
548 | } | 504 | } |
549 | 505 | ||
550 | /* rev 12a only */ | 506 | /* rev 12a only */ |
551 | static void setexposure(struct gspca_dev *gspca_dev) | 507 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
552 | { | 508 | { |
553 | struct sd *sd = (struct sd *) gspca_dev; | ||
554 | int i, expo = 0; | 509 | int i, expo = 0; |
555 | 510 | ||
556 | /* Register 0x8309 controls exposure for the spca561, | 511 | /* Register 0x8309 controls exposure for the spca561, |
@@ -572,8 +527,8 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
572 | int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; | 527 | int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; |
573 | 528 | ||
574 | for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { | 529 | for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { |
575 | if (sd->exposure <= table[i + 1]) { | 530 | if (val <= table[i + 1]) { |
576 | expo = sd->exposure - table[i]; | 531 | expo = val - table[i]; |
577 | if (i) | 532 | if (i) |
578 | expo += 300; | 533 | expo += 300; |
579 | expo |= i << 11; | 534 | expo |= i << 11; |
@@ -587,29 +542,27 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
587 | } | 542 | } |
588 | 543 | ||
589 | /* rev 12a only */ | 544 | /* rev 12a only */ |
590 | static void setgain(struct gspca_dev *gspca_dev) | 545 | static void setgain(struct gspca_dev *gspca_dev, s32 val) |
591 | { | 546 | { |
592 | struct sd *sd = (struct sd *) gspca_dev; | ||
593 | |||
594 | /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the | 547 | /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the |
595 | sensitivity when set, so 31 + one of them set == 63, and 15 | 548 | sensitivity when set, so 31 + one of them set == 63, and 15 |
596 | with both of them set == 63 */ | 549 | with both of them set == 63 */ |
597 | if (sd->gain < 64) | 550 | if (val < 64) |
598 | gspca_dev->usb_buf[0] = sd->gain; | 551 | gspca_dev->usb_buf[0] = val; |
599 | else if (sd->gain < 128) | 552 | else if (val < 128) |
600 | gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40; | 553 | gspca_dev->usb_buf[0] = (val / 2) | 0x40; |
601 | else | 554 | else |
602 | gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0; | 555 | gspca_dev->usb_buf[0] = (val / 4) | 0xc0; |
603 | 556 | ||
604 | gspca_dev->usb_buf[1] = 0; | 557 | gspca_dev->usb_buf[1] = 0; |
605 | reg_w_buf(gspca_dev, 0x8335, 2); | 558 | reg_w_buf(gspca_dev, 0x8335, 2); |
606 | } | 559 | } |
607 | 560 | ||
608 | static void setautogain(struct gspca_dev *gspca_dev) | 561 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
609 | { | 562 | { |
610 | struct sd *sd = (struct sd *) gspca_dev; | 563 | struct sd *sd = (struct sd *) gspca_dev; |
611 | 564 | ||
612 | if (sd->autogain) | 565 | if (val) |
613 | sd->ag_cnt = AG_CNT_START; | 566 | sd->ag_cnt = AG_CNT_START; |
614 | else | 567 | else |
615 | sd->ag_cnt = -1; | 568 | sd->ag_cnt = -1; |
@@ -644,9 +597,6 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) | |||
644 | memcpy(gspca_dev->usb_buf, Reg8391, 8); | 597 | memcpy(gspca_dev->usb_buf, Reg8391, 8); |
645 | reg_w_buf(gspca_dev, 0x8391, 8); | 598 | reg_w_buf(gspca_dev, 0x8391, 8); |
646 | reg_w_buf(gspca_dev, 0x8390, 8); | 599 | reg_w_buf(gspca_dev, 0x8390, 8); |
647 | setwhite(gspca_dev); | ||
648 | setgain(gspca_dev); | ||
649 | setexposure(gspca_dev); | ||
650 | 600 | ||
651 | /* Led ON (bit 3 -> 0 */ | 601 | /* Led ON (bit 3 -> 0 */ |
652 | reg_w_val(gspca_dev->dev, 0x8114, 0x00); | 602 | reg_w_val(gspca_dev->dev, 0x8114, 0x00); |
@@ -654,6 +604,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) | |||
654 | } | 604 | } |
655 | static int sd_start_72a(struct gspca_dev *gspca_dev) | 605 | static int sd_start_72a(struct gspca_dev *gspca_dev) |
656 | { | 606 | { |
607 | struct sd *sd = (struct sd *) gspca_dev; | ||
657 | struct usb_device *dev = gspca_dev->dev; | 608 | struct usb_device *dev = gspca_dev->dev; |
658 | int Clck; | 609 | int Clck; |
659 | int mode; | 610 | int mode; |
@@ -683,9 +634,10 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) | |||
683 | reg_w_val(dev, 0x8702, 0x81); | 634 | reg_w_val(dev, 0x8702, 0x81); |
684 | reg_w_val(dev, 0x8500, mode); /* mode */ | 635 | reg_w_val(dev, 0x8500, mode); /* mode */ |
685 | write_sensor_72a(gspca_dev, rev72a_init_sensor2); | 636 | write_sensor_72a(gspca_dev, rev72a_init_sensor2); |
686 | setcontrast(gspca_dev); | 637 | setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue), |
638 | v4l2_ctrl_g_ctrl(sd->contrast)); | ||
687 | /* setbrightness(gspca_dev); * fixme: bad values */ | 639 | /* setbrightness(gspca_dev); * fixme: bad values */ |
688 | setautogain(gspca_dev); | 640 | setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); |
689 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | 641 | reg_w_val(dev, 0x8112, 0x10 | 0x20); |
690 | return 0; | 642 | return 0; |
691 | } | 643 | } |
@@ -819,221 +771,96 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
819 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 771 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
820 | } | 772 | } |
821 | 773 | ||
822 | /* rev 72a only */ | 774 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
823 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
824 | { | 775 | { |
825 | struct sd *sd = (struct sd *) gspca_dev; | 776 | struct gspca_dev *gspca_dev = |
777 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
778 | struct sd *sd = (struct sd *)gspca_dev; | ||
826 | 779 | ||
827 | sd->brightness = val; | 780 | gspca_dev->usb_err = 0; |
828 | if (gspca_dev->streaming) | ||
829 | setbrightness(gspca_dev); | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
834 | { | ||
835 | struct sd *sd = (struct sd *) gspca_dev; | ||
836 | |||
837 | *val = sd->brightness; | ||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | /* rev 72a only */ | ||
842 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
843 | { | ||
844 | struct sd *sd = (struct sd *) gspca_dev; | ||
845 | 781 | ||
846 | sd->contrast = val; | 782 | if (!gspca_dev->streaming) |
847 | if (gspca_dev->streaming) | 783 | return 0; |
848 | setcontrast(gspca_dev); | ||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
853 | { | ||
854 | struct sd *sd = (struct sd *) gspca_dev; | ||
855 | |||
856 | *val = sd->contrast; | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
861 | { | ||
862 | struct sd *sd = (struct sd *) gspca_dev; | ||
863 | 784 | ||
864 | sd->autogain = val; | 785 | switch (ctrl->id) { |
865 | if (gspca_dev->streaming) | 786 | case V4L2_CID_BRIGHTNESS: |
866 | setautogain(gspca_dev); | 787 | setbrightness(gspca_dev, ctrl->val); |
867 | return 0; | 788 | break; |
868 | } | 789 | case V4L2_CID_CONTRAST: |
869 | 790 | /* hue/contrast control cluster for 72a */ | |
870 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | 791 | setwhite(gspca_dev, sd->hue->val, ctrl->val); |
871 | { | 792 | break; |
872 | struct sd *sd = (struct sd *) gspca_dev; | 793 | case V4L2_CID_HUE: |
873 | 794 | /* just plain hue control for 12a */ | |
874 | *val = sd->autogain; | 795 | setwhite(gspca_dev, ctrl->val, 0); |
875 | return 0; | 796 | break; |
876 | } | 797 | case V4L2_CID_EXPOSURE: |
877 | 798 | setexposure(gspca_dev, ctrl->val); | |
878 | static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val) | 799 | break; |
879 | { | 800 | case V4L2_CID_GAIN: |
880 | struct sd *sd = (struct sd *) gspca_dev; | 801 | setgain(gspca_dev, ctrl->val); |
881 | 802 | break; | |
882 | sd->white = val; | 803 | case V4L2_CID_AUTOGAIN: |
883 | if (gspca_dev->streaming) | 804 | setautogain(gspca_dev, ctrl->val); |
884 | setwhite(gspca_dev); | 805 | break; |
885 | return 0; | 806 | } |
807 | return gspca_dev->usb_err; | ||
886 | } | 808 | } |
887 | 809 | ||
888 | static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val) | 810 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
889 | { | 811 | .s_ctrl = sd_s_ctrl, |
890 | struct sd *sd = (struct sd *) gspca_dev; | 812 | }; |
891 | |||
892 | *val = sd->white; | ||
893 | return 0; | ||
894 | } | ||
895 | 813 | ||
896 | /* rev12a only */ | 814 | static int sd_init_controls_12a(struct gspca_dev *gspca_dev) |
897 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
898 | { | 815 | { |
899 | struct sd *sd = (struct sd *) gspca_dev; | 816 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
900 | 817 | ||
901 | sd->exposure = val; | 818 | gspca_dev->vdev.ctrl_handler = hdl; |
902 | if (gspca_dev->streaming) | 819 | v4l2_ctrl_handler_init(hdl, 3); |
903 | setexposure(gspca_dev); | 820 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
904 | return 0; | 821 | V4L2_CID_HUE, 1, 0x7f, 1, 0x40); |
905 | } | 822 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
823 | V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); | ||
824 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
825 | V4L2_CID_EXPOSURE, 1, EXPOSURE_MAX, 1, 700); | ||
826 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
827 | V4L2_CID_GAIN, 0, 255, 1, 63); | ||
906 | 828 | ||
907 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | 829 | if (hdl->error) { |
908 | { | 830 | pr_err("Could not initialize controls\n"); |
909 | struct sd *sd = (struct sd *) gspca_dev; | 831 | return hdl->error; |
910 | 832 | } | |
911 | *val = sd->exposure; | ||
912 | return 0; | 833 | return 0; |
913 | } | 834 | } |
914 | 835 | ||
915 | /* rev12a only */ | 836 | static int sd_init_controls_72a(struct gspca_dev *gspca_dev) |
916 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
917 | { | 837 | { |
918 | struct sd *sd = (struct sd *) gspca_dev; | 838 | struct sd *sd = (struct sd *)gspca_dev; |
919 | 839 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | |
920 | sd->gain = val; | ||
921 | if (gspca_dev->streaming) | ||
922 | setgain(gspca_dev); | ||
923 | return 0; | ||
924 | } | ||
925 | 840 | ||
926 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | 841 | gspca_dev->vdev.ctrl_handler = hdl; |
927 | { | 842 | v4l2_ctrl_handler_init(hdl, 4); |
928 | struct sd *sd = (struct sd *) gspca_dev; | 843 | sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
844 | V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x20); | ||
845 | sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
846 | V4L2_CID_HUE, 1, 0x7f, 1, 0x40); | ||
847 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
848 | V4L2_CID_BRIGHTNESS, 0, 0x3f, 1, 0x20); | ||
849 | sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
850 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
929 | 851 | ||
930 | *val = sd->gain; | 852 | if (hdl->error) { |
853 | pr_err("Could not initialize controls\n"); | ||
854 | return hdl->error; | ||
855 | } | ||
856 | v4l2_ctrl_cluster(2, &sd->contrast); | ||
931 | return 0; | 857 | return 0; |
932 | } | 858 | } |
933 | 859 | ||
934 | /* control tables */ | ||
935 | static const struct ctrl sd_ctrls_12a[] = { | ||
936 | { | ||
937 | { | ||
938 | .id = V4L2_CID_HUE, | ||
939 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
940 | .name = "Hue", | ||
941 | .minimum = HUE_MIN, | ||
942 | .maximum = HUE_MAX, | ||
943 | .step = 1, | ||
944 | .default_value = HUE_DEF, | ||
945 | }, | ||
946 | .set = sd_setwhite, | ||
947 | .get = sd_getwhite, | ||
948 | }, | ||
949 | { | ||
950 | { | ||
951 | .id = V4L2_CID_EXPOSURE, | ||
952 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
953 | .name = "Exposure", | ||
954 | .minimum = EXPOSURE_MIN, | ||
955 | .maximum = EXPOSURE_MAX, | ||
956 | .step = 1, | ||
957 | .default_value = EXPOSURE_DEF, | ||
958 | }, | ||
959 | .set = sd_setexposure, | ||
960 | .get = sd_getexposure, | ||
961 | }, | ||
962 | { | ||
963 | { | ||
964 | .id = V4L2_CID_GAIN, | ||
965 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
966 | .name = "Gain", | ||
967 | .minimum = GAIN_MIN, | ||
968 | .maximum = GAIN_MAX, | ||
969 | .step = 1, | ||
970 | .default_value = GAIN_DEF, | ||
971 | }, | ||
972 | .set = sd_setgain, | ||
973 | .get = sd_getgain, | ||
974 | }, | ||
975 | }; | ||
976 | |||
977 | static const struct ctrl sd_ctrls_72a[] = { | ||
978 | { | ||
979 | { | ||
980 | .id = V4L2_CID_HUE, | ||
981 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
982 | .name = "Hue", | ||
983 | .minimum = HUE_MIN, | ||
984 | .maximum = HUE_MAX, | ||
985 | .step = 1, | ||
986 | .default_value = HUE_DEF, | ||
987 | }, | ||
988 | .set = sd_setwhite, | ||
989 | .get = sd_getwhite, | ||
990 | }, | ||
991 | { | ||
992 | { | ||
993 | .id = V4L2_CID_BRIGHTNESS, | ||
994 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
995 | .name = "Brightness", | ||
996 | .minimum = BRIGHTNESS_MIN, | ||
997 | .maximum = BRIGHTNESS_MAX, | ||
998 | .step = 1, | ||
999 | .default_value = BRIGHTNESS_DEF, | ||
1000 | }, | ||
1001 | .set = sd_setbrightness, | ||
1002 | .get = sd_getbrightness, | ||
1003 | }, | ||
1004 | { | ||
1005 | { | ||
1006 | .id = V4L2_CID_CONTRAST, | ||
1007 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1008 | .name = "Contrast", | ||
1009 | .minimum = CONTRAST_MIN, | ||
1010 | .maximum = CONTRAST_MAX, | ||
1011 | .step = 1, | ||
1012 | .default_value = CONTRAST_DEF, | ||
1013 | }, | ||
1014 | .set = sd_setcontrast, | ||
1015 | .get = sd_getcontrast, | ||
1016 | }, | ||
1017 | { | ||
1018 | { | ||
1019 | .id = V4L2_CID_AUTOGAIN, | ||
1020 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1021 | .name = "Auto Gain", | ||
1022 | .minimum = AUTOGAIN_MIN, | ||
1023 | .maximum = AUTOGAIN_MAX, | ||
1024 | .step = 1, | ||
1025 | .default_value = AUTOGAIN_DEF, | ||
1026 | }, | ||
1027 | .set = sd_setautogain, | ||
1028 | .get = sd_getautogain, | ||
1029 | }, | ||
1030 | }; | ||
1031 | |||
1032 | /* sub-driver description */ | 860 | /* sub-driver description */ |
1033 | static const struct sd_desc sd_desc_12a = { | 861 | static const struct sd_desc sd_desc_12a = { |
1034 | .name = MODULE_NAME, | 862 | .name = MODULE_NAME, |
1035 | .ctrls = sd_ctrls_12a, | 863 | .init_controls = sd_init_controls_12a, |
1036 | .nctrls = ARRAY_SIZE(sd_ctrls_12a), | ||
1037 | .config = sd_config, | 864 | .config = sd_config, |
1038 | .init = sd_init_12a, | 865 | .init = sd_init_12a, |
1039 | .start = sd_start_12a, | 866 | .start = sd_start_12a, |
@@ -1045,8 +872,7 @@ static const struct sd_desc sd_desc_12a = { | |||
1045 | }; | 872 | }; |
1046 | static const struct sd_desc sd_desc_72a = { | 873 | static const struct sd_desc sd_desc_72a = { |
1047 | .name = MODULE_NAME, | 874 | .name = MODULE_NAME, |
1048 | .ctrls = sd_ctrls_72a, | 875 | .init_controls = sd_init_controls_72a, |
1049 | .nctrls = ARRAY_SIZE(sd_ctrls_72a), | ||
1050 | .config = sd_config, | 876 | .config = sd_config, |
1051 | .init = sd_init_72a, | 877 | .init = sd_init_72a, |
1052 | .start = sd_start_72a, | 878 | .start = sd_start_72a, |
@@ -1103,6 +929,7 @@ static struct usb_driver sd_driver = { | |||
1103 | #ifdef CONFIG_PM | 929 | #ifdef CONFIG_PM |
1104 | .suspend = gspca_suspend, | 930 | .suspend = gspca_suspend, |
1105 | .resume = gspca_resume, | 931 | .resume = gspca_resume, |
932 | .reset_resume = gspca_resume, | ||
1106 | #endif | 933 | #endif |
1107 | }; | 934 | }; |
1108 | 935 | ||
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 04f54654a026..a8ac97931ad6 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c | |||
@@ -433,6 +433,7 @@ static struct usb_driver sd_driver = { | |||
433 | #ifdef CONFIG_PM | 433 | #ifdef CONFIG_PM |
434 | .suspend = gspca_suspend, | 434 | .suspend = gspca_suspend, |
435 | .resume = gspca_resume, | 435 | .resume = gspca_resume, |
436 | .reset_resume = gspca_resume, | ||
436 | #endif | 437 | #endif |
437 | }; | 438 | }; |
438 | 439 | ||
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index f34ddb0570c8..2c2f3d2f357f 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -340,6 +340,7 @@ static struct usb_driver sd_driver = { | |||
340 | #ifdef CONFIG_PM | 340 | #ifdef CONFIG_PM |
341 | .suspend = gspca_suspend, | 341 | .suspend = gspca_suspend, |
342 | .resume = gspca_resume, | 342 | .resume = gspca_resume, |
343 | .reset_resume = gspca_resume, | ||
343 | #endif | 344 | #endif |
344 | }; | 345 | }; |
345 | 346 | ||
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c index 1a8ba9b3550a..3e1e486af883 100644 --- a/drivers/media/video/gspca/sq930x.c +++ b/drivers/media/video/gspca/sq930x.c | |||
@@ -36,8 +36,10 @@ MODULE_LICENSE("GPL"); | |||
36 | struct sd { | 36 | struct sd { |
37 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 37 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
38 | 38 | ||
39 | u16 expo; | 39 | struct { /* exposure/gain control cluster */ |
40 | u8 gain; | 40 | struct v4l2_ctrl *exposure; |
41 | struct v4l2_ctrl *gain; | ||
42 | }; | ||
41 | 43 | ||
42 | u8 do_ctrl; | 44 | u8 do_ctrl; |
43 | u8 gpio[2]; | 45 | u8 gpio[2]; |
@@ -55,42 +57,6 @@ enum sensors { | |||
55 | SENSOR_OV9630, | 57 | SENSOR_OV9630, |
56 | }; | 58 | }; |
57 | 59 | ||
58 | static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val); | ||
59 | static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val); | ||
60 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
61 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
62 | |||
63 | static const struct ctrl sd_ctrls[] = { | ||
64 | { | ||
65 | { | ||
66 | .id = V4L2_CID_EXPOSURE, | ||
67 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
68 | .name = "Exposure", | ||
69 | .minimum = 0x0001, | ||
70 | .maximum = 0x0fff, | ||
71 | .step = 1, | ||
72 | #define EXPO_DEF 0x0356 | ||
73 | .default_value = EXPO_DEF, | ||
74 | }, | ||
75 | .set = sd_setexpo, | ||
76 | .get = sd_getexpo, | ||
77 | }, | ||
78 | { | ||
79 | { | ||
80 | .id = V4L2_CID_GAIN, | ||
81 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
82 | .name = "Gain", | ||
83 | .minimum = 0x01, | ||
84 | .maximum = 0xff, | ||
85 | .step = 1, | ||
86 | #define GAIN_DEF 0x8d | ||
87 | .default_value = GAIN_DEF, | ||
88 | }, | ||
89 | .set = sd_setgain, | ||
90 | .get = sd_getgain, | ||
91 | }, | ||
92 | }; | ||
93 | |||
94 | static struct v4l2_pix_format vga_mode[] = { | 60 | static struct v4l2_pix_format vga_mode[] = { |
95 | {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE, | 61 | {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE, |
96 | .bytesperline = 320, | 62 | .bytesperline = 320, |
@@ -791,7 +757,7 @@ static void lz24bp_ppl(struct sd *sd, u16 ppl) | |||
791 | ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2); | 757 | ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2); |
792 | } | 758 | } |
793 | 759 | ||
794 | static void setexposure(struct gspca_dev *gspca_dev) | 760 | static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain) |
795 | { | 761 | { |
796 | struct sd *sd = (struct sd *) gspca_dev; | 762 | struct sd *sd = (struct sd *) gspca_dev; |
797 | int i, integclks, intstartclk, frameclks, min_frclk; | 763 | int i, integclks, intstartclk, frameclks, min_frclk; |
@@ -799,7 +765,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
799 | u16 cmd; | 765 | u16 cmd; |
800 | u8 buf[15]; | 766 | u8 buf[15]; |
801 | 767 | ||
802 | integclks = sd->expo; | 768 | integclks = expo; |
803 | i = 0; | 769 | i = 0; |
804 | cmd = SQ930_CTRL_SET_EXPOSURE; | 770 | cmd = SQ930_CTRL_SET_EXPOSURE; |
805 | 771 | ||
@@ -818,7 +784,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
818 | buf[i++] = intstartclk; | 784 | buf[i++] = intstartclk; |
819 | buf[i++] = frameclks >> 8; | 785 | buf[i++] = frameclks >> 8; |
820 | buf[i++] = frameclks; | 786 | buf[i++] = frameclks; |
821 | buf[i++] = sd->gain; | 787 | buf[i++] = gain; |
822 | break; | 788 | break; |
823 | default: /* cmos */ | 789 | default: /* cmos */ |
824 | /* case SENSOR_MI0360: */ | 790 | /* case SENSOR_MI0360: */ |
@@ -834,7 +800,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
834 | buf[i++] = 0x35; /* reg = global gain */ | 800 | buf[i++] = 0x35; /* reg = global gain */ |
835 | buf[i++] = 0x00; /* val H */ | 801 | buf[i++] = 0x00; /* val H */ |
836 | buf[i++] = sensor->i2c_dum; | 802 | buf[i++] = sensor->i2c_dum; |
837 | buf[i++] = 0x80 + sd->gain / 2; /* val L */ | 803 | buf[i++] = 0x80 + gain / 2; /* val L */ |
838 | buf[i++] = 0x00; | 804 | buf[i++] = 0x00; |
839 | buf[i++] = 0x00; | 805 | buf[i++] = 0x00; |
840 | buf[i++] = 0x00; | 806 | buf[i++] = 0x00; |
@@ -860,9 +826,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
860 | 826 | ||
861 | cam->bulk = 1; | 827 | cam->bulk = 1; |
862 | 828 | ||
863 | sd->gain = GAIN_DEF; | ||
864 | sd->expo = EXPO_DEF; | ||
865 | |||
866 | return 0; | 829 | return 0; |
867 | } | 830 | } |
868 | 831 | ||
@@ -1089,7 +1052,8 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) | |||
1089 | return; | 1052 | return; |
1090 | sd->do_ctrl = 0; | 1053 | sd->do_ctrl = 0; |
1091 | 1054 | ||
1092 | setexposure(gspca_dev); | 1055 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure), |
1056 | v4l2_ctrl_g_ctrl(sd->gain)); | ||
1093 | 1057 | ||
1094 | gspca_dev->cam.bulk_nurbs = 1; | 1058 | gspca_dev->cam.bulk_nurbs = 1; |
1095 | ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC); | 1059 | ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC); |
@@ -1113,48 +1077,55 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1113 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | 1077 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
1114 | } | 1078 | } |
1115 | 1079 | ||
1116 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 1080 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1117 | { | 1081 | { |
1082 | struct gspca_dev *gspca_dev = | ||
1083 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
1118 | struct sd *sd = (struct sd *) gspca_dev; | 1084 | struct sd *sd = (struct sd *) gspca_dev; |
1119 | 1085 | ||
1120 | sd->gain = val; | 1086 | gspca_dev->usb_err = 0; |
1121 | if (gspca_dev->streaming) | ||
1122 | sd->do_ctrl = 1; | ||
1123 | return 0; | ||
1124 | } | ||
1125 | 1087 | ||
1126 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | 1088 | if (!gspca_dev->streaming) |
1127 | { | 1089 | return 0; |
1128 | struct sd *sd = (struct sd *) gspca_dev; | ||
1129 | 1090 | ||
1130 | *val = sd->gain; | 1091 | switch (ctrl->id) { |
1131 | return 0; | 1092 | case V4L2_CID_EXPOSURE: |
1093 | setexposure(gspca_dev, ctrl->val, sd->gain->val); | ||
1094 | break; | ||
1095 | } | ||
1096 | return gspca_dev->usb_err; | ||
1132 | } | 1097 | } |
1133 | static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val) | ||
1134 | { | ||
1135 | struct sd *sd = (struct sd *) gspca_dev; | ||
1136 | 1098 | ||
1137 | sd->expo = val; | 1099 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
1138 | if (gspca_dev->streaming) | 1100 | .s_ctrl = sd_s_ctrl, |
1139 | sd->do_ctrl = 1; | 1101 | }; |
1140 | return 0; | ||
1141 | } | ||
1142 | 1102 | ||
1143 | static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val) | 1103 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
1144 | { | 1104 | { |
1105 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
1145 | struct sd *sd = (struct sd *) gspca_dev; | 1106 | struct sd *sd = (struct sd *) gspca_dev; |
1146 | 1107 | ||
1147 | *val = sd->expo; | 1108 | gspca_dev->vdev.ctrl_handler = hdl; |
1109 | v4l2_ctrl_handler_init(hdl, 2); | ||
1110 | sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1111 | V4L2_CID_EXPOSURE, 1, 0xfff, 1, 0x356); | ||
1112 | sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1113 | V4L2_CID_GAIN, 1, 255, 1, 0x8d); | ||
1114 | |||
1115 | if (hdl->error) { | ||
1116 | pr_err("Could not initialize controls\n"); | ||
1117 | return hdl->error; | ||
1118 | } | ||
1119 | v4l2_ctrl_cluster(2, &sd->exposure); | ||
1148 | return 0; | 1120 | return 0; |
1149 | } | 1121 | } |
1150 | 1122 | ||
1151 | /* sub-driver description */ | 1123 | /* sub-driver description */ |
1152 | static const struct sd_desc sd_desc = { | 1124 | static const struct sd_desc sd_desc = { |
1153 | .name = MODULE_NAME, | 1125 | .name = MODULE_NAME, |
1154 | .ctrls = sd_ctrls, | ||
1155 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1156 | .config = sd_config, | 1126 | .config = sd_config, |
1157 | .init = sd_init, | 1127 | .init = sd_init, |
1128 | .init_controls = sd_init_controls, | ||
1158 | .isoc_init = sd_isoc_init, | 1129 | .isoc_init = sd_isoc_init, |
1159 | .start = sd_start, | 1130 | .start = sd_start, |
1160 | .stopN = sd_stopN, | 1131 | .stopN = sd_stopN, |
@@ -1194,6 +1165,7 @@ static struct usb_driver sd_driver = { | |||
1194 | #ifdef CONFIG_PM | 1165 | #ifdef CONFIG_PM |
1195 | .suspend = gspca_suspend, | 1166 | .suspend = gspca_suspend, |
1196 | .resume = gspca_resume, | 1167 | .resume = gspca_resume, |
1168 | .reset_resume = gspca_resume, | ||
1197 | #endif | 1169 | #endif |
1198 | }; | 1170 | }; |
1199 | 1171 | ||
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 4ae7cc8f463a..8c0982607f25 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c | |||
@@ -29,86 +29,14 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | |||
29 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); | 29 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); |
30 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
31 | 31 | ||
32 | /* controls */ | 32 | #define QUALITY 50 |
33 | enum e_ctrl { | ||
34 | BRIGHTNESS, | ||
35 | CONTRAST, | ||
36 | COLORS, | ||
37 | LIGHTFREQ, | ||
38 | NCTRLS /* number of controls */ | ||
39 | }; | ||
40 | 33 | ||
41 | /* specific webcam descriptor */ | 34 | /* specific webcam descriptor */ |
42 | struct sd { | 35 | struct sd { |
43 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 36 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
44 | |||
45 | struct gspca_ctrl ctrls[NCTRLS]; | ||
46 | |||
47 | u8 quality; | ||
48 | #define QUALITY_MIN 70 | ||
49 | #define QUALITY_MAX 95 | ||
50 | #define QUALITY_DEF 88 | ||
51 | |||
52 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 37 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
53 | }; | 38 | }; |
54 | 39 | ||
55 | /* V4L2 controls supported by the driver */ | ||
56 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
57 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
58 | static void setcolors(struct gspca_dev *gspca_dev); | ||
59 | static void setlightfreq(struct gspca_dev *gspca_dev); | ||
60 | |||
61 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
62 | [BRIGHTNESS] = { | ||
63 | { | ||
64 | .id = V4L2_CID_BRIGHTNESS, | ||
65 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
66 | .name = "Brightness", | ||
67 | .minimum = 0, | ||
68 | .maximum = 255, | ||
69 | .step = 1, | ||
70 | .default_value = 127, | ||
71 | }, | ||
72 | .set_control = setbrightness | ||
73 | }, | ||
74 | [CONTRAST] = { | ||
75 | { | ||
76 | .id = V4L2_CID_CONTRAST, | ||
77 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
78 | .name = "Contrast", | ||
79 | .minimum = 0, | ||
80 | .maximum = 255, | ||
81 | .step = 1, | ||
82 | .default_value = 127, | ||
83 | }, | ||
84 | .set_control = setcontrast | ||
85 | }, | ||
86 | [COLORS] = { | ||
87 | { | ||
88 | .id = V4L2_CID_SATURATION, | ||
89 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
90 | .name = "Color", | ||
91 | .minimum = 0, | ||
92 | .maximum = 255, | ||
93 | .step = 1, | ||
94 | .default_value = 127, | ||
95 | }, | ||
96 | .set_control = setcolors | ||
97 | }, | ||
98 | [LIGHTFREQ] = { | ||
99 | { | ||
100 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
101 | .type = V4L2_CTRL_TYPE_MENU, | ||
102 | .name = "Light frequency filter", | ||
103 | .minimum = 1, | ||
104 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
105 | .step = 1, | ||
106 | .default_value = 1, | ||
107 | }, | ||
108 | .set_control = setlightfreq | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | static const struct v4l2_pix_format vga_mode[] = { | 40 | static const struct v4l2_pix_format vga_mode[] = { |
113 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 41 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
114 | .bytesperline = 320, | 42 | .bytesperline = 320, |
@@ -255,41 +183,36 @@ static void set_par(struct gspca_dev *gspca_dev, | |||
255 | snd_val(gspca_dev, 0x003f08, parval); | 183 | snd_val(gspca_dev, 0x003f08, parval); |
256 | } | 184 | } |
257 | 185 | ||
258 | static void setbrightness(struct gspca_dev *gspca_dev) | 186 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
259 | { | 187 | { |
260 | struct sd *sd = (struct sd *) gspca_dev; | ||
261 | int parval; | 188 | int parval; |
262 | 189 | ||
263 | parval = 0x06000000 /* whiteness */ | 190 | parval = 0x06000000 /* whiteness */ |
264 | + (sd->ctrls[BRIGHTNESS].val << 16); | 191 | + (val << 16); |
265 | set_par(gspca_dev, parval); | 192 | set_par(gspca_dev, parval); |
266 | } | 193 | } |
267 | 194 | ||
268 | static void setcontrast(struct gspca_dev *gspca_dev) | 195 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
269 | { | 196 | { |
270 | struct sd *sd = (struct sd *) gspca_dev; | ||
271 | int parval; | 197 | int parval; |
272 | 198 | ||
273 | parval = 0x07000000 /* contrast */ | 199 | parval = 0x07000000 /* contrast */ |
274 | + (sd->ctrls[CONTRAST].val << 16); | 200 | + (val << 16); |
275 | set_par(gspca_dev, parval); | 201 | set_par(gspca_dev, parval); |
276 | } | 202 | } |
277 | 203 | ||
278 | static void setcolors(struct gspca_dev *gspca_dev) | 204 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
279 | { | 205 | { |
280 | struct sd *sd = (struct sd *) gspca_dev; | ||
281 | int parval; | 206 | int parval; |
282 | 207 | ||
283 | parval = 0x08000000 /* saturation */ | 208 | parval = 0x08000000 /* saturation */ |
284 | + (sd->ctrls[COLORS].val << 16); | 209 | + (val << 16); |
285 | set_par(gspca_dev, parval); | 210 | set_par(gspca_dev, parval); |
286 | } | 211 | } |
287 | 212 | ||
288 | static void setlightfreq(struct gspca_dev *gspca_dev) | 213 | static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) |
289 | { | 214 | { |
290 | struct sd *sd = (struct sd *) gspca_dev; | 215 | set_par(gspca_dev, val == 1 |
291 | |||
292 | set_par(gspca_dev, sd->ctrls[LIGHTFREQ].val == 1 | ||
293 | ? 0x33640000 /* 50 Hz */ | 216 | ? 0x33640000 /* 50 Hz */ |
294 | : 0x33780000); /* 60 Hz */ | 217 | : 0x33780000); /* 60 Hz */ |
295 | } | 218 | } |
@@ -298,12 +221,8 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
298 | static int sd_config(struct gspca_dev *gspca_dev, | 221 | static int sd_config(struct gspca_dev *gspca_dev, |
299 | const struct usb_device_id *id) | 222 | const struct usb_device_id *id) |
300 | { | 223 | { |
301 | struct sd *sd = (struct sd *) gspca_dev; | ||
302 | |||
303 | gspca_dev->cam.cam_mode = vga_mode; | 224 | gspca_dev->cam.cam_mode = vga_mode; |
304 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | 225 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); |
305 | gspca_dev->cam.ctrls = sd->ctrls; | ||
306 | sd->quality = QUALITY_DEF; | ||
307 | return 0; | 226 | return 0; |
308 | } | 227 | } |
309 | 228 | ||
@@ -333,7 +252,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
333 | /* create the JPEG header */ | 252 | /* create the JPEG header */ |
334 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 253 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
335 | 0x22); /* JPEG 411 */ | 254 | 0x22); /* JPEG 411 */ |
336 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 255 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
337 | 256 | ||
338 | /* work on alternate 1 */ | 257 | /* work on alternate 1 */ |
339 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | 258 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); |
@@ -365,14 +284,10 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
365 | reg_w(gspca_dev, 0x0640, 0); | 284 | reg_w(gspca_dev, 0x0640, 0); |
366 | reg_w(gspca_dev, 0x0650, 0); | 285 | reg_w(gspca_dev, 0x0650, 0); |
367 | reg_w(gspca_dev, 0x0660, 0); | 286 | reg_w(gspca_dev, 0x0660, 0); |
368 | setbrightness(gspca_dev); /* whiteness */ | ||
369 | setcontrast(gspca_dev); /* contrast */ | ||
370 | setcolors(gspca_dev); /* saturation */ | ||
371 | set_par(gspca_dev, 0x09800000); /* Red ? */ | 287 | set_par(gspca_dev, 0x09800000); /* Red ? */ |
372 | set_par(gspca_dev, 0x0a800000); /* Green ? */ | 288 | set_par(gspca_dev, 0x0a800000); /* Green ? */ |
373 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ | 289 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ |
374 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ | 290 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ |
375 | setlightfreq(gspca_dev); | ||
376 | 291 | ||
377 | /* start the video flow */ | 292 | /* start the video flow */ |
378 | set_par(gspca_dev, 0x01000000); | 293 | set_par(gspca_dev, 0x01000000); |
@@ -435,62 +350,70 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
435 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 350 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
436 | } | 351 | } |
437 | 352 | ||
438 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 353 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
439 | struct v4l2_querymenu *menu) | ||
440 | { | 354 | { |
441 | static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"}; | 355 | struct gspca_dev *gspca_dev = |
356 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
442 | 357 | ||
443 | switch (menu->id) { | 358 | gspca_dev->usb_err = 0; |
444 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
445 | if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm)) | ||
446 | break; | ||
447 | strcpy((char *) menu->name, freq_nm[menu->index]); | ||
448 | return 0; | ||
449 | } | ||
450 | return -EINVAL; | ||
451 | } | ||
452 | 359 | ||
453 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 360 | if (!gspca_dev->streaming) |
454 | struct v4l2_jpegcompression *jcomp) | 361 | return 0; |
455 | { | ||
456 | struct sd *sd = (struct sd *) gspca_dev; | ||
457 | 362 | ||
458 | if (jcomp->quality < QUALITY_MIN) | 363 | switch (ctrl->id) { |
459 | sd->quality = QUALITY_MIN; | 364 | case V4L2_CID_BRIGHTNESS: |
460 | else if (jcomp->quality > QUALITY_MAX) | 365 | setbrightness(gspca_dev, ctrl->val); |
461 | sd->quality = QUALITY_MAX; | 366 | break; |
462 | else | 367 | case V4L2_CID_CONTRAST: |
463 | sd->quality = jcomp->quality; | 368 | setcontrast(gspca_dev, ctrl->val); |
464 | if (gspca_dev->streaming) | 369 | break; |
465 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 370 | case V4L2_CID_SATURATION: |
371 | setcolors(gspca_dev, ctrl->val); | ||
372 | break; | ||
373 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
374 | setlightfreq(gspca_dev, ctrl->val); | ||
375 | break; | ||
376 | } | ||
466 | return gspca_dev->usb_err; | 377 | return gspca_dev->usb_err; |
467 | } | 378 | } |
468 | 379 | ||
469 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 380 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
470 | struct v4l2_jpegcompression *jcomp) | 381 | .s_ctrl = sd_s_ctrl, |
471 | { | 382 | }; |
472 | struct sd *sd = (struct sd *) gspca_dev; | ||
473 | 383 | ||
474 | memset(jcomp, 0, sizeof *jcomp); | 384 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
475 | jcomp->quality = sd->quality; | 385 | { |
476 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 386 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
477 | | V4L2_JPEG_MARKER_DQT; | 387 | |
388 | gspca_dev->vdev.ctrl_handler = hdl; | ||
389 | v4l2_ctrl_handler_init(hdl, 4); | ||
390 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
391 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); | ||
392 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
393 | V4L2_CID_CONTRAST, 0, 255, 1, 127); | ||
394 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
395 | V4L2_CID_SATURATION, 0, 255, 1, 127); | ||
396 | v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
397 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
398 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1, | ||
399 | V4L2_CID_POWER_LINE_FREQUENCY_50HZ); | ||
400 | |||
401 | if (hdl->error) { | ||
402 | pr_err("Could not initialize controls\n"); | ||
403 | return hdl->error; | ||
404 | } | ||
478 | return 0; | 405 | return 0; |
479 | } | 406 | } |
480 | 407 | ||
481 | /* sub-driver description */ | 408 | /* sub-driver description */ |
482 | static const struct sd_desc sd_desc = { | 409 | static const struct sd_desc sd_desc = { |
483 | .name = MODULE_NAME, | 410 | .name = MODULE_NAME, |
484 | .ctrls = sd_ctrls, | ||
485 | .nctrls = NCTRLS, | ||
486 | .config = sd_config, | 411 | .config = sd_config, |
487 | .init = sd_init, | 412 | .init = sd_init, |
413 | .init_controls = sd_init_controls, | ||
488 | .start = sd_start, | 414 | .start = sd_start, |
489 | .stopN = sd_stopN, | 415 | .stopN = sd_stopN, |
490 | .pkt_scan = sd_pkt_scan, | 416 | .pkt_scan = sd_pkt_scan, |
491 | .querymenu = sd_querymenu, | ||
492 | .get_jcomp = sd_get_jcomp, | ||
493 | .set_jcomp = sd_set_jcomp, | ||
494 | }; | 417 | }; |
495 | 418 | ||
496 | /* -- module initialisation -- */ | 419 | /* -- module initialisation -- */ |
@@ -516,6 +439,7 @@ static struct usb_driver sd_driver = { | |||
516 | #ifdef CONFIG_PM | 439 | #ifdef CONFIG_PM |
517 | .suspend = gspca_suspend, | 440 | .suspend = gspca_suspend, |
518 | .resume = gspca_resume, | 441 | .resume = gspca_resume, |
442 | .reset_resume = gspca_resume, | ||
519 | #endif | 443 | #endif |
520 | }; | 444 | }; |
521 | 445 | ||
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c index 461ed645f309..67605272aaa8 100644 --- a/drivers/media/video/gspca/stv0680.c +++ b/drivers/media/video/gspca/stv0680.c | |||
@@ -46,10 +46,6 @@ struct sd { | |||
46 | u8 current_mode; | 46 | u8 current_mode; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* V4L2 controls supported by the driver */ | ||
50 | static const struct ctrl sd_ctrls[] = { | ||
51 | }; | ||
52 | |||
53 | static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, | 49 | static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, |
54 | int size) | 50 | int size) |
55 | { | 51 | { |
@@ -318,8 +314,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
318 | /* sub-driver description */ | 314 | /* sub-driver description */ |
319 | static const struct sd_desc sd_desc = { | 315 | static const struct sd_desc sd_desc = { |
320 | .name = MODULE_NAME, | 316 | .name = MODULE_NAME, |
321 | .ctrls = sd_ctrls, | ||
322 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
323 | .config = sd_config, | 317 | .config = sd_config, |
324 | .init = sd_init, | 318 | .init = sd_init, |
325 | .start = sd_start, | 319 | .start = sd_start, |
@@ -352,6 +346,7 @@ static struct usb_driver sd_driver = { | |||
352 | #ifdef CONFIG_PM | 346 | #ifdef CONFIG_PM |
353 | .suspend = gspca_suspend, | 347 | .suspend = gspca_suspend, |
354 | .resume = gspca_resume, | 348 | .resume = gspca_resume, |
349 | .reset_resume = gspca_resume, | ||
355 | #endif | 350 | #endif |
356 | }; | 351 | }; |
357 | 352 | ||
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index c80f0c0c75b6..9ccfcb1c6479 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -30,18 +30,13 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
30 | MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); | 30 | MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); |
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | 32 | ||
33 | #define QUALITY 85 | ||
34 | |||
33 | /* specific webcam descriptor */ | 35 | /* specific webcam descriptor */ |
34 | struct sd { | 36 | struct sd { |
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 37 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
36 | 38 | ||
37 | s8 brightness; | 39 | bool autogain; |
38 | u8 contrast; | ||
39 | u8 colors; | ||
40 | u8 autogain; | ||
41 | u8 quality; | ||
42 | #define QUALITY_MIN 70 | ||
43 | #define QUALITY_MAX 95 | ||
44 | #define QUALITY_DEF 85 | ||
45 | 40 | ||
46 | u8 bridge; | 41 | u8 bridge; |
47 | #define BRIDGE_SPCA504 0 | 42 | #define BRIDGE_SPCA504 0 |
@@ -59,75 +54,6 @@ struct sd { | |||
59 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 54 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
60 | }; | 55 | }; |
61 | 56 | ||
62 | /* V4L2 controls supported by the driver */ | ||
63 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
65 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
70 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
71 | |||
72 | static const struct ctrl sd_ctrls[] = { | ||
73 | { | ||
74 | { | ||
75 | .id = V4L2_CID_BRIGHTNESS, | ||
76 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
77 | .name = "Brightness", | ||
78 | .minimum = -128, | ||
79 | .maximum = 127, | ||
80 | .step = 1, | ||
81 | #define BRIGHTNESS_DEF 0 | ||
82 | .default_value = BRIGHTNESS_DEF, | ||
83 | }, | ||
84 | .set = sd_setbrightness, | ||
85 | .get = sd_getbrightness, | ||
86 | }, | ||
87 | { | ||
88 | { | ||
89 | .id = V4L2_CID_CONTRAST, | ||
90 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
91 | .name = "Contrast", | ||
92 | .minimum = 0, | ||
93 | .maximum = 0xff, | ||
94 | .step = 1, | ||
95 | #define CONTRAST_DEF 0x20 | ||
96 | .default_value = CONTRAST_DEF, | ||
97 | }, | ||
98 | .set = sd_setcontrast, | ||
99 | .get = sd_getcontrast, | ||
100 | }, | ||
101 | { | ||
102 | { | ||
103 | .id = V4L2_CID_SATURATION, | ||
104 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
105 | .name = "Color", | ||
106 | .minimum = 0, | ||
107 | .maximum = 0xff, | ||
108 | .step = 1, | ||
109 | #define COLOR_DEF 0x1a | ||
110 | .default_value = COLOR_DEF, | ||
111 | }, | ||
112 | .set = sd_setcolors, | ||
113 | .get = sd_getcolors, | ||
114 | }, | ||
115 | { | ||
116 | { | ||
117 | .id = V4L2_CID_AUTOGAIN, | ||
118 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
119 | .name = "Auto Gain", | ||
120 | .minimum = 0, | ||
121 | .maximum = 1, | ||
122 | .step = 1, | ||
123 | #define AUTOGAIN_DEF 1 | ||
124 | .default_value = AUTOGAIN_DEF, | ||
125 | }, | ||
126 | .set = sd_setautogain, | ||
127 | .get = sd_getautogain, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | static const struct v4l2_pix_format vga_mode[] = { | 57 | static const struct v4l2_pix_format vga_mode[] = { |
132 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 58 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
133 | .bytesperline = 320, | 59 | .bytesperline = 320, |
@@ -597,31 +523,31 @@ static void spca504B_setQtable(struct gspca_dev *gspca_dev) | |||
597 | spca504B_PollingDataReady(gspca_dev); | 523 | spca504B_PollingDataReady(gspca_dev); |
598 | } | 524 | } |
599 | 525 | ||
600 | static void setbrightness(struct gspca_dev *gspca_dev) | 526 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
601 | { | 527 | { |
602 | struct sd *sd = (struct sd *) gspca_dev; | 528 | struct sd *sd = (struct sd *) gspca_dev; |
603 | u16 reg; | 529 | u16 reg; |
604 | 530 | ||
605 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; | 531 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; |
606 | reg_w_riv(gspca_dev, 0x00, reg, sd->brightness); | 532 | reg_w_riv(gspca_dev, 0x00, reg, val); |
607 | } | 533 | } |
608 | 534 | ||
609 | static void setcontrast(struct gspca_dev *gspca_dev) | 535 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
610 | { | 536 | { |
611 | struct sd *sd = (struct sd *) gspca_dev; | 537 | struct sd *sd = (struct sd *) gspca_dev; |
612 | u16 reg; | 538 | u16 reg; |
613 | 539 | ||
614 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; | 540 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; |
615 | reg_w_riv(gspca_dev, 0x00, reg, sd->contrast); | 541 | reg_w_riv(gspca_dev, 0x00, reg, val); |
616 | } | 542 | } |
617 | 543 | ||
618 | static void setcolors(struct gspca_dev *gspca_dev) | 544 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
619 | { | 545 | { |
620 | struct sd *sd = (struct sd *) gspca_dev; | 546 | struct sd *sd = (struct sd *) gspca_dev; |
621 | u16 reg; | 547 | u16 reg; |
622 | 548 | ||
623 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; | 549 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; |
624 | reg_w_riv(gspca_dev, 0x00, reg, sd->colors); | 550 | reg_w_riv(gspca_dev, 0x00, reg, val); |
625 | } | 551 | } |
626 | 552 | ||
627 | static void init_ctl_reg(struct gspca_dev *gspca_dev) | 553 | static void init_ctl_reg(struct gspca_dev *gspca_dev) |
@@ -629,10 +555,6 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev) | |||
629 | struct sd *sd = (struct sd *) gspca_dev; | 555 | struct sd *sd = (struct sd *) gspca_dev; |
630 | int pollreg = 1; | 556 | int pollreg = 1; |
631 | 557 | ||
632 | setbrightness(gspca_dev); | ||
633 | setcontrast(gspca_dev); | ||
634 | setcolors(gspca_dev); | ||
635 | |||
636 | switch (sd->bridge) { | 558 | switch (sd->bridge) { |
637 | case BRIDGE_SPCA504: | 559 | case BRIDGE_SPCA504: |
638 | case BRIDGE_SPCA504C: | 560 | case BRIDGE_SPCA504C: |
@@ -704,11 +626,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
704 | cam->nmodes = ARRAY_SIZE(vga_mode2); | 626 | cam->nmodes = ARRAY_SIZE(vga_mode2); |
705 | break; | 627 | break; |
706 | } | 628 | } |
707 | sd->brightness = BRIGHTNESS_DEF; | ||
708 | sd->contrast = CONTRAST_DEF; | ||
709 | sd->colors = COLOR_DEF; | ||
710 | sd->autogain = AUTOGAIN_DEF; | ||
711 | sd->quality = QUALITY_DEF; | ||
712 | return 0; | 629 | return 0; |
713 | } | 630 | } |
714 | 631 | ||
@@ -807,7 +724,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
807 | /* create the JPEG header */ | 724 | /* create the JPEG header */ |
808 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 725 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
809 | 0x22); /* JPEG 411 */ | 726 | 0x22); /* JPEG 411 */ |
810 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 727 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
811 | 728 | ||
812 | if (sd->bridge == BRIDGE_SPCA504B) | 729 | if (sd->bridge == BRIDGE_SPCA504B) |
813 | spca504B_setQtable(gspca_dev); | 730 | spca504B_setQtable(gspca_dev); |
@@ -1012,116 +929,69 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1012 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 929 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
1013 | } | 930 | } |
1014 | 931 | ||
1015 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 932 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1016 | { | ||
1017 | struct sd *sd = (struct sd *) gspca_dev; | ||
1018 | |||
1019 | sd->brightness = val; | ||
1020 | if (gspca_dev->streaming) | ||
1021 | setbrightness(gspca_dev); | ||
1022 | return gspca_dev->usb_err; | ||
1023 | } | ||
1024 | |||
1025 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1026 | { | ||
1027 | struct sd *sd = (struct sd *) gspca_dev; | ||
1028 | |||
1029 | *val = sd->brightness; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1034 | { | 933 | { |
1035 | struct sd *sd = (struct sd *) gspca_dev; | 934 | struct gspca_dev *gspca_dev = |
935 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
936 | struct sd *sd = (struct sd *)gspca_dev; | ||
1036 | 937 | ||
1037 | sd->contrast = val; | 938 | gspca_dev->usb_err = 0; |
1038 | if (gspca_dev->streaming) | ||
1039 | setcontrast(gspca_dev); | ||
1040 | return gspca_dev->usb_err; | ||
1041 | } | ||
1042 | 939 | ||
1043 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 940 | if (!gspca_dev->streaming) |
1044 | { | 941 | return 0; |
1045 | struct sd *sd = (struct sd *) gspca_dev; | ||
1046 | 942 | ||
1047 | *val = sd->contrast; | 943 | switch (ctrl->id) { |
1048 | return 0; | 944 | case V4L2_CID_BRIGHTNESS: |
1049 | } | 945 | setbrightness(gspca_dev, ctrl->val); |
1050 | 946 | break; | |
1051 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | 947 | case V4L2_CID_CONTRAST: |
1052 | { | 948 | setcontrast(gspca_dev, ctrl->val); |
1053 | struct sd *sd = (struct sd *) gspca_dev; | 949 | break; |
1054 | 950 | case V4L2_CID_SATURATION: | |
1055 | sd->colors = val; | 951 | setcolors(gspca_dev, ctrl->val); |
1056 | if (gspca_dev->streaming) | 952 | break; |
1057 | setcolors(gspca_dev); | 953 | case V4L2_CID_AUTOGAIN: |
954 | sd->autogain = ctrl->val; | ||
955 | break; | ||
956 | } | ||
1058 | return gspca_dev->usb_err; | 957 | return gspca_dev->usb_err; |
1059 | } | 958 | } |
1060 | 959 | ||
1061 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | 960 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
1062 | { | 961 | .s_ctrl = sd_s_ctrl, |
1063 | struct sd *sd = (struct sd *) gspca_dev; | 962 | }; |
1064 | |||
1065 | *val = sd->colors; | ||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1069 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1070 | { | ||
1071 | struct sd *sd = (struct sd *) gspca_dev; | ||
1072 | |||
1073 | sd->autogain = val; | ||
1074 | return 0; | ||
1075 | } | ||
1076 | |||
1077 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1078 | { | ||
1079 | struct sd *sd = (struct sd *) gspca_dev; | ||
1080 | |||
1081 | *val = sd->autogain; | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | ||
1086 | struct v4l2_jpegcompression *jcomp) | ||
1087 | { | ||
1088 | struct sd *sd = (struct sd *) gspca_dev; | ||
1089 | |||
1090 | if (jcomp->quality < QUALITY_MIN) | ||
1091 | sd->quality = QUALITY_MIN; | ||
1092 | else if (jcomp->quality > QUALITY_MAX) | ||
1093 | sd->quality = QUALITY_MAX; | ||
1094 | else | ||
1095 | sd->quality = jcomp->quality; | ||
1096 | if (gspca_dev->streaming) | ||
1097 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
1098 | return gspca_dev->usb_err; | ||
1099 | } | ||
1100 | 963 | ||
1101 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 964 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
1102 | struct v4l2_jpegcompression *jcomp) | ||
1103 | { | 965 | { |
1104 | struct sd *sd = (struct sd *) gspca_dev; | 966 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
1105 | 967 | ||
1106 | memset(jcomp, 0, sizeof *jcomp); | 968 | gspca_dev->vdev.ctrl_handler = hdl; |
1107 | jcomp->quality = sd->quality; | 969 | v4l2_ctrl_handler_init(hdl, 4); |
1108 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 970 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
1109 | | V4L2_JPEG_MARKER_DQT; | 971 | V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); |
972 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
973 | V4L2_CID_CONTRAST, 0, 255, 1, 0x20); | ||
974 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
975 | V4L2_CID_SATURATION, 0, 255, 1, 0x1a); | ||
976 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
977 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
978 | |||
979 | if (hdl->error) { | ||
980 | pr_err("Could not initialize controls\n"); | ||
981 | return hdl->error; | ||
982 | } | ||
1110 | return 0; | 983 | return 0; |
1111 | } | 984 | } |
1112 | 985 | ||
1113 | /* sub-driver description */ | 986 | /* sub-driver description */ |
1114 | static const struct sd_desc sd_desc = { | 987 | static const struct sd_desc sd_desc = { |
1115 | .name = MODULE_NAME, | 988 | .name = MODULE_NAME, |
1116 | .ctrls = sd_ctrls, | ||
1117 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1118 | .config = sd_config, | 989 | .config = sd_config, |
1119 | .init = sd_init, | 990 | .init = sd_init, |
991 | .init_controls = sd_init_controls, | ||
1120 | .start = sd_start, | 992 | .start = sd_start, |
1121 | .stopN = sd_stopN, | 993 | .stopN = sd_stopN, |
1122 | .pkt_scan = sd_pkt_scan, | 994 | .pkt_scan = sd_pkt_scan, |
1123 | .get_jcomp = sd_get_jcomp, | ||
1124 | .set_jcomp = sd_set_jcomp, | ||
1125 | }; | 995 | }; |
1126 | 996 | ||
1127 | /* -- module initialisation -- */ | 997 | /* -- module initialisation -- */ |
@@ -1208,6 +1078,7 @@ static struct usb_driver sd_driver = { | |||
1208 | #ifdef CONFIG_PM | 1078 | #ifdef CONFIG_PM |
1209 | .suspend = gspca_suspend, | 1079 | .suspend = gspca_suspend, |
1210 | .resume = gspca_resume, | 1080 | .resume = gspca_resume, |
1081 | .reset_resume = gspca_resume, | ||
1211 | #endif | 1082 | #endif |
1212 | }; | 1083 | }; |
1213 | 1084 | ||
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 9b9f85a8e60e..8bc6c3ceec2c 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -34,28 +34,19 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include "gspca.h" | 35 | #include "gspca.h" |
36 | 36 | ||
37 | #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) | ||
38 | |||
39 | MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); | 37 | MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); |
40 | MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); | 38 | MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); |
41 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
42 | 40 | ||
43 | struct sd { | 41 | struct sd { |
44 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 42 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
45 | 43 | struct v4l2_ctrl *freq; | |
46 | u8 brightness; | 44 | struct { /* awb / color gains control cluster */ |
47 | u8 contrast; | 45 | struct v4l2_ctrl *awb; |
48 | u8 colors; | 46 | struct v4l2_ctrl *gain; |
49 | u8 autogain; | 47 | struct v4l2_ctrl *red_balance; |
50 | u8 gamma; | 48 | struct v4l2_ctrl *blue_balance; |
51 | u8 sharpness; | 49 | }; |
52 | u8 freq; | ||
53 | u8 red_gain; | ||
54 | u8 blue_gain; | ||
55 | u8 green_gain; | ||
56 | u8 awb; /* set default r/g/b and activate */ | ||
57 | u8 mirror; | ||
58 | u8 effect; | ||
59 | 50 | ||
60 | u8 sensor; | 51 | u8 sensor; |
61 | u8 button_pressed; | 52 | u8 button_pressed; |
@@ -67,245 +58,31 @@ enum sensors { | |||
67 | SENSOR_LT168G, /* must verify if this is the actual model */ | 58 | SENSOR_LT168G, /* must verify if this is the actual model */ |
68 | }; | 59 | }; |
69 | 60 | ||
70 | /* V4L2 controls supported by the driver */ | ||
71 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
72 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
73 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
74 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
75 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
76 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
77 | static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | |||
86 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); | ||
87 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); | ||
88 | static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
89 | static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
90 | static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
91 | static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
93 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
94 | |||
95 | static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); | ||
97 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); | ||
98 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | |||
100 | static const struct ctrl sd_ctrls[] = { | ||
101 | { | ||
102 | { | ||
103 | .id = V4L2_CID_BRIGHTNESS, | ||
104 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
105 | .name = "Brightness", | ||
106 | .minimum = 0, | ||
107 | .maximum = 14, | ||
108 | .step = 1, | ||
109 | #define BRIGHTNESS_DEF 8 | ||
110 | .default_value = BRIGHTNESS_DEF, | ||
111 | }, | ||
112 | .set = sd_setbrightness, | ||
113 | .get = sd_getbrightness, | ||
114 | }, | ||
115 | { | ||
116 | { | ||
117 | .id = V4L2_CID_CONTRAST, | ||
118 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
119 | .name = "Contrast", | ||
120 | .minimum = 0, | ||
121 | .maximum = 0x0d, | ||
122 | .step = 1, | ||
123 | #define CONTRAST_DEF 0x07 | ||
124 | .default_value = CONTRAST_DEF, | ||
125 | }, | ||
126 | .set = sd_setcontrast, | ||
127 | .get = sd_getcontrast, | ||
128 | }, | ||
129 | { | ||
130 | { | ||
131 | .id = V4L2_CID_SATURATION, | ||
132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
133 | .name = "Color", | ||
134 | .minimum = 0, | ||
135 | .maximum = 0x0f, | ||
136 | .step = 1, | ||
137 | #define COLORS_DEF 0x05 | ||
138 | .default_value = COLORS_DEF, | ||
139 | }, | ||
140 | .set = sd_setcolors, | ||
141 | .get = sd_getcolors, | ||
142 | }, | ||
143 | #define GAMMA_MAX 16 | ||
144 | #define GAMMA_DEF 10 | ||
145 | { | ||
146 | { | ||
147 | .id = V4L2_CID_GAMMA, /* (gamma on win) */ | ||
148 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
149 | .name = "Gamma", | ||
150 | .minimum = 0, | ||
151 | .maximum = GAMMA_MAX - 1, | ||
152 | .step = 1, | ||
153 | .default_value = GAMMA_DEF, | ||
154 | }, | ||
155 | .set = sd_setgamma, | ||
156 | .get = sd_getgamma, | ||
157 | }, | ||
158 | { | ||
159 | { | ||
160 | .id = V4L2_CID_BACKLIGHT_COMPENSATION, /* Activa lowlight, | ||
161 | * some apps dont bring up the | ||
162 | * backligth_compensation control) */ | ||
163 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
164 | .name = "Low Light", | ||
165 | .minimum = 0, | ||
166 | .maximum = 1, | ||
167 | .step = 1, | ||
168 | #define AUTOGAIN_DEF 0x01 | ||
169 | .default_value = AUTOGAIN_DEF, | ||
170 | }, | ||
171 | .set = sd_setlowlight, | ||
172 | .get = sd_getlowlight, | ||
173 | }, | ||
174 | { | ||
175 | { | ||
176 | .id = V4L2_CID_HFLIP, | ||
177 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
178 | .name = "Mirror Image", | ||
179 | .minimum = 0, | ||
180 | .maximum = 1, | ||
181 | .step = 1, | ||
182 | #define MIRROR_DEF 0 | ||
183 | .default_value = MIRROR_DEF, | ||
184 | }, | ||
185 | .set = sd_setmirror, | ||
186 | .get = sd_getmirror | ||
187 | }, | ||
188 | { | ||
189 | { | ||
190 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
191 | .type = V4L2_CTRL_TYPE_MENU, | ||
192 | .name = "Light Frequency Filter", | ||
193 | .minimum = 1, /* 1 -> 0x50, 2->0x60 */ | ||
194 | .maximum = 2, | ||
195 | .step = 1, | ||
196 | #define FREQ_DEF 1 | ||
197 | .default_value = FREQ_DEF, | ||
198 | }, | ||
199 | .set = sd_setfreq, | ||
200 | .get = sd_getfreq}, | ||
201 | |||
202 | { | ||
203 | { | ||
204 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
205 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
206 | .name = "Auto White Balance", | ||
207 | .minimum = 0, | ||
208 | .maximum = 1, | ||
209 | .step = 1, | ||
210 | #define AWB_DEF 0 | ||
211 | .default_value = AWB_DEF, | ||
212 | }, | ||
213 | .set = sd_setawb, | ||
214 | .get = sd_getawb | ||
215 | }, | ||
216 | { | ||
217 | { | ||
218 | .id = V4L2_CID_SHARPNESS, | ||
219 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
220 | .name = "Sharpness", | ||
221 | .minimum = 0, | ||
222 | .maximum = 15, | ||
223 | .step = 1, | ||
224 | #define SHARPNESS_DEF 0x06 | ||
225 | .default_value = SHARPNESS_DEF, | ||
226 | }, | ||
227 | .set = sd_setsharpness, | ||
228 | .get = sd_getsharpness, | ||
229 | }, | ||
230 | { | ||
231 | { | ||
232 | .id = V4L2_CID_EFFECTS, | ||
233 | .type = V4L2_CTRL_TYPE_MENU, | ||
234 | .name = "Webcam Effects", | ||
235 | .minimum = 0, | ||
236 | .maximum = 4, | ||
237 | .step = 1, | ||
238 | #define EFFECTS_DEF 0 | ||
239 | .default_value = EFFECTS_DEF, | ||
240 | }, | ||
241 | .set = sd_seteffect, | ||
242 | .get = sd_geteffect | ||
243 | }, | ||
244 | { | ||
245 | { | ||
246 | .id = V4L2_CID_BLUE_BALANCE, | ||
247 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
248 | .name = "Blue Balance", | ||
249 | .minimum = 0x10, | ||
250 | .maximum = 0x40, | ||
251 | .step = 1, | ||
252 | #define BLUE_GAIN_DEF 0x20 | ||
253 | .default_value = BLUE_GAIN_DEF, | ||
254 | }, | ||
255 | .set = sd_setblue_gain, | ||
256 | .get = sd_getblue_gain, | ||
257 | }, | ||
258 | { | ||
259 | { | ||
260 | .id = V4L2_CID_RED_BALANCE, | ||
261 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
262 | .name = "Red Balance", | ||
263 | .minimum = 0x10, | ||
264 | .maximum = 0x40, | ||
265 | .step = 1, | ||
266 | #define RED_GAIN_DEF 0x20 | ||
267 | .default_value = RED_GAIN_DEF, | ||
268 | }, | ||
269 | .set = sd_setred_gain, | ||
270 | .get = sd_getred_gain, | ||
271 | }, | ||
272 | { | ||
273 | { | ||
274 | .id = V4L2_CID_GAIN, | ||
275 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
276 | .name = "Gain", | ||
277 | .minimum = 0x10, | ||
278 | .maximum = 0x40, | ||
279 | .step = 1, | ||
280 | #define GAIN_DEF 0x20 | ||
281 | .default_value = GAIN_DEF, | ||
282 | }, | ||
283 | .set = sd_setgain, | ||
284 | .get = sd_getgain, | ||
285 | }, | ||
286 | }; | ||
287 | |||
288 | static const struct v4l2_pix_format vga_mode_t16[] = { | 61 | static const struct v4l2_pix_format vga_mode_t16[] = { |
289 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 62 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
290 | .bytesperline = 160, | 63 | .bytesperline = 160, |
291 | .sizeimage = 160 * 120 * 4 / 8 + 590, | 64 | .sizeimage = 160 * 120 * 4 / 8 + 590, |
292 | .colorspace = V4L2_COLORSPACE_JPEG, | 65 | .colorspace = V4L2_COLORSPACE_JPEG, |
293 | .priv = 4}, | 66 | .priv = 4}, |
67 | #if 0 /* HDG: broken with my test cam, so lets disable it */ | ||
294 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 68 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
295 | .bytesperline = 176, | 69 | .bytesperline = 176, |
296 | .sizeimage = 176 * 144 * 3 / 8 + 590, | 70 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
297 | .colorspace = V4L2_COLORSPACE_JPEG, | 71 | .colorspace = V4L2_COLORSPACE_JPEG, |
298 | .priv = 3}, | 72 | .priv = 3}, |
73 | #endif | ||
299 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 74 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
300 | .bytesperline = 320, | 75 | .bytesperline = 320, |
301 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 76 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
302 | .colorspace = V4L2_COLORSPACE_JPEG, | 77 | .colorspace = V4L2_COLORSPACE_JPEG, |
303 | .priv = 2}, | 78 | .priv = 2}, |
79 | #if 0 /* HDG: broken with my test cam, so lets disable it */ | ||
304 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 80 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
305 | .bytesperline = 352, | 81 | .bytesperline = 352, |
306 | .sizeimage = 352 * 288 * 3 / 8 + 590, | 82 | .sizeimage = 352 * 288 * 3 / 8 + 590, |
307 | .colorspace = V4L2_COLORSPACE_JPEG, | 83 | .colorspace = V4L2_COLORSPACE_JPEG, |
308 | .priv = 1}, | 84 | .priv = 1}, |
85 | #endif | ||
309 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 86 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
310 | .bytesperline = 640, | 87 | .bytesperline = 640, |
311 | .sizeimage = 640 * 480 * 3 / 8 + 590, | 88 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
@@ -454,17 +231,6 @@ static const struct additional_sensor_data sensor_data[] = { | |||
454 | }; | 231 | }; |
455 | 232 | ||
456 | #define MAX_EFFECTS 7 | 233 | #define MAX_EFFECTS 7 |
457 | /* easily done by soft, this table could be removed, | ||
458 | * i keep it here just in case */ | ||
459 | static char *effects_control[MAX_EFFECTS] = { | ||
460 | "Normal", | ||
461 | "Emboss", /* disabled */ | ||
462 | "Monochrome", | ||
463 | "Sepia", | ||
464 | "Sketch", | ||
465 | "Sun Effect", /* disabled */ | ||
466 | "Negative", | ||
467 | }; | ||
468 | static const u8 effects_table[MAX_EFFECTS][6] = { | 234 | static const u8 effects_table[MAX_EFFECTS][6] = { |
469 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ | 235 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ |
470 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ | 236 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ |
@@ -475,7 +241,8 @@ static const u8 effects_table[MAX_EFFECTS][6] = { | |||
475 | {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ | 241 | {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ |
476 | }; | 242 | }; |
477 | 243 | ||
478 | static const u8 gamma_table[GAMMA_MAX][17] = { | 244 | #define GAMMA_MAX (15) |
245 | static const u8 gamma_table[GAMMA_MAX+1][17] = { | ||
479 | /* gamma table from cam1690.ini */ | 246 | /* gamma table from cam1690.ini */ |
480 | {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */ | 247 | {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */ |
481 | 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb, | 248 | 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb, |
@@ -683,38 +450,18 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev) | |||
683 | static int sd_config(struct gspca_dev *gspca_dev, | 450 | static int sd_config(struct gspca_dev *gspca_dev, |
684 | const struct usb_device_id *id) | 451 | const struct usb_device_id *id) |
685 | { | 452 | { |
686 | struct sd *sd = (struct sd *) gspca_dev; | 453 | struct cam *cam = &gspca_dev->cam; |
687 | struct cam *cam; | ||
688 | |||
689 | cam = &gspca_dev->cam; | ||
690 | 454 | ||
691 | cam->cam_mode = vga_mode_t16; | 455 | cam->cam_mode = vga_mode_t16; |
692 | cam->nmodes = ARRAY_SIZE(vga_mode_t16); | 456 | cam->nmodes = ARRAY_SIZE(vga_mode_t16); |
693 | 457 | ||
694 | sd->brightness = BRIGHTNESS_DEF; | ||
695 | sd->contrast = CONTRAST_DEF; | ||
696 | sd->colors = COLORS_DEF; | ||
697 | sd->gamma = GAMMA_DEF; | ||
698 | sd->autogain = AUTOGAIN_DEF; | ||
699 | sd->mirror = MIRROR_DEF; | ||
700 | sd->freq = FREQ_DEF; | ||
701 | sd->awb = AWB_DEF; | ||
702 | sd->sharpness = SHARPNESS_DEF; | ||
703 | sd->effect = EFFECTS_DEF; | ||
704 | sd->red_gain = RED_GAIN_DEF; | ||
705 | sd->blue_gain = BLUE_GAIN_DEF; | ||
706 | sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF; | ||
707 | |||
708 | return 0; | 458 | return 0; |
709 | } | 459 | } |
710 | 460 | ||
711 | static void setbrightness(struct gspca_dev *gspca_dev) | 461 | static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) |
712 | { | 462 | { |
713 | struct sd *sd = (struct sd *) gspca_dev; | ||
714 | unsigned int brightness; | ||
715 | u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; | 463 | u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; |
716 | 464 | ||
717 | brightness = sd->brightness; | ||
718 | if (brightness < 7) { | 465 | if (brightness < 7) { |
719 | set6[1] = 0x26; | 466 | set6[1] = 0x26; |
720 | set6[3] = 0x70 - brightness * 0x10; | 467 | set6[3] = 0x70 - brightness * 0x10; |
@@ -725,10 +472,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
725 | reg_w_buf(gspca_dev, set6, sizeof set6); | 472 | reg_w_buf(gspca_dev, set6, sizeof set6); |
726 | } | 473 | } |
727 | 474 | ||
728 | static void setcontrast(struct gspca_dev *gspca_dev) | 475 | static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast) |
729 | { | 476 | { |
730 | struct sd *sd = (struct sd *) gspca_dev; | ||
731 | unsigned int contrast = sd->contrast; | ||
732 | u16 reg_to_write; | 477 | u16 reg_to_write; |
733 | 478 | ||
734 | if (contrast < 7) | 479 | if (contrast < 7) |
@@ -739,89 +484,62 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
739 | reg_w(gspca_dev, reg_to_write); | 484 | reg_w(gspca_dev, reg_to_write); |
740 | } | 485 | } |
741 | 486 | ||
742 | static void setcolors(struct gspca_dev *gspca_dev) | 487 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
743 | { | 488 | { |
744 | struct sd *sd = (struct sd *) gspca_dev; | ||
745 | u16 reg_to_write; | 489 | u16 reg_to_write; |
746 | 490 | ||
747 | reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ | 491 | reg_to_write = 0x80bb + val * 0x100; /* was 0xc0 */ |
748 | reg_w(gspca_dev, reg_to_write); | 492 | reg_w(gspca_dev, reg_to_write); |
749 | } | 493 | } |
750 | 494 | ||
751 | static void setgamma(struct gspca_dev *gspca_dev) | 495 | static void setgamma(struct gspca_dev *gspca_dev, s32 val) |
752 | { | 496 | { |
753 | struct sd *sd = (struct sd *) gspca_dev; | ||
754 | |||
755 | PDEBUG(D_CONF, "Gamma: %d", sd->gamma); | 497 | PDEBUG(D_CONF, "Gamma: %d", sd->gamma); |
756 | reg_w_ixbuf(gspca_dev, 0x90, | 498 | reg_w_ixbuf(gspca_dev, 0x90, |
757 | gamma_table[sd->gamma], sizeof gamma_table[0]); | 499 | gamma_table[val], sizeof gamma_table[0]); |
758 | } | 500 | } |
759 | 501 | ||
760 | static void setRGB(struct gspca_dev *gspca_dev) | 502 | static void setawb_n_RGB(struct gspca_dev *gspca_dev) |
761 | { | 503 | { |
762 | struct sd *sd = (struct sd *) gspca_dev; | 504 | struct sd *sd = (struct sd *) gspca_dev; |
763 | u8 all_gain_reg[6] = | 505 | u8 all_gain_reg[8] = { |
764 | {0x87, 0x00, 0x88, 0x00, 0x89, 0x00}; | 506 | 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 }; |
507 | s32 red_gain, blue_gain, green_gain; | ||
508 | |||
509 | green_gain = sd->gain->val; | ||
510 | |||
511 | red_gain = green_gain + sd->red_balance->val; | ||
512 | if (red_gain > 0x40) | ||
513 | red_gain = 0x40; | ||
514 | else if (red_gain < 0x10) | ||
515 | red_gain = 0x10; | ||
516 | |||
517 | blue_gain = green_gain + sd->blue_balance->val; | ||
518 | if (blue_gain > 0x40) | ||
519 | blue_gain = 0x40; | ||
520 | else if (blue_gain < 0x10) | ||
521 | blue_gain = 0x10; | ||
522 | |||
523 | all_gain_reg[1] = red_gain; | ||
524 | all_gain_reg[3] = blue_gain; | ||
525 | all_gain_reg[5] = green_gain; | ||
526 | all_gain_reg[7] = sensor_data[sd->sensor].reg80; | ||
527 | if (!sd->awb->val) | ||
528 | all_gain_reg[7] &= ~0x04; /* AWB off */ | ||
765 | 529 | ||
766 | all_gain_reg[1] = sd->red_gain; | ||
767 | all_gain_reg[3] = sd->blue_gain; | ||
768 | all_gain_reg[5] = sd->green_gain; | ||
769 | reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); | 530 | reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); |
770 | } | 531 | } |
771 | 532 | ||
772 | /* Generic fnc for r/b balance, exposure and awb */ | 533 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
773 | static void setawb(struct gspca_dev *gspca_dev) | ||
774 | { | 534 | { |
775 | struct sd *sd = (struct sd *) gspca_dev; | ||
776 | u16 reg80; | ||
777 | |||
778 | reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80; | ||
779 | |||
780 | /* on awb leave defaults values */ | ||
781 | if (!sd->awb) { | ||
782 | /* shoud we wait here.. */ | ||
783 | /* update and reset RGB gains with webcam values */ | ||
784 | sd->red_gain = reg_r(gspca_dev, 0x0087); | ||
785 | sd->blue_gain = reg_r(gspca_dev, 0x0088); | ||
786 | sd->green_gain = reg_r(gspca_dev, 0x0089); | ||
787 | reg80 &= ~0x0400; /* AWB off */ | ||
788 | } | ||
789 | reg_w(gspca_dev, reg80); | ||
790 | reg_w(gspca_dev, reg80); | ||
791 | } | ||
792 | |||
793 | static void init_gains(struct gspca_dev *gspca_dev) | ||
794 | { | ||
795 | struct sd *sd = (struct sd *) gspca_dev; | ||
796 | u16 reg80; | ||
797 | u8 all_gain_reg[8] = | ||
798 | {0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00}; | ||
799 | |||
800 | all_gain_reg[1] = sd->red_gain; | ||
801 | all_gain_reg[3] = sd->blue_gain; | ||
802 | all_gain_reg[5] = sd->green_gain; | ||
803 | reg80 = sensor_data[sd->sensor].reg80; | ||
804 | if (!sd->awb) | ||
805 | reg80 &= ~0x04; | ||
806 | all_gain_reg[7] = reg80; | ||
807 | reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); | ||
808 | |||
809 | reg_w(gspca_dev, (sd->red_gain << 8) + 0x87); | ||
810 | reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88); | ||
811 | reg_w(gspca_dev, (sd->green_gain << 8) + 0x89); | ||
812 | } | ||
813 | |||
814 | static void setsharpness(struct gspca_dev *gspca_dev) | ||
815 | { | ||
816 | struct sd *sd = (struct sd *) gspca_dev; | ||
817 | u16 reg_to_write; | 535 | u16 reg_to_write; |
818 | 536 | ||
819 | reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; | 537 | reg_to_write = 0x0aa6 + 0x1000 * val; |
820 | 538 | ||
821 | reg_w(gspca_dev, reg_to_write); | 539 | reg_w(gspca_dev, reg_to_write); |
822 | } | 540 | } |
823 | 541 | ||
824 | static void setfreq(struct gspca_dev *gspca_dev) | 542 | static void setfreq(struct gspca_dev *gspca_dev, s32 val) |
825 | { | 543 | { |
826 | struct sd *sd = (struct sd *) gspca_dev; | 544 | struct sd *sd = (struct sd *) gspca_dev; |
827 | u8 reg66; | 545 | u8 reg66; |
@@ -829,7 +547,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
829 | 547 | ||
830 | switch (sd->sensor) { | 548 | switch (sd->sensor) { |
831 | case SENSOR_LT168G: | 549 | case SENSOR_LT168G: |
832 | if (sd->freq != 0) | 550 | if (val != 0) |
833 | freq[3] = 0xa8; | 551 | freq[3] = 0xa8; |
834 | reg66 = 0x41; | 552 | reg66 = 0x41; |
835 | break; | 553 | break; |
@@ -840,7 +558,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
840 | reg66 = 0x40; | 558 | reg66 = 0x40; |
841 | break; | 559 | break; |
842 | } | 560 | } |
843 | switch (sd->freq) { | 561 | switch (val) { |
844 | case 0: /* no flicker */ | 562 | case 0: /* no flicker */ |
845 | freq[3] = 0xf0; | 563 | freq[3] = 0xf0; |
846 | break; | 564 | break; |
@@ -941,14 +659,9 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
941 | reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); | 659 | reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); |
942 | reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); | 660 | reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); |
943 | reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e); | 661 | reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e); |
944 | 662 | reg_w(gspca_dev, (0x20 << 8) + 0x87); | |
945 | setbrightness(gspca_dev); | 663 | reg_w(gspca_dev, (0x20 << 8) + 0x88); |
946 | setcontrast(gspca_dev); | 664 | reg_w(gspca_dev, (0x20 << 8) + 0x89); |
947 | setgamma(gspca_dev); | ||
948 | setcolors(gspca_dev); | ||
949 | setsharpness(gspca_dev); | ||
950 | init_gains(gspca_dev); | ||
951 | setfreq(gspca_dev); | ||
952 | 665 | ||
953 | reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); | 666 | reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); |
954 | reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); | 667 | reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); |
@@ -968,31 +681,44 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
968 | return 0; | 681 | return 0; |
969 | } | 682 | } |
970 | 683 | ||
971 | static void setmirror(struct gspca_dev *gspca_dev) | 684 | static void setmirror(struct gspca_dev *gspca_dev, s32 val) |
972 | { | 685 | { |
973 | struct sd *sd = (struct sd *) gspca_dev; | ||
974 | u8 hflipcmd[8] = | 686 | u8 hflipcmd[8] = |
975 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; | 687 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; |
976 | 688 | ||
977 | if (sd->mirror) | 689 | if (val) |
978 | hflipcmd[3] = 0x01; | 690 | hflipcmd[3] = 0x01; |
979 | 691 | ||
980 | reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd); | 692 | reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd); |
981 | } | 693 | } |
982 | 694 | ||
983 | static void seteffect(struct gspca_dev *gspca_dev) | 695 | static void seteffect(struct gspca_dev *gspca_dev, s32 val) |
984 | { | 696 | { |
985 | struct sd *sd = (struct sd *) gspca_dev; | 697 | int idx = 0; |
986 | 698 | ||
987 | reg_w_buf(gspca_dev, effects_table[sd->effect], | 699 | switch (val) { |
988 | sizeof effects_table[0]); | 700 | case V4L2_COLORFX_NONE: |
989 | if (sd->effect == 1 || sd->effect == 5) { | 701 | break; |
990 | PDEBUG(D_CONF, | 702 | case V4L2_COLORFX_BW: |
991 | "This effect have been disabled for webcam \"safety\""); | 703 | idx = 2; |
992 | return; | 704 | break; |
705 | case V4L2_COLORFX_SEPIA: | ||
706 | idx = 3; | ||
707 | break; | ||
708 | case V4L2_COLORFX_SKETCH: | ||
709 | idx = 4; | ||
710 | break; | ||
711 | case V4L2_COLORFX_NEGATIVE: | ||
712 | idx = 6; | ||
713 | break; | ||
714 | default: | ||
715 | break; | ||
993 | } | 716 | } |
994 | 717 | ||
995 | if (sd->effect == 1 || sd->effect == 4) | 718 | reg_w_buf(gspca_dev, effects_table[idx], |
719 | sizeof effects_table[0]); | ||
720 | |||
721 | if (val == V4L2_COLORFX_SKETCH) | ||
996 | reg_w(gspca_dev, 0x4aa6); | 722 | reg_w(gspca_dev, 0x4aa6); |
997 | else | 723 | else |
998 | reg_w(gspca_dev, 0xfaa6); | 724 | reg_w(gspca_dev, 0xfaa6); |
@@ -1070,7 +796,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1070 | break; | 796 | break; |
1071 | } | 797 | } |
1072 | sensor = &sensor_data[sd->sensor]; | 798 | sensor = &sensor_data[sd->sensor]; |
1073 | setfreq(gspca_dev); | 799 | setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq)); |
1074 | reg_r(gspca_dev, 0x0012); | 800 | reg_r(gspca_dev, 0x0012); |
1075 | reg_w_buf(gspca_dev, t2, sizeof t2); | 801 | reg_w_buf(gspca_dev, t2, sizeof t2); |
1076 | reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); | 802 | reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); |
@@ -1142,296 +868,157 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1142 | gspca_frame_add(gspca_dev, pkt_type, data, len); | 868 | gspca_frame_add(gspca_dev, pkt_type, data, len); |
1143 | } | 869 | } |
1144 | 870 | ||
1145 | static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val) | 871 | static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
1146 | { | ||
1147 | struct sd *sd = (struct sd *) gspca_dev; | ||
1148 | |||
1149 | sd->blue_gain = val; | ||
1150 | if (gspca_dev->streaming) | ||
1151 | reg_w(gspca_dev, (val << 8) + 0x88); | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1156 | { | ||
1157 | struct sd *sd = (struct sd *) gspca_dev; | ||
1158 | |||
1159 | *val = sd->blue_gain; | ||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
1164 | { | ||
1165 | struct sd *sd = (struct sd *) gspca_dev; | ||
1166 | |||
1167 | sd->red_gain = val; | ||
1168 | if (gspca_dev->streaming) | ||
1169 | reg_w(gspca_dev, (val << 8) + 0x87); | ||
1170 | |||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1175 | { | ||
1176 | struct sd *sd = (struct sd *) gspca_dev; | ||
1177 | |||
1178 | *val = sd->red_gain; | ||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
1183 | { | ||
1184 | struct sd *sd = (struct sd *) gspca_dev; | ||
1185 | u16 psg, nsg; | ||
1186 | |||
1187 | psg = sd->red_gain + sd->blue_gain + sd->green_gain; | ||
1188 | nsg = val * 3; | ||
1189 | sd->red_gain = sd->red_gain * nsg / psg; | ||
1190 | if (sd->red_gain > 0x40) | ||
1191 | sd->red_gain = 0x40; | ||
1192 | else if (sd->red_gain < 0x10) | ||
1193 | sd->red_gain = 0x10; | ||
1194 | sd->blue_gain = sd->blue_gain * nsg / psg; | ||
1195 | if (sd->blue_gain > 0x40) | ||
1196 | sd->blue_gain = 0x40; | ||
1197 | else if (sd->blue_gain < 0x10) | ||
1198 | sd->blue_gain = 0x10; | ||
1199 | sd->green_gain = sd->green_gain * nsg / psg; | ||
1200 | if (sd->green_gain > 0x40) | ||
1201 | sd->green_gain = 0x40; | ||
1202 | else if (sd->green_gain < 0x10) | ||
1203 | sd->green_gain = 0x10; | ||
1204 | |||
1205 | if (gspca_dev->streaming) | ||
1206 | setRGB(gspca_dev); | ||
1207 | return 0; | ||
1208 | } | ||
1209 | |||
1210 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1211 | { | ||
1212 | struct sd *sd = (struct sd *) gspca_dev; | ||
1213 | |||
1214 | *val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3; | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1219 | { | ||
1220 | struct sd *sd = (struct sd *) gspca_dev; | ||
1221 | |||
1222 | sd->brightness = val; | ||
1223 | if (gspca_dev->streaming) | ||
1224 | setbrightness(gspca_dev); | ||
1225 | return 0; | ||
1226 | } | ||
1227 | |||
1228 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1229 | { | ||
1230 | struct sd *sd = (struct sd *) gspca_dev; | ||
1231 | |||
1232 | *val = sd->brightness; | ||
1233 | return *val; | ||
1234 | } | ||
1235 | |||
1236 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val) | ||
1237 | { | ||
1238 | struct sd *sd = (struct sd *) gspca_dev; | ||
1239 | |||
1240 | sd->awb = val; | ||
1241 | if (gspca_dev->streaming) | ||
1242 | setawb(gspca_dev); | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val) | ||
1247 | { | ||
1248 | struct sd *sd = (struct sd *) gspca_dev; | ||
1249 | |||
1250 | *val = sd->awb; | ||
1251 | return *val; | ||
1252 | } | ||
1253 | |||
1254 | static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val) | ||
1255 | { | ||
1256 | struct sd *sd = (struct sd *) gspca_dev; | ||
1257 | |||
1258 | sd->mirror = val; | ||
1259 | if (gspca_dev->streaming) | ||
1260 | setmirror(gspca_dev); | ||
1261 | return 0; | ||
1262 | } | ||
1263 | |||
1264 | static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val) | ||
1265 | { | ||
1266 | struct sd *sd = (struct sd *) gspca_dev; | ||
1267 | |||
1268 | *val = sd->mirror; | ||
1269 | return *val; | ||
1270 | } | ||
1271 | |||
1272 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val) | ||
1273 | { | ||
1274 | struct sd *sd = (struct sd *) gspca_dev; | ||
1275 | |||
1276 | sd->effect = val; | ||
1277 | if (gspca_dev->streaming) | ||
1278 | seteffect(gspca_dev); | ||
1279 | return 0; | ||
1280 | } | ||
1281 | |||
1282 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val) | ||
1283 | { | ||
1284 | struct sd *sd = (struct sd *) gspca_dev; | ||
1285 | |||
1286 | *val = sd->effect; | ||
1287 | return *val; | ||
1288 | } | ||
1289 | |||
1290 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1291 | { | ||
1292 | struct sd *sd = (struct sd *) gspca_dev; | ||
1293 | |||
1294 | sd->contrast = val; | ||
1295 | if (gspca_dev->streaming) | ||
1296 | setcontrast(gspca_dev); | ||
1297 | return 0; | ||
1298 | } | ||
1299 | |||
1300 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1301 | { | ||
1302 | struct sd *sd = (struct sd *) gspca_dev; | ||
1303 | |||
1304 | *val = sd->contrast; | ||
1305 | return *val; | ||
1306 | } | ||
1307 | |||
1308 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1309 | { | ||
1310 | struct sd *sd = (struct sd *) gspca_dev; | ||
1311 | |||
1312 | sd->colors = val; | ||
1313 | if (gspca_dev->streaming) | ||
1314 | setcolors(gspca_dev); | ||
1315 | return 0; | ||
1316 | } | ||
1317 | |||
1318 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1319 | { | ||
1320 | struct sd *sd = (struct sd *) gspca_dev; | ||
1321 | |||
1322 | *val = sd->colors; | ||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
1327 | { | ||
1328 | struct sd *sd = (struct sd *) gspca_dev; | ||
1329 | |||
1330 | sd->gamma = val; | ||
1331 | if (gspca_dev->streaming) | ||
1332 | setgamma(gspca_dev); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
1337 | { | ||
1338 | struct sd *sd = (struct sd *) gspca_dev; | ||
1339 | |||
1340 | *val = sd->gamma; | ||
1341 | return 0; | ||
1342 | } | ||
1343 | |||
1344 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
1345 | { | 872 | { |
1346 | struct sd *sd = (struct sd *) gspca_dev; | 873 | struct gspca_dev *gspca_dev = |
1347 | 874 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
1348 | sd->freq = val; | 875 | struct sd *sd = (struct sd *)gspca_dev; |
1349 | if (gspca_dev->streaming) | 876 | s32 red_gain, blue_gain, green_gain; |
1350 | setfreq(gspca_dev); | 877 | |
878 | gspca_dev->usb_err = 0; | ||
879 | |||
880 | switch (ctrl->id) { | ||
881 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
882 | red_gain = reg_r(gspca_dev, 0x0087); | ||
883 | if (red_gain > 0x40) | ||
884 | red_gain = 0x40; | ||
885 | else if (red_gain < 0x10) | ||
886 | red_gain = 0x10; | ||
887 | |||
888 | blue_gain = reg_r(gspca_dev, 0x0088); | ||
889 | if (blue_gain > 0x40) | ||
890 | blue_gain = 0x40; | ||
891 | else if (blue_gain < 0x10) | ||
892 | blue_gain = 0x10; | ||
893 | |||
894 | green_gain = reg_r(gspca_dev, 0x0089); | ||
895 | if (green_gain > 0x40) | ||
896 | green_gain = 0x40; | ||
897 | else if (green_gain < 0x10) | ||
898 | green_gain = 0x10; | ||
899 | |||
900 | sd->gain->val = green_gain; | ||
901 | sd->red_balance->val = red_gain - green_gain; | ||
902 | sd->blue_balance->val = blue_gain - green_gain; | ||
903 | break; | ||
904 | } | ||
1351 | return 0; | 905 | return 0; |
1352 | } | 906 | } |
1353 | 907 | ||
1354 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | 908 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
1355 | { | 909 | { |
1356 | struct sd *sd = (struct sd *) gspca_dev; | 910 | struct gspca_dev *gspca_dev = |
911 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
1357 | 912 | ||
1358 | *val = sd->freq; | 913 | gspca_dev->usb_err = 0; |
1359 | return 0; | ||
1360 | } | ||
1361 | 914 | ||
1362 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | 915 | if (!gspca_dev->streaming) |
1363 | { | 916 | return 0; |
1364 | struct sd *sd = (struct sd *) gspca_dev; | ||
1365 | 917 | ||
1366 | sd->sharpness = val; | 918 | switch (ctrl->id) { |
1367 | if (gspca_dev->streaming) | 919 | case V4L2_CID_BRIGHTNESS: |
1368 | setsharpness(gspca_dev); | 920 | setbrightness(gspca_dev, ctrl->val); |
1369 | return 0; | 921 | break; |
922 | case V4L2_CID_CONTRAST: | ||
923 | setcontrast(gspca_dev, ctrl->val); | ||
924 | break; | ||
925 | case V4L2_CID_SATURATION: | ||
926 | setcolors(gspca_dev, ctrl->val); | ||
927 | break; | ||
928 | case V4L2_CID_GAMMA: | ||
929 | setgamma(gspca_dev, ctrl->val); | ||
930 | break; | ||
931 | case V4L2_CID_HFLIP: | ||
932 | setmirror(gspca_dev, ctrl->val); | ||
933 | break; | ||
934 | case V4L2_CID_SHARPNESS: | ||
935 | setsharpness(gspca_dev, ctrl->val); | ||
936 | break; | ||
937 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
938 | setfreq(gspca_dev, ctrl->val); | ||
939 | break; | ||
940 | case V4L2_CID_BACKLIGHT_COMPENSATION: | ||
941 | reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e); | ||
942 | break; | ||
943 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
944 | setawb_n_RGB(gspca_dev); | ||
945 | break; | ||
946 | case V4L2_CID_COLORFX: | ||
947 | seteffect(gspca_dev, ctrl->val); | ||
948 | break; | ||
949 | } | ||
950 | return gspca_dev->usb_err; | ||
1370 | } | 951 | } |
1371 | 952 | ||
1372 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | 953 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
1373 | { | 954 | .g_volatile_ctrl = sd_g_volatile_ctrl, |
1374 | struct sd *sd = (struct sd *) gspca_dev; | 955 | .s_ctrl = sd_s_ctrl, |
1375 | 956 | }; | |
1376 | *val = sd->sharpness; | ||
1377 | return 0; | ||
1378 | } | ||
1379 | 957 | ||
1380 | /* Low Light set here......*/ | 958 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
1381 | static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) | ||
1382 | { | 959 | { |
1383 | struct sd *sd = (struct sd *) gspca_dev; | 960 | struct sd *sd = (struct sd *)gspca_dev; |
961 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
962 | |||
963 | gspca_dev->vdev.ctrl_handler = hdl; | ||
964 | v4l2_ctrl_handler_init(hdl, 12); | ||
965 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
966 | V4L2_CID_BRIGHTNESS, 0, 14, 1, 8); | ||
967 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
968 | V4L2_CID_CONTRAST, 0, 0x0d, 1, 7); | ||
969 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
970 | V4L2_CID_SATURATION, 0, 0xf, 1, 5); | ||
971 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
972 | V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10); | ||
973 | /* Activate lowlight, some apps dont bring up the | ||
974 | backlight_compensation control) */ | ||
975 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
976 | V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1); | ||
977 | if (sd->sensor == SENSOR_TAS5130A) | ||
978 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
979 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
980 | sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
981 | V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); | ||
982 | sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
983 | V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20); | ||
984 | sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
985 | V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0); | ||
986 | sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
987 | V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0); | ||
988 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
989 | V4L2_CID_SHARPNESS, 0, 15, 1, 6); | ||
990 | v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
991 | V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH, | ||
992 | ~((1 << V4L2_COLORFX_NONE) | | ||
993 | (1 << V4L2_COLORFX_BW) | | ||
994 | (1 << V4L2_COLORFX_SEPIA) | | ||
995 | (1 << V4L2_COLORFX_SKETCH) | | ||
996 | (1 << V4L2_COLORFX_NEGATIVE)), | ||
997 | V4L2_COLORFX_NONE); | ||
998 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
999 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
1000 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1, | ||
1001 | V4L2_CID_POWER_LINE_FREQUENCY_50HZ); | ||
1002 | |||
1003 | if (hdl->error) { | ||
1004 | pr_err("Could not initialize controls\n"); | ||
1005 | return hdl->error; | ||
1006 | } | ||
1384 | 1007 | ||
1385 | sd->autogain = val; | 1008 | v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true); |
1386 | if (val != 0) | ||
1387 | reg_w(gspca_dev, 0xf48e); | ||
1388 | else | ||
1389 | reg_w(gspca_dev, 0xb48e); | ||
1390 | return 0; | ||
1391 | } | ||
1392 | 1009 | ||
1393 | static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) | ||
1394 | { | ||
1395 | struct sd *sd = (struct sd *) gspca_dev; | ||
1396 | |||
1397 | *val = sd->autogain; | ||
1398 | return 0; | 1010 | return 0; |
1399 | } | 1011 | } |
1400 | 1012 | ||
1401 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
1402 | struct v4l2_querymenu *menu) | ||
1403 | { | ||
1404 | static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"}; | ||
1405 | |||
1406 | switch (menu->id) { | ||
1407 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
1408 | if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm)) | ||
1409 | break; | ||
1410 | strcpy((char *) menu->name, freq_nm[menu->index]); | ||
1411 | return 0; | ||
1412 | case V4L2_CID_EFFECTS: | ||
1413 | if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { | ||
1414 | strlcpy((char *) menu->name, | ||
1415 | effects_control[menu->index], | ||
1416 | sizeof menu->name); | ||
1417 | return 0; | ||
1418 | } | ||
1419 | break; | ||
1420 | } | ||
1421 | return -EINVAL; | ||
1422 | } | ||
1423 | |||
1424 | /* sub-driver description */ | 1013 | /* sub-driver description */ |
1425 | static const struct sd_desc sd_desc = { | 1014 | static const struct sd_desc sd_desc = { |
1426 | .name = MODULE_NAME, | 1015 | .name = MODULE_NAME, |
1427 | .ctrls = sd_ctrls, | ||
1428 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1429 | .config = sd_config, | 1016 | .config = sd_config, |
1430 | .init = sd_init, | 1017 | .init = sd_init, |
1018 | .init_controls = sd_init_controls, | ||
1431 | .start = sd_start, | 1019 | .start = sd_start, |
1432 | .stopN = sd_stopN, | 1020 | .stopN = sd_stopN, |
1433 | .pkt_scan = sd_pkt_scan, | 1021 | .pkt_scan = sd_pkt_scan, |
1434 | .querymenu = sd_querymenu, | ||
1435 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 1022 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1436 | .other_input = 1, | 1023 | .other_input = 1, |
1437 | #endif | 1024 | #endif |
@@ -1460,6 +1047,7 @@ static struct usb_driver sd_driver = { | |||
1460 | #ifdef CONFIG_PM | 1047 | #ifdef CONFIG_PM |
1461 | .suspend = gspca_suspend, | 1048 | .suspend = gspca_suspend, |
1462 | .resume = gspca_resume, | 1049 | .resume = gspca_resume, |
1050 | .reset_resume = gspca_resume, | ||
1463 | #endif | 1051 | #endif |
1464 | }; | 1052 | }; |
1465 | 1053 | ||
diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c index c6326d177a3d..a6055246cb9d 100644 --- a/drivers/media/video/gspca/topro.c +++ b/drivers/media/video/gspca/topro.c | |||
@@ -120,24 +120,13 @@ static const u8 jpeg_head[] = { | |||
120 | #define JPEG_HDR_SZ 521 | 120 | #define JPEG_HDR_SZ 521 |
121 | }; | 121 | }; |
122 | 122 | ||
123 | enum e_ctrl { | ||
124 | EXPOSURE, | ||
125 | QUALITY, | ||
126 | SHARPNESS, | ||
127 | RGAIN, | ||
128 | GAIN, | ||
129 | BGAIN, | ||
130 | GAMMA, | ||
131 | AUTOGAIN, | ||
132 | NCTRLS /* number of controls */ | ||
133 | }; | ||
134 | |||
135 | #define AUTOGAIN_DEF 1 | ||
136 | |||
137 | struct sd { | 123 | struct sd { |
138 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 124 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
139 | 125 | struct v4l2_ctrl *jpegqual; | |
140 | struct gspca_ctrl ctrls[NCTRLS]; | 126 | struct v4l2_ctrl *sharpness; |
127 | struct v4l2_ctrl *gamma; | ||
128 | struct v4l2_ctrl *blue; | ||
129 | struct v4l2_ctrl *red; | ||
141 | 130 | ||
142 | u8 framerate; | 131 | u8 framerate; |
143 | u8 quality; /* webcam current JPEG quality (0..16) */ | 132 | u8 quality; /* webcam current JPEG quality (0..16) */ |
@@ -1415,32 +1404,33 @@ static void soi763a_6810_init(struct gspca_dev *gspca_dev) | |||
1415 | } | 1404 | } |
1416 | 1405 | ||
1417 | /* set the gain and exposure */ | 1406 | /* set the gain and exposure */ |
1418 | static void setexposure(struct gspca_dev *gspca_dev) | 1407 | static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain, |
1408 | s32 blue, s32 red) | ||
1419 | { | 1409 | { |
1420 | struct sd *sd = (struct sd *) gspca_dev; | 1410 | struct sd *sd = (struct sd *) gspca_dev; |
1421 | 1411 | ||
1422 | if (sd->sensor == SENSOR_CX0342) { | 1412 | if (sd->sensor == SENSOR_CX0342) { |
1423 | int expo; | 1413 | expo = (expo << 2) - 1; |
1424 | |||
1425 | expo = (sd->ctrls[EXPOSURE].val << 2) - 1; | ||
1426 | i2c_w(gspca_dev, CX0342_EXPO_LINE_L, expo); | 1414 | i2c_w(gspca_dev, CX0342_EXPO_LINE_L, expo); |
1427 | i2c_w(gspca_dev, CX0342_EXPO_LINE_H, expo >> 8); | 1415 | i2c_w(gspca_dev, CX0342_EXPO_LINE_H, expo >> 8); |
1428 | if (sd->bridge == BRIDGE_TP6800) | 1416 | if (sd->bridge == BRIDGE_TP6800) |
1429 | i2c_w(gspca_dev, CX0342_RAW_GBGAIN_H, | 1417 | i2c_w(gspca_dev, CX0342_RAW_GBGAIN_H, |
1430 | sd->ctrls[GAIN].val >> 8); | 1418 | gain >> 8); |
1431 | i2c_w(gspca_dev, CX0342_RAW_GBGAIN_L, sd->ctrls[GAIN].val); | 1419 | i2c_w(gspca_dev, CX0342_RAW_GBGAIN_L, gain); |
1432 | if (sd->bridge == BRIDGE_TP6800) | 1420 | if (sd->bridge == BRIDGE_TP6800) |
1433 | i2c_w(gspca_dev, CX0342_RAW_GRGAIN_H, | 1421 | i2c_w(gspca_dev, CX0342_RAW_GRGAIN_H, |
1434 | sd->ctrls[GAIN].val >> 8); | 1422 | gain >> 8); |
1435 | i2c_w(gspca_dev, CX0342_RAW_GRGAIN_L, sd->ctrls[GAIN].val); | 1423 | i2c_w(gspca_dev, CX0342_RAW_GRGAIN_L, gain); |
1436 | if (sd->bridge == BRIDGE_TP6800) | 1424 | if (sd->sensor == SENSOR_CX0342) { |
1437 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, | 1425 | if (sd->bridge == BRIDGE_TP6800) |
1438 | sd->ctrls[BGAIN].val >> 8); | 1426 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, |
1439 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, sd->ctrls[BGAIN].val); | 1427 | blue >> 8); |
1440 | if (sd->bridge == BRIDGE_TP6800) | 1428 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, blue); |
1441 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, | 1429 | if (sd->bridge == BRIDGE_TP6800) |
1442 | sd->ctrls[RGAIN].val >> 8); | 1430 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, |
1443 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, sd->ctrls[RGAIN].val); | 1431 | red >> 8); |
1432 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, red); | ||
1433 | } | ||
1444 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, | 1434 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, |
1445 | sd->bridge == BRIDGE_TP6800 ? 0x80 : 0x81); | 1435 | sd->bridge == BRIDGE_TP6800 ? 0x80 : 0x81); |
1446 | return; | 1436 | return; |
@@ -1448,10 +1438,10 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
1448 | 1438 | ||
1449 | /* soi763a */ | 1439 | /* soi763a */ |
1450 | i2c_w(gspca_dev, 0x10, /* AEC_H (exposure time) */ | 1440 | i2c_w(gspca_dev, 0x10, /* AEC_H (exposure time) */ |
1451 | sd->ctrls[EXPOSURE].val); | 1441 | expo); |
1452 | /* i2c_w(gspca_dev, 0x76, 0x02); * AEC_L ([1:0] */ | 1442 | /* i2c_w(gspca_dev, 0x76, 0x02); * AEC_L ([1:0] */ |
1453 | i2c_w(gspca_dev, 0x00, /* gain */ | 1443 | i2c_w(gspca_dev, 0x00, /* gain */ |
1454 | sd->ctrls[GAIN].val); | 1444 | gain); |
1455 | } | 1445 | } |
1456 | 1446 | ||
1457 | /* set the JPEG quantization tables */ | 1447 | /* set the JPEG quantization tables */ |
@@ -1472,12 +1462,10 @@ static void set_dqt(struct gspca_dev *gspca_dev, u8 q) | |||
1472 | } | 1462 | } |
1473 | 1463 | ||
1474 | /* set the JPEG compression quality factor */ | 1464 | /* set the JPEG compression quality factor */ |
1475 | static void setquality(struct gspca_dev *gspca_dev) | 1465 | static void setquality(struct gspca_dev *gspca_dev, s32 q) |
1476 | { | 1466 | { |
1477 | struct sd *sd = (struct sd *) gspca_dev; | 1467 | struct sd *sd = (struct sd *) gspca_dev; |
1478 | u16 q; | ||
1479 | 1468 | ||
1480 | q = sd->ctrls[QUALITY].val; | ||
1481 | if (q != 16) | 1469 | if (q != 16) |
1482 | q = 15 - q; | 1470 | q = 15 - q; |
1483 | 1471 | ||
@@ -1508,10 +1496,9 @@ static const u8 color_gain[NSENSORS][18] = { | |||
1508 | 0xd5, 0x00, 0x46, 0x03, 0xdc, 0x03}, /* V R/G/B */ | 1496 | 0xd5, 0x00, 0x46, 0x03, 0xdc, 0x03}, /* V R/G/B */ |
1509 | }; | 1497 | }; |
1510 | 1498 | ||
1511 | static void setgamma(struct gspca_dev *gspca_dev) | 1499 | static void setgamma(struct gspca_dev *gspca_dev, s32 gamma) |
1512 | { | 1500 | { |
1513 | struct sd *sd = (struct sd *) gspca_dev; | 1501 | struct sd *sd = (struct sd *) gspca_dev; |
1514 | int gamma; | ||
1515 | #define NGAMMA 6 | 1502 | #define NGAMMA 6 |
1516 | static const u8 gamma_tb[NGAMMA][3][1024] = { | 1503 | static const u8 gamma_tb[NGAMMA][3][1024] = { |
1517 | { /* gamma 0 - from tp6800 + soi763a */ | 1504 | { /* gamma 0 - from tp6800 + soi763a */ |
@@ -3836,7 +3823,6 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
3836 | if (sd->bridge == BRIDGE_TP6810) | 3823 | if (sd->bridge == BRIDGE_TP6810) |
3837 | reg_w(gspca_dev, 0x02, 0x28); | 3824 | reg_w(gspca_dev, 0x02, 0x28); |
3838 | /* msleep(50); */ | 3825 | /* msleep(50); */ |
3839 | gamma = sd->ctrls[GAMMA].val; | ||
3840 | bulk_w(gspca_dev, 0x00, gamma_tb[gamma][0], 1024); | 3826 | bulk_w(gspca_dev, 0x00, gamma_tb[gamma][0], 1024); |
3841 | bulk_w(gspca_dev, 0x01, gamma_tb[gamma][1], 1024); | 3827 | bulk_w(gspca_dev, 0x01, gamma_tb[gamma][1], 1024); |
3842 | bulk_w(gspca_dev, 0x02, gamma_tb[gamma][2], 1024); | 3828 | bulk_w(gspca_dev, 0x02, gamma_tb[gamma][2], 1024); |
@@ -3864,43 +3850,35 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
3864 | /* msleep(50); */ | 3850 | /* msleep(50); */ |
3865 | } | 3851 | } |
3866 | 3852 | ||
3867 | static void setsharpness(struct gspca_dev *gspca_dev) | 3853 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
3868 | { | 3854 | { |
3869 | struct sd *sd = (struct sd *) gspca_dev; | 3855 | struct sd *sd = (struct sd *) gspca_dev; |
3870 | u8 val; | ||
3871 | 3856 | ||
3872 | if (sd->bridge == BRIDGE_TP6800) { | 3857 | if (sd->bridge == BRIDGE_TP6800) { |
3873 | val = sd->ctrls[SHARPNESS].val | 3858 | val |= 0x08; /* grid compensation enable */ |
3874 | | 0x08; /* grid compensation enable */ | ||
3875 | if (gspca_dev->width == 640) | 3859 | if (gspca_dev->width == 640) |
3876 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ | 3860 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ |
3877 | else | 3861 | else |
3878 | val |= 0x04; /* scaling down enable */ | 3862 | val |= 0x04; /* scaling down enable */ |
3879 | reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, val); | 3863 | reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, val); |
3880 | } else { | 3864 | } else { |
3881 | val = (sd->ctrls[SHARPNESS].val << 5) | 0x08; | 3865 | val = (val << 5) | 0x08; |
3882 | reg_w(gspca_dev, 0x59, val); | 3866 | reg_w(gspca_dev, 0x59, val); |
3883 | } | 3867 | } |
3884 | } | 3868 | } |
3885 | 3869 | ||
3886 | static void setautogain(struct gspca_dev *gspca_dev) | 3870 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
3887 | { | 3871 | { |
3888 | struct sd *sd = (struct sd *) gspca_dev; | 3872 | struct sd *sd = (struct sd *) gspca_dev; |
3889 | 3873 | ||
3890 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) | 3874 | sd->ag_cnt = val ? AG_CNT_START : -1; |
3891 | return; | ||
3892 | if (sd->ctrls[AUTOGAIN].val) { | ||
3893 | sd->ag_cnt = AG_CNT_START; | ||
3894 | gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); | ||
3895 | } else { | ||
3896 | sd->ag_cnt = -1; | ||
3897 | gspca_dev->ctrl_inac &= ~((1 << EXPOSURE) | (1 << GAIN)); | ||
3898 | } | ||
3899 | } | 3875 | } |
3900 | 3876 | ||
3901 | /* set the resolution for sensor cx0342 */ | 3877 | /* set the resolution for sensor cx0342 */ |
3902 | static void set_resolution(struct gspca_dev *gspca_dev) | 3878 | static void set_resolution(struct gspca_dev *gspca_dev) |
3903 | { | 3879 | { |
3880 | struct sd *sd = (struct sd *) gspca_dev; | ||
3881 | |||
3904 | reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); | 3882 | reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); |
3905 | if (gspca_dev->width == 320) { | 3883 | if (gspca_dev->width == 320) { |
3906 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x06); | 3884 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x06); |
@@ -3926,8 +3904,9 @@ static void set_resolution(struct gspca_dev *gspca_dev) | |||
3926 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01); | 3904 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01); |
3927 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342], | 3905 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342], |
3928 | ARRAY_SIZE(color_gain[0])); | 3906 | ARRAY_SIZE(color_gain[0])); |
3929 | setgamma(gspca_dev); | 3907 | setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); |
3930 | setquality(gspca_dev); | 3908 | if (sd->sensor == SENSOR_SOI763A) |
3909 | setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); | ||
3931 | } | 3910 | } |
3932 | 3911 | ||
3933 | /* convert the frame rate to a tp68x0 value */ | 3912 | /* convert the frame rate to a tp68x0 value */ |
@@ -3963,7 +3942,7 @@ static int get_fr_idx(struct gspca_dev *gspca_dev) | |||
3963 | return i; | 3942 | return i; |
3964 | } | 3943 | } |
3965 | 3944 | ||
3966 | static void setframerate(struct gspca_dev *gspca_dev) | 3945 | static void setframerate(struct gspca_dev *gspca_dev, s32 val) |
3967 | { | 3946 | { |
3968 | struct sd *sd = (struct sd *) gspca_dev; | 3947 | struct sd *sd = (struct sd *) gspca_dev; |
3969 | u8 fr_idx; | 3948 | u8 fr_idx; |
@@ -3974,7 +3953,7 @@ static void setframerate(struct gspca_dev *gspca_dev) | |||
3974 | reg_r(gspca_dev, 0x7b); | 3953 | reg_r(gspca_dev, 0x7b); |
3975 | reg_w(gspca_dev, 0x7b, | 3954 | reg_w(gspca_dev, 0x7b, |
3976 | sd->sensor == SENSOR_CX0342 ? 0x10 : 0x90); | 3955 | sd->sensor == SENSOR_CX0342 ? 0x10 : 0x90); |
3977 | if (sd->ctrls[EXPOSURE].val >= 128) | 3956 | if (val >= 128) |
3978 | fr_idx = 0xf0; /* lower frame rate */ | 3957 | fr_idx = 0xf0; /* lower frame rate */ |
3979 | } | 3958 | } |
3980 | 3959 | ||
@@ -3984,43 +3963,43 @@ static void setframerate(struct gspca_dev *gspca_dev) | |||
3984 | i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); | 3963 | i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); |
3985 | } | 3964 | } |
3986 | 3965 | ||
3987 | static void setrgain(struct gspca_dev *gspca_dev) | 3966 | static void setrgain(struct gspca_dev *gspca_dev, s32 rgain) |
3988 | { | 3967 | { |
3989 | struct sd *sd = (struct sd *) gspca_dev; | ||
3990 | int rgain; | ||
3991 | |||
3992 | rgain = sd->ctrls[RGAIN].val; | ||
3993 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, rgain >> 8); | 3968 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, rgain >> 8); |
3994 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, rgain); | 3969 | i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, rgain); |
3995 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80); | 3970 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80); |
3996 | } | 3971 | } |
3997 | 3972 | ||
3998 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 3973 | static int sd_setgain(struct gspca_dev *gspca_dev) |
3999 | { | 3974 | { |
4000 | struct sd *sd = (struct sd *) gspca_dev; | 3975 | struct sd *sd = (struct sd *) gspca_dev; |
3976 | s32 val = gspca_dev->gain->val; | ||
4001 | 3977 | ||
4002 | if (sd->sensor == SENSOR_CX0342) { | 3978 | if (sd->sensor == SENSOR_CX0342) { |
4003 | sd->ctrls[BGAIN].val = sd->ctrls[BGAIN].val | 3979 | s32 old = gspca_dev->gain->cur.val ? |
4004 | * val / sd->ctrls[GAIN].val; | 3980 | gspca_dev->gain->cur.val : 1; |
4005 | if (sd->ctrls[BGAIN].val > 4095) | 3981 | |
4006 | sd->ctrls[BGAIN].val = 4095; | 3982 | sd->blue->val = sd->blue->val * val / old; |
4007 | sd->ctrls[RGAIN].val = sd->ctrls[RGAIN].val | 3983 | if (sd->blue->val > 4095) |
4008 | * val / sd->ctrls[GAIN].val; | 3984 | sd->blue->val = 4095; |
4009 | if (sd->ctrls[RGAIN].val > 4095) | 3985 | sd->red->val = sd->red->val * val / old; |
4010 | sd->ctrls[RGAIN].val = 4095; | 3986 | if (sd->red->val > 4095) |
3987 | sd->red->val = 4095; | ||
3988 | } | ||
3989 | if (gspca_dev->streaming) { | ||
3990 | if (sd->sensor == SENSOR_CX0342) | ||
3991 | setexposure(gspca_dev, gspca_dev->exposure->val, | ||
3992 | gspca_dev->gain->val, | ||
3993 | sd->blue->val, sd->red->val); | ||
3994 | else | ||
3995 | setexposure(gspca_dev, gspca_dev->exposure->val, | ||
3996 | gspca_dev->gain->val, 0, 0); | ||
4011 | } | 3997 | } |
4012 | sd->ctrls[GAIN].val = val; | ||
4013 | if (gspca_dev->streaming) | ||
4014 | setexposure(gspca_dev); | ||
4015 | return gspca_dev->usb_err; | 3998 | return gspca_dev->usb_err; |
4016 | } | 3999 | } |
4017 | 4000 | ||
4018 | static void setbgain(struct gspca_dev *gspca_dev) | 4001 | static void setbgain(struct gspca_dev *gspca_dev, s32 bgain) |
4019 | { | 4002 | { |
4020 | struct sd *sd = (struct sd *) gspca_dev; | ||
4021 | int bgain; | ||
4022 | |||
4023 | bgain = sd->ctrls[BGAIN].val; | ||
4024 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, bgain >> 8); | 4003 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, bgain >> 8); |
4025 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, bgain); | 4004 | i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, bgain); |
4026 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80); | 4005 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80); |
@@ -4040,7 +4019,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
4040 | framerates : framerates_6810; | 4019 | framerates : framerates_6810; |
4041 | 4020 | ||
4042 | sd->framerate = 30; /* default: 30 fps */ | 4021 | sd->framerate = 30; /* default: 30 fps */ |
4043 | gspca_dev->cam.ctrls = sd->ctrls; | ||
4044 | return 0; | 4022 | return 0; |
4045 | } | 4023 | } |
4046 | 4024 | ||
@@ -4108,32 +4086,16 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
4108 | } | 4086 | } |
4109 | if (sd->sensor == SENSOR_SOI763A) { | 4087 | if (sd->sensor == SENSOR_SOI763A) { |
4110 | pr_info("Sensor soi763a\n"); | 4088 | pr_info("Sensor soi763a\n"); |
4111 | sd->ctrls[GAMMA].def = sd->bridge == BRIDGE_TP6800 ? 0 : 1; | ||
4112 | sd->ctrls[GAIN].max = 15; | ||
4113 | sd->ctrls[GAIN].def = 3; | ||
4114 | gspca_dev->ctrl_dis = (1 << RGAIN) | (1 << BGAIN); | ||
4115 | if (sd->bridge == BRIDGE_TP6810) { | 4089 | if (sd->bridge == BRIDGE_TP6810) { |
4116 | soi763a_6810_init(gspca_dev); | 4090 | soi763a_6810_init(gspca_dev); |
4117 | #if AUTOGAIN_DEF | ||
4118 | gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); | ||
4119 | #endif | ||
4120 | } else { | ||
4121 | gspca_dev->ctrl_dis |= (1 << AUTOGAIN); | ||
4122 | } | 4091 | } |
4123 | } else { | 4092 | } else { |
4124 | pr_info("Sensor cx0342\n"); | 4093 | pr_info("Sensor cx0342\n"); |
4125 | if (sd->bridge == BRIDGE_TP6810) { | 4094 | if (sd->bridge == BRIDGE_TP6810) { |
4126 | cx0342_6810_init(gspca_dev); | 4095 | cx0342_6810_init(gspca_dev); |
4127 | #if AUTOGAIN_DEF | ||
4128 | gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); | ||
4129 | #endif | ||
4130 | } else { | ||
4131 | gspca_dev->ctrl_dis |= (1 << AUTOGAIN); | ||
4132 | } | 4096 | } |
4133 | } | 4097 | } |
4134 | 4098 | ||
4135 | if (sd->bridge == BRIDGE_TP6810) | ||
4136 | sd->ctrls[QUALITY].def = 0; /* auto quality */ | ||
4137 | set_dqt(gspca_dev, 0); | 4099 | set_dqt(gspca_dev, 0); |
4138 | return 0; | 4100 | return 0; |
4139 | } | 4101 | } |
@@ -4207,8 +4169,9 @@ static void set_led(struct gspca_dev *gspca_dev, int on) | |||
4207 | 4169 | ||
4208 | static void cx0342_6800_start(struct gspca_dev *gspca_dev) | 4170 | static void cx0342_6800_start(struct gspca_dev *gspca_dev) |
4209 | { | 4171 | { |
4172 | struct sd *sd = (struct sd *) gspca_dev; | ||
4210 | static const struct cmd reg_init[] = { | 4173 | static const struct cmd reg_init[] = { |
4211 | /*fixme: is this usefull?*/ | 4174 | /* fixme: is this useful? */ |
4212 | {TP6800_R17_GPIO_IO, 0x9f}, | 4175 | {TP6800_R17_GPIO_IO, 0x9f}, |
4213 | {TP6800_R16_GPIO_PD, 0x40}, | 4176 | {TP6800_R16_GPIO_PD, 0x40}, |
4214 | {TP6800_R10_SIF_TYPE, 0x00}, /* i2c 8 bits */ | 4177 | {TP6800_R10_SIF_TYPE, 0x00}, /* i2c 8 bits */ |
@@ -4279,13 +4242,21 @@ static void cx0342_6800_start(struct gspca_dev *gspca_dev) | |||
4279 | reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00); | 4242 | reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00); |
4280 | i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x00); | 4243 | i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x00); |
4281 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01); | 4244 | i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01); |
4282 | setexposure(gspca_dev); | 4245 | if (sd->sensor == SENSOR_CX0342) |
4246 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4247 | v4l2_ctrl_g_ctrl(gspca_dev->gain), | ||
4248 | v4l2_ctrl_g_ctrl(sd->blue), | ||
4249 | v4l2_ctrl_g_ctrl(sd->red)); | ||
4250 | else | ||
4251 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4252 | v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); | ||
4283 | set_led(gspca_dev, 1); | 4253 | set_led(gspca_dev, 1); |
4284 | set_resolution(gspca_dev); | 4254 | set_resolution(gspca_dev); |
4285 | } | 4255 | } |
4286 | 4256 | ||
4287 | static void cx0342_6810_start(struct gspca_dev *gspca_dev) | 4257 | static void cx0342_6810_start(struct gspca_dev *gspca_dev) |
4288 | { | 4258 | { |
4259 | struct sd *sd = (struct sd *) gspca_dev; | ||
4289 | static const struct cmd sensor_init_2[] = { | 4260 | static const struct cmd sensor_init_2[] = { |
4290 | {CX0342_EXPO_LINE_L, 0x6f}, | 4261 | {CX0342_EXPO_LINE_L, 0x6f}, |
4291 | {CX0342_EXPO_LINE_H, 0x02}, | 4262 | {CX0342_EXPO_LINE_H, 0x02}, |
@@ -4366,10 +4337,10 @@ static void cx0342_6810_start(struct gspca_dev *gspca_dev) | |||
4366 | reg_w(gspca_dev, 0x07, 0x85); | 4337 | reg_w(gspca_dev, 0x07, 0x85); |
4367 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ | 4338 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ |
4368 | } | 4339 | } |
4369 | setgamma(gspca_dev); | 4340 | setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); |
4370 | reg_w_buf(gspca_dev, tp6810_bridge_start, | 4341 | reg_w_buf(gspca_dev, tp6810_bridge_start, |
4371 | ARRAY_SIZE(tp6810_bridge_start)); | 4342 | ARRAY_SIZE(tp6810_bridge_start)); |
4372 | setsharpness(gspca_dev); | 4343 | setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); |
4373 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342], | 4344 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342], |
4374 | ARRAY_SIZE(color_gain[0])); | 4345 | ARRAY_SIZE(color_gain[0])); |
4375 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x87); | 4346 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x87); |
@@ -4380,11 +4351,12 @@ static void cx0342_6810_start(struct gspca_dev *gspca_dev) | |||
4380 | i2c_w_buf(gspca_dev, sensor_init_5, ARRAY_SIZE(sensor_init_5)); | 4351 | i2c_w_buf(gspca_dev, sensor_init_5, ARRAY_SIZE(sensor_init_5)); |
4381 | 4352 | ||
4382 | set_led(gspca_dev, 1); | 4353 | set_led(gspca_dev, 1); |
4383 | /* setquality(gspca_dev); */ | 4354 | /* setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); */ |
4384 | } | 4355 | } |
4385 | 4356 | ||
4386 | static void soi763a_6800_start(struct gspca_dev *gspca_dev) | 4357 | static void soi763a_6800_start(struct gspca_dev *gspca_dev) |
4387 | { | 4358 | { |
4359 | struct sd *sd = (struct sd *) gspca_dev; | ||
4388 | static const struct cmd reg_init[] = { | 4360 | static const struct cmd reg_init[] = { |
4389 | {TP6800_R79_QUALITY, 0x04}, | 4361 | {TP6800_R79_QUALITY, 0x04}, |
4390 | {TP6800_R79_QUALITY, 0x01}, | 4362 | {TP6800_R79_QUALITY, 0x01}, |
@@ -4484,19 +4456,28 @@ static void soi763a_6800_start(struct gspca_dev *gspca_dev) | |||
4484 | reg_w(gspca_dev, TP6800_R5C_EDGE_THRLD, 0x10); | 4456 | reg_w(gspca_dev, TP6800_R5C_EDGE_THRLD, 0x10); |
4485 | reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00); | 4457 | reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00); |
4486 | 4458 | ||
4487 | setsharpness(gspca_dev); | 4459 | setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); |
4488 | 4460 | ||
4489 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A], | 4461 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A], |
4490 | ARRAY_SIZE(color_gain[0])); | 4462 | ARRAY_SIZE(color_gain[0])); |
4491 | 4463 | ||
4492 | set_led(gspca_dev, 1); | 4464 | set_led(gspca_dev, 1); |
4493 | setexposure(gspca_dev); | 4465 | if (sd->sensor == SENSOR_CX0342) |
4494 | setquality(gspca_dev); | 4466 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), |
4495 | setgamma(gspca_dev); | 4467 | v4l2_ctrl_g_ctrl(gspca_dev->gain), |
4468 | v4l2_ctrl_g_ctrl(sd->blue), | ||
4469 | v4l2_ctrl_g_ctrl(sd->red)); | ||
4470 | else | ||
4471 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4472 | v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); | ||
4473 | if (sd->sensor == SENSOR_SOI763A) | ||
4474 | setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); | ||
4475 | setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); | ||
4496 | } | 4476 | } |
4497 | 4477 | ||
4498 | static void soi763a_6810_start(struct gspca_dev *gspca_dev) | 4478 | static void soi763a_6810_start(struct gspca_dev *gspca_dev) |
4499 | { | 4479 | { |
4480 | struct sd *sd = (struct sd *) gspca_dev; | ||
4500 | static const struct cmd bridge_init_2[] = { | 4481 | static const struct cmd bridge_init_2[] = { |
4501 | {TP6800_R7A_BLK_THRLD, 0x00}, | 4482 | {TP6800_R7A_BLK_THRLD, 0x00}, |
4502 | {TP6800_R79_QUALITY, 0x04}, | 4483 | {TP6800_R79_QUALITY, 0x04}, |
@@ -4520,7 +4501,14 @@ static void soi763a_6810_start(struct gspca_dev *gspca_dev) | |||
4520 | reg_w(gspca_dev, 0x22, gspca_dev->alt); | 4501 | reg_w(gspca_dev, 0x22, gspca_dev->alt); |
4521 | bulk_w(gspca_dev, 0x03, color_null, sizeof color_null); | 4502 | bulk_w(gspca_dev, 0x03, color_null, sizeof color_null); |
4522 | reg_w(gspca_dev, 0x59, 0x40); | 4503 | reg_w(gspca_dev, 0x59, 0x40); |
4523 | setexposure(gspca_dev); | 4504 | if (sd->sensor == SENSOR_CX0342) |
4505 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4506 | v4l2_ctrl_g_ctrl(gspca_dev->gain), | ||
4507 | v4l2_ctrl_g_ctrl(sd->blue), | ||
4508 | v4l2_ctrl_g_ctrl(sd->red)); | ||
4509 | else | ||
4510 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4511 | v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); | ||
4524 | reg_w_buf(gspca_dev, bridge_init_2, ARRAY_SIZE(bridge_init_2)); | 4512 | reg_w_buf(gspca_dev, bridge_init_2, ARRAY_SIZE(bridge_init_2)); |
4525 | reg_w_buf(gspca_dev, tp6810_ov_init_common, | 4513 | reg_w_buf(gspca_dev, tp6810_ov_init_common, |
4526 | ARRAY_SIZE(tp6810_ov_init_common)); | 4514 | ARRAY_SIZE(tp6810_ov_init_common)); |
@@ -4534,7 +4522,7 @@ static void soi763a_6810_start(struct gspca_dev *gspca_dev) | |||
4534 | reg_w(gspca_dev, 0x07, 0x85); | 4522 | reg_w(gspca_dev, 0x07, 0x85); |
4535 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ | 4523 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ |
4536 | } | 4524 | } |
4537 | setgamma(gspca_dev); | 4525 | setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); |
4538 | reg_w_buf(gspca_dev, tp6810_bridge_start, | 4526 | reg_w_buf(gspca_dev, tp6810_bridge_start, |
4539 | ARRAY_SIZE(tp6810_bridge_start)); | 4527 | ARRAY_SIZE(tp6810_bridge_start)); |
4540 | 4528 | ||
@@ -4545,12 +4533,19 @@ static void soi763a_6810_start(struct gspca_dev *gspca_dev) | |||
4545 | 4533 | ||
4546 | reg_w(gspca_dev, 0x00, 0x00); | 4534 | reg_w(gspca_dev, 0x00, 0x00); |
4547 | 4535 | ||
4548 | setsharpness(gspca_dev); | 4536 | setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); |
4549 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A], | 4537 | bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A], |
4550 | ARRAY_SIZE(color_gain[0])); | 4538 | ARRAY_SIZE(color_gain[0])); |
4551 | set_led(gspca_dev, 1); | 4539 | set_led(gspca_dev, 1); |
4552 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0xf0); | 4540 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0xf0); |
4553 | setexposure(gspca_dev); | 4541 | if (sd->sensor == SENSOR_CX0342) |
4542 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4543 | v4l2_ctrl_g_ctrl(gspca_dev->gain), | ||
4544 | v4l2_ctrl_g_ctrl(sd->blue), | ||
4545 | v4l2_ctrl_g_ctrl(sd->red)); | ||
4546 | else | ||
4547 | setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4548 | v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); | ||
4554 | reg_w_buf(gspca_dev, bridge_init_6, ARRAY_SIZE(bridge_init_6)); | 4549 | reg_w_buf(gspca_dev, bridge_init_6, ARRAY_SIZE(bridge_init_6)); |
4555 | } | 4550 | } |
4556 | 4551 | ||
@@ -4576,12 +4571,25 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
4576 | reg_w(gspca_dev, 0x80, 0x03); | 4571 | reg_w(gspca_dev, 0x80, 0x03); |
4577 | reg_w(gspca_dev, 0x82, gspca_dev->curr_mode ? 0x0a : 0x0e); | 4572 | reg_w(gspca_dev, 0x82, gspca_dev->curr_mode ? 0x0a : 0x0e); |
4578 | 4573 | ||
4579 | setexposure(gspca_dev); | 4574 | if (sd->sensor == SENSOR_CX0342) |
4580 | setquality(gspca_dev); | 4575 | setexposure(gspca_dev, |
4581 | setautogain(gspca_dev); | 4576 | v4l2_ctrl_g_ctrl(gspca_dev->exposure), |
4577 | v4l2_ctrl_g_ctrl(gspca_dev->gain), | ||
4578 | v4l2_ctrl_g_ctrl(sd->blue), | ||
4579 | v4l2_ctrl_g_ctrl(sd->red)); | ||
4580 | else | ||
4581 | setexposure(gspca_dev, | ||
4582 | v4l2_ctrl_g_ctrl(gspca_dev->exposure), | ||
4583 | v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); | ||
4584 | if (sd->sensor == SENSOR_SOI763A) | ||
4585 | setquality(gspca_dev, | ||
4586 | v4l2_ctrl_g_ctrl(sd->jpegqual)); | ||
4587 | if (sd->bridge == BRIDGE_TP6810) | ||
4588 | setautogain(gspca_dev, | ||
4589 | v4l2_ctrl_g_ctrl(gspca_dev->autogain)); | ||
4582 | } | 4590 | } |
4583 | 4591 | ||
4584 | setframerate(gspca_dev); | 4592 | setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure)); |
4585 | 4593 | ||
4586 | return gspca_dev->usb_err; | 4594 | return gspca_dev->usb_err; |
4587 | } | 4595 | } |
@@ -4672,12 +4680,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
4672 | } | 4680 | } |
4673 | } | 4681 | } |
4674 | 4682 | ||
4675 | /* -- do autogain -- */ | ||
4676 | /* gain setting is done in setexposure() for tp6810 */ | ||
4677 | static void setgain(struct gspca_dev *gspca_dev) {} | ||
4678 | #define WANT_REGULAR_AUTOGAIN | ||
4679 | #include "autogain_functions.h" | ||
4680 | |||
4681 | static void sd_dq_callback(struct gspca_dev *gspca_dev) | 4683 | static void sd_dq_callback(struct gspca_dev *gspca_dev) |
4682 | { | 4684 | { |
4683 | struct sd *sd = (struct sd *) gspca_dev; | 4685 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -4739,17 +4741,19 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) | |||
4739 | luma /= 4; | 4741 | luma /= 4; |
4740 | reg_w(gspca_dev, 0x7d, 0x00); | 4742 | reg_w(gspca_dev, 0x7d, 0x00); |
4741 | 4743 | ||
4742 | expo = sd->ctrls[EXPOSURE].val; | 4744 | expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure); |
4743 | ret = auto_gain_n_exposure(gspca_dev, luma, | 4745 | ret = gspca_expo_autogain(gspca_dev, luma, |
4744 | 60, /* desired luma */ | 4746 | 60, /* desired luma */ |
4745 | 6, /* dead zone */ | 4747 | 6, /* dead zone */ |
4746 | 2, /* gain knee */ | 4748 | 2, /* gain knee */ |
4747 | 70); /* expo knee */ | 4749 | 70); /* expo knee */ |
4748 | sd->ag_cnt = AG_CNT_START; | 4750 | sd->ag_cnt = AG_CNT_START; |
4749 | if (sd->bridge == BRIDGE_TP6810) { | 4751 | if (sd->bridge == BRIDGE_TP6810) { |
4750 | if ((expo >= 128 && sd->ctrls[EXPOSURE].val < 128) | 4752 | int new_expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure); |
4751 | || (expo < 128 && sd->ctrls[EXPOSURE].val >= 128)) | 4753 | |
4752 | setframerate(gspca_dev); | 4754 | if ((expo >= 128 && new_expo < 128) |
4755 | || (expo < 128 && new_expo >= 128)) | ||
4756 | setframerate(gspca_dev, new_expo); | ||
4753 | } | 4757 | } |
4754 | break; | 4758 | break; |
4755 | } | 4759 | } |
@@ -4789,7 +4793,7 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev, | |||
4789 | 4793 | ||
4790 | sd->framerate = tpf->denominator / tpf->numerator; | 4794 | sd->framerate = tpf->denominator / tpf->numerator; |
4791 | if (gspca_dev->streaming) | 4795 | if (gspca_dev->streaming) |
4792 | setframerate(gspca_dev); | 4796 | setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure)); |
4793 | 4797 | ||
4794 | /* Return the actual framerate */ | 4798 | /* Return the actual framerate */ |
4795 | i = get_fr_idx(gspca_dev); | 4799 | i = get_fr_idx(gspca_dev); |
@@ -4806,12 +4810,10 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, | |||
4806 | { | 4810 | { |
4807 | struct sd *sd = (struct sd *) gspca_dev; | 4811 | struct sd *sd = (struct sd *) gspca_dev; |
4808 | 4812 | ||
4809 | if (sd->sensor == SENSOR_SOI763A) | 4813 | if (sd->sensor != SENSOR_SOI763A) |
4810 | jpeg_set_qual(sd->jpeg_hdr, jcomp->quality); | 4814 | return -ENOTTY; |
4811 | /* else | 4815 | v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); |
4812 | fixme: TODO | 4816 | return 0; |
4813 | */ | ||
4814 | return gspca_dev->usb_err; | ||
4815 | } | 4817 | } |
4816 | 4818 | ||
4817 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 4819 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, |
@@ -4819,118 +4821,109 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
4819 | { | 4821 | { |
4820 | struct sd *sd = (struct sd *) gspca_dev; | 4822 | struct sd *sd = (struct sd *) gspca_dev; |
4821 | 4823 | ||
4824 | if (sd->sensor != SENSOR_SOI763A) | ||
4825 | return -ENOTTY; | ||
4822 | memset(jcomp, 0, sizeof *jcomp); | 4826 | memset(jcomp, 0, sizeof *jcomp); |
4823 | jcomp->quality = jpeg_q[sd->quality]; | 4827 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); |
4824 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 4828 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT |
4825 | | V4L2_JPEG_MARKER_DQT; | 4829 | | V4L2_JPEG_MARKER_DQT; |
4826 | return 0; | 4830 | return 0; |
4827 | } | 4831 | } |
4828 | 4832 | ||
4829 | static struct ctrl sd_ctrls[NCTRLS] = { | 4833 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
4830 | [EXPOSURE] = { | 4834 | { |
4831 | { | 4835 | struct gspca_dev *gspca_dev = |
4832 | .id = V4L2_CID_EXPOSURE, | 4836 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); |
4833 | .type = V4L2_CTRL_TYPE_INTEGER, | 4837 | struct sd *sd = (struct sd *)gspca_dev; |
4834 | .name = "Exposure", | 4838 | |
4835 | .minimum = 0x01, | 4839 | gspca_dev->usb_err = 0; |
4836 | .maximum = 0xdc, | 4840 | |
4837 | .step = 1, | 4841 | if (!gspca_dev->streaming) |
4838 | .default_value = 0x4e, | 4842 | return 0; |
4839 | }, | 4843 | |
4840 | .set_control = setexposure | 4844 | switch (ctrl->id) { |
4841 | }, | 4845 | case V4L2_CID_SHARPNESS: |
4842 | [QUALITY] = { | 4846 | setsharpness(gspca_dev, ctrl->val); |
4843 | { | 4847 | break; |
4844 | .id = V4L2_CID_PRIVATE_BASE, | 4848 | case V4L2_CID_GAMMA: |
4845 | .type = V4L2_CTRL_TYPE_INTEGER, | 4849 | setgamma(gspca_dev, ctrl->val); |
4846 | .name = "Compression quality", | 4850 | break; |
4847 | .minimum = 0, | 4851 | case V4L2_CID_BLUE_BALANCE: |
4848 | .maximum = 15, | 4852 | setbgain(gspca_dev, ctrl->val); |
4849 | .step = 1, | 4853 | break; |
4850 | .default_value = 13, | 4854 | case V4L2_CID_RED_BALANCE: |
4851 | }, | 4855 | setrgain(gspca_dev, ctrl->val); |
4852 | .set_control = setquality | 4856 | break; |
4853 | }, | 4857 | case V4L2_CID_EXPOSURE: |
4854 | [RGAIN] = { | 4858 | sd_setgain(gspca_dev); |
4855 | { | 4859 | break; |
4856 | .id = V4L2_CID_RED_BALANCE, | 4860 | case V4L2_CID_AUTOGAIN: |
4857 | .type = V4L2_CTRL_TYPE_INTEGER, | 4861 | if (ctrl->val) |
4858 | .name = "Red balance", | 4862 | break; |
4859 | .minimum = 0, | 4863 | sd_setgain(gspca_dev); |
4860 | .maximum = 4095, | 4864 | break; |
4861 | .step = 1, | 4865 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: |
4862 | .default_value = 256, | 4866 | jpeg_set_qual(sd->jpeg_hdr, ctrl->val); |
4863 | }, | 4867 | break; |
4864 | .set_control = setrgain | 4868 | } |
4865 | }, | 4869 | return gspca_dev->usb_err; |
4866 | [GAIN] = { | 4870 | } |
4867 | { | 4871 | |
4868 | .id = V4L2_CID_GAIN, | 4872 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
4869 | .type = V4L2_CTRL_TYPE_INTEGER, | 4873 | .s_ctrl = sd_s_ctrl, |
4870 | .name = "Gain", | ||
4871 | .minimum = 0, | ||
4872 | .maximum = 4095, | ||
4873 | .step = 1, | ||
4874 | .default_value = 256, | ||
4875 | }, | ||
4876 | .set = sd_setgain | ||
4877 | }, | ||
4878 | [BGAIN] = { | ||
4879 | { | ||
4880 | .id = V4L2_CID_BLUE_BALANCE, | ||
4881 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
4882 | .name = "Blue balance", | ||
4883 | .minimum = 0, | ||
4884 | .maximum = 4095, | ||
4885 | .step = 1, | ||
4886 | .default_value = 256, | ||
4887 | }, | ||
4888 | .set_control = setbgain | ||
4889 | }, | ||
4890 | [SHARPNESS] = { | ||
4891 | { | ||
4892 | .id = V4L2_CID_SHARPNESS, | ||
4893 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
4894 | .name = "Sharpness", | ||
4895 | .minimum = 0, | ||
4896 | .maximum = 3, | ||
4897 | .step = 1, | ||
4898 | .default_value = 2, | ||
4899 | }, | ||
4900 | .set_control = setsharpness | ||
4901 | }, | ||
4902 | [GAMMA] = { | ||
4903 | { | ||
4904 | .id = V4L2_CID_GAMMA, | ||
4905 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
4906 | .name = "Gamma", | ||
4907 | .minimum = 0, | ||
4908 | .maximum = NGAMMA - 1, | ||
4909 | .step = 1, | ||
4910 | .default_value = 1, | ||
4911 | }, | ||
4912 | .set_control = setgamma | ||
4913 | }, | ||
4914 | [AUTOGAIN] = { | ||
4915 | { | ||
4916 | .id = V4L2_CID_AUTOGAIN, | ||
4917 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
4918 | .name = "Auto Gain", | ||
4919 | .minimum = 0, | ||
4920 | .maximum = 1, | ||
4921 | .step = 1, | ||
4922 | .default_value = AUTOGAIN_DEF | ||
4923 | }, | ||
4924 | .set_control = setautogain | ||
4925 | }, | ||
4926 | }; | 4874 | }; |
4927 | 4875 | ||
4876 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
4877 | { | ||
4878 | struct sd *sd = (struct sd *)gspca_dev; | ||
4879 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
4880 | |||
4881 | gspca_dev->vdev.ctrl_handler = hdl; | ||
4882 | v4l2_ctrl_handler_init(hdl, 4); | ||
4883 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4884 | V4L2_CID_EXPOSURE, 1, 0xdc, 1, 0x4e); | ||
4885 | if (sd->sensor == SENSOR_CX0342) { | ||
4886 | sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4887 | V4L2_CID_RED_BALANCE, 0, 4095, 1, 256); | ||
4888 | sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4889 | V4L2_CID_BLUE_BALANCE, 0, 4095, 1, 256); | ||
4890 | } | ||
4891 | if (sd->sensor == SENSOR_SOI763A) | ||
4892 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4893 | V4L2_CID_GAIN, 0, 15, 1, 3); | ||
4894 | else | ||
4895 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4896 | V4L2_CID_GAIN, 0, 4095, 1, 256); | ||
4897 | sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4898 | V4L2_CID_SHARPNESS, 0, 3, 1, 2); | ||
4899 | sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4900 | V4L2_CID_GAMMA, 0, NGAMMA - 1, 1, | ||
4901 | (sd->sensor == SENSOR_SOI763A && | ||
4902 | sd->bridge == BRIDGE_TP6800) ? 0 : 1); | ||
4903 | if (sd->bridge == BRIDGE_TP6810) | ||
4904 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4905 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
4906 | if (sd->sensor == SENSOR_SOI763A) | ||
4907 | sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4908 | V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
4909 | 0, 15, 1, (sd->bridge == BRIDGE_TP6810) ? 0 : 13); | ||
4910 | |||
4911 | if (hdl->error) { | ||
4912 | pr_err("Could not initialize controls\n"); | ||
4913 | return hdl->error; | ||
4914 | } | ||
4915 | if (gspca_dev->autogain) | ||
4916 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); | ||
4917 | else | ||
4918 | v4l2_ctrl_cluster(2, &gspca_dev->exposure); | ||
4919 | return 0; | ||
4920 | } | ||
4921 | |||
4928 | static const struct sd_desc sd_desc = { | 4922 | static const struct sd_desc sd_desc = { |
4929 | .name = KBUILD_MODNAME, | 4923 | .name = KBUILD_MODNAME, |
4930 | .ctrls = sd_ctrls, | ||
4931 | .nctrls = NCTRLS, | ||
4932 | .config = sd_config, | 4924 | .config = sd_config, |
4933 | .init = sd_init, | 4925 | .init = sd_init, |
4926 | .init_controls = sd_init_controls, | ||
4934 | .isoc_init = sd_isoc_init, | 4927 | .isoc_init = sd_isoc_init, |
4935 | .start = sd_start, | 4928 | .start = sd_start, |
4936 | .stopN = sd_stopN, | 4929 | .stopN = sd_stopN, |
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index c8922c5ffbf5..8591324a53e1 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -30,49 +30,9 @@ MODULE_LICENSE("GPL"); | |||
30 | struct sd { | 30 | struct sd { |
31 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 31 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
32 | 32 | ||
33 | __u16 exposure; | ||
34 | __u16 gain; | ||
35 | |||
36 | __u8 packet; | 33 | __u8 packet; |
37 | }; | 34 | }; |
38 | 35 | ||
39 | /* V4L2 controls supported by the driver */ | ||
40 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
41 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
42 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
43 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
44 | |||
45 | static const struct ctrl sd_ctrls[] = { | ||
46 | { | ||
47 | { | ||
48 | .id = V4L2_CID_EXPOSURE, | ||
49 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
50 | .name = "Exposure", | ||
51 | .minimum = 1, | ||
52 | .maximum = 0x18f, | ||
53 | .step = 1, | ||
54 | #define EXPOSURE_DEF 0x18f | ||
55 | .default_value = EXPOSURE_DEF, | ||
56 | }, | ||
57 | .set = sd_setexposure, | ||
58 | .get = sd_getexposure, | ||
59 | }, | ||
60 | { | ||
61 | { | ||
62 | .id = V4L2_CID_GAIN, | ||
63 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
64 | .name = "Gain", | ||
65 | .minimum = 0, | ||
66 | .maximum = 0x7ff, | ||
67 | .step = 1, | ||
68 | #define GAIN_DEF 0x100 | ||
69 | .default_value = GAIN_DEF, | ||
70 | }, | ||
71 | .set = sd_setgain, | ||
72 | .get = sd_getgain, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static const struct v4l2_pix_format sif_mode[] = { | 36 | static const struct v4l2_pix_format sif_mode[] = { |
77 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 37 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
78 | .bytesperline = 176, | 38 | .bytesperline = 176, |
@@ -202,15 +162,12 @@ static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) | |||
202 | static int sd_config(struct gspca_dev *gspca_dev, | 162 | static int sd_config(struct gspca_dev *gspca_dev, |
203 | const struct usb_device_id *id) | 163 | const struct usb_device_id *id) |
204 | { | 164 | { |
205 | struct sd *sd = (struct sd *) gspca_dev; | ||
206 | struct cam *cam; | 165 | struct cam *cam; |
207 | 166 | ||
208 | cam = &gspca_dev->cam; | 167 | cam = &gspca_dev->cam; |
209 | cam->cam_mode = sif_mode; | 168 | cam->cam_mode = sif_mode; |
210 | cam->nmodes = ARRAY_SIZE(sif_mode); | 169 | cam->nmodes = ARRAY_SIZE(sif_mode); |
211 | 170 | ||
212 | sd->exposure = EXPOSURE_DEF; | ||
213 | sd->gain = GAIN_DEF; | ||
214 | return 0; | 171 | return 0; |
215 | } | 172 | } |
216 | 173 | ||
@@ -241,23 +198,19 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
241 | return 0; | 198 | return 0; |
242 | } | 199 | } |
243 | 200 | ||
244 | static void setexposure(struct gspca_dev *gspca_dev) | 201 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
245 | { | 202 | { |
246 | struct sd *sd = (struct sd *) gspca_dev; | 203 | reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, val); |
247 | |||
248 | reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->exposure); | ||
249 | reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); | 204 | reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); |
250 | /* 0x84 */ | 205 | /* 0x84 */ |
251 | } | 206 | } |
252 | 207 | ||
253 | static void setgain(struct gspca_dev *gspca_dev) | 208 | static void setgain(struct gspca_dev *gspca_dev, s32 val) |
254 | { | 209 | { |
255 | struct sd *sd = (struct sd *) gspca_dev; | 210 | reg_w2(gspca_dev, R20_GAIN_G1L, val); |
256 | 211 | reg_w2(gspca_dev, R22_GAIN_RL, val); | |
257 | reg_w2(gspca_dev, R20_GAIN_G1L, sd->gain); | 212 | reg_w2(gspca_dev, R24_GAIN_BL, val); |
258 | reg_w2(gspca_dev, R22_GAIN_RL, sd->gain); | 213 | reg_w2(gspca_dev, R26_GAIN_G2L, val); |
259 | reg_w2(gspca_dev, R24_GAIN_BL, sd->gain); | ||
260 | reg_w2(gspca_dev, R26_GAIN_G2L, sd->gain); | ||
261 | } | 214 | } |
262 | 215 | ||
263 | /* -- start the camera -- */ | 216 | /* -- start the camera -- */ |
@@ -289,9 +242,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
289 | 242 | ||
290 | tv_8532_setReg(gspca_dev); | 243 | tv_8532_setReg(gspca_dev); |
291 | 244 | ||
292 | setexposure(gspca_dev); | ||
293 | setgain(gspca_dev); | ||
294 | |||
295 | /************************************************/ | 245 | /************************************************/ |
296 | reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ | 246 | reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ |
297 | msleep(200); | 247 | msleep(200); |
@@ -339,49 +289,55 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
339 | data + gspca_dev->width + 5, gspca_dev->width); | 289 | data + gspca_dev->width + 5, gspca_dev->width); |
340 | } | 290 | } |
341 | 291 | ||
342 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | 292 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
343 | { | 293 | { |
344 | struct sd *sd = (struct sd *) gspca_dev; | 294 | struct gspca_dev *gspca_dev = |
295 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
345 | 296 | ||
346 | sd->exposure = val; | 297 | gspca_dev->usb_err = 0; |
347 | if (gspca_dev->streaming) | ||
348 | setexposure(gspca_dev); | ||
349 | return 0; | ||
350 | } | ||
351 | 298 | ||
352 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | 299 | if (!gspca_dev->streaming) |
353 | { | 300 | return 0; |
354 | struct sd *sd = (struct sd *) gspca_dev; | ||
355 | 301 | ||
356 | *val = sd->exposure; | 302 | switch (ctrl->id) { |
357 | return 0; | 303 | case V4L2_CID_EXPOSURE: |
304 | setexposure(gspca_dev, ctrl->val); | ||
305 | break; | ||
306 | case V4L2_CID_GAIN: | ||
307 | setgain(gspca_dev, ctrl->val); | ||
308 | break; | ||
309 | } | ||
310 | return gspca_dev->usb_err; | ||
358 | } | 311 | } |
359 | 312 | ||
360 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 313 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
361 | { | 314 | .s_ctrl = sd_s_ctrl, |
362 | struct sd *sd = (struct sd *) gspca_dev; | 315 | }; |
363 | |||
364 | sd->gain = val; | ||
365 | if (gspca_dev->streaming) | ||
366 | setgain(gspca_dev); | ||
367 | return 0; | ||
368 | } | ||
369 | 316 | ||
370 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | 317 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
371 | { | 318 | { |
372 | struct sd *sd = (struct sd *) gspca_dev; | 319 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; |
373 | 320 | ||
374 | *val = sd->gain; | 321 | gspca_dev->vdev.ctrl_handler = hdl; |
322 | v4l2_ctrl_handler_init(hdl, 2); | ||
323 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
324 | V4L2_CID_EXPOSURE, 0, 0x18f, 1, 0x18f); | ||
325 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
326 | V4L2_CID_GAIN, 0, 0x7ff, 1, 0x100); | ||
327 | |||
328 | if (hdl->error) { | ||
329 | pr_err("Could not initialize controls\n"); | ||
330 | return hdl->error; | ||
331 | } | ||
375 | return 0; | 332 | return 0; |
376 | } | 333 | } |
377 | 334 | ||
378 | /* sub-driver description */ | 335 | /* sub-driver description */ |
379 | static const struct sd_desc sd_desc = { | 336 | static const struct sd_desc sd_desc = { |
380 | .name = MODULE_NAME, | 337 | .name = MODULE_NAME, |
381 | .ctrls = sd_ctrls, | ||
382 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
383 | .config = sd_config, | 338 | .config = sd_config, |
384 | .init = sd_init, | 339 | .init = sd_init, |
340 | .init_controls = sd_init_controls, | ||
385 | .start = sd_start, | 341 | .start = sd_start, |
386 | .stopN = sd_stopN, | 342 | .stopN = sd_stopN, |
387 | .pkt_scan = sd_pkt_scan, | 343 | .pkt_scan = sd_pkt_scan, |
@@ -415,6 +371,7 @@ static struct usb_driver sd_driver = { | |||
415 | #ifdef CONFIG_PM | 371 | #ifdef CONFIG_PM |
416 | .suspend = gspca_suspend, | 372 | .suspend = gspca_suspend, |
417 | .resume = gspca_resume, | 373 | .resume = gspca_resume, |
374 | .reset_resume = gspca_resume, | ||
418 | #endif | 375 | #endif |
419 | }; | 376 | }; |
420 | 377 | ||
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 208f6b2d512a..f21fd1677c38 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -33,18 +33,10 @@ MODULE_LICENSE("GPL"); | |||
33 | /* specific webcam descriptor */ | 33 | /* specific webcam descriptor */ |
34 | struct sd { | 34 | struct sd { |
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 35 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
36 | 36 | struct { /* hvflip cluster */ | |
37 | u8 brightness; | 37 | struct v4l2_ctrl *hflip; |
38 | u8 contrast; | 38 | struct v4l2_ctrl *vflip; |
39 | u8 colors; | 39 | }; |
40 | u8 hflip; | ||
41 | u8 vflip; | ||
42 | u8 lightfreq; | ||
43 | s8 sharpness; | ||
44 | u16 exposure; | ||
45 | u8 gain; | ||
46 | u8 autogain; | ||
47 | u8 backlight; | ||
48 | 40 | ||
49 | u8 image_offset; | 41 | u8 image_offset; |
50 | 42 | ||
@@ -73,252 +65,6 @@ enum sensors { | |||
73 | NSENSORS | 65 | NSENSORS |
74 | }; | 66 | }; |
75 | 67 | ||
76 | /* V4L2 controls supported by the driver */ | ||
77 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
88 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
90 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
91 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
92 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
93 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
94 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
97 | static int sd_setbacklight(struct gspca_dev *gspca_dev, __s32 val); | ||
98 | static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | |||
100 | static const struct ctrl sd_ctrls[] = { | ||
101 | #define BRIGHTNESS_IDX 0 | ||
102 | { | ||
103 | { | ||
104 | .id = V4L2_CID_BRIGHTNESS, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Brightness", | ||
107 | .minimum = 0, | ||
108 | .maximum = 255, | ||
109 | .step = 1, | ||
110 | #define BRIGHTNESS_DEF 128 | ||
111 | .default_value = BRIGHTNESS_DEF, | ||
112 | }, | ||
113 | .set = sd_setbrightness, | ||
114 | .get = sd_getbrightness, | ||
115 | }, | ||
116 | #define CONTRAST_IDX 1 | ||
117 | { | ||
118 | { | ||
119 | .id = V4L2_CID_CONTRAST, | ||
120 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
121 | .name = "Contrast", | ||
122 | .minimum = 0, | ||
123 | .maximum = 255, | ||
124 | .step = 1, | ||
125 | #define CONTRAST_DEF 127 | ||
126 | .default_value = CONTRAST_DEF, | ||
127 | }, | ||
128 | .set = sd_setcontrast, | ||
129 | .get = sd_getcontrast, | ||
130 | }, | ||
131 | #define COLORS_IDX 2 | ||
132 | { | ||
133 | { | ||
134 | .id = V4L2_CID_SATURATION, | ||
135 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
136 | .name = "Saturation", | ||
137 | .minimum = 1, | ||
138 | .maximum = 127, | ||
139 | .step = 1, | ||
140 | #define COLOR_DEF 63 | ||
141 | .default_value = COLOR_DEF, | ||
142 | }, | ||
143 | .set = sd_setcolors, | ||
144 | .get = sd_getcolors, | ||
145 | }, | ||
146 | /* next 2 controls work with some sensors only */ | ||
147 | #define HFLIP_IDX 3 | ||
148 | { | ||
149 | { | ||
150 | .id = V4L2_CID_HFLIP, | ||
151 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
152 | .name = "Mirror", | ||
153 | .minimum = 0, | ||
154 | .maximum = 1, | ||
155 | .step = 1, | ||
156 | #define HFLIP_DEF 0 | ||
157 | .default_value = HFLIP_DEF, | ||
158 | }, | ||
159 | .set = sd_sethflip, | ||
160 | .get = sd_gethflip, | ||
161 | }, | ||
162 | #define VFLIP_IDX 4 | ||
163 | { | ||
164 | { | ||
165 | .id = V4L2_CID_VFLIP, | ||
166 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
167 | .name = "Vflip", | ||
168 | .minimum = 0, | ||
169 | .maximum = 1, | ||
170 | .step = 1, | ||
171 | #define VFLIP_DEF 0 | ||
172 | .default_value = VFLIP_DEF, | ||
173 | }, | ||
174 | .set = sd_setvflip, | ||
175 | .get = sd_getvflip, | ||
176 | }, | ||
177 | #define LIGHTFREQ_IDX 5 | ||
178 | { | ||
179 | { | ||
180 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
181 | .type = V4L2_CTRL_TYPE_MENU, | ||
182 | .name = "Light frequency filter", | ||
183 | .minimum = 0, | ||
184 | .maximum = 2, /* 0: No, 1: 50Hz, 2:60Hz */ | ||
185 | .step = 1, | ||
186 | #define FREQ_DEF 1 | ||
187 | .default_value = FREQ_DEF, | ||
188 | }, | ||
189 | .set = sd_setfreq, | ||
190 | .get = sd_getfreq, | ||
191 | }, | ||
192 | #define SHARPNESS_IDX 6 | ||
193 | { | ||
194 | { | ||
195 | .id = V4L2_CID_SHARPNESS, | ||
196 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
197 | .name = "Sharpness", | ||
198 | .minimum = -1, | ||
199 | .maximum = 2, | ||
200 | .step = 1, | ||
201 | #define SHARPNESS_DEF -1 | ||
202 | .default_value = SHARPNESS_DEF, | ||
203 | }, | ||
204 | .set = sd_setsharpness, | ||
205 | .get = sd_getsharpness, | ||
206 | }, | ||
207 | #define GAIN_IDX 7 | ||
208 | { | ||
209 | { | ||
210 | .id = V4L2_CID_GAIN, | ||
211 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
212 | .name = "Gain", | ||
213 | .minimum = 0, | ||
214 | .maximum = 78, | ||
215 | .step = 1, | ||
216 | #define GAIN_DEF 0 | ||
217 | .default_value = GAIN_DEF, | ||
218 | }, | ||
219 | .set = sd_setgain, | ||
220 | .get = sd_getgain, | ||
221 | }, | ||
222 | #define EXPOSURE_IDX 8 | ||
223 | { | ||
224 | { | ||
225 | .id = V4L2_CID_EXPOSURE, | ||
226 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
227 | .name = "Exposure", | ||
228 | #define EXPOSURE_DEF 450 | ||
229 | .minimum = 0, | ||
230 | .maximum = 4095, | ||
231 | .step = 1, | ||
232 | .default_value = EXPOSURE_DEF, | ||
233 | }, | ||
234 | .set = sd_setexposure, | ||
235 | .get = sd_getexposure, | ||
236 | }, | ||
237 | #define AUTOGAIN_IDX 9 | ||
238 | { | ||
239 | { | ||
240 | .id = V4L2_CID_AUTOGAIN, | ||
241 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
242 | .name = "Automatic Gain and Exposure", | ||
243 | .minimum = 0, | ||
244 | .maximum = 1, | ||
245 | .step = 1, | ||
246 | #define AUTOGAIN_DEF 1 | ||
247 | .default_value = AUTOGAIN_DEF, | ||
248 | }, | ||
249 | .set = sd_setautogain, | ||
250 | .get = sd_getautogain, | ||
251 | }, | ||
252 | #define BACKLIGHT_IDX 10 | ||
253 | { | ||
254 | { | ||
255 | .id = V4L2_CID_BACKLIGHT_COMPENSATION, | ||
256 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
257 | .name = "Backlight Compensation", | ||
258 | .minimum = 0, | ||
259 | .maximum = 15, | ||
260 | .step = 1, | ||
261 | #define BACKLIGHT_DEF 15 | ||
262 | .default_value = BACKLIGHT_DEF, | ||
263 | }, | ||
264 | .set = sd_setbacklight, | ||
265 | .get = sd_getbacklight, | ||
266 | }, | ||
267 | }; | ||
268 | |||
269 | /* table of the disabled controls */ | ||
270 | static u32 ctrl_dis[NSENSORS] = { | ||
271 | [SENSOR_HV7131R] = | ||
272 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
273 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | ||
274 | | (1 << SHARPNESS_IDX) | ||
275 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
276 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
277 | [SENSOR_MI0360] = | ||
278 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
279 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | ||
280 | | (1 << SHARPNESS_IDX) | ||
281 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
282 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
283 | [SENSOR_MI1310_SOC] = | ||
284 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
285 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
286 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
287 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
288 | [SENSOR_MI1320] = | ||
289 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
290 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
291 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
292 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
293 | [SENSOR_MI1320_SOC] = | ||
294 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
295 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
296 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
297 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
298 | [SENSOR_OV7660] = | ||
299 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
300 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
301 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
302 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
303 | [SENSOR_OV7670] = | ||
304 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
305 | | (1 << SHARPNESS_IDX) | ||
306 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
307 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
308 | [SENSOR_PO1200] = | ||
309 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
310 | | (1 << LIGHTFREQ_IDX) | ||
311 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
312 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
313 | [SENSOR_PO3130NC] = | ||
314 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
315 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | ||
316 | | (1 << SHARPNESS_IDX) | ||
317 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
318 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
319 | [SENSOR_POxxxx] = | ||
320 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX), | ||
321 | }; | ||
322 | 68 | ||
323 | static const struct v4l2_pix_format vc0321_mode[] = { | 69 | static const struct v4l2_pix_format vc0321_mode[] = { |
324 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 70 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, |
@@ -3405,18 +3151,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3405 | (id->idProduct == 0x0892 || id->idProduct == 0x0896)) | 3151 | (id->idProduct == 0x0892 || id->idProduct == 0x0896)) |
3406 | sd->sensor = SENSOR_POxxxx; /* no probe */ | 3152 | sd->sensor = SENSOR_POxxxx; /* no probe */ |
3407 | 3153 | ||
3408 | sd->brightness = BRIGHTNESS_DEF; | ||
3409 | sd->contrast = CONTRAST_DEF; | ||
3410 | sd->colors = COLOR_DEF; | ||
3411 | sd->hflip = HFLIP_DEF; | ||
3412 | sd->vflip = VFLIP_DEF; | ||
3413 | sd->lightfreq = FREQ_DEF; | ||
3414 | sd->sharpness = SHARPNESS_DEF; | ||
3415 | sd->gain = GAIN_DEF; | ||
3416 | sd->exposure = EXPOSURE_DEF; | ||
3417 | sd->autogain = AUTOGAIN_DEF; | ||
3418 | sd->backlight = BACKLIGHT_DEF; | ||
3419 | |||
3420 | return 0; | 3154 | return 0; |
3421 | } | 3155 | } |
3422 | 3156 | ||
@@ -3512,7 +3246,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3512 | } | 3246 | } |
3513 | } | 3247 | } |
3514 | cam->npkt = npkt[sd->sensor]; | 3248 | cam->npkt = npkt[sd->sensor]; |
3515 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | ||
3516 | 3249 | ||
3517 | if (sd->sensor == SENSOR_OV7670) | 3250 | if (sd->sensor == SENSOR_OV7670) |
3518 | sd->flags |= FL_HFLIP | FL_VFLIP; | 3251 | sd->flags |= FL_HFLIP | FL_VFLIP; |
@@ -3534,14 +3267,11 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3534 | return gspca_dev->usb_err; | 3267 | return gspca_dev->usb_err; |
3535 | } | 3268 | } |
3536 | 3269 | ||
3537 | static void setbrightness(struct gspca_dev *gspca_dev) | 3270 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
3538 | { | 3271 | { |
3539 | struct sd *sd = (struct sd *) gspca_dev; | ||
3540 | u8 data; | 3272 | u8 data; |
3541 | 3273 | ||
3542 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) | 3274 | data = val; |
3543 | return; | ||
3544 | data = sd->brightness; | ||
3545 | if (data >= 0x80) | 3275 | if (data >= 0x80) |
3546 | data &= 0x7f; | 3276 | data &= 0x7f; |
3547 | else | 3277 | else |
@@ -3549,36 +3279,27 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
3549 | i2c_write(gspca_dev, 0x98, &data, 1); | 3279 | i2c_write(gspca_dev, 0x98, &data, 1); |
3550 | } | 3280 | } |
3551 | 3281 | ||
3552 | static void setcontrast(struct gspca_dev *gspca_dev) | 3282 | static void setcontrast(struct gspca_dev *gspca_dev, u8 val) |
3553 | { | 3283 | { |
3554 | struct sd *sd = (struct sd *) gspca_dev; | 3284 | i2c_write(gspca_dev, 0x99, &val, 1); |
3555 | |||
3556 | if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX)) | ||
3557 | return; | ||
3558 | i2c_write(gspca_dev, 0x99, &sd->contrast, 1); | ||
3559 | } | 3285 | } |
3560 | 3286 | ||
3561 | static void setcolors(struct gspca_dev *gspca_dev) | 3287 | static void setcolors(struct gspca_dev *gspca_dev, u8 val) |
3562 | { | 3288 | { |
3563 | struct sd *sd = (struct sd *) gspca_dev; | ||
3564 | u8 data; | 3289 | u8 data; |
3565 | 3290 | ||
3566 | if (gspca_dev->ctrl_dis & (1 << COLORS_IDX)) | 3291 | data = val - (val >> 3) - 1; |
3567 | return; | ||
3568 | data = sd->colors - (sd->colors >> 3) - 1; | ||
3569 | i2c_write(gspca_dev, 0x94, &data, 1); | 3292 | i2c_write(gspca_dev, 0x94, &data, 1); |
3570 | i2c_write(gspca_dev, 0x95, &sd->colors, 1); | 3293 | i2c_write(gspca_dev, 0x95, &val, 1); |
3571 | } | 3294 | } |
3572 | 3295 | ||
3573 | static void sethvflip(struct gspca_dev *gspca_dev) | 3296 | static void sethvflip(struct gspca_dev *gspca_dev, bool hflip, bool vflip) |
3574 | { | 3297 | { |
3575 | struct sd *sd = (struct sd *) gspca_dev; | 3298 | struct sd *sd = (struct sd *) gspca_dev; |
3576 | u8 data[2], hflip, vflip; | 3299 | u8 data[2]; |
3577 | 3300 | ||
3578 | hflip = sd->hflip; | ||
3579 | if (sd->flags & FL_HFLIP) | 3301 | if (sd->flags & FL_HFLIP) |
3580 | hflip = !hflip; | 3302 | hflip = !hflip; |
3581 | vflip = sd->vflip; | ||
3582 | if (sd->flags & FL_VFLIP) | 3303 | if (sd->flags & FL_VFLIP) |
3583 | vflip = !vflip; | 3304 | vflip = !vflip; |
3584 | switch (sd->sensor) { | 3305 | switch (sd->sensor) { |
@@ -3610,7 +3331,7 @@ static void sethvflip(struct gspca_dev *gspca_dev) | |||
3610 | } | 3331 | } |
3611 | } | 3332 | } |
3612 | 3333 | ||
3613 | static void setlightfreq(struct gspca_dev *gspca_dev) | 3334 | static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) |
3614 | { | 3335 | { |
3615 | struct sd *sd = (struct sd *) gspca_dev; | 3336 | struct sd *sd = (struct sd *) gspca_dev; |
3616 | static const u8 (*ov7660_freq_tb[3])[4] = | 3337 | static const u8 (*ov7660_freq_tb[3])[4] = |
@@ -3618,10 +3339,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
3618 | 3339 | ||
3619 | if (sd->sensor != SENSOR_OV7660) | 3340 | if (sd->sensor != SENSOR_OV7660) |
3620 | return; | 3341 | return; |
3621 | usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); | 3342 | usb_exchange(gspca_dev, ov7660_freq_tb[val]); |
3622 | } | 3343 | } |
3623 | 3344 | ||
3624 | static void setsharpness(struct gspca_dev *gspca_dev) | 3345 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
3625 | { | 3346 | { |
3626 | struct sd *sd = (struct sd *) gspca_dev; | 3347 | struct sd *sd = (struct sd *) gspca_dev; |
3627 | u8 data; | 3348 | u8 data; |
@@ -3630,51 +3351,41 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
3630 | case SENSOR_PO1200: | 3351 | case SENSOR_PO1200: |
3631 | data = 0; | 3352 | data = 0; |
3632 | i2c_write(gspca_dev, 0x03, &data, 1); | 3353 | i2c_write(gspca_dev, 0x03, &data, 1); |
3633 | if (sd->sharpness < 0) | 3354 | if (val < 0) |
3634 | data = 0x6a; | 3355 | data = 0x6a; |
3635 | else | 3356 | else |
3636 | data = 0xb5 + sd->sharpness * 3; | 3357 | data = 0xb5 + val * 3; |
3637 | i2c_write(gspca_dev, 0x61, &data, 1); | 3358 | i2c_write(gspca_dev, 0x61, &data, 1); |
3638 | break; | 3359 | break; |
3639 | case SENSOR_POxxxx: | 3360 | case SENSOR_POxxxx: |
3640 | if (sd->sharpness < 0) | 3361 | if (val < 0) |
3641 | data = 0x7e; /* def = max */ | 3362 | data = 0x7e; /* def = max */ |
3642 | else | 3363 | else |
3643 | data = 0x60 + sd->sharpness * 0x0f; | 3364 | data = 0x60 + val * 0x0f; |
3644 | i2c_write(gspca_dev, 0x59, &data, 1); | 3365 | i2c_write(gspca_dev, 0x59, &data, 1); |
3645 | break; | 3366 | break; |
3646 | } | 3367 | } |
3647 | } | 3368 | } |
3648 | static void setgain(struct gspca_dev *gspca_dev) | 3369 | static void setgain(struct gspca_dev *gspca_dev, u8 val) |
3649 | { | 3370 | { |
3650 | struct sd *sd = (struct sd *) gspca_dev; | 3371 | i2c_write(gspca_dev, 0x15, &val, 1); |
3651 | |||
3652 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) | ||
3653 | return; | ||
3654 | i2c_write(gspca_dev, 0x15, &sd->gain, 1); | ||
3655 | } | 3372 | } |
3656 | 3373 | ||
3657 | static void setexposure(struct gspca_dev *gspca_dev) | 3374 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
3658 | { | 3375 | { |
3659 | struct sd *sd = (struct sd *) gspca_dev; | ||
3660 | u8 data; | 3376 | u8 data; |
3661 | 3377 | ||
3662 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) | 3378 | data = val >> 8; |
3663 | return; | ||
3664 | data = sd->exposure >> 8; | ||
3665 | i2c_write(gspca_dev, 0x1a, &data, 1); | 3379 | i2c_write(gspca_dev, 0x1a, &data, 1); |
3666 | data = sd->exposure; | 3380 | data = val; |
3667 | i2c_write(gspca_dev, 0x1b, &data, 1); | 3381 | i2c_write(gspca_dev, 0x1b, &data, 1); |
3668 | } | 3382 | } |
3669 | 3383 | ||
3670 | static void setautogain(struct gspca_dev *gspca_dev) | 3384 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
3671 | { | 3385 | { |
3672 | struct sd *sd = (struct sd *) gspca_dev; | ||
3673 | static const u8 data[2] = {0x28, 0x3c}; | 3386 | static const u8 data[2] = {0x28, 0x3c}; |
3674 | 3387 | ||
3675 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) | 3388 | i2c_write(gspca_dev, 0xd1, &data[val], 1); |
3676 | return; | ||
3677 | i2c_write(gspca_dev, 0xd1, &data[sd->autogain], 1); | ||
3678 | } | 3389 | } |
3679 | 3390 | ||
3680 | static void setgamma(struct gspca_dev *gspca_dev) | 3391 | static void setgamma(struct gspca_dev *gspca_dev) |
@@ -3683,30 +3394,29 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
3683 | usb_exchange(gspca_dev, poxxxx_gamma); | 3394 | usb_exchange(gspca_dev, poxxxx_gamma); |
3684 | } | 3395 | } |
3685 | 3396 | ||
3686 | static void setbacklight(struct gspca_dev *gspca_dev) | 3397 | static void setbacklight(struct gspca_dev *gspca_dev, s32 val) |
3687 | { | 3398 | { |
3688 | struct sd *sd = (struct sd *) gspca_dev; | ||
3689 | u16 v; | 3399 | u16 v; |
3690 | u8 data; | 3400 | u8 data; |
3691 | 3401 | ||
3692 | data = (sd->backlight << 4) | 0x0f; | 3402 | data = (val << 4) | 0x0f; |
3693 | i2c_write(gspca_dev, 0xaa, &data, 1); | 3403 | i2c_write(gspca_dev, 0xaa, &data, 1); |
3694 | v = 613 + 12 * sd->backlight; | 3404 | v = 613 + 12 * val; |
3695 | data = v >> 8; | 3405 | data = v >> 8; |
3696 | i2c_write(gspca_dev, 0xc4, &data, 1); | 3406 | i2c_write(gspca_dev, 0xc4, &data, 1); |
3697 | data = v; | 3407 | data = v; |
3698 | i2c_write(gspca_dev, 0xc5, &data, 1); | 3408 | i2c_write(gspca_dev, 0xc5, &data, 1); |
3699 | v = 1093 - 12 * sd->backlight; | 3409 | v = 1093 - 12 * val; |
3700 | data = v >> 8; | 3410 | data = v >> 8; |
3701 | i2c_write(gspca_dev, 0xc6, &data, 1); | 3411 | i2c_write(gspca_dev, 0xc6, &data, 1); |
3702 | data = v; | 3412 | data = v; |
3703 | i2c_write(gspca_dev, 0xc7, &data, 1); | 3413 | i2c_write(gspca_dev, 0xc7, &data, 1); |
3704 | v = 342 + 9 * sd->backlight; | 3414 | v = 342 + 9 * val; |
3705 | data = v >> 8; | 3415 | data = v >> 8; |
3706 | i2c_write(gspca_dev, 0xc8, &data, 1); | 3416 | i2c_write(gspca_dev, 0xc8, &data, 1); |
3707 | data = v; | 3417 | data = v; |
3708 | i2c_write(gspca_dev, 0xc9, &data, 1); | 3418 | i2c_write(gspca_dev, 0xc9, &data, 1); |
3709 | v = 702 - 9 * sd->backlight; | 3419 | v = 702 - 9 * val; |
3710 | data = v >> 8; | 3420 | data = v >> 8; |
3711 | i2c_write(gspca_dev, 0xca, &data, 1); | 3421 | i2c_write(gspca_dev, 0xca, &data, 1); |
3712 | data = v; | 3422 | data = v; |
@@ -3833,14 +3543,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3833 | /* case SENSOR_POxxxx: */ | 3543 | /* case SENSOR_POxxxx: */ |
3834 | usb_exchange(gspca_dev, poxxxx_init_common); | 3544 | usb_exchange(gspca_dev, poxxxx_init_common); |
3835 | setgamma(gspca_dev); | 3545 | setgamma(gspca_dev); |
3836 | setbacklight(gspca_dev); | ||
3837 | setbrightness(gspca_dev); | ||
3838 | setcontrast(gspca_dev); | ||
3839 | setcolors(gspca_dev); | ||
3840 | setsharpness(gspca_dev); | ||
3841 | setautogain(gspca_dev); | ||
3842 | setexposure(gspca_dev); | ||
3843 | setgain(gspca_dev); | ||
3844 | usb_exchange(gspca_dev, poxxxx_init_start_3); | 3546 | usb_exchange(gspca_dev, poxxxx_init_start_3); |
3845 | if (mode) | 3547 | if (mode) |
3846 | init = poxxxx_initQVGA; | 3548 | init = poxxxx_initQVGA; |
@@ -3873,8 +3575,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3873 | break; | 3575 | break; |
3874 | } | 3576 | } |
3875 | msleep(100); | 3577 | msleep(100); |
3876 | sethvflip(gspca_dev); | ||
3877 | setlightfreq(gspca_dev); | ||
3878 | } | 3578 | } |
3879 | switch (sd->sensor) { | 3579 | switch (sd->sensor) { |
3880 | case SENSOR_OV7670: | 3580 | case SENSOR_OV7670: |
@@ -3960,233 +3660,152 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
3960 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 3660 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
3961 | } | 3661 | } |
3962 | 3662 | ||
3963 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 3663 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
3964 | { | ||
3965 | struct sd *sd = (struct sd *) gspca_dev; | ||
3966 | |||
3967 | sd->brightness = val; | ||
3968 | if (gspca_dev->streaming) | ||
3969 | setbrightness(gspca_dev); | ||
3970 | return gspca_dev->usb_err; | ||
3971 | } | ||
3972 | |||
3973 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
3974 | { | ||
3975 | struct sd *sd = (struct sd *) gspca_dev; | ||
3976 | |||
3977 | *val = sd->brightness; | ||
3978 | return 0; | ||
3979 | } | ||
3980 | |||
3981 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
3982 | { | ||
3983 | struct sd *sd = (struct sd *) gspca_dev; | ||
3984 | |||
3985 | sd->contrast = val; | ||
3986 | if (gspca_dev->streaming) | ||
3987 | setcontrast(gspca_dev); | ||
3988 | return gspca_dev->usb_err; | ||
3989 | } | ||
3990 | |||
3991 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
3992 | { | ||
3993 | struct sd *sd = (struct sd *) gspca_dev; | ||
3994 | |||
3995 | *val = sd->contrast; | ||
3996 | return 0; | ||
3997 | } | ||
3998 | |||
3999 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
4000 | { | 3664 | { |
4001 | struct sd *sd = (struct sd *) gspca_dev; | 3665 | struct gspca_dev *gspca_dev = |
4002 | 3666 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
4003 | sd->colors = val; | 3667 | struct sd *sd = (struct sd *)gspca_dev; |
4004 | if (gspca_dev->streaming) | ||
4005 | setcolors(gspca_dev); | ||
4006 | return gspca_dev->usb_err; | ||
4007 | } | ||
4008 | |||
4009 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
4010 | { | ||
4011 | struct sd *sd = (struct sd *) gspca_dev; | ||
4012 | |||
4013 | *val = sd->colors; | ||
4014 | return 0; | ||
4015 | } | ||
4016 | |||
4017 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
4018 | { | ||
4019 | struct sd *sd = (struct sd *) gspca_dev; | ||
4020 | |||
4021 | sd->hflip = val; | ||
4022 | if (gspca_dev->streaming) | ||
4023 | sethvflip(gspca_dev); | ||
4024 | return gspca_dev->usb_err; | ||
4025 | } | ||
4026 | |||
4027 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
4028 | { | ||
4029 | struct sd *sd = (struct sd *) gspca_dev; | ||
4030 | |||
4031 | *val = sd->hflip; | ||
4032 | return 0; | ||
4033 | } | ||
4034 | |||
4035 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
4036 | { | ||
4037 | struct sd *sd = (struct sd *) gspca_dev; | ||
4038 | |||
4039 | sd->vflip = val; | ||
4040 | if (gspca_dev->streaming) | ||
4041 | sethvflip(gspca_dev); | ||
4042 | return gspca_dev->usb_err; | ||
4043 | } | ||
4044 | |||
4045 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
4046 | { | ||
4047 | struct sd *sd = (struct sd *) gspca_dev; | ||
4048 | 3668 | ||
4049 | *val = sd->vflip; | 3669 | gspca_dev->usb_err = 0; |
4050 | return 0; | ||
4051 | } | ||
4052 | 3670 | ||
4053 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | 3671 | if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) |
4054 | { | 3672 | return 0; |
4055 | struct sd *sd = (struct sd *) gspca_dev; | ||
4056 | |||
4057 | sd->lightfreq = val; | ||
4058 | if (gspca_dev->streaming) | ||
4059 | setlightfreq(gspca_dev); | ||
4060 | return gspca_dev->usb_err; | ||
4061 | } | ||
4062 | |||
4063 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
4064 | { | ||
4065 | struct sd *sd = (struct sd *) gspca_dev; | ||
4066 | |||
4067 | *val = sd->lightfreq; | ||
4068 | return 0; | ||
4069 | } | ||
4070 | |||
4071 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
4072 | { | ||
4073 | struct sd *sd = (struct sd *) gspca_dev; | ||
4074 | |||
4075 | sd->sharpness = val; | ||
4076 | if (gspca_dev->streaming) | ||
4077 | setsharpness(gspca_dev); | ||
4078 | return gspca_dev->usb_err; | ||
4079 | } | ||
4080 | |||
4081 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
4082 | { | ||
4083 | struct sd *sd = (struct sd *) gspca_dev; | ||
4084 | |||
4085 | *val = sd->sharpness; | ||
4086 | return 0; | ||
4087 | } | ||
4088 | |||
4089 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
4090 | { | ||
4091 | struct sd *sd = (struct sd *) gspca_dev; | ||
4092 | |||
4093 | sd->gain = val; | ||
4094 | if (gspca_dev->streaming) | ||
4095 | setgain(gspca_dev); | ||
4096 | return gspca_dev->usb_err; | ||
4097 | } | ||
4098 | |||
4099 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
4100 | { | ||
4101 | struct sd *sd = (struct sd *) gspca_dev; | ||
4102 | |||
4103 | *val = sd->gain; | ||
4104 | return 0; | ||
4105 | } | ||
4106 | |||
4107 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
4108 | { | ||
4109 | struct sd *sd = (struct sd *) gspca_dev; | ||
4110 | |||
4111 | sd->exposure = val; | ||
4112 | if (gspca_dev->streaming) | ||
4113 | setexposure(gspca_dev); | ||
4114 | return gspca_dev->usb_err; | ||
4115 | } | ||
4116 | |||
4117 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
4118 | { | ||
4119 | struct sd *sd = (struct sd *) gspca_dev; | ||
4120 | |||
4121 | *val = sd->exposure; | ||
4122 | return 0; | ||
4123 | } | ||
4124 | |||
4125 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
4126 | { | ||
4127 | struct sd *sd = (struct sd *) gspca_dev; | ||
4128 | |||
4129 | sd->autogain = val; | ||
4130 | if (gspca_dev->streaming) | ||
4131 | setautogain(gspca_dev); | ||
4132 | 3673 | ||
3674 | switch (ctrl->id) { | ||
3675 | case V4L2_CID_BRIGHTNESS: | ||
3676 | setbrightness(gspca_dev, ctrl->val); | ||
3677 | break; | ||
3678 | case V4L2_CID_CONTRAST: | ||
3679 | setcontrast(gspca_dev, ctrl->val); | ||
3680 | break; | ||
3681 | case V4L2_CID_SATURATION: | ||
3682 | setcolors(gspca_dev, ctrl->val); | ||
3683 | break; | ||
3684 | case V4L2_CID_HFLIP: | ||
3685 | sethvflip(gspca_dev, sd->hflip->val, sd->vflip->val); | ||
3686 | break; | ||
3687 | case V4L2_CID_SHARPNESS: | ||
3688 | setsharpness(gspca_dev, ctrl->val); | ||
3689 | break; | ||
3690 | case V4L2_CID_AUTOGAIN: | ||
3691 | setautogain(gspca_dev, ctrl->val); | ||
3692 | break; | ||
3693 | case V4L2_CID_GAIN: | ||
3694 | setgain(gspca_dev, ctrl->val); | ||
3695 | break; | ||
3696 | case V4L2_CID_EXPOSURE: | ||
3697 | setexposure(gspca_dev, ctrl->val); | ||
3698 | break; | ||
3699 | case V4L2_CID_BACKLIGHT_COMPENSATION: | ||
3700 | setbacklight(gspca_dev, ctrl->val); | ||
3701 | break; | ||
3702 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
3703 | setlightfreq(gspca_dev, ctrl->val); | ||
3704 | break; | ||
3705 | } | ||
4133 | return gspca_dev->usb_err; | 3706 | return gspca_dev->usb_err; |
4134 | } | 3707 | } |
4135 | 3708 | ||
4136 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | 3709 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
4137 | { | 3710 | .s_ctrl = sd_s_ctrl, |
4138 | struct sd *sd = (struct sd *) gspca_dev; | 3711 | }; |
4139 | |||
4140 | *val = sd->autogain; | ||
4141 | return 0; | ||
4142 | } | ||
4143 | |||
4144 | static int sd_setbacklight(struct gspca_dev *gspca_dev, __s32 val) | ||
4145 | { | ||
4146 | struct sd *sd = (struct sd *) gspca_dev; | ||
4147 | |||
4148 | sd->backlight = val; | ||
4149 | if (gspca_dev->streaming) | ||
4150 | setbacklight(gspca_dev); | ||
4151 | |||
4152 | return gspca_dev->usb_err; | ||
4153 | } | ||
4154 | 3712 | ||
4155 | static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val) | 3713 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
4156 | { | 3714 | { |
4157 | struct sd *sd = (struct sd *) gspca_dev; | 3715 | struct sd *sd = (struct sd *)gspca_dev; |
3716 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
3717 | bool has_brightness = false; | ||
3718 | bool has_contrast = false; | ||
3719 | bool has_sat = false; | ||
3720 | bool has_hvflip = false; | ||
3721 | bool has_freq = false; | ||
3722 | bool has_backlight = false; | ||
3723 | bool has_exposure = false; | ||
3724 | bool has_autogain = false; | ||
3725 | bool has_gain = false; | ||
3726 | bool has_sharpness = false; | ||
4158 | 3727 | ||
4159 | *val = sd->backlight; | 3728 | switch (sd->sensor) { |
4160 | return 0; | 3729 | case SENSOR_HV7131R: |
4161 | } | 3730 | case SENSOR_MI0360: |
4162 | 3731 | case SENSOR_PO3130NC: | |
4163 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 3732 | break; |
4164 | struct v4l2_querymenu *menu) | 3733 | case SENSOR_MI1310_SOC: |
4165 | { | 3734 | case SENSOR_MI1320: |
4166 | static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"}; | 3735 | case SENSOR_MI1320_SOC: |
3736 | case SENSOR_OV7660: | ||
3737 | has_hvflip = true; | ||
3738 | break; | ||
3739 | case SENSOR_OV7670: | ||
3740 | has_hvflip = has_freq = true; | ||
3741 | break; | ||
3742 | case SENSOR_PO1200: | ||
3743 | has_hvflip = has_sharpness = true; | ||
3744 | break; | ||
3745 | case SENSOR_POxxxx: | ||
3746 | has_brightness = has_contrast = has_sat = has_backlight = | ||
3747 | has_exposure = has_autogain = has_gain = | ||
3748 | has_sharpness = true; | ||
3749 | break; | ||
3750 | } | ||
4167 | 3751 | ||
4168 | switch (menu->id) { | 3752 | gspca_dev->vdev.ctrl_handler = hdl; |
4169 | case V4L2_CID_POWER_LINE_FREQUENCY: | 3753 | v4l2_ctrl_handler_init(hdl, 8); |
4170 | if (menu->index >= ARRAY_SIZE(freq_nm)) | 3754 | if (has_brightness) |
4171 | break; | 3755 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
4172 | strcpy((char *) menu->name, freq_nm[menu->index]); | 3756 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); |
4173 | return 0; | 3757 | if (has_contrast) |
3758 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3759 | V4L2_CID_CONTRAST, 0, 255, 1, 127); | ||
3760 | if (has_sat) | ||
3761 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3762 | V4L2_CID_SATURATION, 1, 127, 1, 63); | ||
3763 | if (has_hvflip) { | ||
3764 | sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3765 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
3766 | sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3767 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
4174 | } | 3768 | } |
4175 | return -EINVAL; | 3769 | if (has_sharpness) |
3770 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3771 | V4L2_CID_SHARPNESS, -1, 2, 1, -1); | ||
3772 | if (has_freq) | ||
3773 | v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
3774 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
3775 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, | ||
3776 | V4L2_CID_POWER_LINE_FREQUENCY_50HZ); | ||
3777 | if (has_autogain) | ||
3778 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3779 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
3780 | if (has_gain) | ||
3781 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3782 | V4L2_CID_GAIN, 0, 78, 1, 0); | ||
3783 | if (has_exposure) | ||
3784 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3785 | V4L2_CID_EXPOSURE, 0, 4095, 1, 450); | ||
3786 | if (has_backlight) | ||
3787 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3788 | V4L2_CID_BACKLIGHT_COMPENSATION, 0, 15, 1, 15); | ||
3789 | |||
3790 | if (hdl->error) { | ||
3791 | pr_err("Could not initialize controls\n"); | ||
3792 | return hdl->error; | ||
3793 | } | ||
3794 | if (sd->hflip) | ||
3795 | v4l2_ctrl_cluster(2, &sd->hflip); | ||
3796 | return 0; | ||
4176 | } | 3797 | } |
4177 | 3798 | ||
4178 | /* sub-driver description */ | 3799 | /* sub-driver description */ |
4179 | static const struct sd_desc sd_desc = { | 3800 | static const struct sd_desc sd_desc = { |
4180 | .name = MODULE_NAME, | 3801 | .name = MODULE_NAME, |
4181 | .ctrls = sd_ctrls, | 3802 | .init_controls = sd_init_controls, |
4182 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
4183 | .config = sd_config, | 3803 | .config = sd_config, |
4184 | .init = sd_init, | 3804 | .init = sd_init, |
4185 | .start = sd_start, | 3805 | .start = sd_start, |
4186 | .stopN = sd_stopN, | 3806 | .stopN = sd_stopN, |
4187 | .stop0 = sd_stop0, | 3807 | .stop0 = sd_stop0, |
4188 | .pkt_scan = sd_pkt_scan, | 3808 | .pkt_scan = sd_pkt_scan, |
4189 | .querymenu = sd_querymenu, | ||
4190 | }; | 3809 | }; |
4191 | 3810 | ||
4192 | /* -- module initialisation -- */ | 3811 | /* -- module initialisation -- */ |
@@ -4227,6 +3846,7 @@ static struct usb_driver sd_driver = { | |||
4227 | #ifdef CONFIG_PM | 3846 | #ifdef CONFIG_PM |
4228 | .suspend = gspca_suspend, | 3847 | .suspend = gspca_suspend, |
4229 | .resume = gspca_resume, | 3848 | .resume = gspca_resume, |
3849 | .reset_resume = gspca_resume, | ||
4230 | #endif | 3850 | #endif |
4231 | }; | 3851 | }; |
4232 | 3852 | ||
diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c index 15a30f7a4b2a..b1a64b912666 100644 --- a/drivers/media/video/gspca/vicam.c +++ b/drivers/media/video/gspca/vicam.c | |||
@@ -44,17 +44,10 @@ MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver"); | |||
44 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
45 | MODULE_FIRMWARE(VICAM_FIRMWARE); | 45 | MODULE_FIRMWARE(VICAM_FIRMWARE); |
46 | 46 | ||
47 | enum e_ctrl { | ||
48 | GAIN, | ||
49 | EXPOSURE, | ||
50 | NCTRL /* number of controls */ | ||
51 | }; | ||
52 | |||
53 | struct sd { | 47 | struct sd { |
54 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 48 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
55 | struct work_struct work_struct; | 49 | struct work_struct work_struct; |
56 | struct workqueue_struct *work_thread; | 50 | struct workqueue_struct *work_thread; |
57 | struct gspca_ctrl ctrls[NCTRL]; | ||
58 | }; | 51 | }; |
59 | 52 | ||
60 | /* The vicam sensor has a resolution of 512 x 244, with I believe square | 53 | /* The vicam sensor has a resolution of 512 x 244, with I believe square |
@@ -86,31 +79,6 @@ static struct v4l2_pix_format vicam_mode[] = { | |||
86 | .colorspace = V4L2_COLORSPACE_SRGB,}, | 79 | .colorspace = V4L2_COLORSPACE_SRGB,}, |
87 | }; | 80 | }; |
88 | 81 | ||
89 | static const struct ctrl sd_ctrls[] = { | ||
90 | [GAIN] = { | ||
91 | { | ||
92 | .id = V4L2_CID_GAIN, | ||
93 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
94 | .name = "Gain", | ||
95 | .minimum = 0, | ||
96 | .maximum = 255, | ||
97 | .step = 1, | ||
98 | .default_value = 200, | ||
99 | }, | ||
100 | }, | ||
101 | [EXPOSURE] = { | ||
102 | { | ||
103 | .id = V4L2_CID_EXPOSURE, | ||
104 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
105 | .name = "Exposure", | ||
106 | .minimum = 0, | ||
107 | .maximum = 2047, | ||
108 | .step = 1, | ||
109 | .default_value = 256, | ||
110 | }, | ||
111 | }, | ||
112 | }; | ||
113 | |||
114 | static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request, | 82 | static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request, |
115 | u16 value, u16 index, u8 *data, u16 len) | 83 | u16 value, u16 index, u8 *data, u16 len) |
116 | { | 84 | { |
@@ -146,12 +114,13 @@ static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state) | |||
146 | */ | 114 | */ |
147 | static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) | 115 | static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) |
148 | { | 116 | { |
149 | struct sd *sd = (struct sd *)gspca_dev; | ||
150 | int ret, unscaled_height, act_len = 0; | 117 | int ret, unscaled_height, act_len = 0; |
151 | u8 *req_data = gspca_dev->usb_buf; | 118 | u8 *req_data = gspca_dev->usb_buf; |
119 | s32 expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure); | ||
120 | s32 gain = v4l2_ctrl_g_ctrl(gspca_dev->gain); | ||
152 | 121 | ||
153 | memset(req_data, 0, 16); | 122 | memset(req_data, 0, 16); |
154 | req_data[0] = sd->ctrls[GAIN].val; | 123 | req_data[0] = gain; |
155 | if (gspca_dev->width == 256) | 124 | if (gspca_dev->width == 256) |
156 | req_data[1] |= 0x01; /* low nibble x-scale */ | 125 | req_data[1] |= 0x01; /* low nibble x-scale */ |
157 | if (gspca_dev->height <= 122) { | 126 | if (gspca_dev->height <= 122) { |
@@ -167,9 +136,9 @@ static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) | |||
167 | else /* Up to 244 lines with req_data[3] == 0x08 */ | 136 | else /* Up to 244 lines with req_data[3] == 0x08 */ |
168 | req_data[3] = 0x08; /* vend? */ | 137 | req_data[3] = 0x08; /* vend? */ |
169 | 138 | ||
170 | if (sd->ctrls[EXPOSURE].val < 256) { | 139 | if (expo < 256) { |
171 | /* Frame rate maxed out, use partial frame expo time */ | 140 | /* Frame rate maxed out, use partial frame expo time */ |
172 | req_data[4] = 255 - sd->ctrls[EXPOSURE].val; | 141 | req_data[4] = 255 - expo; |
173 | req_data[5] = 0x00; | 142 | req_data[5] = 0x00; |
174 | req_data[6] = 0x00; | 143 | req_data[6] = 0x00; |
175 | req_data[7] = 0x01; | 144 | req_data[7] = 0x01; |
@@ -177,8 +146,8 @@ static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) | |||
177 | /* Modify frame rate */ | 146 | /* Modify frame rate */ |
178 | req_data[4] = 0x00; | 147 | req_data[4] = 0x00; |
179 | req_data[5] = 0x00; | 148 | req_data[5] = 0x00; |
180 | req_data[6] = sd->ctrls[EXPOSURE].val & 0xFF; | 149 | req_data[6] = expo & 0xFF; |
181 | req_data[7] = sd->ctrls[EXPOSURE].val >> 8; | 150 | req_data[7] = expo >> 8; |
182 | } | 151 | } |
183 | req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */ | 152 | req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */ |
184 | /* bytes 9-15 do not seem to affect exposure or image quality */ | 153 | /* bytes 9-15 do not seem to affect exposure or image quality */ |
@@ -260,7 +229,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
260 | cam->bulk_size = 64; | 229 | cam->bulk_size = 64; |
261 | cam->cam_mode = vicam_mode; | 230 | cam->cam_mode = vicam_mode; |
262 | cam->nmodes = ARRAY_SIZE(vicam_mode); | 231 | cam->nmodes = ARRAY_SIZE(vicam_mode); |
263 | cam->ctrls = sd->ctrls; | ||
264 | 232 | ||
265 | INIT_WORK(&sd->work_struct, vicam_dostream); | 233 | INIT_WORK(&sd->work_struct, vicam_dostream); |
266 | 234 | ||
@@ -335,6 +303,24 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
335 | vicam_set_camera_power(gspca_dev, 0); | 303 | vicam_set_camera_power(gspca_dev, 0); |
336 | } | 304 | } |
337 | 305 | ||
306 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
307 | { | ||
308 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
309 | |||
310 | gspca_dev->vdev.ctrl_handler = hdl; | ||
311 | v4l2_ctrl_handler_init(hdl, 2); | ||
312 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, NULL, | ||
313 | V4L2_CID_EXPOSURE, 0, 2047, 1, 256); | ||
314 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, NULL, | ||
315 | V4L2_CID_GAIN, 0, 255, 1, 200); | ||
316 | |||
317 | if (hdl->error) { | ||
318 | pr_err("Could not initialize controls\n"); | ||
319 | return hdl->error; | ||
320 | } | ||
321 | return 0; | ||
322 | } | ||
323 | |||
338 | /* Table of supported USB devices */ | 324 | /* Table of supported USB devices */ |
339 | static const struct usb_device_id device_table[] = { | 325 | static const struct usb_device_id device_table[] = { |
340 | {USB_DEVICE(0x04c1, 0x009d)}, | 326 | {USB_DEVICE(0x04c1, 0x009d)}, |
@@ -347,10 +333,9 @@ MODULE_DEVICE_TABLE(usb, device_table); | |||
347 | /* sub-driver description */ | 333 | /* sub-driver description */ |
348 | static const struct sd_desc sd_desc = { | 334 | static const struct sd_desc sd_desc = { |
349 | .name = MODULE_NAME, | 335 | .name = MODULE_NAME, |
350 | .ctrls = sd_ctrls, | ||
351 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
352 | .config = sd_config, | 336 | .config = sd_config, |
353 | .init = sd_init, | 337 | .init = sd_init, |
338 | .init_controls = sd_init_controls, | ||
354 | .start = sd_start, | 339 | .start = sd_start, |
355 | .stop0 = sd_stop0, | 340 | .stop0 = sd_stop0, |
356 | }; | 341 | }; |
@@ -373,6 +358,7 @@ static struct usb_driver sd_driver = { | |||
373 | #ifdef CONFIG_PM | 358 | #ifdef CONFIG_PM |
374 | .suspend = gspca_suspend, | 359 | .suspend = gspca_suspend, |
375 | .resume = gspca_resume, | 360 | .resume = gspca_resume, |
361 | .reset_resume = gspca_resume, | ||
376 | #endif | 362 | #endif |
377 | }; | 363 | }; |
378 | 364 | ||
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 27d2cef0692a..9e3a909e0a00 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c | |||
@@ -404,9 +404,14 @@ static void w9968cf_set_crop_window(struct sd *sd) | |||
404 | } | 404 | } |
405 | 405 | ||
406 | if (sd->sensor == SEN_OV7620) { | 406 | if (sd->sensor == SEN_OV7620) { |
407 | /* Sigh, this is dependend on the clock / framerate changes | 407 | /* |
408 | made by the frequency control, sick. */ | 408 | * Sigh, this is dependend on the clock / framerate changes |
409 | if (sd->ctrls[FREQ].val == 1) { | 409 | * made by the frequency control, sick. |
410 | * | ||
411 | * Note we cannot use v4l2_ctrl_g_ctrl here, as we get called | ||
412 | * from ov519.c:setfreq() with the ctrl lock held! | ||
413 | */ | ||
414 | if (sd->freq->val == 1) { | ||
410 | start_cropx = 277; | 415 | start_cropx = 277; |
411 | start_cropy = 37; | 416 | start_cropy = 37; |
412 | } else { | 417 | } else { |
@@ -474,8 +479,9 @@ static void w9968cf_mode_init_regs(struct sd *sd) | |||
474 | /* We may get called multiple times (usb isoc bw negotiat.) */ | 479 | /* We may get called multiple times (usb isoc bw negotiat.) */ |
475 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, | 480 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, |
476 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ | 481 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ |
477 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 482 | jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); |
478 | w9968cf_upload_quantizationtables(sd); | 483 | w9968cf_upload_quantizationtables(sd); |
484 | v4l2_ctrl_grab(sd->jpegqual, true); | ||
479 | } | 485 | } |
480 | 486 | ||
481 | /* Video Capture Control Register */ | 487 | /* Video Capture Control Register */ |
@@ -514,6 +520,7 @@ static void w9968cf_mode_init_regs(struct sd *sd) | |||
514 | 520 | ||
515 | static void w9968cf_stop0(struct sd *sd) | 521 | static void w9968cf_stop0(struct sd *sd) |
516 | { | 522 | { |
523 | v4l2_ctrl_grab(sd->jpegqual, false); | ||
517 | reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ | 524 | reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ |
518 | reg_w(sd, 0x16, 0x0000); /* stop video capture */ | 525 | reg_w(sd, 0x16, 0x0000); /* stop video capture */ |
519 | } | 526 | } |
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c index ecada178bceb..13b8d395d210 100644 --- a/drivers/media/video/gspca/xirlink_cit.c +++ b/drivers/media/video/gspca/xirlink_cit.c | |||
@@ -53,6 +53,7 @@ MODULE_PARM_DESC(rca_input, | |||
53 | /* specific webcam descriptor */ | 53 | /* specific webcam descriptor */ |
54 | struct sd { | 54 | struct sd { |
55 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 55 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
56 | struct v4l2_ctrl *lighting; | ||
56 | u8 model; | 57 | u8 model; |
57 | #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */ | 58 | #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */ |
58 | #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */ | 59 | #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */ |
@@ -65,127 +66,10 @@ struct sd { | |||
65 | u8 stop_on_control_change; | 66 | u8 stop_on_control_change; |
66 | u8 sof_read; | 67 | u8 sof_read; |
67 | u8 sof_len; | 68 | u8 sof_len; |
68 | u8 contrast; | ||
69 | u8 brightness; | ||
70 | u8 hue; | ||
71 | u8 sharpness; | ||
72 | u8 lighting; | ||
73 | u8 hflip; | ||
74 | }; | 69 | }; |
75 | 70 | ||
76 | /* V4L2 controls supported by the driver */ | ||
77 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
88 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | static void sd_stop0(struct gspca_dev *gspca_dev); | 71 | static void sd_stop0(struct gspca_dev *gspca_dev); |
90 | 72 | ||
91 | static const struct ctrl sd_ctrls[] = { | ||
92 | #define SD_BRIGHTNESS 0 | ||
93 | { | ||
94 | { | ||
95 | .id = V4L2_CID_BRIGHTNESS, | ||
96 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
97 | .name = "Brightness", | ||
98 | .minimum = 0, | ||
99 | .maximum = 63, | ||
100 | .step = 1, | ||
101 | #define BRIGHTNESS_DEFAULT 32 | ||
102 | .default_value = BRIGHTNESS_DEFAULT, | ||
103 | .flags = 0, | ||
104 | }, | ||
105 | .set = sd_setbrightness, | ||
106 | .get = sd_getbrightness, | ||
107 | }, | ||
108 | #define SD_CONTRAST 1 | ||
109 | { | ||
110 | { | ||
111 | .id = V4L2_CID_CONTRAST, | ||
112 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
113 | .name = "contrast", | ||
114 | .minimum = 0, | ||
115 | .maximum = 20, | ||
116 | .step = 1, | ||
117 | #define CONTRAST_DEFAULT 10 | ||
118 | .default_value = CONTRAST_DEFAULT, | ||
119 | .flags = 0, | ||
120 | }, | ||
121 | .set = sd_setcontrast, | ||
122 | .get = sd_getcontrast, | ||
123 | }, | ||
124 | #define SD_HUE 2 | ||
125 | { | ||
126 | { | ||
127 | .id = V4L2_CID_HUE, | ||
128 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
129 | .name = "Hue", | ||
130 | .minimum = 0, | ||
131 | .maximum = 127, | ||
132 | .step = 1, | ||
133 | #define HUE_DEFAULT 63 | ||
134 | .default_value = HUE_DEFAULT, | ||
135 | .flags = 0, | ||
136 | }, | ||
137 | .set = sd_sethue, | ||
138 | .get = sd_gethue, | ||
139 | }, | ||
140 | #define SD_SHARPNESS 3 | ||
141 | { | ||
142 | { | ||
143 | .id = V4L2_CID_SHARPNESS, | ||
144 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
145 | .name = "Sharpness", | ||
146 | .minimum = 0, | ||
147 | .maximum = 6, | ||
148 | .step = 1, | ||
149 | #define SHARPNESS_DEFAULT 3 | ||
150 | .default_value = SHARPNESS_DEFAULT, | ||
151 | .flags = 0, | ||
152 | }, | ||
153 | .set = sd_setsharpness, | ||
154 | .get = sd_getsharpness, | ||
155 | }, | ||
156 | #define SD_LIGHTING 4 | ||
157 | { | ||
158 | { | ||
159 | .id = V4L2_CID_BACKLIGHT_COMPENSATION, | ||
160 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
161 | .name = "Lighting", | ||
162 | .minimum = 0, | ||
163 | .maximum = 2, | ||
164 | .step = 1, | ||
165 | #define LIGHTING_DEFAULT 1 | ||
166 | .default_value = LIGHTING_DEFAULT, | ||
167 | .flags = 0, | ||
168 | }, | ||
169 | .set = sd_setlighting, | ||
170 | .get = sd_getlighting, | ||
171 | }, | ||
172 | #define SD_HFLIP 5 | ||
173 | { | ||
174 | { | ||
175 | .id = V4L2_CID_HFLIP, | ||
176 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
177 | .name = "Mirror", | ||
178 | .minimum = 0, | ||
179 | .maximum = 1, | ||
180 | .step = 1, | ||
181 | #define HFLIP_DEFAULT 0 | ||
182 | .default_value = HFLIP_DEFAULT, | ||
183 | }, | ||
184 | .set = sd_sethflip, | ||
185 | .get = sd_gethflip, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static const struct v4l2_pix_format cif_yuv_mode[] = { | 73 | static const struct v4l2_pix_format cif_yuv_mode[] = { |
190 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 74 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
191 | .bytesperline = 176, | 75 | .bytesperline = 176, |
@@ -995,56 +879,36 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
995 | case CIT_MODEL0: | 879 | case CIT_MODEL0: |
996 | cam->cam_mode = model0_mode; | 880 | cam->cam_mode = model0_mode; |
997 | cam->nmodes = ARRAY_SIZE(model0_mode); | 881 | cam->nmodes = ARRAY_SIZE(model0_mode); |
998 | gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP)); | ||
999 | sd->sof_len = 4; | 882 | sd->sof_len = 4; |
1000 | break; | 883 | break; |
1001 | case CIT_MODEL1: | 884 | case CIT_MODEL1: |
1002 | cam->cam_mode = cif_yuv_mode; | 885 | cam->cam_mode = cif_yuv_mode; |
1003 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); | 886 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); |
1004 | gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP); | ||
1005 | sd->sof_len = 4; | 887 | sd->sof_len = 4; |
1006 | break; | 888 | break; |
1007 | case CIT_MODEL2: | 889 | case CIT_MODEL2: |
1008 | cam->cam_mode = model2_mode + 1; /* no 160x120 */ | 890 | cam->cam_mode = model2_mode + 1; /* no 160x120 */ |
1009 | cam->nmodes = 3; | 891 | cam->nmodes = 3; |
1010 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | | ||
1011 | (1 << SD_SHARPNESS) | | ||
1012 | (1 << SD_HFLIP); | ||
1013 | break; | 892 | break; |
1014 | case CIT_MODEL3: | 893 | case CIT_MODEL3: |
1015 | cam->cam_mode = vga_yuv_mode; | 894 | cam->cam_mode = vga_yuv_mode; |
1016 | cam->nmodes = ARRAY_SIZE(vga_yuv_mode); | 895 | cam->nmodes = ARRAY_SIZE(vga_yuv_mode); |
1017 | gspca_dev->ctrl_dis = (1 << SD_HUE) | | ||
1018 | (1 << SD_LIGHTING) | | ||
1019 | (1 << SD_HFLIP); | ||
1020 | sd->stop_on_control_change = 1; | 896 | sd->stop_on_control_change = 1; |
1021 | sd->sof_len = 4; | 897 | sd->sof_len = 4; |
1022 | break; | 898 | break; |
1023 | case CIT_MODEL4: | 899 | case CIT_MODEL4: |
1024 | cam->cam_mode = model2_mode; | 900 | cam->cam_mode = model2_mode; |
1025 | cam->nmodes = ARRAY_SIZE(model2_mode); | 901 | cam->nmodes = ARRAY_SIZE(model2_mode); |
1026 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | | ||
1027 | (1 << SD_SHARPNESS) | | ||
1028 | (1 << SD_LIGHTING) | | ||
1029 | (1 << SD_HFLIP); | ||
1030 | break; | 902 | break; |
1031 | case CIT_IBM_NETCAM_PRO: | 903 | case CIT_IBM_NETCAM_PRO: |
1032 | cam->cam_mode = vga_yuv_mode; | 904 | cam->cam_mode = vga_yuv_mode; |
1033 | cam->nmodes = 2; /* no 640 x 480 */ | 905 | cam->nmodes = 2; /* no 640 x 480 */ |
1034 | cam->input_flags = V4L2_IN_ST_VFLIP; | 906 | cam->input_flags = V4L2_IN_ST_VFLIP; |
1035 | gspca_dev->ctrl_dis = ~(1 << SD_CONTRAST); | ||
1036 | sd->stop_on_control_change = 1; | 907 | sd->stop_on_control_change = 1; |
1037 | sd->sof_len = 4; | 908 | sd->sof_len = 4; |
1038 | break; | 909 | break; |
1039 | } | 910 | } |
1040 | 911 | ||
1041 | sd->brightness = BRIGHTNESS_DEFAULT; | ||
1042 | sd->contrast = CONTRAST_DEFAULT; | ||
1043 | sd->hue = HUE_DEFAULT; | ||
1044 | sd->sharpness = SHARPNESS_DEFAULT; | ||
1045 | sd->lighting = LIGHTING_DEFAULT; | ||
1046 | sd->hflip = HFLIP_DEFAULT; | ||
1047 | |||
1048 | return 0; | 912 | return 0; |
1049 | } | 913 | } |
1050 | 914 | ||
@@ -1287,7 +1151,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1287 | return 0; | 1151 | return 0; |
1288 | } | 1152 | } |
1289 | 1153 | ||
1290 | static int cit_set_brightness(struct gspca_dev *gspca_dev) | 1154 | static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val) |
1291 | { | 1155 | { |
1292 | struct sd *sd = (struct sd *) gspca_dev; | 1156 | struct sd *sd = (struct sd *) gspca_dev; |
1293 | int i; | 1157 | int i; |
@@ -1299,19 +1163,19 @@ static int cit_set_brightness(struct gspca_dev *gspca_dev) | |||
1299 | break; | 1163 | break; |
1300 | case CIT_MODEL1: | 1164 | case CIT_MODEL1: |
1301 | /* Model 1: Brightness range 0 - 63 */ | 1165 | /* Model 1: Brightness range 0 - 63 */ |
1302 | cit_Packet_Format1(gspca_dev, 0x0031, sd->brightness); | 1166 | cit_Packet_Format1(gspca_dev, 0x0031, val); |
1303 | cit_Packet_Format1(gspca_dev, 0x0032, sd->brightness); | 1167 | cit_Packet_Format1(gspca_dev, 0x0032, val); |
1304 | cit_Packet_Format1(gspca_dev, 0x0033, sd->brightness); | 1168 | cit_Packet_Format1(gspca_dev, 0x0033, val); |
1305 | break; | 1169 | break; |
1306 | case CIT_MODEL2: | 1170 | case CIT_MODEL2: |
1307 | /* Model 2: Brightness range 0x60 - 0xee */ | 1171 | /* Model 2: Brightness range 0x60 - 0xee */ |
1308 | /* Scale 0 - 63 to 0x60 - 0xee */ | 1172 | /* Scale 0 - 63 to 0x60 - 0xee */ |
1309 | i = 0x60 + sd->brightness * 2254 / 1000; | 1173 | i = 0x60 + val * 2254 / 1000; |
1310 | cit_model2_Packet1(gspca_dev, 0x001a, i); | 1174 | cit_model2_Packet1(gspca_dev, 0x001a, i); |
1311 | break; | 1175 | break; |
1312 | case CIT_MODEL3: | 1176 | case CIT_MODEL3: |
1313 | /* Model 3: Brightness range 'i' in [0x0C..0x3F] */ | 1177 | /* Model 3: Brightness range 'i' in [0x0C..0x3F] */ |
1314 | i = sd->brightness; | 1178 | i = val; |
1315 | if (i < 0x0c) | 1179 | if (i < 0x0c) |
1316 | i = 0x0c; | 1180 | i = 0x0c; |
1317 | cit_model3_Packet1(gspca_dev, 0x0036, i); | 1181 | cit_model3_Packet1(gspca_dev, 0x0036, i); |
@@ -1319,7 +1183,7 @@ static int cit_set_brightness(struct gspca_dev *gspca_dev) | |||
1319 | case CIT_MODEL4: | 1183 | case CIT_MODEL4: |
1320 | /* Model 4: Brightness range 'i' in [0x04..0xb4] */ | 1184 | /* Model 4: Brightness range 'i' in [0x04..0xb4] */ |
1321 | /* Scale 0 - 63 to 0x04 - 0xb4 */ | 1185 | /* Scale 0 - 63 to 0x04 - 0xb4 */ |
1322 | i = 0x04 + sd->brightness * 2794 / 1000; | 1186 | i = 0x04 + val * 2794 / 1000; |
1323 | cit_model4_BrightnessPacket(gspca_dev, i); | 1187 | cit_model4_BrightnessPacket(gspca_dev, i); |
1324 | break; | 1188 | break; |
1325 | } | 1189 | } |
@@ -1327,7 +1191,7 @@ static int cit_set_brightness(struct gspca_dev *gspca_dev) | |||
1327 | return 0; | 1191 | return 0; |
1328 | } | 1192 | } |
1329 | 1193 | ||
1330 | static int cit_set_contrast(struct gspca_dev *gspca_dev) | 1194 | static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val) |
1331 | { | 1195 | { |
1332 | struct sd *sd = (struct sd *) gspca_dev; | 1196 | struct sd *sd = (struct sd *) gspca_dev; |
1333 | 1197 | ||
@@ -1335,16 +1199,16 @@ static int cit_set_contrast(struct gspca_dev *gspca_dev) | |||
1335 | case CIT_MODEL0: { | 1199 | case CIT_MODEL0: { |
1336 | int i; | 1200 | int i; |
1337 | /* gain 0-15, 0-20 -> 0-15 */ | 1201 | /* gain 0-15, 0-20 -> 0-15 */ |
1338 | i = sd->contrast * 1000 / 1333; | 1202 | i = val * 1000 / 1333; |
1339 | cit_write_reg(gspca_dev, i, 0x0422); | 1203 | cit_write_reg(gspca_dev, i, 0x0422); |
1340 | /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */ | 1204 | /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */ |
1341 | i = sd->contrast * 2000 / 1333; | 1205 | i = val * 2000 / 1333; |
1342 | cit_write_reg(gspca_dev, i, 0x0423); | 1206 | cit_write_reg(gspca_dev, i, 0x0423); |
1343 | /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */ | 1207 | /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */ |
1344 | i = sd->contrast * 4000 / 1333; | 1208 | i = val * 4000 / 1333; |
1345 | cit_write_reg(gspca_dev, i, 0x0424); | 1209 | cit_write_reg(gspca_dev, i, 0x0424); |
1346 | /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */ | 1210 | /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */ |
1347 | i = sd->contrast * 8000 / 1333; | 1211 | i = val * 8000 / 1333; |
1348 | cit_write_reg(gspca_dev, i, 0x0425); | 1212 | cit_write_reg(gspca_dev, i, 0x0425); |
1349 | break; | 1213 | break; |
1350 | } | 1214 | } |
@@ -1355,7 +1219,7 @@ static int cit_set_contrast(struct gspca_dev *gspca_dev) | |||
1355 | case CIT_MODEL1: | 1219 | case CIT_MODEL1: |
1356 | { | 1220 | { |
1357 | /* Scale 0 - 20 to 15 - 0 */ | 1221 | /* Scale 0 - 20 to 15 - 0 */ |
1358 | int i, new_contrast = (20 - sd->contrast) * 1000 / 1333; | 1222 | int i, new_contrast = (20 - val) * 1000 / 1333; |
1359 | for (i = 0; i < cit_model1_ntries; i++) { | 1223 | for (i = 0; i < cit_model1_ntries; i++) { |
1360 | cit_Packet_Format1(gspca_dev, 0x0014, new_contrast); | 1224 | cit_Packet_Format1(gspca_dev, 0x0014, new_contrast); |
1361 | cit_send_FF_04_02(gspca_dev); | 1225 | cit_send_FF_04_02(gspca_dev); |
@@ -1377,20 +1241,20 @@ static int cit_set_contrast(struct gspca_dev *gspca_dev) | |||
1377 | { 0x01, 0x0e, 0x16 }, | 1241 | { 0x01, 0x0e, 0x16 }, |
1378 | { 0x01, 0x10, 0x16 } /* Maximum */ | 1242 | { 0x01, 0x10, 0x16 } /* Maximum */ |
1379 | }; | 1243 | }; |
1380 | int i = sd->contrast / 3; | 1244 | int i = val / 3; |
1381 | cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1); | 1245 | cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1); |
1382 | cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2); | 1246 | cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2); |
1383 | cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3); | 1247 | cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3); |
1384 | break; | 1248 | break; |
1385 | } | 1249 | } |
1386 | case CIT_IBM_NETCAM_PRO: | 1250 | case CIT_IBM_NETCAM_PRO: |
1387 | cit_model3_Packet1(gspca_dev, 0x005b, sd->contrast + 1); | 1251 | cit_model3_Packet1(gspca_dev, 0x005b, val + 1); |
1388 | break; | 1252 | break; |
1389 | } | 1253 | } |
1390 | return 0; | 1254 | return 0; |
1391 | } | 1255 | } |
1392 | 1256 | ||
1393 | static int cit_set_hue(struct gspca_dev *gspca_dev) | 1257 | static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val) |
1394 | { | 1258 | { |
1395 | struct sd *sd = (struct sd *) gspca_dev; | 1259 | struct sd *sd = (struct sd *) gspca_dev; |
1396 | 1260 | ||
@@ -1401,7 +1265,7 @@ static int cit_set_hue(struct gspca_dev *gspca_dev) | |||
1401 | /* No hue control for these models */ | 1265 | /* No hue control for these models */ |
1402 | break; | 1266 | break; |
1403 | case CIT_MODEL2: | 1267 | case CIT_MODEL2: |
1404 | cit_model2_Packet1(gspca_dev, 0x0024, sd->hue); | 1268 | cit_model2_Packet1(gspca_dev, 0x0024, val); |
1405 | /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */ | 1269 | /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */ |
1406 | break; | 1270 | break; |
1407 | case CIT_MODEL3: { | 1271 | case CIT_MODEL3: { |
@@ -1409,7 +1273,7 @@ static int cit_set_hue(struct gspca_dev *gspca_dev) | |||
1409 | /* TESTME according to the ibmcam driver this does not work */ | 1273 | /* TESTME according to the ibmcam driver this does not work */ |
1410 | if (0) { | 1274 | if (0) { |
1411 | /* Scale 0 - 127 to 0x05 - 0x37 */ | 1275 | /* Scale 0 - 127 to 0x05 - 0x37 */ |
1412 | int i = 0x05 + sd->hue * 1000 / 2540; | 1276 | int i = 0x05 + val * 1000 / 2540; |
1413 | cit_model3_Packet1(gspca_dev, 0x007e, i); | 1277 | cit_model3_Packet1(gspca_dev, 0x007e, i); |
1414 | } | 1278 | } |
1415 | break; | 1279 | break; |
@@ -1435,14 +1299,14 @@ static int cit_set_hue(struct gspca_dev *gspca_dev) | |||
1435 | cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */ | 1299 | cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */ |
1436 | cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */ | 1300 | cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */ |
1437 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | 1301 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); |
1438 | cit_write_reg(gspca_dev, sd->hue, 0x012d); /* Hue */ | 1302 | cit_write_reg(gspca_dev, val, 0x012d); /* Hue */ |
1439 | cit_write_reg(gspca_dev, 0xf545, 0x0124); | 1303 | cit_write_reg(gspca_dev, 0xf545, 0x0124); |
1440 | break; | 1304 | break; |
1441 | } | 1305 | } |
1442 | return 0; | 1306 | return 0; |
1443 | } | 1307 | } |
1444 | 1308 | ||
1445 | static int cit_set_sharpness(struct gspca_dev *gspca_dev) | 1309 | static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val) |
1446 | { | 1310 | { |
1447 | struct sd *sd = (struct sd *) gspca_dev; | 1311 | struct sd *sd = (struct sd *) gspca_dev; |
1448 | 1312 | ||
@@ -1459,7 +1323,7 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev) | |||
1459 | 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; | 1323 | 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; |
1460 | 1324 | ||
1461 | for (i = 0; i < cit_model1_ntries; i++) | 1325 | for (i = 0; i < cit_model1_ntries; i++) |
1462 | cit_PacketFormat2(gspca_dev, 0x0013, sa[sd->sharpness]); | 1326 | cit_PacketFormat2(gspca_dev, 0x0013, sa[val]); |
1463 | break; | 1327 | break; |
1464 | } | 1328 | } |
1465 | case CIT_MODEL3: | 1329 | case CIT_MODEL3: |
@@ -1482,10 +1346,10 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev) | |||
1482 | { 0x03, 0x06, 0x05, 0x14 }, | 1346 | { 0x03, 0x06, 0x05, 0x14 }, |
1483 | { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */ | 1347 | { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */ |
1484 | }; | 1348 | }; |
1485 | cit_model3_Packet1(gspca_dev, 0x0060, sv[sd->sharpness].sv1); | 1349 | cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1); |
1486 | cit_model3_Packet1(gspca_dev, 0x0061, sv[sd->sharpness].sv2); | 1350 | cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2); |
1487 | cit_model3_Packet1(gspca_dev, 0x0062, sv[sd->sharpness].sv3); | 1351 | cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3); |
1488 | cit_model3_Packet1(gspca_dev, 0x0063, sv[sd->sharpness].sv4); | 1352 | cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4); |
1489 | break; | 1353 | break; |
1490 | } | 1354 | } |
1491 | } | 1355 | } |
@@ -1510,7 +1374,7 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev) | |||
1510 | * 1/5/00 Created. | 1374 | * 1/5/00 Created. |
1511 | * 2/20/00 Added support for Model 2 cameras. | 1375 | * 2/20/00 Added support for Model 2 cameras. |
1512 | */ | 1376 | */ |
1513 | static void cit_set_lighting(struct gspca_dev *gspca_dev) | 1377 | static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val) |
1514 | { | 1378 | { |
1515 | struct sd *sd = (struct sd *) gspca_dev; | 1379 | struct sd *sd = (struct sd *) gspca_dev; |
1516 | 1380 | ||
@@ -1524,19 +1388,19 @@ static void cit_set_lighting(struct gspca_dev *gspca_dev) | |||
1524 | case CIT_MODEL1: { | 1388 | case CIT_MODEL1: { |
1525 | int i; | 1389 | int i; |
1526 | for (i = 0; i < cit_model1_ntries; i++) | 1390 | for (i = 0; i < cit_model1_ntries; i++) |
1527 | cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting); | 1391 | cit_Packet_Format1(gspca_dev, 0x0027, val); |
1528 | break; | 1392 | break; |
1529 | } | 1393 | } |
1530 | } | 1394 | } |
1531 | } | 1395 | } |
1532 | 1396 | ||
1533 | static void cit_set_hflip(struct gspca_dev *gspca_dev) | 1397 | static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val) |
1534 | { | 1398 | { |
1535 | struct sd *sd = (struct sd *) gspca_dev; | 1399 | struct sd *sd = (struct sd *) gspca_dev; |
1536 | 1400 | ||
1537 | switch (sd->model) { | 1401 | switch (sd->model) { |
1538 | case CIT_MODEL0: | 1402 | case CIT_MODEL0: |
1539 | if (sd->hflip) | 1403 | if (val) |
1540 | cit_write_reg(gspca_dev, 0x0020, 0x0115); | 1404 | cit_write_reg(gspca_dev, 0x0020, 0x0115); |
1541 | else | 1405 | else |
1542 | cit_write_reg(gspca_dev, 0x0040, 0x0115); | 1406 | cit_write_reg(gspca_dev, 0x0040, 0x0115); |
@@ -1831,7 +1695,8 @@ static int cit_start_model1(struct gspca_dev *gspca_dev) | |||
1831 | cit_PacketFormat2(gspca_dev, 0x13, 0x1a); | 1695 | cit_PacketFormat2(gspca_dev, 0x13, 0x1a); |
1832 | 1696 | ||
1833 | /* Default lighting conditions */ | 1697 | /* Default lighting conditions */ |
1834 | cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting); | 1698 | cit_Packet_Format1(gspca_dev, 0x0027, |
1699 | v4l2_ctrl_g_ctrl(sd->lighting)); | ||
1835 | } | 1700 | } |
1836 | 1701 | ||
1837 | /* Assorted init */ | 1702 | /* Assorted init */ |
@@ -2049,9 +1914,10 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
2049 | break; | 1914 | break; |
2050 | } | 1915 | } |
2051 | 1916 | ||
2052 | /* FIXME this cannot be changed while streaming, so we | 1917 | cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting)); |
2053 | should report a grabbed flag for this control. */ | 1918 | /* model2 cannot change the backlight compensation while streaming */ |
2054 | cit_model2_Packet1(gspca_dev, 0x0028, sd->lighting); | 1919 | v4l2_ctrl_grab(sd->lighting, true); |
1920 | |||
2055 | /* color balance rg2 */ | 1921 | /* color balance rg2 */ |
2056 | cit_model2_Packet1(gspca_dev, 0x001e, 0x002f); | 1922 | cit_model2_Packet1(gspca_dev, 0x001e, 0x002f); |
2057 | /* saturation */ | 1923 | /* saturation */ |
@@ -2755,13 +2621,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2755 | break; | 2621 | break; |
2756 | } | 2622 | } |
2757 | 2623 | ||
2758 | cit_set_brightness(gspca_dev); | ||
2759 | cit_set_contrast(gspca_dev); | ||
2760 | cit_set_hue(gspca_dev); | ||
2761 | cit_set_sharpness(gspca_dev); | ||
2762 | cit_set_lighting(gspca_dev); | ||
2763 | cit_set_hflip(gspca_dev); | ||
2764 | |||
2765 | /* Program max isoc packet size */ | 2624 | /* Program max isoc packet size */ |
2766 | cit_write_reg(gspca_dev, packet_size >> 8, 0x0106); | 2625 | cit_write_reg(gspca_dev, packet_size >> 8, 0x0106); |
2767 | cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107); | 2626 | cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107); |
@@ -2857,6 +2716,8 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2857 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ | 2716 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ |
2858 | break; | 2717 | break; |
2859 | case CIT_MODEL2: | 2718 | case CIT_MODEL2: |
2719 | v4l2_ctrl_grab(sd->lighting, false); | ||
2720 | /* Fall through! */ | ||
2860 | case CIT_MODEL4: | 2721 | case CIT_MODEL4: |
2861 | cit_model2_Packet1(gspca_dev, 0x0030, 0x0004); | 2722 | cit_model2_Packet1(gspca_dev, 0x0030, 0x0004); |
2862 | 2723 | ||
@@ -3055,152 +2916,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
3055 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 2916 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
3056 | } | 2917 | } |
3057 | 2918 | ||
3058 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
3059 | { | ||
3060 | struct sd *sd = (struct sd *) gspca_dev; | ||
3061 | |||
3062 | sd->brightness = val; | ||
3063 | if (gspca_dev->streaming) { | ||
3064 | if (sd->stop_on_control_change) | ||
3065 | sd_stopN(gspca_dev); | ||
3066 | cit_set_brightness(gspca_dev); | ||
3067 | if (sd->stop_on_control_change) | ||
3068 | cit_restart_stream(gspca_dev); | ||
3069 | } | ||
3070 | |||
3071 | return 0; | ||
3072 | } | ||
3073 | |||
3074 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
3075 | { | ||
3076 | struct sd *sd = (struct sd *) gspca_dev; | ||
3077 | |||
3078 | *val = sd->brightness; | ||
3079 | |||
3080 | return 0; | ||
3081 | } | ||
3082 | |||
3083 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
3084 | { | ||
3085 | struct sd *sd = (struct sd *) gspca_dev; | ||
3086 | |||
3087 | sd->contrast = val; | ||
3088 | if (gspca_dev->streaming) { | ||
3089 | if (sd->stop_on_control_change) | ||
3090 | sd_stopN(gspca_dev); | ||
3091 | cit_set_contrast(gspca_dev); | ||
3092 | if (sd->stop_on_control_change) | ||
3093 | cit_restart_stream(gspca_dev); | ||
3094 | } | ||
3095 | |||
3096 | return 0; | ||
3097 | } | ||
3098 | |||
3099 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
3100 | { | ||
3101 | struct sd *sd = (struct sd *) gspca_dev; | ||
3102 | |||
3103 | *val = sd->contrast; | ||
3104 | |||
3105 | return 0; | ||
3106 | } | ||
3107 | |||
3108 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
3109 | { | ||
3110 | struct sd *sd = (struct sd *) gspca_dev; | ||
3111 | |||
3112 | sd->hue = val; | ||
3113 | if (gspca_dev->streaming) { | ||
3114 | if (sd->stop_on_control_change) | ||
3115 | sd_stopN(gspca_dev); | ||
3116 | cit_set_hue(gspca_dev); | ||
3117 | if (sd->stop_on_control_change) | ||
3118 | cit_restart_stream(gspca_dev); | ||
3119 | } | ||
3120 | return 0; | ||
3121 | } | ||
3122 | |||
3123 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
3124 | { | ||
3125 | struct sd *sd = (struct sd *) gspca_dev; | ||
3126 | |||
3127 | *val = sd->hue; | ||
3128 | |||
3129 | return 0; | ||
3130 | } | ||
3131 | |||
3132 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
3133 | { | ||
3134 | struct sd *sd = (struct sd *) gspca_dev; | ||
3135 | |||
3136 | sd->sharpness = val; | ||
3137 | if (gspca_dev->streaming) { | ||
3138 | if (sd->stop_on_control_change) | ||
3139 | sd_stopN(gspca_dev); | ||
3140 | cit_set_sharpness(gspca_dev); | ||
3141 | if (sd->stop_on_control_change) | ||
3142 | cit_restart_stream(gspca_dev); | ||
3143 | } | ||
3144 | return 0; | ||
3145 | } | ||
3146 | |||
3147 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
3148 | { | ||
3149 | struct sd *sd = (struct sd *) gspca_dev; | ||
3150 | |||
3151 | *val = sd->sharpness; | ||
3152 | |||
3153 | return 0; | ||
3154 | } | ||
3155 | |||
3156 | static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val) | ||
3157 | { | ||
3158 | struct sd *sd = (struct sd *) gspca_dev; | ||
3159 | |||
3160 | sd->lighting = val; | ||
3161 | if (gspca_dev->streaming) { | ||
3162 | if (sd->stop_on_control_change) | ||
3163 | sd_stopN(gspca_dev); | ||
3164 | cit_set_lighting(gspca_dev); | ||
3165 | if (sd->stop_on_control_change) | ||
3166 | cit_restart_stream(gspca_dev); | ||
3167 | } | ||
3168 | return 0; | ||
3169 | } | ||
3170 | |||
3171 | static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val) | ||
3172 | { | ||
3173 | struct sd *sd = (struct sd *) gspca_dev; | ||
3174 | |||
3175 | *val = sd->lighting; | ||
3176 | |||
3177 | return 0; | ||
3178 | } | ||
3179 | |||
3180 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
3181 | { | ||
3182 | struct sd *sd = (struct sd *) gspca_dev; | ||
3183 | |||
3184 | sd->hflip = val; | ||
3185 | if (gspca_dev->streaming) { | ||
3186 | if (sd->stop_on_control_change) | ||
3187 | sd_stopN(gspca_dev); | ||
3188 | cit_set_hflip(gspca_dev); | ||
3189 | if (sd->stop_on_control_change) | ||
3190 | cit_restart_stream(gspca_dev); | ||
3191 | } | ||
3192 | return 0; | ||
3193 | } | ||
3194 | |||
3195 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
3196 | { | ||
3197 | struct sd *sd = (struct sd *) gspca_dev; | ||
3198 | |||
3199 | *val = sd->hflip; | ||
3200 | |||
3201 | return 0; | ||
3202 | } | ||
3203 | |||
3204 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 2919 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
3205 | static void cit_check_button(struct gspca_dev *gspca_dev) | 2920 | static void cit_check_button(struct gspca_dev *gspca_dev) |
3206 | { | 2921 | { |
@@ -3234,13 +2949,117 @@ static void cit_check_button(struct gspca_dev *gspca_dev) | |||
3234 | } | 2949 | } |
3235 | #endif | 2950 | #endif |
3236 | 2951 | ||
2952 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | ||
2953 | { | ||
2954 | struct gspca_dev *gspca_dev = | ||
2955 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
2956 | struct sd *sd = (struct sd *)gspca_dev; | ||
2957 | |||
2958 | gspca_dev->usb_err = 0; | ||
2959 | |||
2960 | if (!gspca_dev->streaming) | ||
2961 | return 0; | ||
2962 | |||
2963 | if (sd->stop_on_control_change) | ||
2964 | sd_stopN(gspca_dev); | ||
2965 | switch (ctrl->id) { | ||
2966 | case V4L2_CID_BRIGHTNESS: | ||
2967 | cit_set_brightness(gspca_dev, ctrl->val); | ||
2968 | break; | ||
2969 | case V4L2_CID_CONTRAST: | ||
2970 | cit_set_contrast(gspca_dev, ctrl->val); | ||
2971 | break; | ||
2972 | case V4L2_CID_HUE: | ||
2973 | cit_set_hue(gspca_dev, ctrl->val); | ||
2974 | break; | ||
2975 | case V4L2_CID_HFLIP: | ||
2976 | cit_set_hflip(gspca_dev, ctrl->val); | ||
2977 | break; | ||
2978 | case V4L2_CID_SHARPNESS: | ||
2979 | cit_set_sharpness(gspca_dev, ctrl->val); | ||
2980 | break; | ||
2981 | case V4L2_CID_BACKLIGHT_COMPENSATION: | ||
2982 | cit_set_lighting(gspca_dev, ctrl->val); | ||
2983 | break; | ||
2984 | } | ||
2985 | if (sd->stop_on_control_change) | ||
2986 | cit_restart_stream(gspca_dev); | ||
2987 | return gspca_dev->usb_err; | ||
2988 | } | ||
2989 | |||
2990 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
2991 | .s_ctrl = sd_s_ctrl, | ||
2992 | }; | ||
2993 | |||
2994 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
2995 | { | ||
2996 | struct sd *sd = (struct sd *)gspca_dev; | ||
2997 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
2998 | bool has_brightness; | ||
2999 | bool has_contrast; | ||
3000 | bool has_hue; | ||
3001 | bool has_sharpness; | ||
3002 | bool has_lighting; | ||
3003 | bool has_hflip; | ||
3004 | |||
3005 | has_brightness = has_contrast = has_hue = | ||
3006 | has_sharpness = has_hflip = has_lighting = false; | ||
3007 | switch (sd->model) { | ||
3008 | case CIT_MODEL0: | ||
3009 | has_contrast = has_hflip = true; | ||
3010 | break; | ||
3011 | case CIT_MODEL1: | ||
3012 | has_brightness = has_contrast = | ||
3013 | has_sharpness = has_lighting = true; | ||
3014 | break; | ||
3015 | case CIT_MODEL2: | ||
3016 | has_brightness = has_hue = has_lighting = true; | ||
3017 | break; | ||
3018 | case CIT_MODEL3: | ||
3019 | has_brightness = has_contrast = has_sharpness = true; | ||
3020 | break; | ||
3021 | case CIT_MODEL4: | ||
3022 | has_brightness = has_hue = true; | ||
3023 | break; | ||
3024 | case CIT_IBM_NETCAM_PRO: | ||
3025 | has_brightness = has_hue = | ||
3026 | has_sharpness = has_hflip = has_lighting = true; | ||
3027 | break; | ||
3028 | } | ||
3029 | gspca_dev->vdev.ctrl_handler = hdl; | ||
3030 | v4l2_ctrl_handler_init(hdl, 5); | ||
3031 | if (has_brightness) | ||
3032 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3033 | V4L2_CID_BRIGHTNESS, 0, 63, 1, 32); | ||
3034 | if (has_contrast) | ||
3035 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3036 | V4L2_CID_CONTRAST, 0, 20, 1, 10); | ||
3037 | if (has_hue) | ||
3038 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3039 | V4L2_CID_HUE, 0, 127, 1, 63); | ||
3040 | if (has_sharpness) | ||
3041 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3042 | V4L2_CID_SHARPNESS, 0, 6, 1, 3); | ||
3043 | if (has_lighting) | ||
3044 | sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3045 | V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1); | ||
3046 | if (has_hflip) | ||
3047 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3048 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
3049 | |||
3050 | if (hdl->error) { | ||
3051 | pr_err("Could not initialize controls\n"); | ||
3052 | return hdl->error; | ||
3053 | } | ||
3054 | return 0; | ||
3055 | } | ||
3056 | |||
3237 | /* sub-driver description */ | 3057 | /* sub-driver description */ |
3238 | static const struct sd_desc sd_desc = { | 3058 | static const struct sd_desc sd_desc = { |
3239 | .name = MODULE_NAME, | 3059 | .name = MODULE_NAME, |
3240 | .ctrls = sd_ctrls, | ||
3241 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
3242 | .config = sd_config, | 3060 | .config = sd_config, |
3243 | .init = sd_init, | 3061 | .init = sd_init, |
3062 | .init_controls = sd_init_controls, | ||
3244 | .start = sd_start, | 3063 | .start = sd_start, |
3245 | .stopN = sd_stopN, | 3064 | .stopN = sd_stopN, |
3246 | .stop0 = sd_stop0, | 3065 | .stop0 = sd_stop0, |
@@ -3253,10 +3072,9 @@ static const struct sd_desc sd_desc = { | |||
3253 | 3072 | ||
3254 | static const struct sd_desc sd_desc_isoc_nego = { | 3073 | static const struct sd_desc sd_desc_isoc_nego = { |
3255 | .name = MODULE_NAME, | 3074 | .name = MODULE_NAME, |
3256 | .ctrls = sd_ctrls, | ||
3257 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
3258 | .config = sd_config, | 3075 | .config = sd_config, |
3259 | .init = sd_init, | 3076 | .init = sd_init, |
3077 | .init_controls = sd_init_controls, | ||
3260 | .start = sd_start, | 3078 | .start = sd_start, |
3261 | .isoc_init = sd_isoc_init, | 3079 | .isoc_init = sd_isoc_init, |
3262 | .isoc_nego = sd_isoc_nego, | 3080 | .isoc_nego = sd_isoc_nego, |
@@ -3320,6 +3138,7 @@ static struct usb_driver sd_driver = { | |||
3320 | #ifdef CONFIG_PM | 3138 | #ifdef CONFIG_PM |
3321 | .suspend = gspca_suspend, | 3139 | .suspend = gspca_suspend, |
3322 | .resume = gspca_resume, | 3140 | .resume = gspca_resume, |
3141 | .reset_resume = gspca_resume, | ||
3323 | #endif | 3142 | #endif |
3324 | }; | 3143 | }; |
3325 | 3144 | ||