aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-12-28 05:35:27 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:17:21 -0500
commit71e84ea7f082eb02df6ef40f55d2c4a998f6e1df (patch)
treeedc34673c011101d2aea32fed146e954e43fa3ae /drivers/media
parent7e5f9059a807ce9b7a12b2402f5aeae9557c8049 (diff)
[media] gspca - stv06xx/st6422: Use the new video control mechanism
Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c272
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.h10
2 files changed, 118 insertions, 164 deletions
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 42f3a1e41188..8a456de4970a 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -28,6 +28,20 @@
28 28
29#include "stv06xx_st6422.h" 29#include "stv06xx_st6422.h"
30 30
31/* controls */
32enum e_ctrl {
33 BRIGHTNESS,
34 CONTRAST,
35 GAIN,
36 EXPOSURE,
37 NCTRLS /* number of controls */
38};
39
40/* sensor settings */
41struct st6422_settings {
42 struct gspca_ctrl ctrls[NCTRLS];
43};
44
31static struct v4l2_pix_format st6422_mode[] = { 45static struct v4l2_pix_format st6422_mode[] = {
32 /* Note we actually get 124 lines of data, of which we skip the 4st 46 /* Note we actually get 124 lines of data, of which we skip the 4st
33 4 as they are garbage */ 47 4 as they are garbage */
@@ -57,9 +71,14 @@ static struct v4l2_pix_format st6422_mode[] = {
57 }, 71 },
58}; 72};
59 73
60static const struct ctrl st6422_ctrl[] = { 74/* V4L2 controls supported by the driver */
61#define BRIGHTNESS_IDX 0 75static void st6422_set_brightness(struct gspca_dev *gspca_dev);
62 { 76static void st6422_set_contrast(struct gspca_dev *gspca_dev);
77static void st6422_set_gain(struct gspca_dev *gspca_dev);
78static void st6422_set_exposure(struct gspca_dev *gspca_dev);
79
80static const struct ctrl st6422_ctrl[NCTRLS] = {
81[BRIGHTNESS] = {
63 { 82 {
64 .id = V4L2_CID_BRIGHTNESS, 83 .id = V4L2_CID_BRIGHTNESS,
65 .type = V4L2_CTRL_TYPE_INTEGER, 84 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -69,11 +88,9 @@ static const struct ctrl st6422_ctrl[] = {
69 .step = 1, 88 .step = 1,
70 .default_value = 3 89 .default_value = 3
71 }, 90 },
72 .set = st6422_set_brightness, 91 .set_control = st6422_set_brightness
73 .get = st6422_get_brightness
74 }, 92 },
75#define CONTRAST_IDX 1 93[CONTRAST] = {
76 {
77 { 94 {
78 .id = V4L2_CID_CONTRAST, 95 .id = V4L2_CID_CONTRAST,
79 .type = V4L2_CTRL_TYPE_INTEGER, 96 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -83,11 +100,9 @@ static const struct ctrl st6422_ctrl[] = {
83 .step = 1, 100 .step = 1,
84 .default_value = 11 101 .default_value = 11
85 }, 102 },
86 .set = st6422_set_contrast, 103 .set_control = st6422_set_contrast
87 .get = st6422_get_contrast
88 }, 104 },
89#define GAIN_IDX 2 105[GAIN] = {
90 {
91 { 106 {
92 .id = V4L2_CID_GAIN, 107 .id = V4L2_CID_GAIN,
93 .type = V4L2_CTRL_TYPE_INTEGER, 108 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -97,49 +112,43 @@ static const struct ctrl st6422_ctrl[] = {
97 .step = 1, 112 .step = 1,
98 .default_value = 64 113 .default_value = 64
99 }, 114 },
100 .set = st6422_set_gain, 115 .set_control = st6422_set_gain
101 .get = st6422_get_gain
102 }, 116 },
103#define EXPOSURE_IDX 3 117[EXPOSURE] = {
104 {
105 { 118 {
106 .id = V4L2_CID_EXPOSURE, 119 .id = V4L2_CID_EXPOSURE,
107 .type = V4L2_CTRL_TYPE_INTEGER, 120 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Exposure", 121 .name = "Exposure",
109 .minimum = 0, 122 .minimum = 0,
110 .maximum = 1023, 123#define EXPOSURE_MAX 1023
124 .maximum = EXPOSURE_MAX,
111 .step = 1, 125 .step = 1,
112 .default_value = 256 126 .default_value = 256
113 }, 127 },
114 .set = st6422_set_exposure, 128 .set_control = st6422_set_exposure
115 .get = st6422_get_exposure
116 }, 129 },
117}; 130};
118 131
119static int st6422_probe(struct sd *sd) 132static int st6422_probe(struct sd *sd)
120{ 133{
121 int i; 134 struct st6422_settings *sensor_settings;
122 s32 *sensor_settings;
123 135
124 if (sd->bridge != BRIDGE_ST6422) 136 if (sd->bridge != BRIDGE_ST6422)
125 return -ENODEV; 137 return -ENODEV;
126 138
127 info("st6422 sensor detected"); 139 info("st6422 sensor detected");
128 140
129 sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32), 141 sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL);
130 GFP_KERNEL);
131 if (!sensor_settings) 142 if (!sensor_settings)
132 return -ENOMEM; 143 return -ENOMEM;
133 144
134 sd->gspca_dev.cam.cam_mode = st6422_mode; 145 sd->gspca_dev.cam.cam_mode = st6422_mode;
135 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); 146 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
147 sd->gspca_dev.cam.ctrls = sensor_settings->ctrls;
136 sd->desc.ctrls = st6422_ctrl; 148 sd->desc.ctrls = st6422_ctrl;
137 sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl); 149 sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
138 sd->sensor_priv = sensor_settings; 150 sd->sensor_priv = sensor_settings;
139 151
140 for (i = 0; i < sd->desc.nctrls; i++)
141 sensor_settings[i] = st6422_ctrl[i].qctrl.default_value;
142
143 return 0; 152 return 0;
144} 153}
145 154
@@ -234,77 +243,92 @@ static void st6422_disconnect(struct sd *sd)
234 kfree(sd->sensor_priv); 243 kfree(sd->sensor_priv);
235} 244}
236 245
237static int st6422_start(struct sd *sd) 246static int setbrightness(struct sd *sd)
247{
248 struct st6422_settings *sensor_settings = sd->sensor_priv;
249
250 /* val goes from 0 -> 31 */
251 return stv06xx_write_bridge(sd, 0x1432,
252 sensor_settings->ctrls[BRIGHTNESS].val);
253}
254
255static int setcontrast(struct sd *sd)
256{
257 struct st6422_settings *sensor_settings = sd->sensor_priv;
258
259 /* Val goes from 0 -> 15 */
260 return stv06xx_write_bridge(sd, 0x143a,
261 sensor_settings->ctrls[CONTRAST].val | 0xf0);
262}
263
264static int setgain(struct sd *sd)
238{ 265{
266 struct st6422_settings *sensor_settings = sd->sensor_priv;
267 u8 gain;
239 int err; 268 int err;
240 struct cam *cam = &sd->gspca_dev.cam;
241 s32 *sensor_settings = sd->sensor_priv;
242 269
243 if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) 270 gain = sensor_settings->ctrls[GAIN].val;
244 err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
245 else
246 err = stv06xx_write_bridge(sd, 0x1505, 0x02);
247 if (err < 0)
248 return err;
249 271
250 err = st6422_set_brightness(&sd->gspca_dev, 272 /* Set red, green, blue, gain */
251 sensor_settings[BRIGHTNESS_IDX]); 273 err = stv06xx_write_bridge(sd, 0x0509, gain);
252 if (err < 0) 274 if (err < 0)
253 return err; 275 return err;
254 276
255 err = st6422_set_contrast(&sd->gspca_dev, 277 err = stv06xx_write_bridge(sd, 0x050a, gain);
256 sensor_settings[CONTRAST_IDX]);
257 if (err < 0) 278 if (err < 0)
258 return err; 279 return err;
259 280
260 err = st6422_set_exposure(&sd->gspca_dev, 281 err = stv06xx_write_bridge(sd, 0x050b, gain);
261 sensor_settings[EXPOSURE_IDX]);
262 if (err < 0) 282 if (err < 0)
263 return err; 283 return err;
264 284
265 err = st6422_set_gain(&sd->gspca_dev, 285 /* 2 mystery writes */
266 sensor_settings[GAIN_IDX]); 286 err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
267 if (err < 0) 287 if (err < 0)
268 return err; 288 return err;
269 289
270 PDEBUG(D_STREAM, "Starting stream"); 290 return stv06xx_write_bridge(sd, 0x050d, 0x01);
271
272 return 0;
273} 291}
274 292
275static int st6422_stop(struct sd *sd) 293static int setexposure(struct sd *sd)
276{ 294{
277 PDEBUG(D_STREAM, "Halting stream"); 295 struct st6422_settings *sensor_settings = sd->sensor_priv;
278 296 u16 expo;
279 return 0; 297 int err;
280}
281
282static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
283{
284 struct sd *sd = (struct sd *) gspca_dev;
285 s32 *sensor_settings = sd->sensor_priv;
286
287 *val = sensor_settings[BRIGHTNESS_IDX];
288 298
289 PDEBUG(D_V4L2, "Read brightness %d", *val); 299 expo = sensor_settings->ctrls[EXPOSURE].val;
300 err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff);
301 if (err < 0)
302 return err;
290 303
291 return 0; 304 return stv06xx_write_bridge(sd, 0x143e, expo >> 8);
292} 305}
293 306
294static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 307static int st6422_start(struct sd *sd)
295{ 308{
296 int err; 309 int err;
297 struct sd *sd = (struct sd *) gspca_dev; 310 struct cam *cam = &sd->gspca_dev.cam;
298 s32 *sensor_settings = sd->sensor_priv;
299 311
300 sensor_settings[BRIGHTNESS_IDX] = val; 312 if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
313 err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
314 else
315 err = stv06xx_write_bridge(sd, 0x1505, 0x02);
316 if (err < 0)
317 return err;
301 318
302 if (!gspca_dev->streaming) 319 err = setbrightness(sd);
303 return 0; 320 if (err < 0)
321 return err;
304 322
305 /* val goes from 0 -> 31 */ 323 err = setcontrast(sd);
306 PDEBUG(D_V4L2, "Set brightness to %d", val); 324 if (err < 0)
307 err = stv06xx_write_bridge(sd, 0x1432, val); 325 return err;
326
327 err = setexposure(sd);
328 if (err < 0)
329 return err;
330
331 err = setgain(sd);
308 if (err < 0) 332 if (err < 0)
309 return err; 333 return err;
310 334
@@ -313,125 +337,65 @@ static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
313 return (err < 0) ? err : 0; 337 return (err < 0) ? err : 0;
314} 338}
315 339
316static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val) 340static int st6422_stop(struct sd *sd)
317{ 341{
318 struct sd *sd = (struct sd *) gspca_dev; 342 PDEBUG(D_STREAM, "Halting stream");
319 s32 *sensor_settings = sd->sensor_priv;
320
321 *val = sensor_settings[CONTRAST_IDX];
322
323 PDEBUG(D_V4L2, "Read contrast %d", *val);
324 343
325 return 0; 344 return 0;
326} 345}
327 346
328static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val) 347static void st6422_set_brightness(struct gspca_dev *gspca_dev)
329{ 348{
330 int err; 349 int err;
331 struct sd *sd = (struct sd *) gspca_dev; 350 struct sd *sd = (struct sd *) gspca_dev;
332 s32 *sensor_settings = sd->sensor_priv;
333
334 sensor_settings[CONTRAST_IDX] = val;
335 351
336 if (!gspca_dev->streaming) 352 err = setbrightness(sd);
337 return 0;
338
339 /* Val goes from 0 -> 15 */
340 PDEBUG(D_V4L2, "Set contrast to %d\n", val);
341 err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val);
342 if (err < 0)
343 return err;
344 353
345 /* commit settings */ 354 /* commit settings */
346 err = stv06xx_write_bridge(sd, 0x143f, 0x01); 355 if (err >= 0)
347 return (err < 0) ? err : 0; 356 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
348}
349
350static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
351{
352 struct sd *sd = (struct sd *) gspca_dev;
353 s32 *sensor_settings = sd->sensor_priv;
354
355 *val = sensor_settings[GAIN_IDX];
356 357
357 PDEBUG(D_V4L2, "Read gain %d", *val); 358 gspca_dev->usb_err = err;
358
359 return 0;
360} 359}
361 360
362static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val) 361static void st6422_set_contrast(struct gspca_dev *gspca_dev)
363{ 362{
364 int err; 363 int err;
365 struct sd *sd = (struct sd *) gspca_dev; 364 struct sd *sd = (struct sd *) gspca_dev;
366 s32 *sensor_settings = sd->sensor_priv;
367 365
368 sensor_settings[GAIN_IDX] = val; 366 err = setcontrast(sd);
369
370 if (!gspca_dev->streaming)
371 return 0;
372
373 PDEBUG(D_V4L2, "Set gain to %d", val);
374
375 /* Set red, green, blue, gain */
376 err = stv06xx_write_bridge(sd, 0x0509, val);
377 if (err < 0)
378 return err;
379
380 err = stv06xx_write_bridge(sd, 0x050a, val);
381 if (err < 0)
382 return err;
383
384 err = stv06xx_write_bridge(sd, 0x050b, val);
385 if (err < 0)
386 return err;
387
388 /* 2 mystery writes */
389 err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
390 if (err < 0)
391 return err;
392
393 err = stv06xx_write_bridge(sd, 0x050d, 0x01);
394 if (err < 0)
395 return err;
396 367
397 /* commit settings */ 368 /* commit settings */
398 err = stv06xx_write_bridge(sd, 0x143f, 0x01); 369 if (err >= 0)
399 return (err < 0) ? err : 0; 370 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
371
372 gspca_dev->usb_err = err;
400} 373}
401 374
402static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 375static void st6422_set_gain(struct gspca_dev *gspca_dev)
403{ 376{
377 int err;
404 struct sd *sd = (struct sd *) gspca_dev; 378 struct sd *sd = (struct sd *) gspca_dev;
405 s32 *sensor_settings = sd->sensor_priv;
406 379
407 *val = sensor_settings[EXPOSURE_IDX]; 380 err = setgain(sd);
408 381
409 PDEBUG(D_V4L2, "Read exposure %d", *val); 382 /* commit settings */
383 if (err >= 0)
384 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
410 385
411 return 0; 386 gspca_dev->usb_err = err;
412} 387}
413 388
414static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 389static void st6422_set_exposure(struct gspca_dev *gspca_dev)
415{ 390{
416 int err; 391 int err;
417 struct sd *sd = (struct sd *) gspca_dev; 392 struct sd *sd = (struct sd *) gspca_dev;
418 s32 *sensor_settings = sd->sensor_priv;
419
420 sensor_settings[EXPOSURE_IDX] = val;
421
422 if (!gspca_dev->streaming)
423 return 0;
424
425 PDEBUG(D_V4L2, "Set exposure to %d\n", val);
426 err = stv06xx_write_bridge(sd, 0x143d, val & 0xff);
427 if (err < 0)
428 return err;
429 393
430 err = stv06xx_write_bridge(sd, 0x143e, val >> 8); 394 err = setexposure(sd);
431 if (err < 0)
432 return err;
433 395
434 /* commit settings */ 396 /* commit settings */
435 err = stv06xx_write_bridge(sd, 0x143f, 0x01); 397 if (err >= 0)
436 return (err < 0) ? err : 0; 398 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
399
400 gspca_dev->usb_err = err;
437} 401}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
index 12608aebe50b..d7498e06432b 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
@@ -37,16 +37,6 @@ static int st6422_init(struct sd *sd);
37static int st6422_stop(struct sd *sd); 37static int st6422_stop(struct sd *sd);
38static void st6422_disconnect(struct sd *sd); 38static void st6422_disconnect(struct sd *sd);
39 39
40/* V4L2 controls supported by the driver */
41static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
42static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
43static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val);
44static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val);
45static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
46static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val);
47static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
48static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
49
50const struct stv06xx_sensor stv06xx_sensor_st6422 = { 40const struct stv06xx_sensor stv06xx_sensor_st6422 = {
51 .name = "ST6422", 41 .name = "ST6422",
52 /* No known way to lower framerate in case of less bandwidth */ 42 /* No known way to lower framerate in case of less bandwidth */