aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-02-11 04:31:12 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-05 13:05:52 -0500
commitc1f07ab2b3e7a1a0ec8152dc30ab5fec346bf367 (patch)
treef2f0aef3ff5c446e3461d60cf5e426b1dfd210db
parent5ce60d790a246c4c32043ac9b142615466479728 (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.c545
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>");
31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33 33
34/* controls */
35enum 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 */
54struct sd { 35struct 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 */
131static void setbrightness(struct gspca_dev *gspca_dev);
132static void setcontrast(struct gspca_dev *gspca_dev);
133static void setcolors(struct gspca_dev *gspca_dev);
134static void setredblue(struct gspca_dev *gspca_dev);
135static void setgamma(struct gspca_dev *gspca_dev);
136static void setexposure(struct gspca_dev *gspca_dev);
137static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
138static void setgain(struct gspca_dev *gspca_dev);
139static void sethvflip(struct gspca_dev *gspca_dev);
140static void setsharpness(struct gspca_dev *gspca_dev);
141static void setillum(struct gspca_dev *gspca_dev);
142static void setfreq(struct gspca_dev *gspca_dev);
143
144static 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 */
320static 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
407static const struct v4l2_pix_format cif_mode[] = { 124static 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
1618static int sd_s_ctrl(struct v4l2_ctrl *ctrl);
1619
1620static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1621 .s_ctrl = sd_s_ctrl,
1622};
1623
1624/* this function is called at probe time */
1625static 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
1909static u32 expo_adjust(struct gspca_dev *gspca_dev, 1701static 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
2125static void setgamma(struct gspca_dev *gspca_dev) 1916static 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
2270static void setillum(struct gspca_dev *gspca_dev) 2059static 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
2809static void do_autogain(struct gspca_dev *gspca_dev) 2580static 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
3045static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 2816static 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
3059static 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 */
3100static const struct sd_desc sd_desc = { 2885static 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