diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 10:44:15 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-18 23:18:39 -0400 |
commit | 2840d2497b912f25d2957477faa1c922ddd733e0 (patch) | |
tree | 0cb0fe8ced5e55236c448ab001c4c50faeaa3411 /drivers/media | |
parent | a813d01f823259d1b27668c2149785515843a7eb (diff) |
V4L/DVB (12513): soc-camera: add support for camera-host controls
Until now soc-camera only supported client (sensor) controls. This patch
enables camera-host drivers to implement their own controls too.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/soc_camera.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 0a1cb40bfbf6..b3fb8f290ad5 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -633,6 +633,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv, | |||
633 | { | 633 | { |
634 | struct soc_camera_file *icf = file->private_data; | 634 | struct soc_camera_file *icf = file->private_data; |
635 | struct soc_camera_device *icd = icf->icd; | 635 | struct soc_camera_device *icd = icf->icd; |
636 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
636 | int i; | 637 | int i; |
637 | 638 | ||
638 | WARN_ON(priv != file->private_data); | 639 | WARN_ON(priv != file->private_data); |
@@ -640,6 +641,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv, | |||
640 | if (!qc->id) | 641 | if (!qc->id) |
641 | return -EINVAL; | 642 | return -EINVAL; |
642 | 643 | ||
644 | /* First check host controls */ | ||
645 | for (i = 0; i < ici->ops->num_controls; i++) | ||
646 | if (qc->id == ici->ops->controls[i].id) { | ||
647 | memcpy(qc, &(ici->ops->controls[i]), | ||
648 | sizeof(*qc)); | ||
649 | return 0; | ||
650 | } | ||
651 | |||
652 | /* Then device controls */ | ||
643 | for (i = 0; i < icd->ops->num_controls; i++) | 653 | for (i = 0; i < icd->ops->num_controls; i++) |
644 | if (qc->id == icd->ops->controls[i].id) { | 654 | if (qc->id == icd->ops->controls[i].id) { |
645 | memcpy(qc, &(icd->ops->controls[i]), | 655 | memcpy(qc, &(icd->ops->controls[i]), |
@@ -656,6 +666,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv, | |||
656 | struct soc_camera_file *icf = file->private_data; | 666 | struct soc_camera_file *icf = file->private_data; |
657 | struct soc_camera_device *icd = icf->icd; | 667 | struct soc_camera_device *icd = icf->icd; |
658 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 668 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
669 | int ret; | ||
659 | 670 | ||
660 | WARN_ON(priv != file->private_data); | 671 | WARN_ON(priv != file->private_data); |
661 | 672 | ||
@@ -672,6 +683,12 @@ static int soc_camera_g_ctrl(struct file *file, void *priv, | |||
672 | return 0; | 683 | return 0; |
673 | } | 684 | } |
674 | 685 | ||
686 | if (ici->ops->get_ctrl) { | ||
687 | ret = ici->ops->get_ctrl(icd, ctrl); | ||
688 | if (ret != -ENOIOCTLCMD) | ||
689 | return ret; | ||
690 | } | ||
691 | |||
675 | return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl); | 692 | return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl); |
676 | } | 693 | } |
677 | 694 | ||
@@ -681,9 +698,16 @@ static int soc_camera_s_ctrl(struct file *file, void *priv, | |||
681 | struct soc_camera_file *icf = file->private_data; | 698 | struct soc_camera_file *icf = file->private_data; |
682 | struct soc_camera_device *icd = icf->icd; | 699 | struct soc_camera_device *icd = icf->icd; |
683 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 700 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
701 | int ret; | ||
684 | 702 | ||
685 | WARN_ON(priv != file->private_data); | 703 | WARN_ON(priv != file->private_data); |
686 | 704 | ||
705 | if (ici->ops->set_ctrl) { | ||
706 | ret = ici->ops->set_ctrl(icd, ctrl); | ||
707 | if (ret != -ENOIOCTLCMD) | ||
708 | return ret; | ||
709 | } | ||
710 | |||
687 | return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl); | 711 | return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl); |
688 | } | 712 | } |
689 | 713 | ||