diff options
Diffstat (limited to 'drivers/media/video/saa7110.c')
-rw-r--r-- | drivers/media/video/saa7110.c | 115 |
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 | ||
40 | MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); | 41 | MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); |
41 | MODULE_AUTHOR("Pauline Middelink"); | 42 | MODULE_AUTHOR("Pauline Middelink"); |
@@ -53,15 +54,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
53 | 54 | ||
54 | struct saa7110 { | 55 | struct 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 | ||
72 | static 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 | ||
329 | static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | 332 | static 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 | |||
345 | static 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 | |||
368 | static 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 | ||
364 | static const struct v4l2_ctrl_ops saa7110_ctrl_ops = { | ||
365 | .s_ctrl = saa7110_s_ctrl, | ||
366 | }; | ||
367 | |||
412 | static const struct v4l2_subdev_core_ops saa7110_core_ops = { | 368 | static 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, | |||
490 | static int saa7110_remove(struct i2c_client *client) | 465 | static 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 | ||