diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:47:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:47:44 -0400 |
commit | 8762541f067d371320731510669e27f5cc40af38 (patch) | |
tree | fa2890094858614a947ba70612854acde9888940 /drivers/media/video/gspca/ov534_9.c | |
parent | 6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (diff) | |
parent | adfe1560de1c696324554fba70c92f2d7c947ff7 (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.c | 294 |
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>"); | |||
47 | MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); | 47 | MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | /* controls */ | ||
51 | enum 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 */ |
63 | struct sd { | 51 | struct 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 */ | ||
79 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
80 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
81 | static void setautogain(struct gspca_dev *gspca_dev); | ||
82 | static void setexposure(struct gspca_dev *gspca_dev); | ||
83 | static void setsharpness(struct gspca_dev *gspca_dev); | ||
84 | static void setsatur(struct gspca_dev *gspca_dev); | ||
85 | static void setlightfreq(struct gspca_dev *gspca_dev); | ||
86 | |||
87 | static 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 | |||
175 | static const struct v4l2_pix_format ov965x_mode[] = { | 65 | static 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 | ||
1107 | static void setbrightness(struct gspca_dev *gspca_dev) | 997 | static 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 | ||
1141 | static void setcontrast(struct gspca_dev *gspca_dev) | 1029 | static 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 | ||
1151 | static void setautogain(struct gspca_dev *gspca_dev) | 1035 | static 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 | ||
1168 | static void setexposure(struct gspca_dev *gspca_dev) | 1049 | static 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 | ||
1188 | static void setsharpness(struct gspca_dev *gspca_dev) | 1065 | static 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 | ||
1212 | static void setsatur(struct gspca_dev *gspca_dev) | 1083 | static 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 | ||
1242 | static void setlightfreq(struct gspca_dev *gspca_dev) | 1110 | static 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) | |||
1267 | static int sd_config(struct gspca_dev *gspca_dev, | 1132 | static 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 | ||
1544 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 1381 | static 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 | |||
1417 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
1418 | .s_ctrl = sd_s_ctrl, | ||
1419 | }; | ||
1420 | |||
1421 | static 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 */ |
1566 | static const struct sd_desc sd_desc = { | 1461 | static 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 | ||