aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:47:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:47:44 -0400
commit8762541f067d371320731510669e27f5cc40af38 (patch)
treefa2890094858614a947ba70612854acde9888940 /drivers/media/video/gspca
parent6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (diff)
parentadfe1560de1c696324554fba70c92f2d7c947ff7 (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')
-rw-r--r--drivers/media/video/gspca/benq.c7
-rw-r--r--drivers/media/video/gspca/conex.c208
-rw-r--r--drivers/media/video/gspca/cpia1.c486
-rw-r--r--drivers/media/video/gspca/etoms.c221
-rw-r--r--drivers/media/video/gspca/finepix.c1
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c1
-rw-r--r--drivers/media/video/gspca/gspca.c50
-rw-r--r--drivers/media/video/gspca/jeilinj.c219
-rw-r--r--drivers/media/video/gspca/jl2005bcd.c3
-rw-r--r--drivers/media/video/gspca/kinect.c10
-rw-r--r--drivers/media/video/gspca/konica.c289
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c1
-rw-r--r--drivers/media/video/gspca/mars.c48
-rw-r--r--drivers/media/video/gspca/mr97310a.c439
-rw-r--r--drivers/media/video/gspca/nw80x.c203
-rw-r--r--drivers/media/video/gspca/ov519.c600
-rw-r--r--drivers/media/video/gspca/ov534.c570
-rw-r--r--drivers/media/video/gspca/ov534_9.c294
-rw-r--r--drivers/media/video/gspca/pac207.c1
-rw-r--r--drivers/media/video/gspca/pac7302.c372
-rw-r--r--drivers/media/video/gspca/pac7311.c1
-rw-r--r--drivers/media/video/gspca/se401.c184
-rw-r--r--drivers/media/video/gspca/sn9c2028.c7
-rw-r--r--drivers/media/video/gspca/sonixb.c622
-rw-r--r--drivers/media/video/gspca/sonixj.c1
-rw-r--r--drivers/media/video/gspca/spca1528.c271
-rw-r--r--drivers/media/video/gspca/spca500.c201
-rw-r--r--drivers/media/video/gspca/spca501.c257
-rw-r--r--drivers/media/video/gspca/spca505.c77
-rw-r--r--drivers/media/video/gspca/spca506.c209
-rw-r--r--drivers/media/video/gspca/spca508.c71
-rw-r--r--drivers/media/video/gspca/spca561.c393
-rw-r--r--drivers/media/video/gspca/sq905.c1
-rw-r--r--drivers/media/video/gspca/sq905c.c1
-rw-r--r--drivers/media/video/gspca/sq930x.c110
-rw-r--r--drivers/media/video/gspca/stk014.c188
-rw-r--r--drivers/media/video/gspca/stv0680.c7
-rw-r--r--drivers/media/video/gspca/sunplus.c237
-rw-r--r--drivers/media/video/gspca/t613.c824
-rw-r--r--drivers/media/video/gspca/topro.c459
-rw-r--r--drivers/media/video/gspca/tv8532.c125
-rw-r--r--drivers/media/video/gspca/vc032x.c694
-rw-r--r--drivers/media/video/gspca/vicam.c68
-rw-r--r--drivers/media/video/gspca/w996Xcf.c15
-rw-r--r--drivers/media/video/gspca/xirlink_cit.c473
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 */
37static const struct ctrl sd_ctrls[] = {
38};
39
40static const struct v4l2_pix_format vga_mode[] = { 36static 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 */
257static const struct sd_desc sd_desc = { 253static 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>");
31MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); 31MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33 33
34#define QUALITY 50
35
34/* specific webcam descriptor */ 36/* specific webcam descriptor */
35struct sd { 37struct 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 */
50static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
56
57static 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
102static const struct v4l2_pix_format vga_mode[] = { 46static 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)
817static int sd_config(struct gspca_dev *gspca_dev, 761static 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
906static void setbrightness(struct gspca_dev *gspca_dev) 844static 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
929static void setcontrast(struct gspca_dev *gspca_dev) 862static 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
946static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 878static 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
956static 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
964static 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
974static 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
982static 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
994static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 904static 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
1002static 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
1018static int sd_get_jcomp(struct gspca_dev *gspca_dev, 908static 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 */
1031static const struct sd_desc sd_desc = { 929static 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]*/
230static u8 flicker_jumps[2][2][4] = 239static 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 */
369static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
370static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
371static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
372static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
373static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
374static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
375static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
376static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
377static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
378static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
379static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val);
380static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val);
381static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val);
382static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val);
383
384static 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
494static const struct v4l2_pix_format mode[] = { 377static 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)
1551static int sd_config(struct gspca_dev *gspca_dev, 1431static 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
1874static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1755static 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
1891static 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
1899static 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
1910static 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
1918static 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
1929static 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
1937static 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
1967static 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
1975static 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
1986static 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
1994static 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
2020static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val)
2021{
2022 return sd_setilluminator(gspca_dev, val, 1);
2023}
2024
2025static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val)
2026{
2027 return sd_setilluminator(gspca_dev, val, 2);
2028}
2029
2030static 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
2050static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val) 1810static 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
2055static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val) 1814static 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
2060static 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 */
2092static const struct sd_desc sd_desc = { 1863static 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");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 unsigned 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 */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
56
57static 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
117static const struct v4l2_pix_format vga_mode[] = { 44static 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
467static void setbrightness(struct gspca_dev *gspca_dev) 394static 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
477static void setcontrast(struct gspca_dev *gspca_dev) 402static 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
487static void setcolors(struct gspca_dev *gspca_dev) 410static 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
507static void getcolors(struct gspca_dev *gspca_dev) 429static 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
518static void setautogain(struct gspca_dev *gspca_dev) 441static 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
783static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 700static 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
793static 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
801static 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;
811static 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;
819static 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
829static 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
837static 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
847static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 729static 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; 733static 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 */
856static const struct sd_desc sd_desc = { 757static 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
57enum 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 */
67struct sd { 58struct 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
142static void setfreq(struct gspca_dev *gspca_dev) 134static 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
156static void setcamquality(struct gspca_dev *gspca_dev) 147static 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
174static void setautogain(struct gspca_dev *gspca_dev) 164static 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
188static void setred(struct gspca_dev *gspca_dev) 177static 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
202static void setgreen(struct gspca_dev *gspca_dev) 190static 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
216static void setblue(struct gspca_dev *gspca_dev) 203static 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
230static 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
298static int jlj_start(struct gspca_dev *gspca_dev) 216static 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
480MODULE_DEVICE_TABLE(usb, device_table); 397MODULE_DEVICE_TABLE(usb, device_table);
481 398
482static int sd_querymenu(struct gspca_dev *gspca_dev, 399static 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
434static const struct v4l2_ctrl_ops sd_ctrl_ops = {
435 .s_ctrl = sd_s_ctrl,
436};
437
438static 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
503static int sd_set_jcomp(struct gspca_dev *gspca_dev, 476static 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 */
506static const struct sd_desc sd_desc = { 506static 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
69static 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 */
374static const struct sd_desc sd_desc = { 368static 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 */
61static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
62static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
63static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
64static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
65static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
66static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val);
69static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
71
72static 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)
242static int sd_config(struct gspca_dev *gspca_dev, 144static 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 */
261static int sd_init(struct gspca_dev *gspca_dev) 155static 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
275static int sd_start(struct gspca_dev *gspca_dev) 176static 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
482static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 377static 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
496static 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
505static 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
519static 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
528static 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
541static 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
550static 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
563static 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
572static 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
585static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) 417static 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
421static 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 */
595static const struct sd_desc sd_desc = { 448static 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>");
30MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33#define QUALITY 50
34
33/* specific webcam descriptor */ 35/* specific webcam descriptor */
34struct sd { 36struct 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)
244static int sd_config(struct gspca_dev *gspca_dev, 233static 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
414static 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
427static 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 */
440static const struct sd_desc sd_desc = { 402static 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 */
85struct sd { 86struct 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
100struct sensor_w_data { 99struct sensor_w_data {
@@ -105,132 +104,6 @@ struct sensor_w_data {
105}; 104};
106 105
107static void sd_stopN(struct gspca_dev *gspca_dev); 106static void sd_stopN(struct gspca_dev *gspca_dev);
108static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
109static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
110static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
111static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
112static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
113static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
114static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
115static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
116static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
117static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
118static void setbrightness(struct gspca_dev *gspca_dev);
119static void setexposure(struct gspca_dev *gspca_dev);
120static void setgain(struct gspca_dev *gspca_dev);
121static void setcontrast(struct gspca_dev *gspca_dev);
122
123/* V4L2 controls supported by the driver */
124static 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
235static const struct v4l2_pix_format vga_mode[] = { 108static 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
974static void setbrightness(struct gspca_dev *gspca_dev) 795static 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
1013static void setexposure(struct gspca_dev *gspca_dev) 822static 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
1068static void setgain(struct gspca_dev *gspca_dev) 874static 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
1088static 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
1099static 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
1109static 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
1117static 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
1127static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 890static 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
1135static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 895static 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
1145static 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
1153static 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
924static const struct v4l2_ctrl_ops sd_ctrl_ops = {
925 .s_ctrl = sd_s_ctrl,
926};
1163 927
1164static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 928static 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
1172static 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
1182static 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 */
1222static const struct sd_desc sd_desc = { 1051static 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
33static int webcam; 33static int webcam;
34 34
35/* controls */
36enum 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 */
46struct sd { 36struct 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
1670static void setgain(struct gspca_dev *gspca_dev) 1658static 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
1693static void setexposure(struct gspca_dev *gspca_dev) 1677static 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
1716static void setautogain(struct gspca_dev *gspca_dev) 1698static 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
1990static 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
2008static void do_autogain(struct gspca_dev *gspca_dev) 1940static 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
2036static const struct ctrl sd_ctrls[NCTRLS] = { 1968static 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, 2000static 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
2004static 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 */
2077static const struct sd_desc sd_desc = { 2048static 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..." */
61static int i2c_detect_tries = 10; 61static int i2c_detect_tries = 10;
62 62
63/* controls */
64enum 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 */
78struct sd { 64struct 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 */
149static void setbrightness(struct gspca_dev *gspca_dev); 143struct ctrl_valid {
150static void setcontrast(struct gspca_dev *gspca_dev); 144 int has_brightness:1;
151static void setexposure(struct gspca_dev *gspca_dev); 145 int has_contrast:1;
152static void setcolors(struct gspca_dev *gspca_dev); 146 int has_exposure:1;
153static void sethvflip(struct gspca_dev *gspca_dev); 147 int has_autogain:1;
154static void setautobright(struct gspca_dev *gspca_dev); 148 int has_sat:1;
155static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 149 int has_hvflip:1;
156static void setfreq(struct gspca_dev *gspca_dev); 150 int has_autobright:1;
157static void setfreq_i(struct sd *sd); 151 int has_freq:1;
158 152};
159static const struct ctrl sd_ctrls[] = { 153
160[BRIGHTNESS] = { 154static 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 */
273static 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
353static const struct v4l2_pix_format ov519_vga_mode[] = { 250static 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
3309static void setautogain(struct gspca_dev *gspca_dev) 3206static 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 */
4180static void sethvflip(struct gspca_dev *gspca_dev) 4057static 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
4608static void setbrightness(struct gspca_dev *gspca_dev) 4467static 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
4659static void setcontrast(struct gspca_dev *gspca_dev) 4514static 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
4763static void setexposure(struct gspca_dev *gspca_dev) 4616static 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
4771static void setcolors(struct gspca_dev *gspca_dev) 4623static 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
4822static void setautobright(struct gspca_dev *gspca_dev) 4672static 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
4829static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 4679static 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
4845static 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}
4903static void setfreq(struct gspca_dev *gspca_dev) 4737
4738static 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
4914static 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
4943static int sd_get_jcomp(struct gspca_dev *gspca_dev, 4749static 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) 4776static 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
4792static 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 */ 4837static 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
4842static 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 */
4983static const struct sd_desc sd_desc = { 4914static 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>");
53MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); 54MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
54MODULE_LICENSE("GPL"); 55MODULE_LICENSE("GPL");
55 56
56/* controls */
57enum 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 */
75struct sd { 58struct 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 */
93static void sethue(struct gspca_dev *gspca_dev);
94static void setsaturation(struct gspca_dev *gspca_dev);
95static void setbrightness(struct gspca_dev *gspca_dev);
96static void setcontrast(struct gspca_dev *gspca_dev);
97static void setgain(struct gspca_dev *gspca_dev);
98static void setexposure(struct gspca_dev *gspca_dev);
99static void setagc(struct gspca_dev *gspca_dev);
100static void setawb(struct gspca_dev *gspca_dev);
101static void setaec(struct gspca_dev *gspca_dev);
102static void setsharpness(struct gspca_dev *gspca_dev);
103static void sethvflip(struct gspca_dev *gspca_dev);
104static void setlightfreq(struct gspca_dev *gspca_dev);
105
106static int sd_start(struct gspca_dev *gspca_dev); 92static int sd_start(struct gspca_dev *gspca_dev);
107static void sd_stopN(struct gspca_dev *gspca_dev); 93static void sd_stopN(struct gspca_dev *gspca_dev);
108 94
109static 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
268static const struct v4l2_pix_format ov772x_mode[] = { 96static 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
975static void sethue(struct gspca_dev *gspca_dev) 803static 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
1017static void setsaturation(struct gspca_dev *gspca_dev) 843static 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
1043static void setbrightness(struct gspca_dev *gspca_dev) 867static 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
1058static void setcontrast(struct gspca_dev *gspca_dev) 880static 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
1070static void setgain(struct gspca_dev *gspca_dev) 890static 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
1100static void setexposure(struct gspca_dev *gspca_dev) 913static 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) 918static 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
1126static void setagc(struct gspca_dev *gspca_dev) 939static 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
953static 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
1145static void setawb(struct gspca_dev *gspca_dev) 968static 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
1164static void setaec(struct gspca_dev *gspca_dev) 987static 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
1186static void setsharpness(struct gspca_dev *gspca_dev) 1007static 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
1196static void sethvflip(struct gspca_dev *gspca_dev) 1013static 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
1220static void setlightfreq(struct gspca_dev *gspca_dev) 1037static 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
1068static 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
1090static 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
1144static const struct v4l2_ctrl_ops ov534_ctrl_ops = {
1145 .g_volatile_ctrl = ov534_g_volatile_ctrl,
1146 .s_ctrl = ov534_s_ctrl,
1147};
1148
1149static 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 */
1255static int sd_init(struct gspca_dev *gspca_dev) 1258static 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
1486static 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) */
1506static void sd_get_streamparm(struct gspca_dev *gspca_dev, 1473static 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 */
1537static const struct sd_desc sd_desc = { 1504static 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>");
47MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50/* controls */
51enum 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 */
63struct sd { 51struct 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 */
79static void setbrightness(struct gspca_dev *gspca_dev);
80static void setcontrast(struct gspca_dev *gspca_dev);
81static void setautogain(struct gspca_dev *gspca_dev);
82static void setexposure(struct gspca_dev *gspca_dev);
83static void setsharpness(struct gspca_dev *gspca_dev);
84static void setsatur(struct gspca_dev *gspca_dev);
85static void setlightfreq(struct gspca_dev *gspca_dev);
86
87static 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
175static const struct v4l2_pix_format ov965x_mode[] = { 65static 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
1107static void setbrightness(struct gspca_dev *gspca_dev) 997static 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
1141static void setcontrast(struct gspca_dev *gspca_dev) 1029static 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
1151static void setautogain(struct gspca_dev *gspca_dev) 1035static 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
1168static void setexposure(struct gspca_dev *gspca_dev) 1049static 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
1188static void setsharpness(struct gspca_dev *gspca_dev) 1065static 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
1212static void setsatur(struct gspca_dev *gspca_dev) 1083static 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
1242static void setlightfreq(struct gspca_dev *gspca_dev) 1110static 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)
1267static int sd_config(struct gspca_dev *gspca_dev, 1132static 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
1544static int sd_querymenu(struct gspca_dev *gspca_dev, 1381static 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
1417static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1418 .s_ctrl = sd_s_ctrl,
1419};
1420
1421static 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 */
1566static const struct sd_desc sd_desc = { 1461static 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
87MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " 92MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
88 "Thomas Kaiser thomas@kaiser-linux.li"); 93 "Thomas Kaiser thomas@kaiser-linux.li");
89MODULE_DESCRIPTION("Pixart PAC7302"); 94MODULE_DESCRIPTION("Pixart PAC7302");
90MODULE_LICENSE("GPL"); 95MODULE_LICENSE("GPL");
91 96
92enum 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
107struct sd { 97struct 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 */
123static void setbrightcont(struct gspca_dev *gspca_dev);
124static void setcolors(struct gspca_dev *gspca_dev);
125static void setwhitebalance(struct gspca_dev *gspca_dev);
126static void setredbalance(struct gspca_dev *gspca_dev);
127static void setbluebalance(struct gspca_dev *gspca_dev);
128static void setgain(struct gspca_dev *gspca_dev);
129static void setexposure(struct gspca_dev *gspca_dev);
130static void setautogain(struct gspca_dev *gspca_dev);
131static void sethvflip(struct gspca_dev *gspca_dev);
132
133static 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
276static const struct v4l2_pix_format vga_mode[] = { 122static 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
601static void setgain(struct gspca_dev *gspca_dev) 446static 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
622static void setexposure(struct gspca_dev *gspca_dev) 466static 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
671static 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
693static void sethvflip(struct gspca_dev *gspca_dev) 514static 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
541static 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
593static const struct v4l2_ctrl_ops sd_ctrl_ops = {
594 .s_ctrl = sd_s_ctrl,
595};
596
597/* this function is called at probe time */
598static 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 -- */
720static int sd_start(struct gspca_dev *gspca_dev) 647static 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
764static void do_autogain(struct gspca_dev *gspca_dev) 690static 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 */
945static const struct sd_desc sd_desc = { 873static 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>");
45MODULE_DESCRIPTION("Endpoints se401"); 45MODULE_DESCRIPTION("Endpoints se401");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
47 47
48/* controls */
49enum 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 */
58enum { 49enum {
59 EXPO_CHANGED, 50 EXPO_CHANGED,
@@ -64,7 +55,11 @@ enum {
64/* specific webcam descriptor */ 55/* specific webcam descriptor */
65struct sd { 56struct 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
80static void setbrightness(struct gspca_dev *gspca_dev);
81static void setgain(struct gspca_dev *gspca_dev);
82static void setexposure(struct gspca_dev *gspca_dev);
83
84static 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
135static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value, 76static 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
227static void setbrightness(struct gspca_dev *gspca_dev) 168static 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
239static void setgain(struct gspca_dev *gspca_dev) 174static 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
252static void setexposure(struct gspca_dev *gspca_dev) 186static 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
669static 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)
691static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) 598static 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
624static 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
649static const struct v4l2_ctrl_ops sd_ctrl_ops = {
650 .s_ctrl = sd_s_ctrl,
651};
652
653static 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 */
718static const struct sd_desc sd_desc = { 681static 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 */
44static 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 */
48static const struct v4l2_pix_format vga_mode[] = { 44static 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 */
696static const struct sd_desc sd_desc = { 692static 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>");
56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); 56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
57MODULE_LICENSE("GPL"); 57MODULE_LICENSE("GPL");
58 58
59/* controls */
60enum 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 */
70struct sd { 60struct 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 */
151static void setbrightness(struct gspca_dev *gspca_dev);
152static void setgain(struct gspca_dev *gspca_dev);
153static void setexposure(struct gspca_dev *gspca_dev);
154static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
155static void setfreq(struct gspca_dev *gspca_dev);
156
157static 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
231static const struct v4l2_pix_format vga_mode[] = { 132static 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
534static const struct sensor_data sensor_data[] = { 435static const struct sensor_data sensor_data[] = {
535SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), 436 SENS(initHv7131d, hv7131d_sensor_init, 0, 0),
536SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), 437 SENS(initHv7131r, hv7131r_sensor_init, 0, 0),
537SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), 438 SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60),
538SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21), 439 SENS(initOv7630, ov7630_sensor_init, 0, 0x21),
539SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0), 440 SENS(initPas106, pas106_sensor_init, F_SIF, 0),
540SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0), 441 SENS(initPas202, pas202_sensor_init, 0, 0),
541SENS(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),
543SENS(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),
545SENS(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 */
550static void reg_r(struct gspca_dev *gspca_dev, 448static 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
563static void reg_w(struct gspca_dev *gspca_dev, 472static 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
585static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) 499static 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
603static void i2c_w_vector(struct gspca_dev *gspca_dev, 527static 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;
661err:
662 PDEBUG(D_ERR, "i2c error brightness");
663} 585}
664 586
665static void setsensorgain(struct gspca_dev *gspca_dev) 587static 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;
756err:
757 PDEBUG(D_ERR, "i2c error gain");
758}
759
760static 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, &reg, 1); 710 reg_w(gspca_dev, 0x19, &reg, 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;
968err:
969 PDEBUG(D_ERR, "i2c error exposure");
970} 855}
971 856
972static void setfreq(struct gspca_dev *gspca_dev) 857static 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
1007static void do_autogain(struct gspca_dev *gspca_dev) 883static 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 */
1088static int sd_init(struct gspca_dev *gspca_dev) 952static 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; 961static 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
1001static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1002 .s_ctrl = sd_s_ctrl,
1003};
1004
1005/* this function is called at probe time */
1006static 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
1251static void sd_stopN(struct gspca_dev *gspca_dev) 1240static 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
1390static 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
1421static int sd_querymenu(struct gspca_dev *gspca_dev, 1379static 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 */
1462static const struct sd_desc sd_desc = { 1420static 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");
33struct sd { 33struct 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 */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val);
56static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
57static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
58
59static 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
132static const struct v4l2_pix_format vga_mode[] = { 41static 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
262static void setbrightness(struct gspca_dev *gspca_dev) 171static 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
269static void setcontrast(struct gspca_dev *gspca_dev) 176static 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
276static void sethue(struct gspca_dev *gspca_dev) 181static 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
283static void setcolor(struct gspca_dev *gspca_dev) 186static 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
290static void setsharpness(struct gspca_dev *gspca_dev) 191static 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 */
298static int sd_config(struct gspca_dev *gspca_dev, 197static 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
460static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 343static 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
470static 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
478static 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
488static 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:
496static 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
506static 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
514static 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
524static int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val) 373static 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
532static 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
542static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) 377static 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 */
551static const struct sd_desc sd_desc = { 402static 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>");
30MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33#define QUALITY 85
34
33/* specific webcam descriptor */ 35/* specific webcam descriptor */
34struct sd { 36struct 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 */
66static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
72
73static 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
118static const struct v4l2_pix_format vga_mode[] = { 59static 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
937static void setbrightness(struct gspca_dev *gspca_dev) 874static 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
945static void setcontrast(struct gspca_dev *gspca_dev) 880static 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
952static void setcolors(struct gspca_dev *gspca_dev) 885static 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
959static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 890static 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
969static 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
977static 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
987static 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;
995static 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
1005static 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
1013static int sd_set_jcomp(struct gspca_dev *gspca_dev, 914static 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
1029static int sd_get_jcomp(struct gspca_dev *gspca_dev, 918static 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 */
1042static const struct sd_desc sd_desc = { 939static 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 */
53static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
55static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
59static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
60static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
61static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
62static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
63
64static 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
137static const struct v4l2_pix_format vga_mode[] = { 52static 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
1881static void setbrightness(struct gspca_dev *gspca_dev) 1796static 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
1888static void setcontrast(struct gspca_dev *gspca_dev) 1801static 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
1898static void setcolors(struct gspca_dev *gspca_dev) 1809static 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
1905static void setblue_balance(struct gspca_dev *gspca_dev) 1814static 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
1912static void setred_balance(struct gspca_dev *gspca_dev) 1819static 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
2056static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1951static 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
2066static 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
2074static 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
2084static 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
2092static 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);
2102static 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:
2110static 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
2120static 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
2128static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) 1981static 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
2138static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) 1985static 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 */
2147static const struct sd_desc sd_desc = { 2010static 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");
33struct sd { 33struct 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 */
44static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
45static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
46
47static 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
64static const struct v4l2_pix_format vga_mode[] = { 41static 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
654static void setbrightness(struct gspca_dev *gspca_dev) 630static 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
718static void sd_stopN(struct gspca_dev *gspca_dev) 687static 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
759static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 728static 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
769static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 746static const struct v4l2_ctrl_ops sd_ctrl_ops = {
747 .s_ctrl = sd_s_ctrl,
748};
749
750static 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 */
778static const struct sd_desc sd_desc = { 767static 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");
33struct sd { 33struct 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 */
45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
47static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
49static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
53
54static 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
113static const struct v4l2_pix_format vga_mode[] = { 40static 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,
281static int sd_config(struct gspca_dev *gspca_dev, 208static 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
567static void setbrightness(struct gspca_dev *gspca_dev) 489static 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
576static void setcontrast(struct gspca_dev *gspca_dev) 496static 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
585static void setcolors(struct gspca_dev *gspca_dev) 503static 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
594static void sethue(struct gspca_dev *gspca_dev) 510static 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
603static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 517static 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
613static 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
621static 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
631static 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;
639static 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 }
649static 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
657static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) 544static 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
667static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) 548static 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 */
676static const struct sd_desc sd_desc = { 571static 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");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 u8 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 */
47static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
49
50static 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
67static const struct v4l2_pix_format sif_mode[] = { 44static 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
1474static void setbrightness(struct gspca_dev *gspca_dev) 1450static 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
1486static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1459static 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
1496static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 1477static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1478 .s_ctrl = sd_s_ctrl,
1479};
1480
1481static 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 */
1505static const struct sd_desc sd_desc = { 1498static 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>");
31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); 31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33 33
34#define EXPOSURE_MAX (2047 + 325)
35
34/* specific webcam descriptor */ 36/* specific webcam descriptor */
35struct sd { 37struct 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 */ 466static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
495static 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
510static void setwhite(struct gspca_dev *gspca_dev) 483static 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
532static 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 */
551static void setexposure(struct gspca_dev *gspca_dev) 507static 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 */
590static void setgain(struct gspca_dev *gspca_dev) 545static 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
608static void setautogain(struct gspca_dev *gspca_dev) 561static 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}
655static int sd_start_72a(struct gspca_dev *gspca_dev) 605static 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 */ 774static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
823static 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
833static 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 */
842static 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
852static 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
860static 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 */
870static 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);
878static 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
888static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val) 810static 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 */ 814static int sd_init_controls_12a(struct gspca_dev *gspca_dev)
897static 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
907static 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 */ 836static int sd_init_controls_72a(struct gspca_dev *gspca_dev)
916static 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
926static 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 */
935static 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
977static 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 */
1033static const struct sd_desc sd_desc_12a = { 861static 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};
1046static const struct sd_desc sd_desc_72a = { 873static 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");
36struct sd { 36struct 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
58static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val);
59static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val);
60static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
61static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
62
63static 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
94static struct v4l2_pix_format vga_mode[] = { 60static 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
794static void setexposure(struct gspca_dev *gspca_dev) 760static 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
1116static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1080static 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
1126static 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}
1133static 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; 1099static 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
1143static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val) 1103static 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 */
1152static const struct sd_desc sd_desc = { 1124static 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>");
29MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); 29MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31 31
32/* controls */ 32#define QUALITY 50
33enum 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 */
42struct sd { 35struct 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 */
56static void setbrightness(struct gspca_dev *gspca_dev);
57static void setcontrast(struct gspca_dev *gspca_dev);
58static void setcolors(struct gspca_dev *gspca_dev);
59static void setlightfreq(struct gspca_dev *gspca_dev);
60
61static 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
112static const struct v4l2_pix_format vga_mode[] = { 40static 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
258static void setbrightness(struct gspca_dev *gspca_dev) 186static 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
268static void setcontrast(struct gspca_dev *gspca_dev) 195static 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
278static void setcolors(struct gspca_dev *gspca_dev) 204static 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
288static void setlightfreq(struct gspca_dev *gspca_dev) 213static 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)
298static int sd_config(struct gspca_dev *gspca_dev, 221static 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
438static int sd_querymenu(struct gspca_dev *gspca_dev, 353static 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
453static 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
469static int sd_get_jcomp(struct gspca_dev *gspca_dev, 380static 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); 384static 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 */
482static const struct sd_desc sd_desc = { 409static 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 */
50static const struct ctrl sd_ctrls[] = {
51};
52
53static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, 49static 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 */
319static const struct sd_desc sd_desc = { 315static 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>");
30MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33#define QUALITY 85
34
33/* specific webcam descriptor */ 35/* specific webcam descriptor */
34struct sd { 36struct 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 */
63static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
64static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
65static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
66static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
69static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
71
72static 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
131static const struct v4l2_pix_format vga_mode[] = { 57static 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
600static void setbrightness(struct gspca_dev *gspca_dev) 526static 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
609static void setcontrast(struct gspca_dev *gspca_dev) 535static 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
618static void setcolors(struct gspca_dev *gspca_dev) 544static 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
627static void init_ctl_reg(struct gspca_dev *gspca_dev) 553static 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
1015static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 932static 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
1025static 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
1033static 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
1043static 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;
1051static 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
1061static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 960static 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
1069static 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
1077static 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
1085static 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
1101static int sd_get_jcomp(struct gspca_dev *gspca_dev, 964static 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 */
1114static const struct sd_desc sd_desc = { 987static 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
39MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); 37MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
40MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); 38MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
41MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
42 40
43struct sd { 41struct 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 */
71static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
85
86static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
94
95static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
99
100static 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
288static const struct v4l2_pix_format vga_mode_t16[] = { 61static 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 */
459static char *effects_control[MAX_EFFECTS] = {
460 "Normal",
461 "Emboss", /* disabled */
462 "Monochrome",
463 "Sepia",
464 "Sketch",
465 "Sun Effect", /* disabled */
466 "Negative",
467};
468static const u8 effects_table[MAX_EFFECTS][6] = { 234static 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
478static const u8 gamma_table[GAMMA_MAX][17] = { 244#define GAMMA_MAX (15)
245static 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)
683static int sd_config(struct gspca_dev *gspca_dev, 450static 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
711static void setbrightness(struct gspca_dev *gspca_dev) 461static 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
728static void setcontrast(struct gspca_dev *gspca_dev) 475static 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
742static void setcolors(struct gspca_dev *gspca_dev) 487static 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
751static void setgamma(struct gspca_dev *gspca_dev) 495static 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
760static void setRGB(struct gspca_dev *gspca_dev) 502static 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 */ 533static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
773static 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
793static 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
814static 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
824static void setfreq(struct gspca_dev *gspca_dev) 542static 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
971static void setmirror(struct gspca_dev *gspca_dev) 684static 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
983static void seteffect(struct gspca_dev *gspca_dev) 695static 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
1145static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val) 871static 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
1155static 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
1163static 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
1174static 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
1182static 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
1210static 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
1218static 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
1228static 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
1236static 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
1246static 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
1254static 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
1264static 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
1272static 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
1282static 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
1290static 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
1300static 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
1308static 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
1318static 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
1326static 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
1336static 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
1344static 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
1354static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) 908static 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
1362static 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
1372static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) 953static 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......*/ 958static int sd_init_controls(struct gspca_dev *gspca_dev)
1381static 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
1393static 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
1401static 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 */
1425static const struct sd_desc sd_desc = { 1014static 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
123enum 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
137struct sd { 123struct 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 */
1418static void setexposure(struct gspca_dev *gspca_dev) 1407static 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 */
1475static void setquality(struct gspca_dev *gspca_dev) 1465static 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
1511static void setgamma(struct gspca_dev *gspca_dev) 1499static 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
3867static void setsharpness(struct gspca_dev *gspca_dev) 3853static 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
3886static void setautogain(struct gspca_dev *gspca_dev) 3870static 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 */
3902static void set_resolution(struct gspca_dev *gspca_dev) 3878static 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
3966static void setframerate(struct gspca_dev *gspca_dev) 3945static 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
3987static void setrgain(struct gspca_dev *gspca_dev) 3966static 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
3998static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 3973static 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
4018static void setbgain(struct gspca_dev *gspca_dev) 4001static 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
4208static void cx0342_6800_start(struct gspca_dev *gspca_dev) 4170static 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
4287static void cx0342_6810_start(struct gspca_dev *gspca_dev) 4257static 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
4386static void soi763a_6800_start(struct gspca_dev *gspca_dev) 4357static 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
4498static void soi763a_6810_start(struct gspca_dev *gspca_dev) 4478static 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 */
4677static void setgain(struct gspca_dev *gspca_dev) {}
4678#define WANT_REGULAR_AUTOGAIN
4679#include "autogain_functions.h"
4680
4681static void sd_dq_callback(struct gspca_dev *gspca_dev) 4683static 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
4817static int sd_get_jcomp(struct gspca_dev *gspca_dev, 4819static 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
4829static struct ctrl sd_ctrls[NCTRLS] = { 4833static 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, 4872static 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
4876static 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
4928static const struct sd_desc sd_desc = { 4922static 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");
30struct sd { 30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */ 31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 32
33 __u16 exposure;
34 __u16 gain;
35
36 __u8 packet; 33 __u8 packet;
37}; 34};
38 35
39/* V4L2 controls supported by the driver */
40static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
41static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
42static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
43static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
44
45static 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
76static const struct v4l2_pix_format sif_mode[] = { 36static 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)
202static int sd_config(struct gspca_dev *gspca_dev, 162static 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
244static void setexposure(struct gspca_dev *gspca_dev) 201static 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
253static void setgain(struct gspca_dev *gspca_dev) 208static 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
342static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) 292static 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
352static 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
360static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 313static 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
370static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 317static 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 */
379static const struct sd_desc sd_desc = { 336static 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 */
34struct sd { 34struct 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 */
77static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setbacklight(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val);
99
100static 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 */
270static 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
323static const struct v4l2_pix_format vc0321_mode[] = { 69static 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
3537static void setbrightness(struct gspca_dev *gspca_dev) 3270static 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
3552static void setcontrast(struct gspca_dev *gspca_dev) 3282static 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
3561static void setcolors(struct gspca_dev *gspca_dev) 3287static 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
3573static void sethvflip(struct gspca_dev *gspca_dev) 3296static 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
3613static void setlightfreq(struct gspca_dev *gspca_dev) 3334static 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
3624static void setsharpness(struct gspca_dev *gspca_dev) 3345static 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}
3648static void setgain(struct gspca_dev *gspca_dev) 3369static 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
3657static void setexposure(struct gspca_dev *gspca_dev) 3374static 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
3670static void setautogain(struct gspca_dev *gspca_dev) 3384static 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
3680static void setgamma(struct gspca_dev *gspca_dev) 3391static 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
3686static void setbacklight(struct gspca_dev *gspca_dev) 3397static 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
3963static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 3663static 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
3973static 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
3981static 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
3991static 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
3999static 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
4009static 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
4017static 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
4027static 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
4035static 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
4045static 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
4053static 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
4063static 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
4071static 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
4081static 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
4089static 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
4099static 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
4107static 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
4117static 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
4125static 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
4136static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 3709static 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
4144static 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
4155static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val) 3713static 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:
4163static 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 */
4179static const struct sd_desc sd_desc = { 3800static 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");
44MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
45MODULE_FIRMWARE(VICAM_FIRMWARE); 45MODULE_FIRMWARE(VICAM_FIRMWARE);
46 46
47enum e_ctrl {
48 GAIN,
49 EXPOSURE,
50 NCTRL /* number of controls */
51};
52
53struct sd { 47struct 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
89static 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
114static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request, 82static 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 */
147static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) 115static 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
306static 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 */
339static const struct usb_device_id device_table[] = { 325static 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 */
348static const struct sd_desc sd_desc = { 334static 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
515static void w9968cf_stop0(struct sd *sd) 521static 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 */
54struct sd { 54struct 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 */
77static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
89static void sd_stop0(struct gspca_dev *gspca_dev); 71static void sd_stop0(struct gspca_dev *gspca_dev);
90 72
91static 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
189static const struct v4l2_pix_format cif_yuv_mode[] = { 73static 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
1290static int cit_set_brightness(struct gspca_dev *gspca_dev) 1154static 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
1330static int cit_set_contrast(struct gspca_dev *gspca_dev) 1194static 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
1393static int cit_set_hue(struct gspca_dev *gspca_dev) 1257static 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
1445static int cit_set_sharpness(struct gspca_dev *gspca_dev) 1309static 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 */
1513static void cit_set_lighting(struct gspca_dev *gspca_dev) 1377static 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
1533static void cit_set_hflip(struct gspca_dev *gspca_dev) 1397static 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
3058static 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
3074static 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
3083static 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
3099static 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
3108static 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
3123static 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
3132static 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
3147static 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
3156static 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
3171static 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
3180static 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
3195static 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)
3205static void cit_check_button(struct gspca_dev *gspca_dev) 2920static 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
2952static 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
2990static const struct v4l2_ctrl_ops sd_ctrl_ops = {
2991 .s_ctrl = sd_s_ctrl,
2992};
2993
2994static 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 */
3238static const struct sd_desc sd_desc = { 3058static 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
3254static const struct sd_desc sd_desc_isoc_nego = { 3073static 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