aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/tvp7002.c117
1 files changed, 43 insertions, 74 deletions
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index c799e4eb6fcd..b799851bf3d0 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -32,6 +32,7 @@
32#include <media/v4l2-device.h> 32#include <media/v4l2-device.h>
33#include <media/v4l2-chip-ident.h> 33#include <media/v4l2-chip-ident.h>
34#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
35#include <media/v4l2-ctrls.h>
35#include "tvp7002_reg.h" 36#include "tvp7002_reg.h"
36 37
37MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver"); 38MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
@@ -421,13 +422,13 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
421/* Device definition */ 422/* Device definition */
422struct tvp7002 { 423struct tvp7002 {
423 struct v4l2_subdev sd; 424 struct v4l2_subdev sd;
425 struct v4l2_ctrl_handler hdl;
424 const struct tvp7002_config *pdata; 426 const struct tvp7002_config *pdata;
425 427
426 int ver; 428 int ver;
427 int streaming; 429 int streaming;
428 430
429 const struct tvp7002_preset_definition *current_preset; 431 const struct tvp7002_preset_definition *current_preset;
430 u8 gain;
431}; 432};
432 433
433/* 434/*
@@ -441,6 +442,11 @@ static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
441 return container_of(sd, struct tvp7002, sd); 442 return container_of(sd, struct tvp7002, sd);
442} 443}
443 444
445static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
446{
447 return &container_of(ctrl->handler, struct tvp7002, hdl)->sd;
448}
449
444/* 450/*
445 * tvp7002_read - Read a value from a register in an TVP7002 451 * tvp7002_read - Read a value from a register in an TVP7002
446 * @sd: ptr to v4l2_subdev struct 452 * @sd: ptr to v4l2_subdev struct
@@ -606,78 +612,25 @@ static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
606} 612}
607 613
608/* 614/*
609 * tvp7002_g_ctrl() - Get a control
610 * @sd: ptr to v4l2_subdev struct
611 * @ctrl: ptr to v4l2_control struct
612 *
613 * Get a control for a TVP7002 decoder device.
614 * Returns zero when successful or -EINVAL if register access fails.
615 */
616static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
617{
618 struct tvp7002 *device = to_tvp7002(sd);
619
620 switch (ctrl->id) {
621 case V4L2_CID_GAIN:
622 ctrl->value = device->gain;
623 return 0;
624 default:
625 return -EINVAL;
626 }
627}
628
629/*
630 * tvp7002_s_ctrl() - Set a control 615 * tvp7002_s_ctrl() - Set a control
631 * @sd: ptr to v4l2_subdev struct 616 * @ctrl: ptr to v4l2_ctrl struct
632 * @ctrl: ptr to v4l2_control struct
633 * 617 *
634 * Set a control in TVP7002 decoder device. 618 * Set a control in TVP7002 decoder device.
635 * Returns zero when successful or -EINVAL if register access fails. 619 * Returns zero when successful or -EINVAL if register access fails.
636 */ 620 */
637static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 621static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
638{ 622{
639 struct tvp7002 *device = to_tvp7002(sd); 623 struct v4l2_subdev *sd = to_sd(ctrl);
640 int error = 0; 624 int error = 0;
641 625
642 switch (ctrl->id) { 626 switch (ctrl->id) {
643 case V4L2_CID_GAIN: 627 case V4L2_CID_GAIN:
644 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, 628 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, ctrl->val, &error);
645 ctrl->value & 0xff, &error); 629 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, ctrl->val, &error);
646 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, 630 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN, ctrl->val, &error);
647 ctrl->value & 0xff, &error); 631 return error;
648 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
649 ctrl->value & 0xff, &error);
650
651 if (error < 0)
652 return error;
653
654 /* Set only after knowing there is no error */
655 device->gain = ctrl->value & 0xff;
656 return 0;
657 default:
658 return -EINVAL;
659 }
660}
661
662/*
663 * tvp7002_queryctrl() - Query a control
664 * @sd: ptr to v4l2_subdev struct
665 * @qc: ptr to v4l2_queryctrl struct
666 *
667 * Query a control of a TVP7002 decoder device.
668 * Returns zero when successful or -EINVAL if register read fails.
669 */
670static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
671{
672 switch (qc->id) {
673 case V4L2_CID_GAIN:
674 /*
675 * Gain is supported [0-255, default=0, step=1]
676 */
677 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
678 default:
679 return -EINVAL;
680 } 632 }
633 return -EINVAL;
681} 634}
682 635
683/* 636/*
@@ -924,7 +877,7 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
924 device->streaming ? "yes" : "no"); 877 device->streaming ? "yes" : "no");
925 878
926 /* Print the current value of the gain control */ 879 /* Print the current value of the gain control */
927 v4l2_info(sd, "Gain: %u\n", device->gain); 880 v4l2_ctrl_handler_log_status(&device->hdl, sd->name);
928 881
929 return 0; 882 return 0;
930} 883}
@@ -946,13 +899,21 @@ static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
946 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset); 899 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
947} 900}
948 901
902static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
903 .s_ctrl = tvp7002_s_ctrl,
904};
905
949/* V4L2 core operation handlers */ 906/* V4L2 core operation handlers */
950static const struct v4l2_subdev_core_ops tvp7002_core_ops = { 907static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
951 .g_chip_ident = tvp7002_g_chip_ident, 908 .g_chip_ident = tvp7002_g_chip_ident,
952 .log_status = tvp7002_log_status, 909 .log_status = tvp7002_log_status,
953 .g_ctrl = tvp7002_g_ctrl, 910 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
954 .s_ctrl = tvp7002_s_ctrl, 911 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
955 .queryctrl = tvp7002_queryctrl, 912 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
913 .g_ctrl = v4l2_subdev_g_ctrl,
914 .s_ctrl = v4l2_subdev_s_ctrl,
915 .queryctrl = v4l2_subdev_queryctrl,
916 .querymenu = v4l2_subdev_querymenu,
956#ifdef CONFIG_VIDEO_ADV_DEBUG 917#ifdef CONFIG_VIDEO_ADV_DEBUG
957 .g_register = tvp7002_g_register, 918 .g_register = tvp7002_g_register,
958 .s_register = tvp7002_s_register, 919 .s_register = tvp7002_s_register,
@@ -977,12 +938,6 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
977 .video = &tvp7002_video_ops, 938 .video = &tvp7002_video_ops,
978}; 939};
979 940
980static struct tvp7002 tvp7002_dev = {
981 .streaming = 0,
982 .current_preset = tvp7002_presets,
983 .gain = 0,
984};
985
986/* 941/*
987 * tvp7002_probe - Probe a TVP7002 device 942 * tvp7002_probe - Probe a TVP7002 device
988 * @c: ptr to i2c_client struct 943 * @c: ptr to i2c_client struct
@@ -1013,14 +968,14 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1013 return -ENODEV; 968 return -ENODEV;
1014 } 969 }
1015 970
1016 device = kmalloc(sizeof(struct tvp7002), GFP_KERNEL); 971 device = kzalloc(sizeof(struct tvp7002), GFP_KERNEL);
1017 972
1018 if (!device) 973 if (!device)
1019 return -ENOMEM; 974 return -ENOMEM;
1020 975
1021 *device = tvp7002_dev;
1022 sd = &device->sd; 976 sd = &device->sd;
1023 device->pdata = c->dev.platform_data; 977 device->pdata = c->dev.platform_data;
978 device->current_preset = tvp7002_presets;
1024 979
1025 /* Tell v4l2 the device is ready */ 980 /* Tell v4l2 the device is ready */
1026 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops); 981 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
@@ -1060,6 +1015,19 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1060 preset.preset = device->current_preset->preset; 1015 preset.preset = device->current_preset->preset;
1061 error = tvp7002_s_dv_preset(sd, &preset); 1016 error = tvp7002_s_dv_preset(sd, &preset);
1062 1017
1018 v4l2_ctrl_handler_init(&device->hdl, 1);
1019 v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
1020 V4L2_CID_GAIN, 0, 255, 1, 0);
1021 sd->ctrl_handler = &device->hdl;
1022 if (device->hdl.error) {
1023 int err = device->hdl.error;
1024
1025 v4l2_ctrl_handler_free(&device->hdl);
1026 kfree(device);
1027 return err;
1028 }
1029 v4l2_ctrl_handler_setup(&device->hdl);
1030
1063found_error: 1031found_error:
1064 if (error < 0) 1032 if (error < 0)
1065 kfree(device); 1033 kfree(device);
@@ -1083,6 +1051,7 @@ static int tvp7002_remove(struct i2c_client *c)
1083 "on address 0x%x\n", c->addr); 1051 "on address 0x%x\n", c->addr);
1084 1052
1085 v4l2_device_unregister_subdev(sd); 1053 v4l2_device_unregister_subdev(sd);
1054 v4l2_ctrl_handler_free(&device->hdl);
1086 kfree(device); 1055 kfree(device);
1087 return 0; 1056 return 0;
1088} 1057}