aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2015-01-23 10:52:26 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-02-02 08:45:35 -0500
commitd5d51a827bb86103d4874a864f72674b281408ac (patch)
tree083cec6e49e4a52e1309651923bc45cd44ebeeff /drivers/media/i2c
parentc18818e99067ea084e07cbb9a590389180252b7e (diff)
[media] adv7180: Add media controller support
Add media controller support to the adv7180 driver by registering a media entity instance for it as well as implementing pad ops for configuring the format. As there currently don't seem to be any users of the video ops format operations those are removed as well in this patch. Also set the V4L2_SUBDEV_FL_HAS_DEVNODE flag for the subdevice so it is possible to create a subdevice device node. Since the driver now depends on VIDEO_V4L2_SUBDEV_API all drivers which select the driver need to depend on that symbol as well. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Federico Vaga <federico.vaga@gmail.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/Kconfig2
-rw-r--r--drivers/media/i2c/adv7180.c50
2 files changed, 41 insertions, 11 deletions
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 0828b6b28fa4..da58c9bb67c2 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -177,7 +177,7 @@ comment "Video decoders"
177 177
178config VIDEO_ADV7180 178config VIDEO_ADV7180
179 tristate "Analog Devices ADV7180 decoder" 179 tristate "Analog Devices ADV7180 decoder"
180 depends on VIDEO_V4L2 && I2C 180 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
181 ---help--- 181 ---help---
182 Support for the Analog Devices ADV7180 video decoder. 182 Support for the Analog Devices ADV7180 video decoder.
183 183
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 44a2832d8d11..5193596b68ff 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -124,6 +124,7 @@
124struct adv7180_state { 124struct adv7180_state {
125 struct v4l2_ctrl_handler ctrl_hdl; 125 struct v4l2_ctrl_handler ctrl_hdl;
126 struct v4l2_subdev sd; 126 struct v4l2_subdev sd;
127 struct media_pad pad;
127 struct mutex mutex; /* mutual excl. when accessing chip */ 128 struct mutex mutex; /* mutual excl. when accessing chip */
128 int irq; 129 int irq;
129 v4l2_std_id curr_norm; 130 v4l2_std_id curr_norm;
@@ -441,13 +442,14 @@ static void adv7180_exit_controls(struct adv7180_state *state)
441 v4l2_ctrl_handler_free(&state->ctrl_hdl); 442 v4l2_ctrl_handler_free(&state->ctrl_hdl);
442} 443}
443 444
444static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, 445static int adv7180_enum_mbus_code(struct v4l2_subdev *sd,
445 u32 *code) 446 struct v4l2_subdev_fh *fh,
447 struct v4l2_subdev_mbus_code_enum *code)
446{ 448{
447 if (index > 0) 449 if (code->index != 0)
448 return -EINVAL; 450 return -EINVAL;
449 451
450 *code = MEDIA_BUS_FMT_YUYV8_2X8; 452 code->code = MEDIA_BUS_FMT_YUYV8_2X8;
451 453
452 return 0; 454 return 0;
453} 455}
@@ -466,6 +468,20 @@ static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
466 return 0; 468 return 0;
467} 469}
468 470
471static int adv7180_get_pad_format(struct v4l2_subdev *sd,
472 struct v4l2_subdev_fh *fh,
473 struct v4l2_subdev_format *format)
474{
475 return adv7180_mbus_fmt(sd, &format->format);
476}
477
478static int adv7180_set_pad_format(struct v4l2_subdev *sd,
479 struct v4l2_subdev_fh *fh,
480 struct v4l2_subdev_format *format)
481{
482 return adv7180_mbus_fmt(sd, &format->format);
483}
484
469static int adv7180_g_mbus_config(struct v4l2_subdev *sd, 485static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
470 struct v4l2_mbus_config *cfg) 486 struct v4l2_mbus_config *cfg)
471{ 487{
@@ -485,10 +501,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
485 .querystd = adv7180_querystd, 501 .querystd = adv7180_querystd,
486 .g_input_status = adv7180_g_input_status, 502 .g_input_status = adv7180_g_input_status,
487 .s_routing = adv7180_s_routing, 503 .s_routing = adv7180_s_routing,
488 .enum_mbus_fmt = adv7180_enum_mbus_fmt,
489 .try_mbus_fmt = adv7180_mbus_fmt,
490 .g_mbus_fmt = adv7180_mbus_fmt,
491 .s_mbus_fmt = adv7180_mbus_fmt,
492 .g_mbus_config = adv7180_g_mbus_config, 504 .g_mbus_config = adv7180_g_mbus_config,
493}; 505};
494 506
@@ -496,9 +508,16 @@ static const struct v4l2_subdev_core_ops adv7180_core_ops = {
496 .s_power = adv7180_s_power, 508 .s_power = adv7180_s_power,
497}; 509};
498 510
511static const struct v4l2_subdev_pad_ops adv7180_pad_ops = {
512 .enum_mbus_code = adv7180_enum_mbus_code,
513 .set_fmt = adv7180_set_pad_format,
514 .get_fmt = adv7180_get_pad_format,
515};
516
499static const struct v4l2_subdev_ops adv7180_ops = { 517static const struct v4l2_subdev_ops adv7180_ops = {
500 .core = &adv7180_core_ops, 518 .core = &adv7180_core_ops,
501 .video = &adv7180_video_ops, 519 .video = &adv7180_video_ops,
520 .pad = &adv7180_pad_ops,
502}; 521};
503 522
504static irqreturn_t adv7180_irq(int irq, void *devid) 523static irqreturn_t adv7180_irq(int irq, void *devid)
@@ -627,20 +646,28 @@ static int adv7180_probe(struct i2c_client *client,
627 state->input = 0; 646 state->input = 0;
628 sd = &state->sd; 647 sd = &state->sd;
629 v4l2_i2c_subdev_init(sd, client, &adv7180_ops); 648 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
649 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
630 650
631 ret = adv7180_init_controls(state); 651 ret = adv7180_init_controls(state);
632 if (ret) 652 if (ret)
633 goto err_unreg_subdev; 653 goto err_unreg_subdev;
634 ret = init_device(state); 654
655 state->pad.flags = MEDIA_PAD_FL_SOURCE;
656 sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
657 ret = media_entity_init(&sd->entity, 1, &state->pad, 0);
635 if (ret) 658 if (ret)
636 goto err_free_ctrl; 659 goto err_free_ctrl;
637 660
661 ret = init_device(state);
662 if (ret)
663 goto err_media_entity_cleanup;
664
638 if (state->irq) { 665 if (state->irq) {
639 ret = request_threaded_irq(client->irq, NULL, adv7180_irq, 666 ret = request_threaded_irq(client->irq, NULL, adv7180_irq,
640 IRQF_ONESHOT | IRQF_TRIGGER_FALLING, 667 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
641 KBUILD_MODNAME, state); 668 KBUILD_MODNAME, state);
642 if (ret) 669 if (ret)
643 goto err_free_ctrl; 670 goto err_media_entity_cleanup;
644 } 671 }
645 672
646 ret = v4l2_async_register_subdev(sd); 673 ret = v4l2_async_register_subdev(sd);
@@ -652,6 +679,8 @@ static int adv7180_probe(struct i2c_client *client,
652err_free_irq: 679err_free_irq:
653 if (state->irq > 0) 680 if (state->irq > 0)
654 free_irq(client->irq, state); 681 free_irq(client->irq, state);
682err_media_entity_cleanup:
683 media_entity_cleanup(&sd->entity);
655err_free_ctrl: 684err_free_ctrl:
656 adv7180_exit_controls(state); 685 adv7180_exit_controls(state);
657err_unreg_subdev: 686err_unreg_subdev:
@@ -669,6 +698,7 @@ static int adv7180_remove(struct i2c_client *client)
669 if (state->irq > 0) 698 if (state->irq > 0)
670 free_irq(client->irq, state); 699 free_irq(client->irq, state);
671 700
701 media_entity_cleanup(&sd->entity);
672 adv7180_exit_controls(state); 702 adv7180_exit_controls(state);
673 mutex_destroy(&state->mutex); 703 mutex_destroy(&state->mutex);
674 return 0; 704 return 0;