aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/ov534_9.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:47:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:47:44 -0400
commit8762541f067d371320731510669e27f5cc40af38 (patch)
treefa2890094858614a947ba70612854acde9888940 /drivers/media/video/gspca/ov534_9.c
parent6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (diff)
parentadfe1560de1c696324554fba70c92f2d7c947ff7 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull second set of media updates from Mauro Carvalho Chehab: - radio API: add support to work with radio frequency bands - new AM/FM radio drivers: radio-shark, radio-shark2 - new Remote Controller USB driver: iguanair - conversion of several drivers to the v4l2 core control framework - new board additions at existing drivers - the remaining (and vast majority of the patches) are due to drivers/DocBook fixes/cleanups. * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (154 commits) [media] radio-tea5777: use library for 64bits div [media] tlg2300: Declare MODULE_FIRMWARE usage [media] lgs8gxx: Declare MODULE_FIRMWARE usage [media] xc5000: Add MODULE_FIRMWARE statements [media] s2255drv: Add MODULE_FIRMWARE statement [media] dib8000: move dereference after check for NULL [media] Documentation: Update cardlists [media] bttv: add support for Aposonic W-DVR [media] cx25821: Remove bad strcpy to read-only char* [media] pms.c: remove duplicated include [media] smiapp-core.c: remove duplicated include [media] via-camera: pass correct format settings to sensor [media] rtl2832.c: minor cleanup [media] Add support for the IguanaWorks USB IR Transceiver [media] Minor cleanups for MCE USB [media] drivers/media/dvb/siano/smscoreapi.c: use list_for_each_entry [media] Use a named union in struct v4l2_ioctl_info [media] mceusb: Add Twisted Melon USB IDs [media] staging/media/solo6x10: use module_pci_driver macro [media] staging/media/dt3155v4l: use module_pci_driver macro ... Conflicts: Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/media/video/gspca/ov534_9.c')
-rw-r--r--drivers/media/video/gspca/ov534_9.c294
1 files changed, 94 insertions, 200 deletions
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
index 1fd41f0d2e95..c4cd028fe0b4 100644
--- a/drivers/media/video/gspca/ov534_9.c
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -47,22 +47,9 @@ MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
47MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50/* controls */
51enum e_ctrl {
52 BRIGHTNESS,
53 CONTRAST,
54 AUTOGAIN,
55 EXPOSURE,
56 SHARPNESS,
57 SATUR,
58 LIGHTFREQ,
59 NCTRLS /* number of controls */
60};
61
62/* specific webcam descriptor */ 50/* specific webcam descriptor */
63struct sd { 51struct sd {
64 struct gspca_dev gspca_dev; /* !! must be the first item */ 52 struct gspca_dev gspca_dev; /* !! must be the first item */
65 struct gspca_ctrl ctrls[NCTRLS];
66 __u32 last_pts; 53 __u32 last_pts;
67 u8 last_fid; 54 u8 last_fid;
68 55
@@ -75,103 +62,6 @@ enum sensors {
75 NSENSORS 62 NSENSORS
76}; 63};
77 64
78/* V4L2 controls supported by the driver */
79static void setbrightness(struct gspca_dev *gspca_dev);
80static void setcontrast(struct gspca_dev *gspca_dev);
81static void setautogain(struct gspca_dev *gspca_dev);
82static void setexposure(struct gspca_dev *gspca_dev);
83static void setsharpness(struct gspca_dev *gspca_dev);
84static void setsatur(struct gspca_dev *gspca_dev);
85static void setlightfreq(struct gspca_dev *gspca_dev);
86
87static const struct ctrl sd_ctrls[NCTRLS] = {
88[BRIGHTNESS] = {
89 {
90 .id = V4L2_CID_BRIGHTNESS,
91 .type = V4L2_CTRL_TYPE_INTEGER,
92 .name = "Brightness",
93 .minimum = 0,
94 .maximum = 15,
95 .step = 1,
96 .default_value = 7
97 },
98 .set_control = setbrightness
99 },
100[CONTRAST] = {
101 {
102 .id = V4L2_CID_CONTRAST,
103 .type = V4L2_CTRL_TYPE_INTEGER,
104 .name = "Contrast",
105 .minimum = 0,
106 .maximum = 15,
107 .step = 1,
108 .default_value = 3
109 },
110 .set_control = setcontrast
111 },
112[AUTOGAIN] = {
113 {
114 .id = V4L2_CID_AUTOGAIN,
115 .type = V4L2_CTRL_TYPE_BOOLEAN,
116 .name = "Autogain",
117 .minimum = 0,
118 .maximum = 1,
119 .step = 1,
120#define AUTOGAIN_DEF 1
121 .default_value = AUTOGAIN_DEF,
122 },
123 .set_control = setautogain
124 },
125[EXPOSURE] = {
126 {
127 .id = V4L2_CID_EXPOSURE,
128 .type = V4L2_CTRL_TYPE_INTEGER,
129 .name = "Exposure",
130 .minimum = 0,
131 .maximum = 3,
132 .step = 1,
133 .default_value = 0
134 },
135 .set_control = setexposure
136 },
137[SHARPNESS] = {
138 {
139 .id = V4L2_CID_SHARPNESS,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Sharpness",
142 .minimum = -1, /* -1 = auto */
143 .maximum = 4,
144 .step = 1,
145 .default_value = -1
146 },
147 .set_control = setsharpness
148 },
149[SATUR] = {
150 {
151 .id = V4L2_CID_SATURATION,
152 .type = V4L2_CTRL_TYPE_INTEGER,
153 .name = "Saturation",
154 .minimum = 0,
155 .maximum = 4,
156 .step = 1,
157 .default_value = 2
158 },
159 .set_control = setsatur
160 },
161[LIGHTFREQ] = {
162 {
163 .id = V4L2_CID_POWER_LINE_FREQUENCY,
164 .type = V4L2_CTRL_TYPE_MENU,
165 .name = "Light frequency filter",
166 .minimum = 0,
167 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
168 .step = 1,
169 .default_value = 0
170 },
171 .set_control = setlightfreq
172 },
173};
174
175static const struct v4l2_pix_format ov965x_mode[] = { 65static const struct v4l2_pix_format ov965x_mode[] = {
176#define QVGA_MODE 0 66#define QVGA_MODE 0
177 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 67 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -1104,16 +994,14 @@ static void set_led(struct gspca_dev *gspca_dev, int status)
1104 } 994 }
1105} 995}
1106 996
1107static void setbrightness(struct gspca_dev *gspca_dev) 997static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
1108{ 998{
1109 struct sd *sd = (struct sd *) gspca_dev; 999 struct sd *sd = (struct sd *) gspca_dev;
1110 u8 val; 1000 u8 val;
1111 s8 sval; 1001 s8 sval;
1112 1002
1113 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS))
1114 return;
1115 if (sd->sensor == SENSOR_OV562x) { 1003 if (sd->sensor == SENSOR_OV562x) {
1116 sval = sd->ctrls[BRIGHTNESS].val; 1004 sval = brightness;
1117 val = 0x76; 1005 val = 0x76;
1118 val += sval; 1006 val += sval;
1119 sccb_write(gspca_dev, 0x24, val); 1007 sccb_write(gspca_dev, 0x24, val);
@@ -1128,7 +1016,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1128 val = 0xe6; 1016 val = 0xe6;
1129 sccb_write(gspca_dev, 0x26, val); 1017 sccb_write(gspca_dev, 0x26, val);
1130 } else { 1018 } else {
1131 val = sd->ctrls[BRIGHTNESS].val; 1019 val = brightness;
1132 if (val < 8) 1020 if (val < 8)
1133 val = 15 - val; /* f .. 8 */ 1021 val = 15 - val; /* f .. 8 */
1134 else 1022 else
@@ -1138,43 +1026,32 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1138 } 1026 }
1139} 1027}
1140 1028
1141static void setcontrast(struct gspca_dev *gspca_dev) 1029static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
1142{ 1030{
1143 struct sd *sd = (struct sd *) gspca_dev;
1144
1145 if (gspca_dev->ctrl_dis & (1 << CONTRAST))
1146 return;
1147 sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ 1031 sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1148 sd->ctrls[CONTRAST].val << 4); 1032 val << 4);
1149} 1033}
1150 1034
1151static void setautogain(struct gspca_dev *gspca_dev) 1035static void setautogain(struct gspca_dev *gspca_dev, s32 autogain)
1152{ 1036{
1153 struct sd *sd = (struct sd *) gspca_dev;
1154 u8 val; 1037 u8 val;
1155 1038
1156 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
1157 return;
1158/*fixme: should adjust agc/awb/aec by different controls */ 1039/*fixme: should adjust agc/awb/aec by different controls */
1159 val = sccb_read(gspca_dev, 0x13); /* com8 */ 1040 val = sccb_read(gspca_dev, 0x13); /* com8 */
1160 sccb_write(gspca_dev, 0xff, 0x00); 1041 sccb_write(gspca_dev, 0xff, 0x00);
1161 if (sd->ctrls[AUTOGAIN].val) 1042 if (autogain)
1162 val |= 0x05; /* agc & aec */ 1043 val |= 0x05; /* agc & aec */
1163 else 1044 else
1164 val &= 0xfa; 1045 val &= 0xfa;
1165 sccb_write(gspca_dev, 0x13, val); 1046 sccb_write(gspca_dev, 0x13, val);
1166} 1047}
1167 1048
1168static void setexposure(struct gspca_dev *gspca_dev) 1049static void setexposure(struct gspca_dev *gspca_dev, s32 exposure)
1169{ 1050{
1170 struct sd *sd = (struct sd *) gspca_dev;
1171 u8 val;
1172 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; 1051 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1052 u8 val;
1173 1053
1174 if (gspca_dev->ctrl_dis & (1 << EXPOSURE)) 1054 sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */
1175 return;
1176 sccb_write(gspca_dev, 0x10, /* aec[9:2] */
1177 expo[sd->ctrls[EXPOSURE].val]);
1178 1055
1179 val = sccb_read(gspca_dev, 0x13); /* com8 */ 1056 val = sccb_read(gspca_dev, 0x13); /* com8 */
1180 sccb_write(gspca_dev, 0xff, 0x00); 1057 sccb_write(gspca_dev, 0xff, 0x00);
@@ -1185,14 +1062,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
1185 sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ 1062 sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
1186} 1063}
1187 1064
1188static void setsharpness(struct gspca_dev *gspca_dev) 1065static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
1189{ 1066{
1190 struct sd *sd = (struct sd *) gspca_dev;
1191 s8 val;
1192
1193 if (gspca_dev->ctrl_dis & (1 << SHARPNESS))
1194 return;
1195 val = sd->ctrls[SHARPNESS].val;
1196 if (val < 0) { /* auto */ 1067 if (val < 0) { /* auto */
1197 val = sccb_read(gspca_dev, 0x42); /* com17 */ 1068 val = sccb_read(gspca_dev, 0x42); /* com17 */
1198 sccb_write(gspca_dev, 0xff, 0x00); 1069 sccb_write(gspca_dev, 0xff, 0x00);
@@ -1209,9 +1080,8 @@ static void setsharpness(struct gspca_dev *gspca_dev)
1209 sccb_write(gspca_dev, 0x42, val & 0xbf); 1080 sccb_write(gspca_dev, 0x42, val & 0xbf);
1210} 1081}
1211 1082
1212static void setsatur(struct gspca_dev *gspca_dev) 1083static void setsatur(struct gspca_dev *gspca_dev, s32 val)
1213{ 1084{
1214 struct sd *sd = (struct sd *) gspca_dev;
1215 u8 val1, val2, val3; 1085 u8 val1, val2, val3;
1216 static const u8 matrix[5][2] = { 1086 static const u8 matrix[5][2] = {
1217 {0x14, 0x38}, 1087 {0x14, 0x38},
@@ -1221,10 +1091,8 @@ static void setsatur(struct gspca_dev *gspca_dev)
1221 {0x48, 0x90} 1091 {0x48, 0x90}
1222 }; 1092 };
1223 1093
1224 if (gspca_dev->ctrl_dis & (1 << SATUR)) 1094 val1 = matrix[val][0];
1225 return; 1095 val2 = matrix[val][1];
1226 val1 = matrix[sd->ctrls[SATUR].val][0];
1227 val2 = matrix[sd->ctrls[SATUR].val][1];
1228 val3 = val1 + val2; 1096 val3 = val1 + val2;
1229 sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ 1097 sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1230 sccb_write(gspca_dev, 0x50, val3); 1098 sccb_write(gspca_dev, 0x50, val3);
@@ -1239,16 +1107,13 @@ static void setsatur(struct gspca_dev *gspca_dev)
1239 sccb_write(gspca_dev, 0x41, val1); 1107 sccb_write(gspca_dev, 0x41, val1);
1240} 1108}
1241 1109
1242static void setlightfreq(struct gspca_dev *gspca_dev) 1110static void setlightfreq(struct gspca_dev *gspca_dev, s32 freq)
1243{ 1111{
1244 struct sd *sd = (struct sd *) gspca_dev;
1245 u8 val; 1112 u8 val;
1246 1113
1247 if (gspca_dev->ctrl_dis & (1 << LIGHTFREQ))
1248 return;
1249 val = sccb_read(gspca_dev, 0x13); /* com8 */ 1114 val = sccb_read(gspca_dev, 0x13); /* com8 */
1250 sccb_write(gspca_dev, 0xff, 0x00); 1115 sccb_write(gspca_dev, 0xff, 0x00);
1251 if (sd->ctrls[LIGHTFREQ].val == 0) { 1116 if (freq == 0) {
1252 sccb_write(gspca_dev, 0x13, val & 0xdf); 1117 sccb_write(gspca_dev, 0x13, val & 0xdf);
1253 return; 1118 return;
1254 } 1119 }
@@ -1256,7 +1121,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
1256 1121
1257 val = sccb_read(gspca_dev, 0x42); /* com17 */ 1122 val = sccb_read(gspca_dev, 0x42); /* com17 */
1258 sccb_write(gspca_dev, 0xff, 0x00); 1123 sccb_write(gspca_dev, 0xff, 0x00);
1259 if (sd->ctrls[LIGHTFREQ].val == 1) 1124 if (freq == 1)
1260 val |= 0x01; 1125 val |= 0x01;
1261 else 1126 else
1262 val &= 0xfe; 1127 val &= 0xfe;
@@ -1267,13 +1132,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
1267static int sd_config(struct gspca_dev *gspca_dev, 1132static int sd_config(struct gspca_dev *gspca_dev,
1268 const struct usb_device_id *id) 1133 const struct usb_device_id *id)
1269{ 1134{
1270 struct sd *sd = (struct sd *) gspca_dev;
1271
1272 gspca_dev->cam.ctrls = sd->ctrls;
1273
1274#if AUTOGAIN_DEF != 0
1275 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
1276#endif
1277 return 0; 1135 return 0;
1278} 1136}
1279 1137
@@ -1330,9 +1188,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1330 gspca_dev->cam.cam_mode = ov971x_mode; 1188 gspca_dev->cam.cam_mode = ov971x_mode;
1331 gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); 1189 gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode);
1332 1190
1333 /* no control yet */
1334 gspca_dev->ctrl_dis = (1 << NCTRLS) - 1;
1335
1336 gspca_dev->cam.bulk = 1; 1191 gspca_dev->cam.bulk = 1;
1337 gspca_dev->cam.bulk_size = 16384; 1192 gspca_dev->cam.bulk_size = 16384;
1338 gspca_dev->cam.bulk_nurbs = 2; 1193 gspca_dev->cam.bulk_nurbs = 2;
@@ -1358,16 +1213,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1358 reg_w(gspca_dev, 0x56, 0x17); 1213 reg_w(gspca_dev, 0x56, 0x17);
1359 } else if ((sensor_id & 0xfff0) == 0x5620) { 1214 } else if ((sensor_id & 0xfff0) == 0x5620) {
1360 sd->sensor = SENSOR_OV562x; 1215 sd->sensor = SENSOR_OV562x;
1361 gspca_dev->ctrl_dis = (1 << CONTRAST) |
1362 (1 << AUTOGAIN) |
1363 (1 << EXPOSURE) |
1364 (1 << SHARPNESS) |
1365 (1 << SATUR) |
1366 (1 << LIGHTFREQ);
1367
1368 sd->ctrls[BRIGHTNESS].min = -90;
1369 sd->ctrls[BRIGHTNESS].max = 90;
1370 sd->ctrls[BRIGHTNESS].def = 0;
1371 gspca_dev->cam.cam_mode = ov562x_mode; 1216 gspca_dev->cam.cam_mode = ov562x_mode;
1372 gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); 1217 gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode);
1373 1218
@@ -1390,10 +1235,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1390 1235
1391 if (sd->sensor == SENSOR_OV971x) 1236 if (sd->sensor == SENSOR_OV971x)
1392 return gspca_dev->usb_err; 1237 return gspca_dev->usb_err;
1393 else if (sd->sensor == SENSOR_OV562x) { 1238 if (sd->sensor == SENSOR_OV562x)
1394 setbrightness(gspca_dev);
1395 return gspca_dev->usb_err; 1239 return gspca_dev->usb_err;
1396 } 1240
1397 switch (gspca_dev->curr_mode) { 1241 switch (gspca_dev->curr_mode) {
1398 case QVGA_MODE: /* 320x240 */ 1242 case QVGA_MODE: /* 320x240 */
1399 sccb_w_array(gspca_dev, ov965x_start_1_vga, 1243 sccb_w_array(gspca_dev, ov965x_start_1_vga,
@@ -1437,13 +1281,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1437 ARRAY_SIZE(ov965x_start_2_sxga)); 1281 ARRAY_SIZE(ov965x_start_2_sxga));
1438 break; 1282 break;
1439 } 1283 }
1440 setlightfreq(gspca_dev);
1441 setautogain(gspca_dev);
1442 setbrightness(gspca_dev);
1443 setcontrast(gspca_dev);
1444 setexposure(gspca_dev);
1445 setsharpness(gspca_dev);
1446 setsatur(gspca_dev);
1447 1284
1448 reg_w(gspca_dev, 0xe0, 0x00); 1285 reg_w(gspca_dev, 0xe0, 0x00);
1449 reg_w(gspca_dev, 0xe0, 0x00); 1286 reg_w(gspca_dev, 0xe0, 0x00);
@@ -1541,38 +1378,94 @@ scan_next:
1541 } while (remaining_len > 0); 1378 } while (remaining_len > 0);
1542} 1379}
1543 1380
1544static int sd_querymenu(struct gspca_dev *gspca_dev, 1381static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1545 struct v4l2_querymenu *menu)
1546{ 1382{
1547 switch (menu->id) { 1383 struct gspca_dev *gspca_dev =
1384 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1385
1386 gspca_dev->usb_err = 0;
1387
1388 if (!gspca_dev->streaming)
1389 return 0;
1390
1391 switch (ctrl->id) {
1392 case V4L2_CID_BRIGHTNESS:
1393 setbrightness(gspca_dev, ctrl->val);
1394 break;
1395 case V4L2_CID_CONTRAST:
1396 setcontrast(gspca_dev, ctrl->val);
1397 break;
1398 case V4L2_CID_SATURATION:
1399 setsatur(gspca_dev, ctrl->val);
1400 break;
1548 case V4L2_CID_POWER_LINE_FREQUENCY: 1401 case V4L2_CID_POWER_LINE_FREQUENCY:
1549 switch (menu->index) { 1402 setlightfreq(gspca_dev, ctrl->val);
1550 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1551 strcpy((char *) menu->name, "NoFliker");
1552 return 0;
1553 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1554 strcpy((char *) menu->name, "50 Hz");
1555 return 0;
1556 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1557 strcpy((char *) menu->name, "60 Hz");
1558 return 0;
1559 }
1560 break; 1403 break;
1404 case V4L2_CID_SHARPNESS:
1405 setsharpness(gspca_dev, ctrl->val);
1406 break;
1407 case V4L2_CID_AUTOGAIN:
1408 if (ctrl->is_new)
1409 setautogain(gspca_dev, ctrl->val);
1410 if (!ctrl->val && gspca_dev->exposure->is_new)
1411 setexposure(gspca_dev, gspca_dev->exposure->val);
1412 break;
1413 }
1414 return gspca_dev->usb_err;
1415}
1416
1417static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1418 .s_ctrl = sd_s_ctrl,
1419};
1420
1421static int sd_init_controls(struct gspca_dev *gspca_dev)
1422{
1423 struct sd *sd = (struct sd *)gspca_dev;
1424 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1425
1426 if (sd->sensor == SENSOR_OV971x)
1427 return 0;
1428 gspca_dev->vdev.ctrl_handler = hdl;
1429 v4l2_ctrl_handler_init(hdl, 7);
1430 if (sd->sensor == SENSOR_OV562x) {
1431 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1432 V4L2_CID_BRIGHTNESS, -90, 90, 1, 0);
1433 } else {
1434 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1435 V4L2_CID_BRIGHTNESS, 0, 15, 1, 7);
1436 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1437 V4L2_CID_CONTRAST, 0, 15, 1, 3);
1438 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1439 V4L2_CID_SATURATION, 0, 4, 1, 2);
1440 /* -1 = auto */
1441 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1442 V4L2_CID_SHARPNESS, -1, 4, 1, -1);
1443 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1444 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1445 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1446 V4L2_CID_EXPOSURE, 0, 3, 1, 0);
1447 v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1448 V4L2_CID_POWER_LINE_FREQUENCY,
1449 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
1450 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
1561 } 1451 }
1562 return -EINVAL; 1452
1453 if (hdl->error) {
1454 pr_err("Could not initialize controls\n");
1455 return hdl->error;
1456 }
1457 return 0;
1563} 1458}
1564 1459
1565/* sub-driver description */ 1460/* sub-driver description */
1566static const struct sd_desc sd_desc = { 1461static const struct sd_desc sd_desc = {
1567 .name = MODULE_NAME, 1462 .name = MODULE_NAME,
1568 .ctrls = sd_ctrls,
1569 .nctrls = NCTRLS,
1570 .config = sd_config, 1463 .config = sd_config,
1571 .init = sd_init, 1464 .init = sd_init,
1465 .init_controls = sd_init_controls,
1572 .start = sd_start, 1466 .start = sd_start,
1573 .stopN = sd_stopN, 1467 .stopN = sd_stopN,
1574 .pkt_scan = sd_pkt_scan, 1468 .pkt_scan = sd_pkt_scan,
1575 .querymenu = sd_querymenu,
1576}; 1469};
1577 1470
1578/* -- module initialisation -- */ 1471/* -- module initialisation -- */
@@ -1600,6 +1493,7 @@ static struct usb_driver sd_driver = {
1600#ifdef CONFIG_PM 1493#ifdef CONFIG_PM
1601 .suspend = gspca_suspend, 1494 .suspend = gspca_suspend,
1602 .resume = gspca_resume, 1495 .resume = gspca_resume,
1496 .reset_resume = gspca_resume,
1603#endif 1497#endif
1604}; 1498};
1605 1499