diff options
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-gpio.c | 77 |
3 files changed, 38 insertions, 41 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index f72e9d1cee0..53ea31aab15 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -1386,6 +1386,7 @@ static void ivtv_remove(struct pci_dev *pdev) | |||
1386 | printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name); | 1386 | printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name); |
1387 | 1387 | ||
1388 | v4l2_device_unregister(&itv->v4l2_dev); | 1388 | v4l2_device_unregister(&itv->v4l2_dev); |
1389 | v4l2_ctrl_handler_free(&itv->hdl_gpio); | ||
1389 | kfree(itv); | 1390 | kfree(itv); |
1390 | } | 1391 | } |
1391 | 1392 | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 10207124621..d2260de4c81 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -632,6 +632,7 @@ struct ivtv { | |||
632 | 632 | ||
633 | struct v4l2_device v4l2_dev; | 633 | struct v4l2_device v4l2_dev; |
634 | struct v4l2_subdev sd_gpio; /* GPIO sub-device */ | 634 | struct v4l2_subdev sd_gpio; /* GPIO sub-device */ |
635 | struct v4l2_ctrl_handler hdl_gpio; | ||
635 | u16 instance; | 636 | u16 instance; |
636 | 637 | ||
637 | /* High-level state info */ | 638 | /* High-level state info */ |
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index aede061cae5..8f0d0778905 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.c +++ b/drivers/media/video/ivtv/ivtv-gpio.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "ivtv-gpio.h" | 24 | #include "ivtv-gpio.h" |
25 | #include "tuner-xc2028.h" | 25 | #include "tuner-xc2028.h" |
26 | #include <media/tuner.h> | 26 | #include <media/tuner.h> |
27 | #include <media/v4l2-ctrls.h> | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * GPIO assignment of Yuan MPG600/MPG160 | 30 | * GPIO assignment of Yuan MPG600/MPG160 |
@@ -149,16 +150,10 @@ static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd) | |||
149 | return container_of(sd, struct ivtv, sd_gpio); | 150 | return container_of(sd, struct ivtv, sd_gpio); |
150 | } | 151 | } |
151 | 152 | ||
152 | static struct v4l2_queryctrl gpio_ctrl_mute = { | 153 | static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) |
153 | .id = V4L2_CID_AUDIO_MUTE, | 154 | { |
154 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 155 | return &container_of(ctrl->handler, struct ivtv, hdl_gpio)->sd_gpio; |
155 | .name = "Mute", | 156 | } |
156 | .minimum = 0, | ||
157 | .maximum = 1, | ||
158 | .step = 1, | ||
159 | .default_value = 1, | ||
160 | .flags = 0, | ||
161 | }; | ||
162 | 157 | ||
163 | static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq) | 158 | static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq) |
164 | { | 159 | { |
@@ -262,40 +257,24 @@ static int subdev_s_audio_routing(struct v4l2_subdev *sd, | |||
262 | return 0; | 257 | return 0; |
263 | } | 258 | } |
264 | 259 | ||
265 | static int subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 260 | static int subdev_s_ctrl(struct v4l2_ctrl *ctrl) |
266 | { | 261 | { |
262 | struct v4l2_subdev *sd = to_sd(ctrl); | ||
267 | struct ivtv *itv = sd_to_ivtv(sd); | 263 | struct ivtv *itv = sd_to_ivtv(sd); |
268 | u16 mask, data; | 264 | u16 mask, data; |
269 | 265 | ||
270 | if (ctrl->id != V4L2_CID_AUDIO_MUTE) | 266 | switch (ctrl->id) { |
271 | return -EINVAL; | 267 | case V4L2_CID_AUDIO_MUTE: |
272 | mask = itv->card->gpio_audio_mute.mask; | 268 | mask = itv->card->gpio_audio_mute.mask; |
273 | data = itv->card->gpio_audio_mute.mute; | 269 | data = ctrl->val ? itv->card->gpio_audio_mute.mute : 0; |
274 | ctrl->value = (read_reg(IVTV_REG_GPIO_OUT) & mask) == data; | 270 | if (mask) |
275 | return 0; | 271 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | |
276 | } | 272 | (data & mask), IVTV_REG_GPIO_OUT); |
277 | 273 | return 0; | |
278 | static int subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 274 | } |
279 | { | 275 | return -EINVAL; |
280 | struct ivtv *itv = sd_to_ivtv(sd); | ||
281 | u16 mask, data; | ||
282 | |||
283 | if (ctrl->id != V4L2_CID_AUDIO_MUTE) | ||
284 | return -EINVAL; | ||
285 | mask = itv->card->gpio_audio_mute.mask; | ||
286 | data = ctrl->value ? itv->card->gpio_audio_mute.mute : 0; | ||
287 | if (mask) | ||
288 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); | ||
289 | return 0; | ||
290 | } | 276 | } |
291 | 277 | ||
292 | static int subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
293 | { | ||
294 | if (qc->id != V4L2_CID_AUDIO_MUTE) | ||
295 | return -EINVAL; | ||
296 | *qc = gpio_ctrl_mute; | ||
297 | return 0; | ||
298 | } | ||
299 | 278 | ||
300 | static int subdev_log_status(struct v4l2_subdev *sd) | 279 | static int subdev_log_status(struct v4l2_subdev *sd) |
301 | { | 280 | { |
@@ -304,6 +283,7 @@ static int subdev_log_status(struct v4l2_subdev *sd) | |||
304 | IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n", | 283 | IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n", |
305 | read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT), | 284 | read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT), |
306 | read_reg(IVTV_REG_GPIO_IN)); | 285 | read_reg(IVTV_REG_GPIO_IN)); |
286 | v4l2_ctrl_handler_log_status(&itv->hdl_gpio, sd->name); | ||
307 | return 0; | 287 | return 0; |
308 | } | 288 | } |
309 | 289 | ||
@@ -327,11 +307,19 @@ static int subdev_s_video_routing(struct v4l2_subdev *sd, | |||
327 | return 0; | 307 | return 0; |
328 | } | 308 | } |
329 | 309 | ||
310 | static const struct v4l2_ctrl_ops gpio_ctrl_ops = { | ||
311 | .s_ctrl = subdev_s_ctrl, | ||
312 | }; | ||
313 | |||
330 | static const struct v4l2_subdev_core_ops subdev_core_ops = { | 314 | static const struct v4l2_subdev_core_ops subdev_core_ops = { |
331 | .log_status = subdev_log_status, | 315 | .log_status = subdev_log_status, |
332 | .g_ctrl = subdev_g_ctrl, | 316 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, |
333 | .s_ctrl = subdev_s_ctrl, | 317 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, |
334 | .queryctrl = subdev_queryctrl, | 318 | .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, |
319 | .g_ctrl = v4l2_subdev_g_ctrl, | ||
320 | .s_ctrl = v4l2_subdev_s_ctrl, | ||
321 | .queryctrl = v4l2_subdev_queryctrl, | ||
322 | .querymenu = v4l2_subdev_querymenu, | ||
335 | }; | 323 | }; |
336 | 324 | ||
337 | static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = { | 325 | static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = { |
@@ -375,5 +363,12 @@ int ivtv_gpio_init(struct ivtv *itv) | |||
375 | v4l2_subdev_init(&itv->sd_gpio, &subdev_ops); | 363 | v4l2_subdev_init(&itv->sd_gpio, &subdev_ops); |
376 | snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name); | 364 | snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name); |
377 | itv->sd_gpio.grp_id = IVTV_HW_GPIO; | 365 | itv->sd_gpio.grp_id = IVTV_HW_GPIO; |
366 | v4l2_ctrl_handler_init(&itv->hdl_gpio, 1); | ||
367 | v4l2_ctrl_new_std(&itv->hdl_gpio, &gpio_ctrl_ops, | ||
368 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | ||
369 | if (itv->hdl_gpio.error) | ||
370 | return itv->hdl_gpio.error; | ||
371 | itv->sd_gpio.ctrl_handler = &itv->hdl_gpio; | ||
372 | v4l2_ctrl_handler_setup(&itv->hdl_gpio); | ||
378 | return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio); | 373 | return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio); |
379 | } | 374 | } |