aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2011-09-06 11:36:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-03 16:28:34 -0400
commitee02da64558f04fb30c2462fdeabdfafc87a9799 (patch)
treed031730f52e2ea35e14398d75dc9beb1666dcdb1
parent1d3564d91f94d0b598304eb6ebe3b83a83176f7a (diff)
[media] soc_camera: add control handler support
The soc_camera framework is switched over to use the control framework. After this patch none of the controls in subdevs or host drivers are available, until those drivers are also converted to the control framework. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> [g.liakhovetski@gmx.de: moved code around, fixed problems] Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/soc_camera.c94
-rw-r--r--include/media/soc_camera.h2
2 files changed, 21 insertions, 75 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index ac23916552d..b56f4b78273 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -512,6 +512,7 @@ static int soc_camera_open(struct file *file)
512 if (ret < 0) 512 if (ret < 0)
513 goto einitvb; 513 goto einitvb;
514 } 514 }
515 v4l2_ctrl_handler_setup(&icd->ctrl_handler);
515 } 516 }
516 517
517 file->private_data = icd; 518 file->private_data = icd;
@@ -781,78 +782,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
781 return 0; 782 return 0;
782} 783}
783 784
784static int soc_camera_queryctrl(struct file *file, void *priv,
785 struct v4l2_queryctrl *qc)
786{
787 struct soc_camera_device *icd = file->private_data;
788 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
789 int i;
790
791 WARN_ON(priv != file->private_data);
792
793 if (!qc->id)
794 return -EINVAL;
795
796 /* First check host controls */
797 for (i = 0; i < ici->ops->num_controls; i++)
798 if (qc->id == ici->ops->controls[i].id) {
799 memcpy(qc, &(ici->ops->controls[i]),
800 sizeof(*qc));
801 return 0;
802 }
803
804 if (!icd->ops)
805 return -EINVAL;
806
807 /* Then device controls */
808 for (i = 0; i < icd->ops->num_controls; i++)
809 if (qc->id == icd->ops->controls[i].id) {
810 memcpy(qc, &(icd->ops->controls[i]),
811 sizeof(*qc));
812 return 0;
813 }
814
815 return -EINVAL;
816}
817
818static int soc_camera_g_ctrl(struct file *file, void *priv,
819 struct v4l2_control *ctrl)
820{
821 struct soc_camera_device *icd = file->private_data;
822 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
823 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
824 int ret;
825
826 WARN_ON(priv != file->private_data);
827
828 if (ici->ops->get_ctrl) {
829 ret = ici->ops->get_ctrl(icd, ctrl);
830 if (ret != -ENOIOCTLCMD)
831 return ret;
832 }
833
834 return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
835}
836
837static int soc_camera_s_ctrl(struct file *file, void *priv,
838 struct v4l2_control *ctrl)
839{
840 struct soc_camera_device *icd = file->private_data;
841 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
842 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
843 int ret;
844
845 WARN_ON(priv != file->private_data);
846
847 if (ici->ops->set_ctrl) {
848 ret = ici->ops->set_ctrl(icd, ctrl);
849 if (ret != -ENOIOCTLCMD)
850 return ret;
851 }
852
853 return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
854}
855
856static int soc_camera_cropcap(struct file *file, void *fh, 785static int soc_camera_cropcap(struct file *file, void *fh,
857 struct v4l2_cropcap *a) 786 struct v4l2_cropcap *a)
858{ 787{
@@ -1055,6 +984,17 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1055 984
1056 dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev)); 985 dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
1057 986
987 /*
988 * Currently the subdev with the largest number of controls (13) is
989 * ov6550. So let's pick 16 as a hint for the control handler. Note
990 * that this is a hint only: too large and you waste some memory, too
991 * small and there is a (very) small performance hit when looking up
992 * controls in the internal hash.
993 */
994 ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
995 if (ret < 0)
996 return ret;
997
1058 ret = regulator_bulk_get(icd->pdev, icl->num_regulators, 998 ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
1059 icl->regulators); 999 icl->regulators);
1060 if (ret < 0) 1000 if (ret < 0)
@@ -1108,6 +1048,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1108 sd = soc_camera_to_subdev(icd); 1048 sd = soc_camera_to_subdev(icd);
1109 sd->grp_id = (long)icd; 1049 sd->grp_id = (long)icd;
1110 1050
1051 if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
1052 goto ectrl;
1053
1111 /* At this point client .probe() should have run already */ 1054 /* At this point client .probe() should have run already */
1112 ret = soc_camera_init_user_formats(icd); 1055 ret = soc_camera_init_user_formats(icd);
1113 if (ret < 0) 1056 if (ret < 0)
@@ -1146,6 +1089,7 @@ evidstart:
1146 mutex_unlock(&icd->video_lock); 1089 mutex_unlock(&icd->video_lock);
1147 soc_camera_free_user_formats(icd); 1090 soc_camera_free_user_formats(icd);
1148eiufmt: 1091eiufmt:
1092ectrl:
1149 if (icl->board_info) { 1093 if (icl->board_info) {
1150 soc_camera_free_i2c(icd); 1094 soc_camera_free_i2c(icd);
1151 } else { 1095 } else {
@@ -1162,6 +1106,7 @@ eadd:
1162epower: 1106epower:
1163 regulator_bulk_free(icl->num_regulators, icl->regulators); 1107 regulator_bulk_free(icl->num_regulators, icl->regulators);
1164ereg: 1108ereg:
1109 v4l2_ctrl_handler_free(&icd->ctrl_handler);
1165 return ret; 1110 return ret;
1166} 1111}
1167 1112
@@ -1176,6 +1121,7 @@ static int soc_camera_remove(struct soc_camera_device *icd)
1176 1121
1177 BUG_ON(!icd->parent); 1122 BUG_ON(!icd->parent);
1178 1123
1124 v4l2_ctrl_handler_free(&icd->ctrl_handler);
1179 if (vdev) { 1125 if (vdev) {
1180 video_unregister_device(vdev); 1126 video_unregister_device(vdev);
1181 icd->vdev = NULL; 1127 icd->vdev = NULL;
@@ -1381,9 +1327,6 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1381 .vidioc_dqbuf = soc_camera_dqbuf, 1327 .vidioc_dqbuf = soc_camera_dqbuf,
1382 .vidioc_streamon = soc_camera_streamon, 1328 .vidioc_streamon = soc_camera_streamon,
1383 .vidioc_streamoff = soc_camera_streamoff, 1329 .vidioc_streamoff = soc_camera_streamoff,
1384 .vidioc_queryctrl = soc_camera_queryctrl,
1385 .vidioc_g_ctrl = soc_camera_g_ctrl,
1386 .vidioc_s_ctrl = soc_camera_s_ctrl,
1387 .vidioc_cropcap = soc_camera_cropcap, 1330 .vidioc_cropcap = soc_camera_cropcap,
1388 .vidioc_g_crop = soc_camera_g_crop, 1331 .vidioc_g_crop = soc_camera_g_crop,
1389 .vidioc_s_crop = soc_camera_s_crop, 1332 .vidioc_s_crop = soc_camera_s_crop,
@@ -1412,6 +1355,7 @@ static int video_dev_create(struct soc_camera_device *icd)
1412 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1355 vdev->ioctl_ops = &soc_camera_ioctl_ops;
1413 vdev->release = video_device_release; 1356 vdev->release = video_device_release;
1414 vdev->tvnorms = V4L2_STD_UNKNOWN; 1357 vdev->tvnorms = V4L2_STD_UNKNOWN;
1358 vdev->ctrl_handler = &icd->ctrl_handler;
1415 vdev->lock = &icd->video_lock; 1359 vdev->lock = &icd->video_lock;
1416 1360
1417 icd->vdev = vdev; 1361 icd->vdev = vdev;
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 1864e2242d4..2e15e17130d 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -19,6 +19,7 @@
19#include <linux/videodev2.h> 19#include <linux/videodev2.h>
20#include <media/videobuf-core.h> 20#include <media/videobuf-core.h>
21#include <media/videobuf2-core.h> 21#include <media/videobuf2-core.h>
22#include <media/v4l2-ctrls.h>
22#include <media/v4l2-device.h> 23#include <media/v4l2-device.h>
23 24
24struct file; 25struct file;
@@ -40,6 +41,7 @@ struct soc_camera_device {
40 struct soc_camera_sense *sense; /* See comment in struct definition */ 41 struct soc_camera_sense *sense; /* See comment in struct definition */
41 struct soc_camera_ops *ops; 42 struct soc_camera_ops *ops;
42 struct video_device *vdev; 43 struct video_device *vdev;
44 struct v4l2_ctrl_handler ctrl_handler;
43 const struct soc_camera_format_xlate *current_fmt; 45 const struct soc_camera_format_xlate *current_fmt;
44 struct soc_camera_format_xlate *user_formats; 46 struct soc_camera_format_xlate *user_formats;
45 int num_user_formats; 47 int num_user_formats;