diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-02-11 04:31:12 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-05 13:05:52 -0500 |
commit | c1f07ab2b3e7a1a0ec8152dc30ab5fec346bf367 (patch) | |
tree | f2f0aef3ff5c446e3461d60cf5e426b1dfd210db | |
parent | 5ce60d790a246c4c32043ac9b142615466479728 (diff) |
[media] gspca_sonixj: 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/usb/gspca/sonixj.c | 545 |
1 files changed, 164 insertions, 381 deletions
diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c index 671d0c6dece3..8246e1dc3e9d 100644 --- a/drivers/media/usb/gspca/sonixj.c +++ b/drivers/media/usb/gspca/sonixj.c | |||
@@ -31,32 +31,26 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); | |||
31 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); | 31 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); |
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | 33 | ||
34 | /* controls */ | ||
35 | enum e_ctrl { | ||
36 | BRIGHTNESS, | ||
37 | CONTRAST, | ||
38 | COLORS, | ||
39 | BLUE, | ||
40 | RED, | ||
41 | GAMMA, | ||
42 | EXPOSURE, | ||
43 | AUTOGAIN, | ||
44 | GAIN, | ||
45 | HFLIP, | ||
46 | VFLIP, | ||
47 | SHARPNESS, | ||
48 | ILLUM, | ||
49 | FREQ, | ||
50 | NCTRLS /* number of controls */ | ||
51 | }; | ||
52 | |||
53 | /* specific webcam descriptor */ | 34 | /* specific webcam descriptor */ |
54 | struct sd { | 35 | struct sd { |
55 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 36 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
56 | 37 | ||
57 | struct gspca_ctrl ctrls[NCTRLS]; | ||
58 | |||
59 | atomic_t avg_lum; | 38 | atomic_t avg_lum; |
39 | struct v4l2_ctrl *brightness; | ||
40 | struct v4l2_ctrl *contrast; | ||
41 | struct v4l2_ctrl *saturation; | ||
42 | struct { /* red/blue balance control cluster */ | ||
43 | struct v4l2_ctrl *red_bal; | ||
44 | struct v4l2_ctrl *blue_bal; | ||
45 | }; | ||
46 | struct { /* hflip/vflip control cluster */ | ||
47 | struct v4l2_ctrl *vflip; | ||
48 | struct v4l2_ctrl *hflip; | ||
49 | }; | ||
50 | struct v4l2_ctrl *gamma; | ||
51 | struct v4l2_ctrl *illum; | ||
52 | struct v4l2_ctrl *sharpness; | ||
53 | struct v4l2_ctrl *freq; | ||
60 | u32 exposure; | 54 | u32 exposure; |
61 | 55 | ||
62 | struct work_struct work; | 56 | struct work_struct work; |
@@ -127,283 +121,6 @@ static void qual_upd(struct work_struct *work); | |||
127 | #define SEN_CLK_EN 0x20 /* enable sensor clock */ | 121 | #define SEN_CLK_EN 0x20 /* enable sensor clock */ |
128 | #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ | 122 | #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ |
129 | 123 | ||
130 | /* V4L2 controls supported by the driver */ | ||
131 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
132 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
133 | static void setcolors(struct gspca_dev *gspca_dev); | ||
134 | static void setredblue(struct gspca_dev *gspca_dev); | ||
135 | static void setgamma(struct gspca_dev *gspca_dev); | ||
136 | static void setexposure(struct gspca_dev *gspca_dev); | ||
137 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
138 | static void setgain(struct gspca_dev *gspca_dev); | ||
139 | static void sethvflip(struct gspca_dev *gspca_dev); | ||
140 | static void setsharpness(struct gspca_dev *gspca_dev); | ||
141 | static void setillum(struct gspca_dev *gspca_dev); | ||
142 | static void setfreq(struct gspca_dev *gspca_dev); | ||
143 | |||
144 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
145 | [BRIGHTNESS] = { | ||
146 | { | ||
147 | .id = V4L2_CID_BRIGHTNESS, | ||
148 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
149 | .name = "Brightness", | ||
150 | .minimum = 0, | ||
151 | .maximum = 0xff, | ||
152 | .step = 1, | ||
153 | .default_value = 0x80, | ||
154 | }, | ||
155 | .set_control = setbrightness | ||
156 | }, | ||
157 | [CONTRAST] = { | ||
158 | { | ||
159 | .id = V4L2_CID_CONTRAST, | ||
160 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
161 | .name = "Contrast", | ||
162 | .minimum = 0, | ||
163 | #define CONTRAST_MAX 127 | ||
164 | .maximum = CONTRAST_MAX, | ||
165 | .step = 1, | ||
166 | .default_value = 20, | ||
167 | }, | ||
168 | .set_control = setcontrast | ||
169 | }, | ||
170 | [COLORS] = { | ||
171 | { | ||
172 | .id = V4L2_CID_SATURATION, | ||
173 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
174 | .name = "Saturation", | ||
175 | .minimum = 0, | ||
176 | .maximum = 40, | ||
177 | .step = 1, | ||
178 | #define COLORS_DEF 25 | ||
179 | .default_value = COLORS_DEF, | ||
180 | }, | ||
181 | .set_control = setcolors | ||
182 | }, | ||
183 | [BLUE] = { | ||
184 | { | ||
185 | .id = V4L2_CID_BLUE_BALANCE, | ||
186 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
187 | .name = "Blue Balance", | ||
188 | .minimum = 24, | ||
189 | .maximum = 40, | ||
190 | .step = 1, | ||
191 | .default_value = 32, | ||
192 | }, | ||
193 | .set_control = setredblue | ||
194 | }, | ||
195 | [RED] = { | ||
196 | { | ||
197 | .id = V4L2_CID_RED_BALANCE, | ||
198 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
199 | .name = "Red Balance", | ||
200 | .minimum = 24, | ||
201 | .maximum = 40, | ||
202 | .step = 1, | ||
203 | .default_value = 32, | ||
204 | }, | ||
205 | .set_control = setredblue | ||
206 | }, | ||
207 | [GAMMA] = { | ||
208 | { | ||
209 | .id = V4L2_CID_GAMMA, | ||
210 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
211 | .name = "Gamma", | ||
212 | .minimum = 0, | ||
213 | .maximum = 40, | ||
214 | .step = 1, | ||
215 | #define GAMMA_DEF 20 | ||
216 | .default_value = GAMMA_DEF, | ||
217 | }, | ||
218 | .set_control = setgamma | ||
219 | }, | ||
220 | [EXPOSURE] = { | ||
221 | { | ||
222 | .id = V4L2_CID_EXPOSURE, | ||
223 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
224 | .name = "Exposure", | ||
225 | .minimum = 500, | ||
226 | .maximum = 1500, | ||
227 | .step = 1, | ||
228 | .default_value = 1024 | ||
229 | }, | ||
230 | .set_control = setexposure | ||
231 | }, | ||
232 | [AUTOGAIN] = { | ||
233 | { | ||
234 | .id = V4L2_CID_AUTOGAIN, | ||
235 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
236 | .name = "Auto Gain", | ||
237 | .minimum = 0, | ||
238 | .maximum = 1, | ||
239 | .step = 1, | ||
240 | .default_value = 1 | ||
241 | }, | ||
242 | .set = sd_setautogain, | ||
243 | }, | ||
244 | [GAIN] = { | ||
245 | { | ||
246 | .id = V4L2_CID_GAIN, | ||
247 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
248 | .name = "Gain", | ||
249 | .minimum = 4, | ||
250 | .maximum = 49, | ||
251 | .step = 1, | ||
252 | .default_value = 15 | ||
253 | }, | ||
254 | .set_control = setgain | ||
255 | }, | ||
256 | [HFLIP] = { | ||
257 | { | ||
258 | .id = V4L2_CID_HFLIP, | ||
259 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
260 | .name = "Mirror", | ||
261 | .minimum = 0, | ||
262 | .maximum = 1, | ||
263 | .step = 1, | ||
264 | .default_value = 0, | ||
265 | }, | ||
266 | .set_control = sethvflip | ||
267 | }, | ||
268 | [VFLIP] = { | ||
269 | { | ||
270 | .id = V4L2_CID_VFLIP, | ||
271 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
272 | .name = "Vflip", | ||
273 | .minimum = 0, | ||
274 | .maximum = 1, | ||
275 | .step = 1, | ||
276 | .default_value = 0, | ||
277 | }, | ||
278 | .set_control = sethvflip | ||
279 | }, | ||
280 | [SHARPNESS] = { | ||
281 | { | ||
282 | .id = V4L2_CID_SHARPNESS, | ||
283 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
284 | .name = "Sharpness", | ||
285 | .minimum = 0, | ||
286 | .maximum = 255, | ||
287 | .step = 1, | ||
288 | .default_value = 90, | ||
289 | }, | ||
290 | .set_control = setsharpness | ||
291 | }, | ||
292 | [ILLUM] = { | ||
293 | { | ||
294 | .id = V4L2_CID_ILLUMINATORS_1, | ||
295 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
296 | .name = "Illuminator / infrared", | ||
297 | .minimum = 0, | ||
298 | .maximum = 1, | ||
299 | .step = 1, | ||
300 | .default_value = 0, | ||
301 | }, | ||
302 | .set_control = setillum | ||
303 | }, | ||
304 | /* ov7630/ov7648/ov7660 only */ | ||
305 | [FREQ] = { | ||
306 | { | ||
307 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
308 | .type = V4L2_CTRL_TYPE_MENU, | ||
309 | .name = "Light frequency filter", | ||
310 | .minimum = 0, | ||
311 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
312 | .step = 1, | ||
313 | .default_value = 1, | ||
314 | }, | ||
315 | .set_control = setfreq | ||
316 | }, | ||
317 | }; | ||
318 | |||
319 | /* table of the disabled controls */ | ||
320 | static const __u32 ctrl_dis[] = { | ||
321 | [SENSOR_ADCM1700] = (1 << EXPOSURE) | | ||
322 | (1 << AUTOGAIN) | | ||
323 | (1 << GAIN) | | ||
324 | (1 << HFLIP) | | ||
325 | (1 << VFLIP) | | ||
326 | (1 << FREQ), | ||
327 | |||
328 | [SENSOR_GC0307] = (1 << EXPOSURE) | | ||
329 | (1 << GAIN) | | ||
330 | (1 << HFLIP) | | ||
331 | (1 << VFLIP) | | ||
332 | (1 << FREQ), | ||
333 | |||
334 | [SENSOR_HV7131R] = (1 << EXPOSURE) | | ||
335 | (1 << GAIN) | | ||
336 | (1 << HFLIP) | | ||
337 | (1 << FREQ), | ||
338 | |||
339 | [SENSOR_MI0360] = (1 << EXPOSURE) | | ||
340 | (1 << GAIN) | | ||
341 | (1 << HFLIP) | | ||
342 | (1 << VFLIP) | | ||
343 | (1 << FREQ), | ||
344 | |||
345 | [SENSOR_MI0360B] = (1 << EXPOSURE) | | ||
346 | (1 << GAIN) | | ||
347 | (1 << HFLIP) | | ||
348 | (1 << VFLIP) | | ||
349 | (1 << FREQ), | ||
350 | |||
351 | [SENSOR_MO4000] = (1 << EXPOSURE) | | ||
352 | (1 << GAIN) | | ||
353 | (1 << HFLIP) | | ||
354 | (1 << VFLIP) | | ||
355 | (1 << FREQ), | ||
356 | |||
357 | [SENSOR_MT9V111] = (1 << EXPOSURE) | | ||
358 | (1 << GAIN) | | ||
359 | (1 << HFLIP) | | ||
360 | (1 << VFLIP) | | ||
361 | (1 << FREQ), | ||
362 | |||
363 | [SENSOR_OM6802] = (1 << EXPOSURE) | | ||
364 | (1 << GAIN) | | ||
365 | (1 << HFLIP) | | ||
366 | (1 << VFLIP) | | ||
367 | (1 << FREQ), | ||
368 | |||
369 | [SENSOR_OV7630] = (1 << EXPOSURE) | | ||
370 | (1 << GAIN) | | ||
371 | (1 << HFLIP), | ||
372 | |||
373 | [SENSOR_OV7648] = (1 << EXPOSURE) | | ||
374 | (1 << GAIN) | | ||
375 | (1 << HFLIP), | ||
376 | |||
377 | [SENSOR_OV7660] = (1 << EXPOSURE) | | ||
378 | (1 << AUTOGAIN) | | ||
379 | (1 << GAIN) | | ||
380 | (1 << HFLIP) | | ||
381 | (1 << VFLIP), | ||
382 | |||
383 | [SENSOR_PO1030] = (1 << EXPOSURE) | | ||
384 | (1 << AUTOGAIN) | | ||
385 | (1 << GAIN) | | ||
386 | (1 << HFLIP) | | ||
387 | (1 << VFLIP) | | ||
388 | (1 << FREQ), | ||
389 | |||
390 | [SENSOR_PO2030N] = (1 << FREQ), | ||
391 | |||
392 | [SENSOR_SOI768] = (1 << EXPOSURE) | | ||
393 | (1 << AUTOGAIN) | | ||
394 | (1 << GAIN) | | ||
395 | (1 << HFLIP) | | ||
396 | (1 << VFLIP) | | ||
397 | (1 << FREQ), | ||
398 | |||
399 | [SENSOR_SP80708] = (1 << EXPOSURE) | | ||
400 | (1 << AUTOGAIN) | | ||
401 | (1 << GAIN) | | ||
402 | (1 << HFLIP) | | ||
403 | (1 << VFLIP) | | ||
404 | (1 << FREQ), | ||
405 | }; | ||
406 | |||
407 | static const struct v4l2_pix_format cif_mode[] = { | 124 | static const struct v4l2_pix_format cif_mode[] = { |
408 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 125 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
409 | .bytesperline = 352, | 126 | .bytesperline = 352, |
@@ -1822,7 +1539,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1822 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1539 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1823 | } | 1540 | } |
1824 | cam->npkt = 24; /* 24 packets per ISOC message */ | 1541 | cam->npkt = 24; /* 24 packets per ISOC message */ |
1825 | cam->ctrls = sd->ctrls; | ||
1826 | 1542 | ||
1827 | sd->ag_cnt = -1; | 1543 | sd->ag_cnt = -1; |
1828 | sd->quality = QUALITY_DEF; | 1544 | sd->quality = QUALITY_DEF; |
@@ -1888,9 +1604,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1888 | break; | 1604 | break; |
1889 | } | 1605 | } |
1890 | 1606 | ||
1891 | if (sd->sensor == SENSOR_OM6802) | ||
1892 | sd->ctrls[SHARPNESS].def = 0x10; | ||
1893 | |||
1894 | /* Note we do not disable the sensor clock here (power saving mode), | 1607 | /* Note we do not disable the sensor clock here (power saving mode), |
1895 | as that also disables the button on the cam. */ | 1608 | as that also disables the button on the cam. */ |
1896 | reg_w1(gspca_dev, 0xf1, 0x00); | 1609 | reg_w1(gspca_dev, 0xf1, 0x00); |
@@ -1899,13 +1612,92 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1899 | sn9c1xx = sn_tb[sd->sensor]; | 1612 | sn9c1xx = sn_tb[sd->sensor]; |
1900 | sd->i2c_addr = sn9c1xx[9]; | 1613 | sd->i2c_addr = sn9c1xx[9]; |
1901 | 1614 | ||
1902 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | ||
1903 | if (!(sd->flags & F_ILLUM)) | ||
1904 | gspca_dev->ctrl_dis |= (1 << ILLUM); | ||
1905 | |||
1906 | return gspca_dev->usb_err; | 1615 | return gspca_dev->usb_err; |
1907 | } | 1616 | } |
1908 | 1617 | ||
1618 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl); | ||
1619 | |||
1620 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
1621 | .s_ctrl = sd_s_ctrl, | ||
1622 | }; | ||
1623 | |||
1624 | /* this function is called at probe time */ | ||
1625 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
1626 | { | ||
1627 | struct sd *sd = (struct sd *) gspca_dev; | ||
1628 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
1629 | |||
1630 | gspca_dev->vdev.ctrl_handler = hdl; | ||
1631 | v4l2_ctrl_handler_init(hdl, 14); | ||
1632 | |||
1633 | sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1634 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); | ||
1635 | #define CONTRAST_MAX 127 | ||
1636 | sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1637 | V4L2_CID_CONTRAST, 0, CONTRAST_MAX, 1, 20); | ||
1638 | #define COLORS_DEF 25 | ||
1639 | sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1640 | V4L2_CID_SATURATION, 0, 40, 1, COLORS_DEF); | ||
1641 | sd->red_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1642 | V4L2_CID_RED_BALANCE, 24, 40, 1, 32); | ||
1643 | sd->blue_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1644 | V4L2_CID_BLUE_BALANCE, 24, 40, 1, 32); | ||
1645 | #define GAMMA_DEF 20 | ||
1646 | sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1647 | V4L2_CID_GAMMA, 0, 40, 1, GAMMA_DEF); | ||
1648 | |||
1649 | if (sd->sensor == SENSOR_OM6802) | ||
1650 | sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1651 | V4L2_CID_SHARPNESS, 0, 255, 1, 16); | ||
1652 | else | ||
1653 | sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1654 | V4L2_CID_SHARPNESS, 0, 255, 1, 90); | ||
1655 | |||
1656 | if (sd->flags & F_ILLUM) | ||
1657 | sd->illum = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1658 | V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); | ||
1659 | |||
1660 | if (sd->sensor == SENSOR_PO2030N) { | ||
1661 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1662 | V4L2_CID_EXPOSURE, 500, 1500, 1, 1024); | ||
1663 | gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1664 | V4L2_CID_GAIN, 4, 49, 1, 15); | ||
1665 | sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1666 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
1667 | } | ||
1668 | |||
1669 | if (sd->sensor != SENSOR_ADCM1700 && sd->sensor != SENSOR_OV7660 && | ||
1670 | sd->sensor != SENSOR_PO1030 && sd->sensor != SENSOR_SOI768 && | ||
1671 | sd->sensor != SENSOR_SP80708) | ||
1672 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1673 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
1674 | |||
1675 | if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_OV7630 || | ||
1676 | sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_PO2030N) | ||
1677 | sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
1678 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
1679 | |||
1680 | if (sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 || | ||
1681 | sd->sensor == SENSOR_OV7660) | ||
1682 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
1683 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
1684 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, | ||
1685 | V4L2_CID_POWER_LINE_FREQUENCY_50HZ); | ||
1686 | |||
1687 | if (hdl->error) { | ||
1688 | pr_err("Could not initialize controls\n"); | ||
1689 | return hdl->error; | ||
1690 | } | ||
1691 | |||
1692 | v4l2_ctrl_cluster(2, &sd->red_bal); | ||
1693 | if (sd->sensor == SENSOR_PO2030N) { | ||
1694 | v4l2_ctrl_cluster(2, &sd->vflip); | ||
1695 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); | ||
1696 | } | ||
1697 | |||
1698 | return 0; | ||
1699 | } | ||
1700 | |||
1909 | static u32 expo_adjust(struct gspca_dev *gspca_dev, | 1701 | static u32 expo_adjust(struct gspca_dev *gspca_dev, |
1910 | u32 expo) | 1702 | u32 expo) |
1911 | { | 1703 | { |
@@ -2014,10 +1806,9 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
2014 | { | 1806 | { |
2015 | struct sd *sd = (struct sd *) gspca_dev; | 1807 | struct sd *sd = (struct sd *) gspca_dev; |
2016 | unsigned int expo; | 1808 | unsigned int expo; |
2017 | int brightness; | 1809 | int brightness = sd->brightness->val; |
2018 | u8 k2; | 1810 | u8 k2; |
2019 | 1811 | ||
2020 | brightness = sd->ctrls[BRIGHTNESS].val; | ||
2021 | k2 = (brightness - 0x80) >> 2; | 1812 | k2 = (brightness - 0x80) >> 2; |
2022 | switch (sd->sensor) { | 1813 | switch (sd->sensor) { |
2023 | case SENSOR_ADCM1700: | 1814 | case SENSOR_ADCM1700: |
@@ -2064,7 +1855,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
2064 | u8 k2; | 1855 | u8 k2; |
2065 | u8 contrast[6]; | 1856 | u8 contrast[6]; |
2066 | 1857 | ||
2067 | k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1) | 1858 | k2 = sd->contrast->val * 37 / (CONTRAST_MAX + 1) |
2068 | + 37; /* 37..73 */ | 1859 | + 37; /* 37..73 */ |
2069 | contrast[0] = (k2 + 1) / 2; /* red */ | 1860 | contrast[0] = (k2 + 1) / 2; /* red */ |
2070 | contrast[1] = 0; | 1861 | contrast[1] = 0; |
@@ -2090,7 +1881,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
2090 | 60, -51, -9 /* VR VG VB */ | 1881 | 60, -51, -9 /* VR VG VB */ |
2091 | }; | 1882 | }; |
2092 | 1883 | ||
2093 | colors = sd->ctrls[COLORS].val; | 1884 | colors = sd->saturation->val; |
2094 | if (sd->sensor == SENSOR_MI0360B) | 1885 | if (sd->sensor == SENSOR_MI0360B) |
2095 | uv = uv_mi0360b; | 1886 | uv = uv_mi0360b; |
2096 | else | 1887 | else |
@@ -2112,14 +1903,14 @@ static void setredblue(struct gspca_dev *gspca_dev) | |||
2112 | {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; | 1903 | {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; |
2113 | 1904 | ||
2114 | /* 0x40 = normal value = gain x 1 */ | 1905 | /* 0x40 = normal value = gain x 1 */ |
2115 | rg1b[3] = sd->ctrls[RED].val * 2; | 1906 | rg1b[3] = sd->red_bal->val * 2; |
2116 | rg1b[5] = sd->ctrls[BLUE].val * 2; | 1907 | rg1b[5] = sd->blue_bal->val * 2; |
2117 | i2c_w8(gspca_dev, rg1b); | 1908 | i2c_w8(gspca_dev, rg1b); |
2118 | return; | 1909 | return; |
2119 | } | 1910 | } |
2120 | reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); | 1911 | reg_w1(gspca_dev, 0x05, sd->red_bal->val); |
2121 | /* reg_w1(gspca_dev, 0x07, 32); */ | 1912 | /* reg_w1(gspca_dev, 0x07, 32); */ |
2122 | reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); | 1913 | reg_w1(gspca_dev, 0x06, sd->blue_bal->val); |
2123 | } | 1914 | } |
2124 | 1915 | ||
2125 | static void setgamma(struct gspca_dev *gspca_dev) | 1916 | static void setgamma(struct gspca_dev *gspca_dev) |
@@ -2153,7 +1944,7 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
2153 | break; | 1944 | break; |
2154 | } | 1945 | } |
2155 | 1946 | ||
2156 | val = sd->ctrls[GAMMA].val; | 1947 | val = sd->gamma->val; |
2157 | for (i = 0; i < sizeof gamma; i++) | 1948 | for (i = 0; i < sizeof gamma; i++) |
2158 | gamma[i] = gamma_base[i] | 1949 | gamma[i] = gamma_base[i] |
2159 | + delta[i] * (val - GAMMA_DEF) / 32; | 1950 | + delta[i] * (val - GAMMA_DEF) / 32; |
@@ -2168,11 +1959,11 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
2168 | u8 rexpo[] = /* 1a: expo H, 1b: expo M */ | 1959 | u8 rexpo[] = /* 1a: expo H, 1b: expo M */ |
2169 | {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; | 1960 | {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; |
2170 | 1961 | ||
2171 | rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; | 1962 | rexpo[3] = gspca_dev->exposure->val >> 8; |
2172 | i2c_w8(gspca_dev, rexpo); | 1963 | i2c_w8(gspca_dev, rexpo); |
2173 | msleep(6); | 1964 | msleep(6); |
2174 | rexpo[2] = 0x1b; | 1965 | rexpo[2] = 0x1b; |
2175 | rexpo[3] = sd->ctrls[EXPOSURE].val; | 1966 | rexpo[3] = gspca_dev->exposure->val; |
2176 | i2c_w8(gspca_dev, rexpo); | 1967 | i2c_w8(gspca_dev, rexpo); |
2177 | } | 1968 | } |
2178 | } | 1969 | } |
@@ -2181,8 +1972,6 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
2181 | { | 1972 | { |
2182 | struct sd *sd = (struct sd *) gspca_dev; | 1973 | struct sd *sd = (struct sd *) gspca_dev; |
2183 | 1974 | ||
2184 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) | ||
2185 | return; | ||
2186 | switch (sd->sensor) { | 1975 | switch (sd->sensor) { |
2187 | case SENSOR_OV7630: | 1976 | case SENSOR_OV7630: |
2188 | case SENSOR_OV7648: { | 1977 | case SENSOR_OV7648: { |
@@ -2192,13 +1981,13 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
2192 | comb = 0xc0; | 1981 | comb = 0xc0; |
2193 | else | 1982 | else |
2194 | comb = 0xa0; | 1983 | comb = 0xa0; |
2195 | if (sd->ctrls[AUTOGAIN].val) | 1984 | if (gspca_dev->autogain->val) |
2196 | comb |= 0x03; | 1985 | comb |= 0x03; |
2197 | i2c_w1(&sd->gspca_dev, 0x13, comb); | 1986 | i2c_w1(&sd->gspca_dev, 0x13, comb); |
2198 | return; | 1987 | return; |
2199 | } | 1988 | } |
2200 | } | 1989 | } |
2201 | if (sd->ctrls[AUTOGAIN].val) | 1990 | if (gspca_dev->autogain->val) |
2202 | sd->ag_cnt = AG_CNT_START; | 1991 | sd->ag_cnt = AG_CNT_START; |
2203 | else | 1992 | else |
2204 | sd->ag_cnt = -1; | 1993 | sd->ag_cnt = -1; |
@@ -2212,7 +2001,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
2212 | u8 rgain[] = /* 15: gain */ | 2001 | u8 rgain[] = /* 15: gain */ |
2213 | {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; | 2002 | {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; |
2214 | 2003 | ||
2215 | rgain[3] = sd->ctrls[GAIN].val; | 2004 | rgain[3] = gspca_dev->gain->val; |
2216 | i2c_w8(gspca_dev, rgain); | 2005 | i2c_w8(gspca_dev, rgain); |
2217 | } | 2006 | } |
2218 | } | 2007 | } |
@@ -2225,19 +2014,19 @@ static void sethvflip(struct gspca_dev *gspca_dev) | |||
2225 | switch (sd->sensor) { | 2014 | switch (sd->sensor) { |
2226 | case SENSOR_HV7131R: | 2015 | case SENSOR_HV7131R: |
2227 | comn = 0x18; /* clkdiv = 1, ablcen = 1 */ | 2016 | comn = 0x18; /* clkdiv = 1, ablcen = 1 */ |
2228 | if (sd->ctrls[VFLIP].val) | 2017 | if (sd->vflip->val) |
2229 | comn |= 0x01; | 2018 | comn |= 0x01; |
2230 | i2c_w1(gspca_dev, 0x01, comn); /* sctra */ | 2019 | i2c_w1(gspca_dev, 0x01, comn); /* sctra */ |
2231 | break; | 2020 | break; |
2232 | case SENSOR_OV7630: | 2021 | case SENSOR_OV7630: |
2233 | comn = 0x02; | 2022 | comn = 0x02; |
2234 | if (!sd->ctrls[VFLIP].val) | 2023 | if (!sd->vflip->val) |
2235 | comn |= 0x80; | 2024 | comn |= 0x80; |
2236 | i2c_w1(gspca_dev, 0x75, comn); | 2025 | i2c_w1(gspca_dev, 0x75, comn); |
2237 | break; | 2026 | break; |
2238 | case SENSOR_OV7648: | 2027 | case SENSOR_OV7648: |
2239 | comn = 0x06; | 2028 | comn = 0x06; |
2240 | if (sd->ctrls[VFLIP].val) | 2029 | if (sd->vflip->val) |
2241 | comn |= 0x80; | 2030 | comn |= 0x80; |
2242 | i2c_w1(gspca_dev, 0x75, comn); | 2031 | i2c_w1(gspca_dev, 0x75, comn); |
2243 | break; | 2032 | break; |
@@ -2251,9 +2040,9 @@ static void sethvflip(struct gspca_dev *gspca_dev) | |||
2251 | * bit3-0: X | 2040 | * bit3-0: X |
2252 | */ | 2041 | */ |
2253 | comn = 0x0a; | 2042 | comn = 0x0a; |
2254 | if (sd->ctrls[HFLIP].val) | 2043 | if (sd->hflip->val) |
2255 | comn |= 0x80; | 2044 | comn |= 0x80; |
2256 | if (sd->ctrls[VFLIP].val) | 2045 | if (sd->vflip->val) |
2257 | comn |= 0x40; | 2046 | comn |= 0x40; |
2258 | i2c_w1(&sd->gspca_dev, 0x1e, comn); | 2047 | i2c_w1(&sd->gspca_dev, 0x1e, comn); |
2259 | break; | 2048 | break; |
@@ -2264,23 +2053,21 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
2264 | { | 2053 | { |
2265 | struct sd *sd = (struct sd *) gspca_dev; | 2054 | struct sd *sd = (struct sd *) gspca_dev; |
2266 | 2055 | ||
2267 | reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); | 2056 | reg_w1(gspca_dev, 0x99, sd->sharpness->val); |
2268 | } | 2057 | } |
2269 | 2058 | ||
2270 | static void setillum(struct gspca_dev *gspca_dev) | 2059 | static void setillum(struct gspca_dev *gspca_dev) |
2271 | { | 2060 | { |
2272 | struct sd *sd = (struct sd *) gspca_dev; | 2061 | struct sd *sd = (struct sd *) gspca_dev; |
2273 | 2062 | ||
2274 | if (gspca_dev->ctrl_dis & (1 << ILLUM)) | ||
2275 | return; | ||
2276 | switch (sd->sensor) { | 2063 | switch (sd->sensor) { |
2277 | case SENSOR_ADCM1700: | 2064 | case SENSOR_ADCM1700: |
2278 | reg_w1(gspca_dev, 0x02, /* gpio */ | 2065 | reg_w1(gspca_dev, 0x02, /* gpio */ |
2279 | sd->ctrls[ILLUM].val ? 0x64 : 0x60); | 2066 | sd->illum->val ? 0x64 : 0x60); |
2280 | break; | 2067 | break; |
2281 | case SENSOR_MT9V111: | 2068 | case SENSOR_MT9V111: |
2282 | reg_w1(gspca_dev, 0x02, | 2069 | reg_w1(gspca_dev, 0x02, |
2283 | sd->ctrls[ILLUM].val ? 0x77 : 0x74); | 2070 | sd->illum->val ? 0x77 : 0x74); |
2284 | /* should have been: */ | 2071 | /* should have been: */ |
2285 | /* 0x55 : 0x54); * 370i */ | 2072 | /* 0x55 : 0x54); * 370i */ |
2286 | /* 0x66 : 0x64); * Clip */ | 2073 | /* 0x66 : 0x64); * Clip */ |
@@ -2292,13 +2079,11 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
2292 | { | 2079 | { |
2293 | struct sd *sd = (struct sd *) gspca_dev; | 2080 | struct sd *sd = (struct sd *) gspca_dev; |
2294 | 2081 | ||
2295 | if (gspca_dev->ctrl_dis & (1 << FREQ)) | ||
2296 | return; | ||
2297 | if (sd->sensor == SENSOR_OV7660) { | 2082 | if (sd->sensor == SENSOR_OV7660) { |
2298 | u8 com8; | 2083 | u8 com8; |
2299 | 2084 | ||
2300 | com8 = 0xdf; /* auto gain/wb/expo */ | 2085 | com8 = 0xdf; /* auto gain/wb/expo */ |
2301 | switch (sd->ctrls[FREQ].val) { | 2086 | switch (sd->freq->val) { |
2302 | case 0: /* Banding filter disabled */ | 2087 | case 0: /* Banding filter disabled */ |
2303 | i2c_w1(gspca_dev, 0x13, com8 | 0x20); | 2088 | i2c_w1(gspca_dev, 0x13, com8 | 0x20); |
2304 | break; | 2089 | break; |
@@ -2326,7 +2111,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
2326 | break; | 2111 | break; |
2327 | } | 2112 | } |
2328 | 2113 | ||
2329 | switch (sd->ctrls[FREQ].val) { | 2114 | switch (sd->freq->val) { |
2330 | case 0: /* Banding filter disabled */ | 2115 | case 0: /* Banding filter disabled */ |
2331 | break; | 2116 | break; |
2332 | case 1: /* 50 hz (filter on and framerate adj) */ | 2117 | case 1: /* 50 hz (filter on and framerate adj) */ |
@@ -2698,17 +2483,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2698 | sd->reg01 = reg01; | 2483 | sd->reg01 = reg01; |
2699 | sd->reg17 = reg17; | 2484 | sd->reg17 = reg17; |
2700 | 2485 | ||
2701 | sethvflip(gspca_dev); | ||
2702 | setbrightness(gspca_dev); | ||
2703 | setcontrast(gspca_dev); | ||
2704 | setcolors(gspca_dev); | ||
2705 | setautogain(gspca_dev); | ||
2706 | if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { | ||
2707 | setexposure(gspca_dev); | ||
2708 | setgain(gspca_dev); | ||
2709 | } | ||
2710 | setfreq(gspca_dev); | ||
2711 | |||
2712 | sd->pktsz = sd->npkt = 0; | 2486 | sd->pktsz = sd->npkt = 0; |
2713 | sd->nchg = sd->short_mark = 0; | 2487 | sd->nchg = sd->short_mark = 0; |
2714 | sd->work_thread = create_singlethread_workqueue(MODULE_NAME); | 2488 | sd->work_thread = create_singlethread_workqueue(MODULE_NAME); |
@@ -2803,9 +2577,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2803 | } | 2577 | } |
2804 | } | 2578 | } |
2805 | 2579 | ||
2806 | #define WANT_REGULAR_AUTOGAIN | ||
2807 | #include "autogain_functions.h" | ||
2808 | |||
2809 | static void do_autogain(struct gspca_dev *gspca_dev) | 2580 | static void do_autogain(struct gspca_dev *gspca_dev) |
2810 | { | 2581 | { |
2811 | struct sd *sd = (struct sd *) gspca_dev; | 2582 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -2825,7 +2596,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2825 | PDEBUG(D_FRAM, "mean lum %d", delta); | 2596 | PDEBUG(D_FRAM, "mean lum %d", delta); |
2826 | 2597 | ||
2827 | if (sd->sensor == SENSOR_PO2030N) { | 2598 | if (sd->sensor == SENSOR_PO2030N) { |
2828 | auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, | 2599 | gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta, |
2829 | 15, 1024); | 2600 | 15, 1024); |
2830 | return; | 2601 | return; |
2831 | } | 2602 | } |
@@ -3042,39 +2813,53 @@ marker_found: | |||
3042 | } | 2813 | } |
3043 | } | 2814 | } |
3044 | 2815 | ||
3045 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 2816 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
3046 | { | 2817 | { |
3047 | struct sd *sd = (struct sd *) gspca_dev; | 2818 | struct gspca_dev *gspca_dev = |
2819 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
3048 | 2820 | ||
3049 | sd->ctrls[AUTOGAIN].val = val; | 2821 | gspca_dev->usb_err = 0; |
3050 | if (val) | ||
3051 | gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); | ||
3052 | else | ||
3053 | gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); | ||
3054 | if (gspca_dev->streaming) | ||
3055 | setautogain(gspca_dev); | ||
3056 | return gspca_dev->usb_err; | ||
3057 | } | ||
3058 | 2822 | ||
3059 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 2823 | if (!gspca_dev->streaming) |
3060 | struct v4l2_querymenu *menu) | 2824 | return 0; |
3061 | { | 2825 | |
3062 | switch (menu->id) { | 2826 | switch (ctrl->id) { |
2827 | case V4L2_CID_BRIGHTNESS: | ||
2828 | setbrightness(gspca_dev); | ||
2829 | break; | ||
2830 | case V4L2_CID_CONTRAST: | ||
2831 | setcontrast(gspca_dev); | ||
2832 | break; | ||
2833 | case V4L2_CID_SATURATION: | ||
2834 | setcolors(gspca_dev); | ||
2835 | break; | ||
2836 | case V4L2_CID_RED_BALANCE: | ||
2837 | setredblue(gspca_dev); | ||
2838 | break; | ||
2839 | case V4L2_CID_GAMMA: | ||
2840 | setgamma(gspca_dev); | ||
2841 | break; | ||
2842 | case V4L2_CID_AUTOGAIN: | ||
2843 | setautogain(gspca_dev); | ||
2844 | setexposure(gspca_dev); | ||
2845 | setgain(gspca_dev); | ||
2846 | break; | ||
2847 | case V4L2_CID_VFLIP: | ||
2848 | sethvflip(gspca_dev); | ||
2849 | break; | ||
2850 | case V4L2_CID_SHARPNESS: | ||
2851 | setsharpness(gspca_dev); | ||
2852 | break; | ||
2853 | case V4L2_CID_ILLUMINATORS_1: | ||
2854 | setillum(gspca_dev); | ||
2855 | break; | ||
3063 | case V4L2_CID_POWER_LINE_FREQUENCY: | 2856 | case V4L2_CID_POWER_LINE_FREQUENCY: |
3064 | switch (menu->index) { | 2857 | setfreq(gspca_dev); |
3065 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
3066 | strcpy((char *) menu->name, "NoFliker"); | ||
3067 | return 0; | ||
3068 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
3069 | strcpy((char *) menu->name, "50 Hz"); | ||
3070 | return 0; | ||
3071 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
3072 | strcpy((char *) menu->name, "60 Hz"); | ||
3073 | return 0; | ||
3074 | } | ||
3075 | break; | 2858 | break; |
2859 | default: | ||
2860 | return -EINVAL; | ||
3076 | } | 2861 | } |
3077 | return -EINVAL; | 2862 | return gspca_dev->usb_err; |
3078 | } | 2863 | } |
3079 | 2864 | ||
3080 | #if IS_ENABLED(CONFIG_INPUT) | 2865 | #if IS_ENABLED(CONFIG_INPUT) |
@@ -3099,16 +2884,14 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | |||
3099 | /* sub-driver description */ | 2884 | /* sub-driver description */ |
3100 | static const struct sd_desc sd_desc = { | 2885 | static const struct sd_desc sd_desc = { |
3101 | .name = MODULE_NAME, | 2886 | .name = MODULE_NAME, |
3102 | .ctrls = sd_ctrls, | ||
3103 | .nctrls = NCTRLS, | ||
3104 | .config = sd_config, | 2887 | .config = sd_config, |
3105 | .init = sd_init, | 2888 | .init = sd_init, |
2889 | .init_controls = sd_init_controls, | ||
3106 | .start = sd_start, | 2890 | .start = sd_start, |
3107 | .stopN = sd_stopN, | 2891 | .stopN = sd_stopN, |
3108 | .stop0 = sd_stop0, | 2892 | .stop0 = sd_stop0, |
3109 | .pkt_scan = sd_pkt_scan, | 2893 | .pkt_scan = sd_pkt_scan, |
3110 | .dq_callback = do_autogain, | 2894 | .dq_callback = do_autogain, |
3111 | .querymenu = sd_querymenu, | ||
3112 | #if IS_ENABLED(CONFIG_INPUT) | 2895 | #if IS_ENABLED(CONFIG_INPUT) |
3113 | .int_pkt_scan = sd_int_pkt_scan, | 2896 | .int_pkt_scan = sd_int_pkt_scan, |
3114 | #endif | 2897 | #endif |