aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2011-09-07 04:43:05 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-03 16:28:49 -0400
commitf026671d2bbbe8b25906bd266a1164a73fdeaa7f (patch)
tree3b1603253a609ba15951f0db1e17ab20eeb627a8 /drivers/media
parentab7b50ae406ee918ba68a13133a9cdf89c70fe4f (diff)
[media] ov2640: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> 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/ov2640.c90
1 files changed, 27 insertions, 63 deletions
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c
index 2826aff5ea27..981767f2d8ea 100644
--- a/drivers/media/video/ov2640.c
+++ b/drivers/media/video/ov2640.c
@@ -24,6 +24,7 @@
24#include <media/soc_mediabus.h> 24#include <media/soc_mediabus.h>
25#include <media/v4l2-chip-ident.h> 25#include <media/v4l2-chip-ident.h>
26#include <media/v4l2-subdev.h> 26#include <media/v4l2-subdev.h>
27#include <media/v4l2-ctrls.h>
27 28
28#define VAL_SET(x, mask, rshift, lshift) \ 29#define VAL_SET(x, mask, rshift, lshift) \
29 ((((x) >> rshift) & mask) << lshift) 30 ((((x) >> rshift) & mask) << lshift)
@@ -300,11 +301,10 @@ struct ov2640_win_size {
300 301
301struct ov2640_priv { 302struct ov2640_priv {
302 struct v4l2_subdev subdev; 303 struct v4l2_subdev subdev;
304 struct v4l2_ctrl_handler hdl;
303 enum v4l2_mbus_pixelcode cfmt_code; 305 enum v4l2_mbus_pixelcode cfmt_code;
304 const struct ov2640_win_size *win; 306 const struct ov2640_win_size *win;
305 int model; 307 int model;
306 u16 flag_vflip:1;
307 u16 flag_hflip:1;
308}; 308};
309 309
310/* 310/*
@@ -610,29 +610,6 @@ static enum v4l2_mbus_pixelcode ov2640_codes[] = {
610}; 610};
611 611
612/* 612/*
613 * Supported controls
614 */
615static const struct v4l2_queryctrl ov2640_controls[] = {
616 {
617 .id = V4L2_CID_VFLIP,
618 .type = V4L2_CTRL_TYPE_BOOLEAN,
619 .name = "Flip Vertically",
620 .minimum = 0,
621 .maximum = 1,
622 .step = 1,
623 .default_value = 0,
624 }, {
625 .id = V4L2_CID_HFLIP,
626 .type = V4L2_CTRL_TYPE_BOOLEAN,
627 .name = "Flip Horizontally",
628 .minimum = 0,
629 .maximum = 1,
630 .step = 1,
631 .default_value = 0,
632 },
633};
634
635/*
636 * General functions 613 * General functions
637 */ 614 */
638static struct ov2640_priv *to_ov2640(const struct i2c_client *client) 615static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
@@ -701,43 +678,23 @@ static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
701 return 0; 678 return 0;
702} 679}
703 680
704static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 681static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
705{
706 struct i2c_client *client = v4l2_get_subdevdata(sd);
707 struct ov2640_priv *priv = to_ov2640(client);
708
709 switch (ctrl->id) {
710 case V4L2_CID_VFLIP:
711 ctrl->value = priv->flag_vflip;
712 break;
713 case V4L2_CID_HFLIP:
714 ctrl->value = priv->flag_hflip;
715 break;
716 }
717 return 0;
718}
719
720static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
721{ 682{
683 struct v4l2_subdev *sd =
684 &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
722 struct i2c_client *client = v4l2_get_subdevdata(sd); 685 struct i2c_client *client = v4l2_get_subdevdata(sd);
723 struct ov2640_priv *priv = to_ov2640(client);
724 int ret = 0;
725 u8 val; 686 u8 val;
726 687
727 switch (ctrl->id) { 688 switch (ctrl->id) {
728 case V4L2_CID_VFLIP: 689 case V4L2_CID_VFLIP:
729 val = ctrl->value ? REG04_VFLIP_IMG : 0x00; 690 val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
730 priv->flag_vflip = ctrl->value ? 1 : 0; 691 return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
731 ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
732 break;
733 case V4L2_CID_HFLIP: 692 case V4L2_CID_HFLIP:
734 val = ctrl->value ? REG04_HFLIP_IMG : 0x00; 693 val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
735 priv->flag_hflip = ctrl->value ? 1 : 0; 694 return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
736 ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
737 break;
738 } 695 }
739 696
740 return ret; 697 return -EINVAL;
741} 698}
742 699
743static int ov2640_g_chip_ident(struct v4l2_subdev *sd, 700static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
@@ -1022,20 +979,17 @@ static int ov2640_video_probe(struct soc_camera_device *icd,
1022 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 979 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
1023 devname, pid, ver, midh, midl); 980 devname, pid, ver, midh, midl);
1024 981
1025 return 0; 982 return v4l2_ctrl_handler_setup(&priv->hdl);
1026 983
1027err: 984err:
1028 return ret; 985 return ret;
1029} 986}
1030 987
1031static struct soc_camera_ops ov2640_ops = { 988static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
1032 .controls = ov2640_controls, 989 .s_ctrl = ov2640_s_ctrl,
1033 .num_controls = ARRAY_SIZE(ov2640_controls),
1034}; 990};
1035 991
1036static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { 992static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1037 .g_ctrl = ov2640_g_ctrl,
1038 .s_ctrl = ov2640_s_ctrl,
1039 .g_chip_ident = ov2640_g_chip_ident, 993 .g_chip_ident = ov2640_g_chip_ident,
1040#ifdef CONFIG_VIDEO_ADV_DEBUG 994#ifdef CONFIG_VIDEO_ADV_DEBUG
1041 .g_register = ov2640_g_register, 995 .g_register = ov2640_g_register,
@@ -1113,12 +1067,22 @@ static int ov2640_probe(struct i2c_client *client,
1113 } 1067 }
1114 1068
1115 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); 1069 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1070 v4l2_ctrl_handler_init(&priv->hdl, 2);
1071 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1072 V4L2_CID_VFLIP, 0, 1, 1, 0);
1073 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1074 V4L2_CID_HFLIP, 0, 1, 1, 0);
1075 priv->subdev.ctrl_handler = &priv->hdl;
1076 if (priv->hdl.error) {
1077 int err = priv->hdl.error;
1116 1078
1117 icd->ops = &ov2640_ops; 1079 kfree(priv);
1080 return err;
1081 }
1118 1082
1119 ret = ov2640_video_probe(icd, client); 1083 ret = ov2640_video_probe(icd, client);
1120 if (ret) { 1084 if (ret) {
1121 icd->ops = NULL; 1085 v4l2_ctrl_handler_free(&priv->hdl);
1122 kfree(priv); 1086 kfree(priv);
1123 } else { 1087 } else {
1124 dev_info(&adapter->dev, "OV2640 Probed\n"); 1088 dev_info(&adapter->dev, "OV2640 Probed\n");
@@ -1130,9 +1094,9 @@ static int ov2640_probe(struct i2c_client *client,
1130static int ov2640_remove(struct i2c_client *client) 1094static int ov2640_remove(struct i2c_client *client)
1131{ 1095{
1132 struct ov2640_priv *priv = to_ov2640(client); 1096 struct ov2640_priv *priv = to_ov2640(client);
1133 struct soc_camera_device *icd = client->dev.platform_data;
1134 1097
1135 icd->ops = NULL; 1098 v4l2_device_unregister_subdev(&priv->subdev);
1099 v4l2_ctrl_handler_free(&priv->hdl);
1136 kfree(priv); 1100 kfree(priv);
1137 return 0; 1101 return 0;
1138} 1102}