diff options
-rw-r--r-- | drivers/media/video/tvp7002.c | 117 |
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 | ||
37 | MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver"); | 38 | MODULE_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 */ |
422 | struct tvp7002 { | 423 | struct 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 | ||
445 | static 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 | */ | ||
616 | static 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 | */ |
637 | static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 621 | static 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 | */ | ||
670 | static 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 | ||
902 | static 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 */ |
950 | static const struct v4l2_subdev_core_ops tvp7002_core_ops = { | 907 | static 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 | ||
980 | static 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 | |||
1063 | found_error: | 1031 | found_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 | } |