aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-18 05:45:30 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 17:35:37 -0400
commit930806cb92325e43889b320ae2e705af774742ff (patch)
tree004fe20197bad19042be746612a87f5a1355ca4f
parentd5d875cb8fb7206305ae6ca0240ccc396cb8b1be (diff)
[media] vc032x: convert to the control framework
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/vc032x.c695
1 files changed, 158 insertions, 537 deletions
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 208f6b2d512a..ee1a1c558e48 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,7 @@ 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); 3546 v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler);
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); 3547 usb_exchange(gspca_dev, poxxxx_init_start_3);
3845 if (mode) 3548 if (mode)
3846 init = poxxxx_initQVGA; 3549 init = poxxxx_initQVGA;
@@ -3873,8 +3576,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
3873 break; 3576 break;
3874 } 3577 }
3875 msleep(100); 3578 msleep(100);
3876 sethvflip(gspca_dev); 3579 v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler);
3877 setlightfreq(gspca_dev);
3878 } 3580 }
3879 switch (sd->sensor) { 3581 switch (sd->sensor) {
3880 case SENSOR_OV7670: 3582 case SENSOR_OV7670:
@@ -3960,233 +3662,152 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3960 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 3662 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3961} 3663}
3962 3664
3963static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 3665static 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{ 3666{
4001 struct sd *sd = (struct sd *) gspca_dev; 3667 struct gspca_dev *gspca_dev =
4002 3668 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
4003 sd->colors = val; 3669 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 3670
4049 *val = sd->vflip; 3671 gspca_dev->usb_err = 0;
4050 return 0;
4051}
4052 3672
4053static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) 3673 if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
4054{ 3674 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 3675
3676 switch (ctrl->id) {
3677 case V4L2_CID_BRIGHTNESS:
3678 setbrightness(gspca_dev, ctrl->val);
3679 break;
3680 case V4L2_CID_CONTRAST:
3681 setcontrast(gspca_dev, ctrl->val);
3682 break;
3683 case V4L2_CID_SATURATION:
3684 setcolors(gspca_dev, ctrl->val);
3685 break;
3686 case V4L2_CID_HFLIP:
3687 sethvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
3688 break;
3689 case V4L2_CID_SHARPNESS:
3690 setsharpness(gspca_dev, ctrl->val);
3691 break;
3692 case V4L2_CID_AUTOGAIN:
3693 setautogain(gspca_dev, ctrl->val);
3694 break;
3695 case V4L2_CID_GAIN:
3696 setgain(gspca_dev, ctrl->val);
3697 break;
3698 case V4L2_CID_EXPOSURE:
3699 setexposure(gspca_dev, ctrl->val);
3700 break;
3701 case V4L2_CID_BACKLIGHT_COMPENSATION:
3702 setbacklight(gspca_dev, ctrl->val);
3703 break;
3704 case V4L2_CID_POWER_LINE_FREQUENCY:
3705 setlightfreq(gspca_dev, ctrl->val);
3706 break;
3707 }
4133 return gspca_dev->usb_err; 3708 return gspca_dev->usb_err;
4134} 3709}
4135 3710
4136static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 3711static const struct v4l2_ctrl_ops sd_ctrl_ops = {
4137{ 3712 .s_ctrl = sd_s_ctrl,
4138 struct sd *sd = (struct sd *) gspca_dev; 3713};
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 3714
4155static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val) 3715static int sd_init_controls(struct gspca_dev *gspca_dev)
4156{ 3716{
4157 struct sd *sd = (struct sd *) gspca_dev; 3717 struct sd *sd = (struct sd *)gspca_dev;
3718 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
3719 bool has_brightness = false;
3720 bool has_contrast = false;
3721 bool has_sat = false;
3722 bool has_hvflip = false;
3723 bool has_freq = false;
3724 bool has_backlight = false;
3725 bool has_exposure = false;
3726 bool has_autogain = false;
3727 bool has_gain = false;
3728 bool has_sharpness = false;
4158 3729
4159 *val = sd->backlight; 3730 switch (sd->sensor) {
4160 return 0; 3731 case SENSOR_HV7131R:
4161} 3732 case SENSOR_MI0360:
4162 3733 case SENSOR_PO3130NC:
4163static int sd_querymenu(struct gspca_dev *gspca_dev, 3734 break;
4164 struct v4l2_querymenu *menu) 3735 case SENSOR_MI1310_SOC:
4165{ 3736 case SENSOR_MI1320:
4166 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"}; 3737 case SENSOR_MI1320_SOC:
3738 case SENSOR_OV7660:
3739 has_hvflip = true;
3740 break;
3741 case SENSOR_OV7670:
3742 has_hvflip = has_freq = true;
3743 break;
3744 case SENSOR_PO1200:
3745 has_hvflip = has_sharpness = true;
3746 break;
3747 case SENSOR_POxxxx:
3748 has_brightness = has_contrast = has_sat = has_backlight =
3749 has_exposure = has_autogain = has_gain =
3750 has_sharpness = true;
3751 break;
3752 }
4167 3753
4168 switch (menu->id) { 3754 gspca_dev->vdev.ctrl_handler = hdl;
4169 case V4L2_CID_POWER_LINE_FREQUENCY: 3755 v4l2_ctrl_handler_init(hdl, 8);
4170 if (menu->index >= ARRAY_SIZE(freq_nm)) 3756 if (has_brightness)
4171 break; 3757 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4172 strcpy((char *) menu->name, freq_nm[menu->index]); 3758 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
4173 return 0; 3759 if (has_contrast)
3760 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3761 V4L2_CID_CONTRAST, 0, 255, 1, 127);
3762 if (has_sat)
3763 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3764 V4L2_CID_SATURATION, 1, 127, 1, 63);
3765 if (has_hvflip) {
3766 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3767 V4L2_CID_HFLIP, 0, 1, 1, 0);
3768 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3769 V4L2_CID_VFLIP, 0, 1, 1, 0);
4174 } 3770 }
4175 return -EINVAL; 3771 if (has_sharpness)
3772 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3773 V4L2_CID_SHARPNESS, -1, 2, 1, -1);
3774 if (has_freq)
3775 v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
3776 V4L2_CID_POWER_LINE_FREQUENCY,
3777 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
3778 V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
3779 if (has_autogain)
3780 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3781 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
3782 if (has_gain)
3783 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3784 V4L2_CID_GAIN, 0, 78, 1, 0);
3785 if (has_exposure)
3786 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3787 V4L2_CID_EXPOSURE, 0, 4095, 1, 450);
3788 if (has_backlight)
3789 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3790 V4L2_CID_BACKLIGHT_COMPENSATION, 0, 15, 1, 15);
3791
3792 if (hdl->error) {
3793 pr_err("Could not initialize controls\n");
3794 return hdl->error;
3795 }
3796 if (sd->hflip)
3797 v4l2_ctrl_cluster(2, &sd->hflip);
3798 return 0;
4176} 3799}
4177 3800
4178/* sub-driver description */ 3801/* sub-driver description */
4179static const struct sd_desc sd_desc = { 3802static const struct sd_desc sd_desc = {
4180 .name = MODULE_NAME, 3803 .name = MODULE_NAME,
4181 .ctrls = sd_ctrls, 3804 .init_controls = sd_init_controls,
4182 .nctrls = ARRAY_SIZE(sd_ctrls),
4183 .config = sd_config, 3805 .config = sd_config,
4184 .init = sd_init, 3806 .init = sd_init,
4185 .start = sd_start, 3807 .start = sd_start,
4186 .stopN = sd_stopN, 3808 .stopN = sd_stopN,
4187 .stop0 = sd_stop0, 3809 .stop0 = sd_stop0,
4188 .pkt_scan = sd_pkt_scan, 3810 .pkt_scan = sd_pkt_scan,
4189 .querymenu = sd_querymenu,
4190}; 3811};
4191 3812
4192/* -- module initialisation -- */ 3813/* -- module initialisation -- */