aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-06 08:28:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 08:36:05 -0400
commitc06ba2804a50076cc0c5a4d65466a37b8eaa4455 (patch)
tree985d80aa5a50ba98e6e75b16c19b069d6f4268ee
parent1b3bbcf5ab7250527a629ec1ffc36c8d1ea12681 (diff)
[media] gspca_zc3xx: Convert to the control framework
The initial version was done by HV, corrections were made by HdG, and some final small changes again by HV. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/zc3xx.c438
1 files changed, 170 insertions, 268 deletions
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 998017eacc1f..a8839fb3c1d6 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -35,26 +35,23 @@ static int force_sensor = -1;
35#define REG08_DEF 3 /* default JPEG compression (75%) */ 35#define REG08_DEF 3 /* default JPEG compression (75%) */
36#include "zc3xx-reg.h" 36#include "zc3xx-reg.h"
37 37
38/* controls */
39enum e_ctrl {
40 BRIGHTNESS,
41 CONTRAST,
42 EXPOSURE,
43 GAMMA,
44 AUTOGAIN,
45 LIGHTFREQ,
46 SHARPNESS,
47 QUALITY,
48 NCTRLS /* number of controls */
49};
50
51#define AUTOGAIN_DEF 1
52
53/* specific webcam descriptor */ 38/* specific webcam descriptor */
54struct sd { 39struct sd {
55 struct gspca_dev gspca_dev; /* !! must be the first item */ 40 struct gspca_dev gspca_dev; /* !! must be the first item */
56 41
57 struct gspca_ctrl ctrls[NCTRLS]; 42 struct v4l2_ctrl_handler ctrl_handler;
43 struct { /* gamma/brightness/contrast control cluster */
44 struct v4l2_ctrl *gamma;
45 struct v4l2_ctrl *brightness;
46 struct v4l2_ctrl *contrast;
47 };
48 struct { /* autogain/exposure control cluster */
49 struct v4l2_ctrl *autogain;
50 struct v4l2_ctrl *exposure;
51 };
52 struct v4l2_ctrl *plfreq;
53 struct v4l2_ctrl *sharpness;
54 struct v4l2_ctrl *jpegqual;
58 55
59 struct work_struct work; 56 struct work_struct work;
60 struct workqueue_struct *work_thread; 57 struct workqueue_struct *work_thread;
@@ -94,114 +91,6 @@ enum sensors {
94 SENSOR_MAX 91 SENSOR_MAX
95}; 92};
96 93
97/* V4L2 controls supported by the driver */
98static void setcontrast(struct gspca_dev *gspca_dev);
99static void setexposure(struct gspca_dev *gspca_dev);
100static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
101static void setlightfreq(struct gspca_dev *gspca_dev);
102static void setsharpness(struct gspca_dev *gspca_dev);
103static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val);
104
105static const struct ctrl sd_ctrls[NCTRLS] = {
106[BRIGHTNESS] = {
107 {
108 .id = V4L2_CID_BRIGHTNESS,
109 .type = V4L2_CTRL_TYPE_INTEGER,
110 .name = "Brightness",
111 .minimum = 0,
112 .maximum = 255,
113 .step = 1,
114 .default_value = 128,
115 },
116 .set_control = setcontrast
117 },
118[CONTRAST] = {
119 {
120 .id = V4L2_CID_CONTRAST,
121 .type = V4L2_CTRL_TYPE_INTEGER,
122 .name = "Contrast",
123 .minimum = 0,
124 .maximum = 255,
125 .step = 1,
126 .default_value = 128,
127 },
128 .set_control = setcontrast
129 },
130[EXPOSURE] = {
131 {
132 .id = V4L2_CID_EXPOSURE,
133 .type = V4L2_CTRL_TYPE_INTEGER,
134 .name = "Exposure",
135 .minimum = 0x30d,
136 .maximum = 0x493e,
137 .step = 1,
138 .default_value = 0x927
139 },
140 .set_control = setexposure
141 },
142[GAMMA] = {
143 {
144 .id = V4L2_CID_GAMMA,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Gamma",
147 .minimum = 1,
148 .maximum = 6,
149 .step = 1,
150 .default_value = 4,
151 },
152 .set_control = setcontrast
153 },
154[AUTOGAIN] = {
155 {
156 .id = V4L2_CID_AUTOGAIN,
157 .type = V4L2_CTRL_TYPE_BOOLEAN,
158 .name = "Auto Gain",
159 .minimum = 0,
160 .maximum = 1,
161 .step = 1,
162 .default_value = AUTOGAIN_DEF,
163 .flags = V4L2_CTRL_FLAG_UPDATE
164 },
165 .set = sd_setautogain
166 },
167[LIGHTFREQ] = {
168 {
169 .id = V4L2_CID_POWER_LINE_FREQUENCY,
170 .type = V4L2_CTRL_TYPE_MENU,
171 .name = "Light frequency filter",
172 .minimum = 0,
173 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
174 .step = 1,
175 .default_value = 0,
176 },
177 .set_control = setlightfreq
178 },
179[SHARPNESS] = {
180 {
181 .id = V4L2_CID_SHARPNESS,
182 .type = V4L2_CTRL_TYPE_INTEGER,
183 .name = "Sharpness",
184 .minimum = 0,
185 .maximum = 3,
186 .step = 1,
187 .default_value = 2,
188 },
189 .set_control = setsharpness
190 },
191[QUALITY] = {
192 {
193 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Compression Quality",
196 .minimum = 50,
197 .maximum = 87,
198 .step = 1,
199 .default_value = 75,
200 },
201 .set = sd_setquality
202 },
203};
204
205static const struct v4l2_pix_format vga_mode[] = { 94static const struct v4l2_pix_format vga_mode[] = {
206 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 95 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
207 .bytesperline = 320, 96 .bytesperline = 320,
@@ -5821,10 +5710,8 @@ static void setmatrix(struct gspca_dev *gspca_dev)
5821 reg_w(gspca_dev, matrix[i], 0x010a + i); 5710 reg_w(gspca_dev, matrix[i], 0x010a + i);
5822} 5711}
5823 5712
5824static void setsharpness(struct gspca_dev *gspca_dev) 5713static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
5825{ 5714{
5826 struct sd *sd = (struct sd *) gspca_dev;
5827 int sharpness;
5828 static const u8 sharpness_tb[][2] = { 5715 static const u8 sharpness_tb[][2] = {
5829 {0x02, 0x03}, 5716 {0x02, 0x03},
5830 {0x04, 0x07}, 5717 {0x04, 0x07},
@@ -5832,19 +5719,18 @@ static void setsharpness(struct gspca_dev *gspca_dev)
5832 {0x10, 0x1e} 5719 {0x10, 0x1e}
5833 }; 5720 };
5834 5721
5835 sharpness = sd->ctrls[SHARPNESS].val; 5722 reg_w(gspca_dev, sharpness_tb[val][0], 0x01c6);
5836 reg_w(gspca_dev, sharpness_tb[sharpness][0], 0x01c6);
5837 reg_r(gspca_dev, 0x01c8); 5723 reg_r(gspca_dev, 0x01c8);
5838 reg_r(gspca_dev, 0x01c9); 5724 reg_r(gspca_dev, 0x01c9);
5839 reg_r(gspca_dev, 0x01ca); 5725 reg_r(gspca_dev, 0x01ca);
5840 reg_w(gspca_dev, sharpness_tb[sharpness][1], 0x01cb); 5726 reg_w(gspca_dev, sharpness_tb[val][1], 0x01cb);
5841} 5727}
5842 5728
5843static void setcontrast(struct gspca_dev *gspca_dev) 5729static void setcontrast(struct gspca_dev *gspca_dev,
5730 s32 gamma, s32 brightness, s32 contrast)
5844{ 5731{
5845 struct sd *sd = (struct sd *) gspca_dev;
5846 const u8 *Tgamma; 5732 const u8 *Tgamma;
5847 int g, i, brightness, contrast, adj, gp1, gp2; 5733 int g, i, adj, gp1, gp2;
5848 u8 gr[16]; 5734 u8 gr[16];
5849 static const u8 delta_b[16] = /* delta for brightness */ 5735 static const u8 delta_b[16] = /* delta for brightness */
5850 {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d, 5736 {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
@@ -5867,10 +5753,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
5867 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}, 5753 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
5868 }; 5754 };
5869 5755
5870 Tgamma = gamma_tb[sd->ctrls[GAMMA].val - 1]; 5756 Tgamma = gamma_tb[gamma - 1];
5871 5757
5872 contrast = ((int) sd->ctrls[CONTRAST].val - 128); /* -128 / 127 */ 5758 contrast -= 128; /* -128 / 127 */
5873 brightness = ((int) sd->ctrls[BRIGHTNESS].val - 128); /* -128 / 92 */ 5759 brightness -= 128; /* -128 / 92 */
5874 adj = 0; 5760 adj = 0;
5875 gp1 = gp2 = 0; 5761 gp1 = gp2 = 0;
5876 for (i = 0; i < 16; i++) { 5762 for (i = 0; i < 16; i++) {
@@ -5897,25 +5783,15 @@ static void setcontrast(struct gspca_dev *gspca_dev)
5897 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */ 5783 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */
5898} 5784}
5899 5785
5900static void getexposure(struct gspca_dev *gspca_dev) 5786static s32 getexposure(struct gspca_dev *gspca_dev)
5901{ 5787{
5902 struct sd *sd = (struct sd *) gspca_dev; 5788 return (i2c_read(gspca_dev, 0x25) << 9)
5903
5904 if (sd->sensor != SENSOR_HV7131R)
5905 return;
5906 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
5907 | (i2c_read(gspca_dev, 0x26) << 1) 5789 | (i2c_read(gspca_dev, 0x26) << 1)
5908 | (i2c_read(gspca_dev, 0x27) >> 7); 5790 | (i2c_read(gspca_dev, 0x27) >> 7);
5909} 5791}
5910 5792
5911static void setexposure(struct gspca_dev *gspca_dev) 5793static void setexposure(struct gspca_dev *gspca_dev, s32 val)
5912{ 5794{
5913 struct sd *sd = (struct sd *) gspca_dev;
5914 int val;
5915
5916 if (sd->sensor != SENSOR_HV7131R)
5917 return;
5918 val = sd->ctrls[EXPOSURE].val;
5919 i2c_write(gspca_dev, 0x25, val >> 9, 0x00); 5795 i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
5920 i2c_write(gspca_dev, 0x26, val >> 1, 0x00); 5796 i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
5921 i2c_write(gspca_dev, 0x27, val << 7, 0x00); 5797 i2c_write(gspca_dev, 0x27, val << 7, 0x00);
@@ -5934,7 +5810,7 @@ static void setquality(struct gspca_dev *gspca_dev)
5934 * 60Hz, for American lighting 5810 * 60Hz, for American lighting
5935 * 0 = No Fliker (for outdoore usage) 5811 * 0 = No Fliker (for outdoore usage)
5936 */ 5812 */
5937static void setlightfreq(struct gspca_dev *gspca_dev) 5813static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
5938{ 5814{
5939 struct sd *sd = (struct sd *) gspca_dev; 5815 struct sd *sd = (struct sd *) gspca_dev;
5940 int i, mode; 5816 int i, mode;
@@ -6018,7 +5894,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
6018 tas5130c_60HZ, tas5130c_60HZScale}, 5894 tas5130c_60HZ, tas5130c_60HZScale},
6019 }; 5895 };
6020 5896
6021 i = sd->ctrls[LIGHTFREQ].val * 2; 5897 i = val * 2;
6022 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 5898 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6023 if (mode) 5899 if (mode)
6024 i++; /* 320x240 */ 5900 i++; /* 320x240 */
@@ -6028,14 +5904,14 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
6028 usb_exchange(gspca_dev, zc3_freq); 5904 usb_exchange(gspca_dev, zc3_freq);
6029 switch (sd->sensor) { 5905 switch (sd->sensor) {
6030 case SENSOR_GC0305: 5906 case SENSOR_GC0305:
6031 if (mode /* if 320x240 */ 5907 if (mode /* if 320x240 */
6032 && sd->ctrls[LIGHTFREQ].val == 1) /* and 50Hz */ 5908 && val == 1) /* and 50Hz */
6033 reg_w(gspca_dev, 0x85, 0x018d); 5909 reg_w(gspca_dev, 0x85, 0x018d);
6034 /* win: 0x80, 0x018d */ 5910 /* win: 0x80, 0x018d */
6035 break; 5911 break;
6036 case SENSOR_OV7620: 5912 case SENSOR_OV7620:
6037 if (!mode) { /* if 640x480 */ 5913 if (!mode) { /* if 640x480 */
6038 if (sd->ctrls[LIGHTFREQ].val != 0) /* and filter */ 5914 if (val != 0) /* and filter */
6039 reg_w(gspca_dev, 0x40, 0x0002); 5915 reg_w(gspca_dev, 0x40, 0x0002);
6040 else 5916 else
6041 reg_w(gspca_dev, 0x44, 0x0002); 5917 reg_w(gspca_dev, 0x44, 0x0002);
@@ -6047,16 +5923,9 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
6047 } 5923 }
6048} 5924}
6049 5925
6050static void setautogain(struct gspca_dev *gspca_dev) 5926static void setautogain(struct gspca_dev *gspca_dev, s32 val)
6051{ 5927{
6052 struct sd *sd = (struct sd *) gspca_dev; 5928 reg_w(gspca_dev, val ? 0x42 : 0x02, 0x0180);
6053 u8 autoval;
6054
6055 if (sd->ctrls[AUTOGAIN].val)
6056 autoval = 0x42;
6057 else
6058 autoval = 0x02;
6059 reg_w(gspca_dev, autoval, 0x0180);
6060} 5929}
6061 5930
6062/* 5931/*
@@ -6450,7 +6319,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
6450 /* define some sensors from the vendor/product */ 6319 /* define some sensors from the vendor/product */
6451 sd->sensor = id->driver_info; 6320 sd->sensor = id->driver_info;
6452 6321
6453 gspca_dev->cam.ctrls = sd->ctrls;
6454 sd->reg08 = REG08_DEF; 6322 sd->reg08 = REG08_DEF;
6455 6323
6456 INIT_WORK(&sd->work, transfer_update); 6324 INIT_WORK(&sd->work, transfer_update);
@@ -6458,12 +6326,85 @@ static int sd_config(struct gspca_dev *gspca_dev,
6458 return 0; 6326 return 0;
6459} 6327}
6460 6328
6461/* this function is called at probe and resume time */ 6329static int zcxx_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
6462static int sd_init(struct gspca_dev *gspca_dev)
6463{ 6330{
6464 struct sd *sd = (struct sd *) gspca_dev; 6331 struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler);
6465 struct cam *cam; 6332 struct gspca_dev *gspca_dev = &sd->gspca_dev;
6466 int sensor; 6333
6334 switch (ctrl->id) {
6335 case V4L2_CID_AUTOGAIN:
6336 gspca_dev->usb_err = 0;
6337 if (ctrl->val && sd->exposure && gspca_dev->streaming)
6338 sd->exposure->val = getexposure(gspca_dev);
6339 return gspca_dev->usb_err;
6340 }
6341 return -EINVAL;
6342}
6343
6344static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl)
6345{
6346 struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler);
6347 struct gspca_dev *gspca_dev = &sd->gspca_dev;
6348 int i, qual;
6349
6350 gspca_dev->usb_err = 0;
6351
6352 if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY) {
6353 qual = sd->reg08 >> 1;
6354
6355 for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) {
6356 if (ctrl->val <= jpeg_qual[i])
6357 break;
6358 }
6359 if (i > 0 && i == qual && ctrl->val < jpeg_qual[i])
6360 i--;
6361
6362 /* With high quality settings we need max bandwidth */
6363 if (i >= 2 && gspca_dev->streaming &&
6364 !gspca_dev->cam.needs_full_bandwidth)
6365 return -EBUSY;
6366
6367 sd->reg08 = (i << 1) | 1;
6368 ctrl->val = jpeg_qual[i];
6369 }
6370
6371 if (!gspca_dev->streaming)
6372 return 0;
6373
6374 switch (ctrl->id) {
6375 /* gamma/brightness/contrast cluster */
6376 case V4L2_CID_GAMMA:
6377 setcontrast(gspca_dev, sd->gamma->val,
6378 sd->brightness->val, sd->contrast->val);
6379 break;
6380 /* autogain/exposure cluster */
6381 case V4L2_CID_AUTOGAIN:
6382 setautogain(gspca_dev, ctrl->val);
6383 if (!gspca_dev->usb_err && !ctrl->val && sd->exposure)
6384 setexposure(gspca_dev, sd->exposure->val);
6385 break;
6386 case V4L2_CID_POWER_LINE_FREQUENCY:
6387 setlightfreq(gspca_dev, ctrl->val);
6388 break;
6389 case V4L2_CID_SHARPNESS:
6390 setsharpness(gspca_dev, ctrl->val);
6391 break;
6392 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
6393 setquality(gspca_dev);
6394 break;
6395 }
6396 return gspca_dev->usb_err;
6397}
6398
6399static const struct v4l2_ctrl_ops zcxx_ctrl_ops = {
6400 .g_volatile_ctrl = zcxx_g_volatile_ctrl,
6401 .s_ctrl = zcxx_s_ctrl,
6402};
6403
6404static int sd_init_controls(struct gspca_dev *gspca_dev)
6405{
6406 struct sd *sd = (struct sd *)gspca_dev;
6407 struct v4l2_ctrl_handler *hdl = &sd->ctrl_handler;
6467 static const u8 gamma[SENSOR_MAX] = { 6408 static const u8 gamma[SENSOR_MAX] = {
6468 [SENSOR_ADCM2700] = 4, 6409 [SENSOR_ADCM2700] = 4,
6469 [SENSOR_CS2102] = 4, 6410 [SENSOR_CS2102] = 4,
@@ -6485,6 +6426,48 @@ static int sd_init(struct gspca_dev *gspca_dev)
6485 [SENSOR_PO2030] = 4, 6426 [SENSOR_PO2030] = 4,
6486 [SENSOR_TAS5130C] = 3, 6427 [SENSOR_TAS5130C] = 3,
6487 }; 6428 };
6429
6430 gspca_dev->vdev.ctrl_handler = hdl;
6431 v4l2_ctrl_handler_init(hdl, 8);
6432 sd->brightness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6433 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
6434 sd->contrast = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6435 V4L2_CID_CONTRAST, 0, 255, 1, 128);
6436 sd->gamma = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6437 V4L2_CID_GAMMA, 1, 6, 1, gamma[sd->sensor]);
6438 if (sd->sensor == SENSOR_HV7131R)
6439 sd->exposure = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6440 V4L2_CID_EXPOSURE, 0x30d, 0x493e, 1, 0x927);
6441 sd->autogain = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6442 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
6443 if (sd->sensor != SENSOR_OV7630C)
6444 sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &zcxx_ctrl_ops,
6445 V4L2_CID_POWER_LINE_FREQUENCY,
6446 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
6447 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
6448 sd->sharpness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6449 V4L2_CID_SHARPNESS, 0, 3, 1,
6450 sd->sensor == SENSOR_PO2030 ? 0 : 2);
6451 sd->jpegqual = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6452 V4L2_CID_JPEG_COMPRESSION_QUALITY,
6453 jpeg_qual[0], jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1], 1,
6454 jpeg_qual[REG08_DEF >> 1]);
6455 if (hdl->error) {
6456 pr_err("Could not initialize controls\n");
6457 return hdl->error;
6458 }
6459 v4l2_ctrl_cluster(3, &sd->gamma);
6460 if (sd->sensor == SENSOR_HV7131R)
6461 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true);
6462 return 0;
6463}
6464
6465/* this function is called at probe and resume time */
6466static int sd_init(struct gspca_dev *gspca_dev)
6467{
6468 struct sd *sd = (struct sd *) gspca_dev;
6469 struct cam *cam;
6470 int sensor;
6488 static const u8 mode_tb[SENSOR_MAX] = { 6471 static const u8 mode_tb[SENSOR_MAX] = {
6489 [SENSOR_ADCM2700] = 2, 6472 [SENSOR_ADCM2700] = 2,
6490 [SENSOR_CS2102] = 1, 6473 [SENSOR_CS2102] = 1,
@@ -6614,7 +6597,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
6614 case 0x2030: 6597 case 0x2030:
6615 PDEBUG(D_PROBE, "Find Sensor PO2030"); 6598 PDEBUG(D_PROBE, "Find Sensor PO2030");
6616 sd->sensor = SENSOR_PO2030; 6599 sd->sensor = SENSOR_PO2030;
6617 sd->ctrls[SHARPNESS].def = 0; /* from win traces */
6618 break; 6600 break;
6619 case 0x7620: 6601 case 0x7620:
6620 PDEBUG(D_PROBE, "Find Sensor OV7620"); 6602 PDEBUG(D_PROBE, "Find Sensor OV7620");
@@ -6656,26 +6638,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
6656 break; 6638 break;
6657 } 6639 }
6658 6640
6659 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6660 sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08 >> 1];
6661 sd->ctrls[QUALITY].min = jpeg_qual[0];
6662 sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1];
6663
6664 switch (sd->sensor) {
6665 case SENSOR_HV7131R:
6666 break;
6667 case SENSOR_OV7630C:
6668 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6669 break;
6670 default:
6671 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6672 break;
6673 }
6674#if AUTOGAIN_DEF
6675 if (sd->ctrls[AUTOGAIN].val)
6676 gspca_dev->ctrl_inac = (1 << EXPOSURE);
6677#endif
6678
6679 /* switch off the led */ 6641 /* switch off the led */
6680 reg_w(gspca_dev, 0x01, 0x0000); 6642 reg_w(gspca_dev, 0x01, 0x0000);
6681 return gspca_dev->usb_err; 6643 return gspca_dev->usb_err;
@@ -6792,7 +6754,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6792 reg_w(gspca_dev, 0x03, 0x0008); 6754 reg_w(gspca_dev, 0x03, 0x0008);
6793 break; 6755 break;
6794 } 6756 }
6795 setsharpness(gspca_dev); 6757 setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
6796 6758
6797 /* set the gamma tables when not set */ 6759 /* set the gamma tables when not set */
6798 switch (sd->sensor) { 6760 switch (sd->sensor) {
@@ -6801,7 +6763,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
6801 case SENSOR_OV7630C: 6763 case SENSOR_OV7630C:
6802 break; 6764 break;
6803 default: 6765 default:
6804 setcontrast(gspca_dev); 6766 setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma),
6767 v4l2_ctrl_g_ctrl(sd->brightness),
6768 v4l2_ctrl_g_ctrl(sd->contrast));
6805 break; 6769 break;
6806 } 6770 }
6807 setmatrix(gspca_dev); /* one more time? */ 6771 setmatrix(gspca_dev); /* one more time? */
@@ -6815,7 +6779,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
6815 setquality(gspca_dev); 6779 setquality(gspca_dev);
6816 /* Start with BRC disabled, transfer_update will enable it if needed */ 6780 /* Start with BRC disabled, transfer_update will enable it if needed */
6817 reg_w(gspca_dev, 0x00, 0x0007); 6781 reg_w(gspca_dev, 0x00, 0x0007);
6818 setlightfreq(gspca_dev); 6782 if (sd->plfreq)
6783 setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq));
6819 6784
6820 switch (sd->sensor) { 6785 switch (sd->sensor) {
6821 case SENSOR_ADCM2700: 6786 case SENSOR_ADCM2700:
@@ -6826,7 +6791,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6826 reg_w(gspca_dev, 0x40, 0x0117); 6791 reg_w(gspca_dev, 0x40, 0x0117);
6827 break; 6792 break;
6828 case SENSOR_HV7131R: 6793 case SENSOR_HV7131R:
6829 setexposure(gspca_dev); 6794 setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
6830 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6795 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
6831 break; 6796 break;
6832 case SENSOR_GC0305: 6797 case SENSOR_GC0305:
@@ -6850,7 +6815,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6850 break; 6815 break;
6851 } 6816 }
6852 6817
6853 setautogain(gspca_dev); 6818 setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
6854 6819
6855 if (gspca_dev->usb_err < 0) 6820 if (gspca_dev->usb_err < 0)
6856 return gspca_dev->usb_err; 6821 return gspca_dev->usb_err;
@@ -6911,79 +6876,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
6911 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 6876 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
6912} 6877}
6913 6878
6914static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
6915{
6916 struct sd *sd = (struct sd *) gspca_dev;
6917
6918 sd->ctrls[AUTOGAIN].val = val;
6919 if (val) {
6920 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
6921 } else {
6922 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
6923 if (gspca_dev->streaming)
6924 getexposure(gspca_dev);
6925 }
6926 if (gspca_dev->streaming)
6927 setautogain(gspca_dev);
6928 return gspca_dev->usb_err;
6929}
6930
6931static int sd_querymenu(struct gspca_dev *gspca_dev,
6932 struct v4l2_querymenu *menu)
6933{
6934 switch (menu->id) {
6935 case V4L2_CID_POWER_LINE_FREQUENCY:
6936 switch (menu->index) {
6937 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
6938 strcpy((char *) menu->name, "NoFliker");
6939 return 0;
6940 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
6941 strcpy((char *) menu->name, "50 Hz");
6942 return 0;
6943 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
6944 strcpy((char *) menu->name, "60 Hz");
6945 return 0;
6946 }
6947 break;
6948 }
6949 return -EINVAL;
6950}
6951
6952static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val)
6953{
6954 struct sd *sd = (struct sd *) gspca_dev;
6955 int i, qual = sd->reg08 >> 1;
6956
6957 for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) {
6958 if (val <= jpeg_qual[i])
6959 break;
6960 }
6961 if (i > 0
6962 && i == qual
6963 && val < jpeg_qual[i])
6964 i--;
6965
6966 /* With high quality settings we need max bandwidth */
6967 if (i >= 2 && gspca_dev->streaming &&
6968 !gspca_dev->cam.needs_full_bandwidth)
6969 return -EBUSY;
6970
6971 sd->reg08 = (i << 1) | 1;
6972 sd->ctrls[QUALITY].val = jpeg_qual[i];
6973
6974 if (gspca_dev->streaming)
6975 setquality(gspca_dev);
6976 return gspca_dev->usb_err;
6977}
6978
6979static int sd_set_jcomp(struct gspca_dev *gspca_dev, 6879static int sd_set_jcomp(struct gspca_dev *gspca_dev,
6980 struct v4l2_jpegcompression *jcomp) 6880 struct v4l2_jpegcompression *jcomp)
6981{ 6881{
6982 struct sd *sd = (struct sd *) gspca_dev; 6882 struct sd *sd = (struct sd *) gspca_dev;
6883 int ret;
6983 6884
6984 sd_setquality(gspca_dev, jcomp->quality); 6885 ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
6985 jcomp->quality = sd->ctrls[QUALITY].val; 6886 if (ret)
6986 return gspca_dev->usb_err; 6887 return ret;
6888 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
6889 return 0;
6987} 6890}
6988 6891
6989static int sd_get_jcomp(struct gspca_dev *gspca_dev, 6892static int sd_get_jcomp(struct gspca_dev *gspca_dev,
@@ -6992,7 +6895,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
6992 struct sd *sd = (struct sd *) gspca_dev; 6895 struct sd *sd = (struct sd *) gspca_dev;
6993 6896
6994 memset(jcomp, 0, sizeof *jcomp); 6897 memset(jcomp, 0, sizeof *jcomp);
6995 jcomp->quality = sd->ctrls[QUALITY].val; 6898 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
6996 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 6899 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
6997 | V4L2_JPEG_MARKER_DQT; 6900 | V4L2_JPEG_MARKER_DQT;
6998 return 0; 6901 return 0;
@@ -7016,15 +6919,13 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
7016 6919
7017static const struct sd_desc sd_desc = { 6920static const struct sd_desc sd_desc = {
7018 .name = KBUILD_MODNAME, 6921 .name = KBUILD_MODNAME,
7019 .ctrls = sd_ctrls,
7020 .nctrls = ARRAY_SIZE(sd_ctrls),
7021 .config = sd_config, 6922 .config = sd_config,
7022 .init = sd_init, 6923 .init = sd_init,
6924 .init_controls = sd_init_controls,
7023 .isoc_init = sd_pre_start, 6925 .isoc_init = sd_pre_start,
7024 .start = sd_start, 6926 .start = sd_start,
7025 .stop0 = sd_stop0, 6927 .stop0 = sd_stop0,
7026 .pkt_scan = sd_pkt_scan, 6928 .pkt_scan = sd_pkt_scan,
7027 .querymenu = sd_querymenu,
7028 .get_jcomp = sd_get_jcomp, 6929 .get_jcomp = sd_get_jcomp,
7029 .set_jcomp = sd_set_jcomp, 6930 .set_jcomp = sd_set_jcomp,
7030#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 6931#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
@@ -7108,6 +7009,7 @@ static struct usb_driver sd_driver = {
7108#ifdef CONFIG_PM 7009#ifdef CONFIG_PM
7109 .suspend = gspca_suspend, 7010 .suspend = gspca_suspend,
7110 .resume = gspca_resume, 7011 .resume = gspca_resume,
7012 .reset_resume = gspca_resume,
7111#endif 7013#endif
7112}; 7014};
7113 7015