aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7110.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/saa7110.c')
-rw-r--r--drivers/media/video/saa7110.c115
1 files changed, 46 insertions, 69 deletions
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 7913f93979b8..99664205ef4e 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -36,6 +36,7 @@
36#include <linux/videodev2.h> 36#include <linux/videodev2.h>
37#include <media/v4l2-device.h> 37#include <media/v4l2-device.h>
38#include <media/v4l2-chip-ident.h> 38#include <media/v4l2-chip-ident.h>
39#include <media/v4l2-ctrls.h>
39 40
40MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); 41MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
41MODULE_AUTHOR("Pauline Middelink"); 42MODULE_AUTHOR("Pauline Middelink");
@@ -53,15 +54,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54struct saa7110 { 55struct saa7110 {
55 struct v4l2_subdev sd; 56 struct v4l2_subdev sd;
57 struct v4l2_ctrl_handler hdl;
56 u8 reg[SAA7110_NR_REG]; 58 u8 reg[SAA7110_NR_REG];
57 59
58 v4l2_std_id norm; 60 v4l2_std_id norm;
59 int input; 61 int input;
60 int enable; 62 int enable;
61 int bright;
62 int contrast;
63 int hue;
64 int sat;
65 63
66 wait_queue_head_t wq; 64 wait_queue_head_t wq;
67}; 65};
@@ -71,6 +69,11 @@ static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
71 return container_of(sd, struct saa7110, sd); 69 return container_of(sd, struct saa7110, sd);
72} 70}
73 71
72static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
73{
74 return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
75}
76
74/* ----------------------------------------------------------------------- */ 77/* ----------------------------------------------------------------------- */
75/* I2C support functions */ 78/* I2C support functions */
76/* ----------------------------------------------------------------------- */ 79/* ----------------------------------------------------------------------- */
@@ -326,73 +329,22 @@ static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
326 return 0; 329 return 0;
327} 330}
328 331
329static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 332static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
330{
331 switch (qc->id) {
332 case V4L2_CID_BRIGHTNESS:
333 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
334 case V4L2_CID_CONTRAST:
335 case V4L2_CID_SATURATION:
336 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
337 case V4L2_CID_HUE:
338 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
339 default:
340 return -EINVAL;
341 }
342 return 0;
343}
344
345static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
346{
347 struct saa7110 *decoder = to_saa7110(sd);
348
349 switch (ctrl->id) {
350 case V4L2_CID_BRIGHTNESS:
351 ctrl->value = decoder->bright;
352 break;
353 case V4L2_CID_CONTRAST:
354 ctrl->value = decoder->contrast;
355 break;
356 case V4L2_CID_SATURATION:
357 ctrl->value = decoder->sat;
358 break;
359 case V4L2_CID_HUE:
360 ctrl->value = decoder->hue;
361 break;
362 default:
363 return -EINVAL;
364 }
365 return 0;
366}
367
368static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
369{ 333{
370 struct saa7110 *decoder = to_saa7110(sd); 334 struct v4l2_subdev *sd = to_sd(ctrl);
371 335
372 switch (ctrl->id) { 336 switch (ctrl->id) {
373 case V4L2_CID_BRIGHTNESS: 337 case V4L2_CID_BRIGHTNESS:
374 if (decoder->bright != ctrl->value) { 338 saa7110_write(sd, 0x19, ctrl->val);
375 decoder->bright = ctrl->value;
376 saa7110_write(sd, 0x19, decoder->bright);
377 }
378 break; 339 break;
379 case V4L2_CID_CONTRAST: 340 case V4L2_CID_CONTRAST:
380 if (decoder->contrast != ctrl->value) { 341 saa7110_write(sd, 0x13, ctrl->val);
381 decoder->contrast = ctrl->value;
382 saa7110_write(sd, 0x13, decoder->contrast);
383 }
384 break; 342 break;
385 case V4L2_CID_SATURATION: 343 case V4L2_CID_SATURATION:
386 if (decoder->sat != ctrl->value) { 344 saa7110_write(sd, 0x12, ctrl->val);
387 decoder->sat = ctrl->value;
388 saa7110_write(sd, 0x12, decoder->sat);
389 }
390 break; 345 break;
391 case V4L2_CID_HUE: 346 case V4L2_CID_HUE:
392 if (decoder->hue != ctrl->value) { 347 saa7110_write(sd, 0x07, ctrl->val);
393 decoder->hue = ctrl->value;
394 saa7110_write(sd, 0x07, decoder->hue);
395 }
396 break; 348 break;
397 default: 349 default:
398 return -EINVAL; 350 return -EINVAL;
@@ -409,11 +361,19 @@ static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
409 361
410/* ----------------------------------------------------------------------- */ 362/* ----------------------------------------------------------------------- */
411 363
364static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
365 .s_ctrl = saa7110_s_ctrl,
366};
367
412static const struct v4l2_subdev_core_ops saa7110_core_ops = { 368static const struct v4l2_subdev_core_ops saa7110_core_ops = {
413 .g_chip_ident = saa7110_g_chip_ident, 369 .g_chip_ident = saa7110_g_chip_ident,
414 .g_ctrl = saa7110_g_ctrl, 370 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
415 .s_ctrl = saa7110_s_ctrl, 371 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
416 .queryctrl = saa7110_queryctrl, 372 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
373 .g_ctrl = v4l2_subdev_g_ctrl,
374 .s_ctrl = v4l2_subdev_s_ctrl,
375 .queryctrl = v4l2_subdev_queryctrl,
376 .querymenu = v4l2_subdev_querymenu,
417 .s_std = saa7110_s_std, 377 .s_std = saa7110_s_std,
418}; 378};
419 379
@@ -454,10 +414,25 @@ static int saa7110_probe(struct i2c_client *client,
454 decoder->norm = V4L2_STD_PAL; 414 decoder->norm = V4L2_STD_PAL;
455 decoder->input = 0; 415 decoder->input = 0;
456 decoder->enable = 1; 416 decoder->enable = 1;
457 decoder->bright = 32768; 417 v4l2_ctrl_handler_init(&decoder->hdl, 2);
458 decoder->contrast = 32768; 418 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
459 decoder->hue = 32768; 419 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
460 decoder->sat = 32768; 420 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
421 V4L2_CID_CONTRAST, 0, 127, 1, 64);
422 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
423 V4L2_CID_SATURATION, 0, 127, 1, 64);
424 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
425 V4L2_CID_HUE, -128, 127, 1, 0);
426 sd->ctrl_handler = &decoder->hdl;
427 if (decoder->hdl.error) {
428 int err = decoder->hdl.error;
429
430 v4l2_ctrl_handler_free(&decoder->hdl);
431 kfree(decoder);
432 return err;
433 }
434 v4l2_ctrl_handler_setup(&decoder->hdl);
435
461 init_waitqueue_head(&decoder->wq); 436 init_waitqueue_head(&decoder->wq);
462 437
463 rv = saa7110_write_block(sd, initseq, sizeof(initseq)); 438 rv = saa7110_write_block(sd, initseq, sizeof(initseq));
@@ -490,9 +465,11 @@ static int saa7110_probe(struct i2c_client *client,
490static int saa7110_remove(struct i2c_client *client) 465static int saa7110_remove(struct i2c_client *client)
491{ 466{
492 struct v4l2_subdev *sd = i2c_get_clientdata(client); 467 struct v4l2_subdev *sd = i2c_get_clientdata(client);
468 struct saa7110 *decoder = to_saa7110(sd);
493 469
494 v4l2_device_unregister_subdev(sd); 470 v4l2_device_unregister_subdev(sd);
495 kfree(to_saa7110(sd)); 471 v4l2_ctrl_handler_free(&decoder->hdl);
472 kfree(decoder);
496 return 0; 473 return 0;
497} 474}
498 475