aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/adv7180.c
diff options
context:
space:
mode:
authorRichard Röjfors <richard.rojfors@mocean-labs.com>2009-09-22 05:06:34 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:42 -0500
commitc277b60a08fe9e201656528b3f5cd35b554e24af (patch)
tree1ab89da0a82d8cfd21a50ad510f747708e47b6a2 /drivers/media/video/adv7180.c
parentd31242943a73aba0e5cfd0ea674b5e694b4a39e6 (diff)
V4L/DVB (13174): adv7180: Support for setting input status
Support for settings the input standard of the ADV7180. When the input standard is set there is no use to ask the chip for standard, therefore it is cached in the driver. Signed-off-by: Richard Röjfors <richard.rojfors@mocean-labs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/adv7180.c')
-rw-r--r--drivers/media/video/adv7180.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index f3fce398020a..8b199a86a3a9 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -69,7 +69,9 @@
69 69
70 70
71struct adv7180_state { 71struct adv7180_state {
72 struct v4l2_subdev sd; 72 struct v4l2_subdev sd;
73 v4l2_std_id curr_norm;
74 bool autodetect;
73}; 75};
74 76
75static v4l2_std_id adv7180_std_to_v4l2(u8 status1) 77static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
@@ -96,6 +98,29 @@ static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
96 } 98 }
97} 99}
98 100
101static int v4l2_std_to_adv7180(v4l2_std_id std)
102{
103 if (std == V4L2_STD_PAL_60)
104 return ADV7180_INPUT_CONTROL_PAL60;
105 if (std == V4L2_STD_NTSC_443)
106 return ADV7180_INPUT_CONTROL_NTSC_443;
107 if (std == V4L2_STD_PAL_N)
108 return ADV7180_INPUT_CONTROL_PAL_N;
109 if (std == V4L2_STD_PAL_M)
110 return ADV7180_INPUT_CONTROL_PAL_M;
111 if (std == V4L2_STD_PAL_Nc)
112 return ADV7180_INPUT_CONTROL_PAL_COMB_N;
113
114 if (std & V4L2_STD_PAL)
115 return ADV7180_INPUT_CONTROL_PAL_BG;
116 if (std & V4L2_STD_NTSC)
117 return ADV7180_INPUT_CONTROL_NTSC_M;
118 if (std & V4L2_STD_SECAM)
119 return ADV7180_INPUT_CONTROL_PAL_SECAM;
120
121 return -EINVAL;
122}
123
99static u32 adv7180_status_to_v4l2(u8 status1) 124static u32 adv7180_status_to_v4l2(u8 status1)
100{ 125{
101 if (!(status1 & ADV7180_STATUS1_IN_LOCK)) 126 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
@@ -127,7 +152,15 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
127 152
128static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 153static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
129{ 154{
130 return __adv7180_status(v4l2_get_subdevdata(sd), NULL, std); 155 struct adv7180_state *state = to_state(sd);
156 int err = 0;
157
158 if (!state->autodetect)
159 *std = state->curr_norm;
160 else
161 err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
162
163 return err;
131} 164}
132 165
133static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status) 166static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
@@ -143,6 +176,39 @@ static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
143 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0); 176 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
144} 177}
145 178
179static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
180{
181 struct adv7180_state *state = to_state(sd);
182 struct i2c_client *client = v4l2_get_subdevdata(sd);
183 int ret;
184
185 /* all standards -> autodetect */
186 if (std == V4L2_STD_ALL) {
187 ret = i2c_smbus_write_byte_data(client,
188 ADV7180_INPUT_CONTROL_REG,
189 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
190 if (ret < 0)
191 goto out;
192
193 state->autodetect = true;
194 } else {
195 ret = v4l2_std_to_adv7180(std);
196 if (ret < 0)
197 goto out;
198
199 ret = i2c_smbus_write_byte_data(client,
200 ADV7180_INPUT_CONTROL_REG, ret);
201 if (ret < 0)
202 goto out;
203
204 state->curr_norm = std;
205 state->autodetect = false;
206 }
207 ret = 0;
208out:
209 return ret;
210}
211
146static const struct v4l2_subdev_video_ops adv7180_video_ops = { 212static const struct v4l2_subdev_video_ops adv7180_video_ops = {
147 .querystd = adv7180_querystd, 213 .querystd = adv7180_querystd,
148 .g_input_status = adv7180_g_input_status, 214 .g_input_status = adv7180_g_input_status,
@@ -150,6 +216,7 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
150 216
151static const struct v4l2_subdev_core_ops adv7180_core_ops = { 217static const struct v4l2_subdev_core_ops adv7180_core_ops = {
152 .g_chip_ident = adv7180_g_chip_ident, 218 .g_chip_ident = adv7180_g_chip_ident,
219 .s_std = adv7180_s_std,
153}; 220};
154 221
155static const struct v4l2_subdev_ops adv7180_ops = { 222static const struct v4l2_subdev_ops adv7180_ops = {
@@ -179,6 +246,7 @@ static int adv7180_probe(struct i2c_client *client,
179 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL); 246 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
180 if (state == NULL) 247 if (state == NULL)
181 return -ENOMEM; 248 return -ENOMEM;
249 state->autodetect = true;
182 sd = &state->sd; 250 sd = &state->sd;
183 v4l2_i2c_subdev_init(sd, client, &adv7180_ops); 251 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
184 252