diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2010-12-12 06:45:43 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:50 -0400 |
commit | 6c45ec718e3b641da41654b31f35ae3e13306264 (patch) | |
tree | 501195cb21d5da8b3145ca630b543e3ff717aec2 | |
parent | cf6832afe59f37b154bf0e41bf5e59cfd7f46d24 (diff) |
[media] tvp5150: use the control framework
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/tvp5150.c | 157 |
1 files changed, 46 insertions, 111 deletions
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 58927664d3ea..959d690363bb 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <media/v4l2-device.h> | 12 | #include <media/v4l2-device.h> |
13 | #include <media/tvp5150.h> | 13 | #include <media/tvp5150.h> |
14 | #include <media/v4l2-chip-ident.h> | 14 | #include <media/v4l2-chip-ident.h> |
15 | #include <media/v4l2-ctrls.h> | ||
15 | 16 | ||
16 | #include "tvp5150_reg.h" | 17 | #include "tvp5150_reg.h" |
17 | 18 | ||
@@ -24,58 +25,14 @@ static int debug; | |||
24 | module_param(debug, int, 0); | 25 | module_param(debug, int, 0); |
25 | MODULE_PARM_DESC(debug, "Debug level (0-2)"); | 26 | MODULE_PARM_DESC(debug, "Debug level (0-2)"); |
26 | 27 | ||
27 | /* supported controls */ | ||
28 | static struct v4l2_queryctrl tvp5150_qctrl[] = { | ||
29 | { | ||
30 | .id = V4L2_CID_BRIGHTNESS, | ||
31 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
32 | .name = "Brightness", | ||
33 | .minimum = 0, | ||
34 | .maximum = 255, | ||
35 | .step = 1, | ||
36 | .default_value = 128, | ||
37 | .flags = 0, | ||
38 | }, { | ||
39 | .id = V4L2_CID_CONTRAST, | ||
40 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
41 | .name = "Contrast", | ||
42 | .minimum = 0, | ||
43 | .maximum = 255, | ||
44 | .step = 0x1, | ||
45 | .default_value = 128, | ||
46 | .flags = 0, | ||
47 | }, { | ||
48 | .id = V4L2_CID_SATURATION, | ||
49 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
50 | .name = "Saturation", | ||
51 | .minimum = 0, | ||
52 | .maximum = 255, | ||
53 | .step = 0x1, | ||
54 | .default_value = 128, | ||
55 | .flags = 0, | ||
56 | }, { | ||
57 | .id = V4L2_CID_HUE, | ||
58 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
59 | .name = "Hue", | ||
60 | .minimum = -128, | ||
61 | .maximum = 127, | ||
62 | .step = 0x1, | ||
63 | .default_value = 0, | ||
64 | .flags = 0, | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | struct tvp5150 { | 28 | struct tvp5150 { |
69 | struct v4l2_subdev sd; | 29 | struct v4l2_subdev sd; |
30 | struct v4l2_ctrl_handler hdl; | ||
70 | 31 | ||
71 | v4l2_std_id norm; /* Current set standard */ | 32 | v4l2_std_id norm; /* Current set standard */ |
72 | u32 input; | 33 | u32 input; |
73 | u32 output; | 34 | u32 output; |
74 | int enable; | 35 | int enable; |
75 | int bright; | ||
76 | int contrast; | ||
77 | int hue; | ||
78 | int sat; | ||
79 | }; | 36 | }; |
80 | 37 | ||
81 | static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd) | 38 | static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd) |
@@ -83,6 +40,11 @@ static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd) | |||
83 | return container_of(sd, struct tvp5150, sd); | 40 | return container_of(sd, struct tvp5150, sd); |
84 | } | 41 | } |
85 | 42 | ||
43 | static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) | ||
44 | { | ||
45 | return &container_of(ctrl->handler, struct tvp5150, hdl)->sd; | ||
46 | } | ||
47 | |||
86 | static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) | 48 | static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) |
87 | { | 49 | { |
88 | struct i2c_client *c = v4l2_get_subdevdata(sd); | 50 | struct i2c_client *c = v4l2_get_subdevdata(sd); |
@@ -810,64 +772,28 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) | |||
810 | tvp5150_write_inittab(sd, tvp5150_init_enable); | 772 | tvp5150_write_inittab(sd, tvp5150_init_enable); |
811 | 773 | ||
812 | /* Initialize image preferences */ | 774 | /* Initialize image preferences */ |
813 | tvp5150_write(sd, TVP5150_BRIGHT_CTL, decoder->bright); | 775 | v4l2_ctrl_handler_setup(&decoder->hdl); |
814 | tvp5150_write(sd, TVP5150_CONTRAST_CTL, decoder->contrast); | ||
815 | tvp5150_write(sd, TVP5150_SATURATION_CTL, decoder->contrast); | ||
816 | tvp5150_write(sd, TVP5150_HUE_CTL, decoder->hue); | ||
817 | 776 | ||
818 | tvp5150_set_std(sd, decoder->norm); | 777 | tvp5150_set_std(sd, decoder->norm); |
819 | return 0; | 778 | return 0; |
820 | }; | 779 | }; |
821 | 780 | ||
822 | static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 781 | static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl) |
823 | { | ||
824 | v4l2_dbg(1, debug, sd, "g_ctrl called\n"); | ||
825 | |||
826 | switch (ctrl->id) { | ||
827 | case V4L2_CID_BRIGHTNESS: | ||
828 | ctrl->value = tvp5150_read(sd, TVP5150_BRIGHT_CTL); | ||
829 | return 0; | ||
830 | case V4L2_CID_CONTRAST: | ||
831 | ctrl->value = tvp5150_read(sd, TVP5150_CONTRAST_CTL); | ||
832 | return 0; | ||
833 | case V4L2_CID_SATURATION: | ||
834 | ctrl->value = tvp5150_read(sd, TVP5150_SATURATION_CTL); | ||
835 | return 0; | ||
836 | case V4L2_CID_HUE: | ||
837 | ctrl->value = tvp5150_read(sd, TVP5150_HUE_CTL); | ||
838 | return 0; | ||
839 | } | ||
840 | return -EINVAL; | ||
841 | } | ||
842 | |||
843 | static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
844 | { | 782 | { |
845 | u8 i, n; | 783 | struct v4l2_subdev *sd = to_sd(ctrl); |
846 | n = ARRAY_SIZE(tvp5150_qctrl); | ||
847 | |||
848 | for (i = 0; i < n; i++) { | ||
849 | if (ctrl->id != tvp5150_qctrl[i].id) | ||
850 | continue; | ||
851 | if (ctrl->value < tvp5150_qctrl[i].minimum || | ||
852 | ctrl->value > tvp5150_qctrl[i].maximum) | ||
853 | return -ERANGE; | ||
854 | v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n", | ||
855 | ctrl->id, ctrl->value); | ||
856 | break; | ||
857 | } | ||
858 | 784 | ||
859 | switch (ctrl->id) { | 785 | switch (ctrl->id) { |
860 | case V4L2_CID_BRIGHTNESS: | 786 | case V4L2_CID_BRIGHTNESS: |
861 | tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->value); | 787 | tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val); |
862 | return 0; | 788 | return 0; |
863 | case V4L2_CID_CONTRAST: | 789 | case V4L2_CID_CONTRAST: |
864 | tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->value); | 790 | tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val); |
865 | return 0; | 791 | return 0; |
866 | case V4L2_CID_SATURATION: | 792 | case V4L2_CID_SATURATION: |
867 | tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->value); | 793 | tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val); |
868 | return 0; | 794 | return 0; |
869 | case V4L2_CID_HUE: | 795 | case V4L2_CID_HUE: |
870 | tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->value); | 796 | tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val); |
871 | return 0; | 797 | return 0; |
872 | } | 798 | } |
873 | return -EINVAL; | 799 | return -EINVAL; |
@@ -995,29 +921,21 @@ static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
995 | return 0; | 921 | return 0; |
996 | } | 922 | } |
997 | 923 | ||
998 | static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
999 | { | ||
1000 | int i; | ||
1001 | |||
1002 | v4l2_dbg(1, debug, sd, "queryctrl called\n"); | ||
1003 | |||
1004 | for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) | ||
1005 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { | ||
1006 | memcpy(qc, &(tvp5150_qctrl[i]), | ||
1007 | sizeof(*qc)); | ||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | return -EINVAL; | ||
1012 | } | ||
1013 | |||
1014 | /* ----------------------------------------------------------------------- */ | 924 | /* ----------------------------------------------------------------------- */ |
1015 | 925 | ||
926 | static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = { | ||
927 | .s_ctrl = tvp5150_s_ctrl, | ||
928 | }; | ||
929 | |||
1016 | static const struct v4l2_subdev_core_ops tvp5150_core_ops = { | 930 | static const struct v4l2_subdev_core_ops tvp5150_core_ops = { |
1017 | .log_status = tvp5150_log_status, | 931 | .log_status = tvp5150_log_status, |
1018 | .g_ctrl = tvp5150_g_ctrl, | 932 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, |
1019 | .s_ctrl = tvp5150_s_ctrl, | 933 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, |
1020 | .queryctrl = tvp5150_queryctrl, | 934 | .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, |
935 | .g_ctrl = v4l2_subdev_g_ctrl, | ||
936 | .s_ctrl = v4l2_subdev_s_ctrl, | ||
937 | .queryctrl = v4l2_subdev_queryctrl, | ||
938 | .querymenu = v4l2_subdev_querymenu, | ||
1021 | .s_std = tvp5150_s_std, | 939 | .s_std = tvp5150_s_std, |
1022 | .reset = tvp5150_reset, | 940 | .reset = tvp5150_reset, |
1023 | .g_chip_ident = tvp5150_g_chip_ident, | 941 | .g_chip_ident = tvp5150_g_chip_ident, |
@@ -1077,10 +995,25 @@ static int tvp5150_probe(struct i2c_client *c, | |||
1077 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ | 995 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ |
1078 | core->input = TVP5150_COMPOSITE1; | 996 | core->input = TVP5150_COMPOSITE1; |
1079 | core->enable = 1; | 997 | core->enable = 1; |
1080 | core->bright = 128; | 998 | |
1081 | core->contrast = 128; | 999 | v4l2_ctrl_handler_init(&core->hdl, 4); |
1082 | core->hue = 0; | 1000 | v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops, |
1083 | core->sat = 128; | 1001 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); |
1002 | v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops, | ||
1003 | V4L2_CID_CONTRAST, 0, 255, 1, 128); | ||
1004 | v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops, | ||
1005 | V4L2_CID_SATURATION, 0, 255, 1, 128); | ||
1006 | v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops, | ||
1007 | V4L2_CID_HUE, -128, 127, 1, 0); | ||
1008 | sd->ctrl_handler = &core->hdl; | ||
1009 | if (core->hdl.error) { | ||
1010 | int err = core->hdl.error; | ||
1011 | |||
1012 | v4l2_ctrl_handler_free(&core->hdl); | ||
1013 | kfree(core); | ||
1014 | return err; | ||
1015 | } | ||
1016 | v4l2_ctrl_handler_setup(&core->hdl); | ||
1084 | 1017 | ||
1085 | if (debug > 1) | 1018 | if (debug > 1) |
1086 | tvp5150_log_status(sd); | 1019 | tvp5150_log_status(sd); |
@@ -1090,12 +1023,14 @@ static int tvp5150_probe(struct i2c_client *c, | |||
1090 | static int tvp5150_remove(struct i2c_client *c) | 1023 | static int tvp5150_remove(struct i2c_client *c) |
1091 | { | 1024 | { |
1092 | struct v4l2_subdev *sd = i2c_get_clientdata(c); | 1025 | struct v4l2_subdev *sd = i2c_get_clientdata(c); |
1026 | struct tvp5150 *decoder = to_tvp5150(sd); | ||
1093 | 1027 | ||
1094 | v4l2_dbg(1, debug, sd, | 1028 | v4l2_dbg(1, debug, sd, |
1095 | "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", | 1029 | "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", |
1096 | c->addr << 1); | 1030 | c->addr << 1); |
1097 | 1031 | ||
1098 | v4l2_device_unregister_subdev(sd); | 1032 | v4l2_device_unregister_subdev(sd); |
1033 | v4l2_ctrl_handler_free(&decoder->hdl); | ||
1099 | kfree(to_tvp5150(sd)); | 1034 | kfree(to_tvp5150(sd)); |
1100 | return 0; | 1035 | return 0; |
1101 | } | 1036 | } |