aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-16 07:29:16 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 17:31:16 -0400
commitdf0df1accaf5a5a36901ad4019dd22b59ab8974d (patch)
tree8695e09df459117cc4bd38756b8490caaab7c7f1
parent3fa24bf5e159d10d160015e08decb48cfa1663a8 (diff)
[media] sq930x: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/sq930x.c109
1 files changed, 40 insertions, 69 deletions
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
index 1a8ba9b3550a..2d068867d0a4 100644
--- a/drivers/media/video/gspca/sq930x.c
+++ b/drivers/media/video/gspca/sq930x.c
@@ -36,8 +36,10 @@ MODULE_LICENSE("GPL");
36struct sd { 36struct sd {
37 struct gspca_dev gspca_dev; /* !! must be the first item */ 37 struct gspca_dev gspca_dev; /* !! must be the first item */
38 38
39 u16 expo; 39 struct { /* exposure/gain control cluster */
40 u8 gain; 40 struct v4l2_ctrl *exposure;
41 struct v4l2_ctrl *gain;
42 };
41 43
42 u8 do_ctrl; 44 u8 do_ctrl;
43 u8 gpio[2]; 45 u8 gpio[2];
@@ -55,42 +57,6 @@ enum sensors {
55 SENSOR_OV9630, 57 SENSOR_OV9630,
56}; 58};
57 59
58static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val);
59static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val);
60static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
61static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
62
63static const struct ctrl sd_ctrls[] = {
64 {
65 {
66 .id = V4L2_CID_EXPOSURE,
67 .type = V4L2_CTRL_TYPE_INTEGER,
68 .name = "Exposure",
69 .minimum = 0x0001,
70 .maximum = 0x0fff,
71 .step = 1,
72#define EXPO_DEF 0x0356
73 .default_value = EXPO_DEF,
74 },
75 .set = sd_setexpo,
76 .get = sd_getexpo,
77 },
78 {
79 {
80 .id = V4L2_CID_GAIN,
81 .type = V4L2_CTRL_TYPE_INTEGER,
82 .name = "Gain",
83 .minimum = 0x01,
84 .maximum = 0xff,
85 .step = 1,
86#define GAIN_DEF 0x8d
87 .default_value = GAIN_DEF,
88 },
89 .set = sd_setgain,
90 .get = sd_getgain,
91 },
92};
93
94static struct v4l2_pix_format vga_mode[] = { 60static struct v4l2_pix_format vga_mode[] = {
95 {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE, 61 {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
96 .bytesperline = 320, 62 .bytesperline = 320,
@@ -791,7 +757,7 @@ static void lz24bp_ppl(struct sd *sd, u16 ppl)
791 ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2); 757 ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2);
792} 758}
793 759
794static void setexposure(struct gspca_dev *gspca_dev) 760static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain)
795{ 761{
796 struct sd *sd = (struct sd *) gspca_dev; 762 struct sd *sd = (struct sd *) gspca_dev;
797 int i, integclks, intstartclk, frameclks, min_frclk; 763 int i, integclks, intstartclk, frameclks, min_frclk;
@@ -799,7 +765,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
799 u16 cmd; 765 u16 cmd;
800 u8 buf[15]; 766 u8 buf[15];
801 767
802 integclks = sd->expo; 768 integclks = expo;
803 i = 0; 769 i = 0;
804 cmd = SQ930_CTRL_SET_EXPOSURE; 770 cmd = SQ930_CTRL_SET_EXPOSURE;
805 771
@@ -818,7 +784,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
818 buf[i++] = intstartclk; 784 buf[i++] = intstartclk;
819 buf[i++] = frameclks >> 8; 785 buf[i++] = frameclks >> 8;
820 buf[i++] = frameclks; 786 buf[i++] = frameclks;
821 buf[i++] = sd->gain; 787 buf[i++] = gain;
822 break; 788 break;
823 default: /* cmos */ 789 default: /* cmos */
824/* case SENSOR_MI0360: */ 790/* case SENSOR_MI0360: */
@@ -834,7 +800,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
834 buf[i++] = 0x35; /* reg = global gain */ 800 buf[i++] = 0x35; /* reg = global gain */
835 buf[i++] = 0x00; /* val H */ 801 buf[i++] = 0x00; /* val H */
836 buf[i++] = sensor->i2c_dum; 802 buf[i++] = sensor->i2c_dum;
837 buf[i++] = 0x80 + sd->gain / 2; /* val L */ 803 buf[i++] = 0x80 + gain / 2; /* val L */
838 buf[i++] = 0x00; 804 buf[i++] = 0x00;
839 buf[i++] = 0x00; 805 buf[i++] = 0x00;
840 buf[i++] = 0x00; 806 buf[i++] = 0x00;
@@ -860,9 +826,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
860 826
861 cam->bulk = 1; 827 cam->bulk = 1;
862 828
863 sd->gain = GAIN_DEF;
864 sd->expo = EXPO_DEF;
865
866 return 0; 829 return 0;
867} 830}
868 831
@@ -1089,7 +1052,8 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev)
1089 return; 1052 return;
1090 sd->do_ctrl = 0; 1053 sd->do_ctrl = 0;
1091 1054
1092 setexposure(gspca_dev); 1055 setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure),
1056 v4l2_ctrl_g_ctrl(sd->gain));
1093 1057
1094 gspca_dev->cam.bulk_nurbs = 1; 1058 gspca_dev->cam.bulk_nurbs = 1;
1095 ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC); 1059 ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC);
@@ -1113,48 +1077,55 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1113 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 1077 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1114} 1078}
1115 1079
1116static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1080static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1117{ 1081{
1082 struct gspca_dev *gspca_dev =
1083 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1118 struct sd *sd = (struct sd *) gspca_dev; 1084 struct sd *sd = (struct sd *) gspca_dev;
1119 1085
1120 sd->gain = val; 1086 gspca_dev->usb_err = 0;
1121 if (gspca_dev->streaming)
1122 sd->do_ctrl = 1;
1123 return 0;
1124}
1125 1087
1126static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 1088 if (!gspca_dev->streaming)
1127{ 1089 return 0;
1128 struct sd *sd = (struct sd *) gspca_dev;
1129 1090
1130 *val = sd->gain; 1091 switch (ctrl->id) {
1131 return 0; 1092 case V4L2_CID_EXPOSURE:
1093 setexposure(gspca_dev, ctrl->val, sd->gain->val);
1094 break;
1095 }
1096 return gspca_dev->usb_err;
1132} 1097}
1133static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val)
1134{
1135 struct sd *sd = (struct sd *) gspca_dev;
1136 1098
1137 sd->expo = val; 1099static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1138 if (gspca_dev->streaming) 1100 .s_ctrl = sd_s_ctrl,
1139 sd->do_ctrl = 1; 1101};
1140 return 0;
1141}
1142 1102
1143static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val) 1103static int sd_init_controls(struct gspca_dev *gspca_dev)
1144{ 1104{
1105 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1145 struct sd *sd = (struct sd *) gspca_dev; 1106 struct sd *sd = (struct sd *) gspca_dev;
1146 1107
1147 *val = sd->expo; 1108 gspca_dev->vdev.ctrl_handler = hdl;
1109 v4l2_ctrl_handler_init(hdl, 2);
1110 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1111 V4L2_CID_EXPOSURE, 1, 0xfff, 1, 0x356);
1112 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1113 V4L2_CID_GAIN, 1, 255, 1, 0x8d);
1114
1115 if (hdl->error) {
1116 pr_err("Could not initialize controls\n");
1117 return hdl->error;
1118 }
1119 v4l2_ctrl_cluster(2, &sd->exposure);
1148 return 0; 1120 return 0;
1149} 1121}
1150 1122
1151/* sub-driver description */ 1123/* sub-driver description */
1152static const struct sd_desc sd_desc = { 1124static const struct sd_desc sd_desc = {
1153 .name = MODULE_NAME, 1125 .name = MODULE_NAME,
1154 .ctrls = sd_ctrls,
1155 .nctrls = ARRAY_SIZE(sd_ctrls),
1156 .config = sd_config, 1126 .config = sd_config,
1157 .init = sd_init, 1127 .init = sd_init,
1128 .init_controls = sd_init_controls,
1158 .isoc_init = sd_isoc_init, 1129 .isoc_init = sd_isoc_init,
1159 .start = sd_start, 1130 .start = sd_start,
1160 .stopN = sd_stopN, 1131 .stopN = sd_stopN,