diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-18 05:45:30 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-07-30 17:35:37 -0400 |
commit | 930806cb92325e43889b320ae2e705af774742ff (patch) | |
tree | 004fe20197bad19042be746612a87f5a1355ca4f | |
parent | d5d875cb8fb7206305ae6ca0240ccc396cb8b1be (diff) |
[media] vc032x: 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/vc032x.c | 695 |
1 files changed, 158 insertions, 537 deletions
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 208f6b2d512a..ee1a1c558e48 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -33,18 +33,10 @@ MODULE_LICENSE("GPL"); | |||
33 | /* specific webcam descriptor */ | 33 | /* specific webcam descriptor */ |
34 | struct sd { | 34 | struct sd { |
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 35 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
36 | 36 | struct { /* hvflip cluster */ | |
37 | u8 brightness; | 37 | struct v4l2_ctrl *hflip; |
38 | u8 contrast; | 38 | struct v4l2_ctrl *vflip; |
39 | u8 colors; | 39 | }; |
40 | u8 hflip; | ||
41 | u8 vflip; | ||
42 | u8 lightfreq; | ||
43 | s8 sharpness; | ||
44 | u16 exposure; | ||
45 | u8 gain; | ||
46 | u8 autogain; | ||
47 | u8 backlight; | ||
48 | 40 | ||
49 | u8 image_offset; | 41 | u8 image_offset; |
50 | 42 | ||
@@ -73,252 +65,6 @@ enum sensors { | |||
73 | NSENSORS | 65 | NSENSORS |
74 | }; | 66 | }; |
75 | 67 | ||
76 | /* V4L2 controls supported by the driver */ | ||
77 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
88 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
90 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
91 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
92 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
93 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
94 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
97 | static int sd_setbacklight(struct gspca_dev *gspca_dev, __s32 val); | ||
98 | static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | |||
100 | static const struct ctrl sd_ctrls[] = { | ||
101 | #define BRIGHTNESS_IDX 0 | ||
102 | { | ||
103 | { | ||
104 | .id = V4L2_CID_BRIGHTNESS, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Brightness", | ||
107 | .minimum = 0, | ||
108 | .maximum = 255, | ||
109 | .step = 1, | ||
110 | #define BRIGHTNESS_DEF 128 | ||
111 | .default_value = BRIGHTNESS_DEF, | ||
112 | }, | ||
113 | .set = sd_setbrightness, | ||
114 | .get = sd_getbrightness, | ||
115 | }, | ||
116 | #define CONTRAST_IDX 1 | ||
117 | { | ||
118 | { | ||
119 | .id = V4L2_CID_CONTRAST, | ||
120 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
121 | .name = "Contrast", | ||
122 | .minimum = 0, | ||
123 | .maximum = 255, | ||
124 | .step = 1, | ||
125 | #define CONTRAST_DEF 127 | ||
126 | .default_value = CONTRAST_DEF, | ||
127 | }, | ||
128 | .set = sd_setcontrast, | ||
129 | .get = sd_getcontrast, | ||
130 | }, | ||
131 | #define COLORS_IDX 2 | ||
132 | { | ||
133 | { | ||
134 | .id = V4L2_CID_SATURATION, | ||
135 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
136 | .name = "Saturation", | ||
137 | .minimum = 1, | ||
138 | .maximum = 127, | ||
139 | .step = 1, | ||
140 | #define COLOR_DEF 63 | ||
141 | .default_value = COLOR_DEF, | ||
142 | }, | ||
143 | .set = sd_setcolors, | ||
144 | .get = sd_getcolors, | ||
145 | }, | ||
146 | /* next 2 controls work with some sensors only */ | ||
147 | #define HFLIP_IDX 3 | ||
148 | { | ||
149 | { | ||
150 | .id = V4L2_CID_HFLIP, | ||
151 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
152 | .name = "Mirror", | ||
153 | .minimum = 0, | ||
154 | .maximum = 1, | ||
155 | .step = 1, | ||
156 | #define HFLIP_DEF 0 | ||
157 | .default_value = HFLIP_DEF, | ||
158 | }, | ||
159 | .set = sd_sethflip, | ||
160 | .get = sd_gethflip, | ||
161 | }, | ||
162 | #define VFLIP_IDX 4 | ||
163 | { | ||
164 | { | ||
165 | .id = V4L2_CID_VFLIP, | ||
166 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
167 | .name = "Vflip", | ||
168 | .minimum = 0, | ||
169 | .maximum = 1, | ||
170 | .step = 1, | ||
171 | #define VFLIP_DEF 0 | ||
172 | .default_value = VFLIP_DEF, | ||
173 | }, | ||
174 | .set = sd_setvflip, | ||
175 | .get = sd_getvflip, | ||
176 | }, | ||
177 | #define LIGHTFREQ_IDX 5 | ||
178 | { | ||
179 | { | ||
180 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
181 | .type = V4L2_CTRL_TYPE_MENU, | ||
182 | .name = "Light frequency filter", | ||
183 | .minimum = 0, | ||
184 | .maximum = 2, /* 0: No, 1: 50Hz, 2:60Hz */ | ||
185 | .step = 1, | ||
186 | #define FREQ_DEF 1 | ||
187 | .default_value = FREQ_DEF, | ||
188 | }, | ||
189 | .set = sd_setfreq, | ||
190 | .get = sd_getfreq, | ||
191 | }, | ||
192 | #define SHARPNESS_IDX 6 | ||
193 | { | ||
194 | { | ||
195 | .id = V4L2_CID_SHARPNESS, | ||
196 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
197 | .name = "Sharpness", | ||
198 | .minimum = -1, | ||
199 | .maximum = 2, | ||
200 | .step = 1, | ||
201 | #define SHARPNESS_DEF -1 | ||
202 | .default_value = SHARPNESS_DEF, | ||
203 | }, | ||
204 | .set = sd_setsharpness, | ||
205 | .get = sd_getsharpness, | ||
206 | }, | ||
207 | #define GAIN_IDX 7 | ||
208 | { | ||
209 | { | ||
210 | .id = V4L2_CID_GAIN, | ||
211 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
212 | .name = "Gain", | ||
213 | .minimum = 0, | ||
214 | .maximum = 78, | ||
215 | .step = 1, | ||
216 | #define GAIN_DEF 0 | ||
217 | .default_value = GAIN_DEF, | ||
218 | }, | ||
219 | .set = sd_setgain, | ||
220 | .get = sd_getgain, | ||
221 | }, | ||
222 | #define EXPOSURE_IDX 8 | ||
223 | { | ||
224 | { | ||
225 | .id = V4L2_CID_EXPOSURE, | ||
226 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
227 | .name = "Exposure", | ||
228 | #define EXPOSURE_DEF 450 | ||
229 | .minimum = 0, | ||
230 | .maximum = 4095, | ||
231 | .step = 1, | ||
232 | .default_value = EXPOSURE_DEF, | ||
233 | }, | ||
234 | .set = sd_setexposure, | ||
235 | .get = sd_getexposure, | ||
236 | }, | ||
237 | #define AUTOGAIN_IDX 9 | ||
238 | { | ||
239 | { | ||
240 | .id = V4L2_CID_AUTOGAIN, | ||
241 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
242 | .name = "Automatic Gain and Exposure", | ||
243 | .minimum = 0, | ||
244 | .maximum = 1, | ||
245 | .step = 1, | ||
246 | #define AUTOGAIN_DEF 1 | ||
247 | .default_value = AUTOGAIN_DEF, | ||
248 | }, | ||
249 | .set = sd_setautogain, | ||
250 | .get = sd_getautogain, | ||
251 | }, | ||
252 | #define BACKLIGHT_IDX 10 | ||
253 | { | ||
254 | { | ||
255 | .id = V4L2_CID_BACKLIGHT_COMPENSATION, | ||
256 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
257 | .name = "Backlight Compensation", | ||
258 | .minimum = 0, | ||
259 | .maximum = 15, | ||
260 | .step = 1, | ||
261 | #define BACKLIGHT_DEF 15 | ||
262 | .default_value = BACKLIGHT_DEF, | ||
263 | }, | ||
264 | .set = sd_setbacklight, | ||
265 | .get = sd_getbacklight, | ||
266 | }, | ||
267 | }; | ||
268 | |||
269 | /* table of the disabled controls */ | ||
270 | static u32 ctrl_dis[NSENSORS] = { | ||
271 | [SENSOR_HV7131R] = | ||
272 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
273 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | ||
274 | | (1 << SHARPNESS_IDX) | ||
275 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
276 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
277 | [SENSOR_MI0360] = | ||
278 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
279 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | ||
280 | | (1 << SHARPNESS_IDX) | ||
281 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
282 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
283 | [SENSOR_MI1310_SOC] = | ||
284 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
285 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
286 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
287 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
288 | [SENSOR_MI1320] = | ||
289 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
290 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
291 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
292 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
293 | [SENSOR_MI1320_SOC] = | ||
294 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
295 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
296 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
297 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
298 | [SENSOR_OV7660] = | ||
299 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
300 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | ||
301 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
302 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
303 | [SENSOR_OV7670] = | ||
304 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
305 | | (1 << SHARPNESS_IDX) | ||
306 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
307 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
308 | [SENSOR_PO1200] = | ||
309 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
310 | | (1 << LIGHTFREQ_IDX) | ||
311 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
312 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
313 | [SENSOR_PO3130NC] = | ||
314 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | ||
315 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | ||
316 | | (1 << SHARPNESS_IDX) | ||
317 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | ||
318 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | ||
319 | [SENSOR_POxxxx] = | ||
320 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX), | ||
321 | }; | ||
322 | 68 | ||
323 | static const struct v4l2_pix_format vc0321_mode[] = { | 69 | static const struct v4l2_pix_format vc0321_mode[] = { |
324 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 70 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, |
@@ -3405,18 +3151,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3405 | (id->idProduct == 0x0892 || id->idProduct == 0x0896)) | 3151 | (id->idProduct == 0x0892 || id->idProduct == 0x0896)) |
3406 | sd->sensor = SENSOR_POxxxx; /* no probe */ | 3152 | sd->sensor = SENSOR_POxxxx; /* no probe */ |
3407 | 3153 | ||
3408 | sd->brightness = BRIGHTNESS_DEF; | ||
3409 | sd->contrast = CONTRAST_DEF; | ||
3410 | sd->colors = COLOR_DEF; | ||
3411 | sd->hflip = HFLIP_DEF; | ||
3412 | sd->vflip = VFLIP_DEF; | ||
3413 | sd->lightfreq = FREQ_DEF; | ||
3414 | sd->sharpness = SHARPNESS_DEF; | ||
3415 | sd->gain = GAIN_DEF; | ||
3416 | sd->exposure = EXPOSURE_DEF; | ||
3417 | sd->autogain = AUTOGAIN_DEF; | ||
3418 | sd->backlight = BACKLIGHT_DEF; | ||
3419 | |||
3420 | return 0; | 3154 | return 0; |
3421 | } | 3155 | } |
3422 | 3156 | ||
@@ -3512,7 +3246,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3512 | } | 3246 | } |
3513 | } | 3247 | } |
3514 | cam->npkt = npkt[sd->sensor]; | 3248 | cam->npkt = npkt[sd->sensor]; |
3515 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | ||
3516 | 3249 | ||
3517 | if (sd->sensor == SENSOR_OV7670) | 3250 | if (sd->sensor == SENSOR_OV7670) |
3518 | sd->flags |= FL_HFLIP | FL_VFLIP; | 3251 | sd->flags |= FL_HFLIP | FL_VFLIP; |
@@ -3534,14 +3267,11 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3534 | return gspca_dev->usb_err; | 3267 | return gspca_dev->usb_err; |
3535 | } | 3268 | } |
3536 | 3269 | ||
3537 | static void setbrightness(struct gspca_dev *gspca_dev) | 3270 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
3538 | { | 3271 | { |
3539 | struct sd *sd = (struct sd *) gspca_dev; | ||
3540 | u8 data; | 3272 | u8 data; |
3541 | 3273 | ||
3542 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) | 3274 | data = val; |
3543 | return; | ||
3544 | data = sd->brightness; | ||
3545 | if (data >= 0x80) | 3275 | if (data >= 0x80) |
3546 | data &= 0x7f; | 3276 | data &= 0x7f; |
3547 | else | 3277 | else |
@@ -3549,36 +3279,27 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
3549 | i2c_write(gspca_dev, 0x98, &data, 1); | 3279 | i2c_write(gspca_dev, 0x98, &data, 1); |
3550 | } | 3280 | } |
3551 | 3281 | ||
3552 | static void setcontrast(struct gspca_dev *gspca_dev) | 3282 | static void setcontrast(struct gspca_dev *gspca_dev, u8 val) |
3553 | { | 3283 | { |
3554 | struct sd *sd = (struct sd *) gspca_dev; | 3284 | i2c_write(gspca_dev, 0x99, &val, 1); |
3555 | |||
3556 | if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX)) | ||
3557 | return; | ||
3558 | i2c_write(gspca_dev, 0x99, &sd->contrast, 1); | ||
3559 | } | 3285 | } |
3560 | 3286 | ||
3561 | static void setcolors(struct gspca_dev *gspca_dev) | 3287 | static void setcolors(struct gspca_dev *gspca_dev, u8 val) |
3562 | { | 3288 | { |
3563 | struct sd *sd = (struct sd *) gspca_dev; | ||
3564 | u8 data; | 3289 | u8 data; |
3565 | 3290 | ||
3566 | if (gspca_dev->ctrl_dis & (1 << COLORS_IDX)) | 3291 | data = val - (val >> 3) - 1; |
3567 | return; | ||
3568 | data = sd->colors - (sd->colors >> 3) - 1; | ||
3569 | i2c_write(gspca_dev, 0x94, &data, 1); | 3292 | i2c_write(gspca_dev, 0x94, &data, 1); |
3570 | i2c_write(gspca_dev, 0x95, &sd->colors, 1); | 3293 | i2c_write(gspca_dev, 0x95, &val, 1); |
3571 | } | 3294 | } |
3572 | 3295 | ||
3573 | static void sethvflip(struct gspca_dev *gspca_dev) | 3296 | static void sethvflip(struct gspca_dev *gspca_dev, bool hflip, bool vflip) |
3574 | { | 3297 | { |
3575 | struct sd *sd = (struct sd *) gspca_dev; | 3298 | struct sd *sd = (struct sd *) gspca_dev; |
3576 | u8 data[2], hflip, vflip; | 3299 | u8 data[2]; |
3577 | 3300 | ||
3578 | hflip = sd->hflip; | ||
3579 | if (sd->flags & FL_HFLIP) | 3301 | if (sd->flags & FL_HFLIP) |
3580 | hflip = !hflip; | 3302 | hflip = !hflip; |
3581 | vflip = sd->vflip; | ||
3582 | if (sd->flags & FL_VFLIP) | 3303 | if (sd->flags & FL_VFLIP) |
3583 | vflip = !vflip; | 3304 | vflip = !vflip; |
3584 | switch (sd->sensor) { | 3305 | switch (sd->sensor) { |
@@ -3610,7 +3331,7 @@ static void sethvflip(struct gspca_dev *gspca_dev) | |||
3610 | } | 3331 | } |
3611 | } | 3332 | } |
3612 | 3333 | ||
3613 | static void setlightfreq(struct gspca_dev *gspca_dev) | 3334 | static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) |
3614 | { | 3335 | { |
3615 | struct sd *sd = (struct sd *) gspca_dev; | 3336 | struct sd *sd = (struct sd *) gspca_dev; |
3616 | static const u8 (*ov7660_freq_tb[3])[4] = | 3337 | static const u8 (*ov7660_freq_tb[3])[4] = |
@@ -3618,10 +3339,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
3618 | 3339 | ||
3619 | if (sd->sensor != SENSOR_OV7660) | 3340 | if (sd->sensor != SENSOR_OV7660) |
3620 | return; | 3341 | return; |
3621 | usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); | 3342 | usb_exchange(gspca_dev, ov7660_freq_tb[val]); |
3622 | } | 3343 | } |
3623 | 3344 | ||
3624 | static void setsharpness(struct gspca_dev *gspca_dev) | 3345 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
3625 | { | 3346 | { |
3626 | struct sd *sd = (struct sd *) gspca_dev; | 3347 | struct sd *sd = (struct sd *) gspca_dev; |
3627 | u8 data; | 3348 | u8 data; |
@@ -3630,51 +3351,41 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
3630 | case SENSOR_PO1200: | 3351 | case SENSOR_PO1200: |
3631 | data = 0; | 3352 | data = 0; |
3632 | i2c_write(gspca_dev, 0x03, &data, 1); | 3353 | i2c_write(gspca_dev, 0x03, &data, 1); |
3633 | if (sd->sharpness < 0) | 3354 | if (val < 0) |
3634 | data = 0x6a; | 3355 | data = 0x6a; |
3635 | else | 3356 | else |
3636 | data = 0xb5 + sd->sharpness * 3; | 3357 | data = 0xb5 + val * 3; |
3637 | i2c_write(gspca_dev, 0x61, &data, 1); | 3358 | i2c_write(gspca_dev, 0x61, &data, 1); |
3638 | break; | 3359 | break; |
3639 | case SENSOR_POxxxx: | 3360 | case SENSOR_POxxxx: |
3640 | if (sd->sharpness < 0) | 3361 | if (val < 0) |
3641 | data = 0x7e; /* def = max */ | 3362 | data = 0x7e; /* def = max */ |
3642 | else | 3363 | else |
3643 | data = 0x60 + sd->sharpness * 0x0f; | 3364 | data = 0x60 + val * 0x0f; |
3644 | i2c_write(gspca_dev, 0x59, &data, 1); | 3365 | i2c_write(gspca_dev, 0x59, &data, 1); |
3645 | break; | 3366 | break; |
3646 | } | 3367 | } |
3647 | } | 3368 | } |
3648 | static void setgain(struct gspca_dev *gspca_dev) | 3369 | static void setgain(struct gspca_dev *gspca_dev, u8 val) |
3649 | { | 3370 | { |
3650 | struct sd *sd = (struct sd *) gspca_dev; | 3371 | i2c_write(gspca_dev, 0x15, &val, 1); |
3651 | |||
3652 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) | ||
3653 | return; | ||
3654 | i2c_write(gspca_dev, 0x15, &sd->gain, 1); | ||
3655 | } | 3372 | } |
3656 | 3373 | ||
3657 | static void setexposure(struct gspca_dev *gspca_dev) | 3374 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
3658 | { | 3375 | { |
3659 | struct sd *sd = (struct sd *) gspca_dev; | ||
3660 | u8 data; | 3376 | u8 data; |
3661 | 3377 | ||
3662 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) | 3378 | data = val >> 8; |
3663 | return; | ||
3664 | data = sd->exposure >> 8; | ||
3665 | i2c_write(gspca_dev, 0x1a, &data, 1); | 3379 | i2c_write(gspca_dev, 0x1a, &data, 1); |
3666 | data = sd->exposure; | 3380 | data = val; |
3667 | i2c_write(gspca_dev, 0x1b, &data, 1); | 3381 | i2c_write(gspca_dev, 0x1b, &data, 1); |
3668 | } | 3382 | } |
3669 | 3383 | ||
3670 | static void setautogain(struct gspca_dev *gspca_dev) | 3384 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
3671 | { | 3385 | { |
3672 | struct sd *sd = (struct sd *) gspca_dev; | ||
3673 | static const u8 data[2] = {0x28, 0x3c}; | 3386 | static const u8 data[2] = {0x28, 0x3c}; |
3674 | 3387 | ||
3675 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) | 3388 | i2c_write(gspca_dev, 0xd1, &data[val], 1); |
3676 | return; | ||
3677 | i2c_write(gspca_dev, 0xd1, &data[sd->autogain], 1); | ||
3678 | } | 3389 | } |
3679 | 3390 | ||
3680 | static void setgamma(struct gspca_dev *gspca_dev) | 3391 | static void setgamma(struct gspca_dev *gspca_dev) |
@@ -3683,30 +3394,29 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
3683 | usb_exchange(gspca_dev, poxxxx_gamma); | 3394 | usb_exchange(gspca_dev, poxxxx_gamma); |
3684 | } | 3395 | } |
3685 | 3396 | ||
3686 | static void setbacklight(struct gspca_dev *gspca_dev) | 3397 | static void setbacklight(struct gspca_dev *gspca_dev, s32 val) |
3687 | { | 3398 | { |
3688 | struct sd *sd = (struct sd *) gspca_dev; | ||
3689 | u16 v; | 3399 | u16 v; |
3690 | u8 data; | 3400 | u8 data; |
3691 | 3401 | ||
3692 | data = (sd->backlight << 4) | 0x0f; | 3402 | data = (val << 4) | 0x0f; |
3693 | i2c_write(gspca_dev, 0xaa, &data, 1); | 3403 | i2c_write(gspca_dev, 0xaa, &data, 1); |
3694 | v = 613 + 12 * sd->backlight; | 3404 | v = 613 + 12 * val; |
3695 | data = v >> 8; | 3405 | data = v >> 8; |
3696 | i2c_write(gspca_dev, 0xc4, &data, 1); | 3406 | i2c_write(gspca_dev, 0xc4, &data, 1); |
3697 | data = v; | 3407 | data = v; |
3698 | i2c_write(gspca_dev, 0xc5, &data, 1); | 3408 | i2c_write(gspca_dev, 0xc5, &data, 1); |
3699 | v = 1093 - 12 * sd->backlight; | 3409 | v = 1093 - 12 * val; |
3700 | data = v >> 8; | 3410 | data = v >> 8; |
3701 | i2c_write(gspca_dev, 0xc6, &data, 1); | 3411 | i2c_write(gspca_dev, 0xc6, &data, 1); |
3702 | data = v; | 3412 | data = v; |
3703 | i2c_write(gspca_dev, 0xc7, &data, 1); | 3413 | i2c_write(gspca_dev, 0xc7, &data, 1); |
3704 | v = 342 + 9 * sd->backlight; | 3414 | v = 342 + 9 * val; |
3705 | data = v >> 8; | 3415 | data = v >> 8; |
3706 | i2c_write(gspca_dev, 0xc8, &data, 1); | 3416 | i2c_write(gspca_dev, 0xc8, &data, 1); |
3707 | data = v; | 3417 | data = v; |
3708 | i2c_write(gspca_dev, 0xc9, &data, 1); | 3418 | i2c_write(gspca_dev, 0xc9, &data, 1); |
3709 | v = 702 - 9 * sd->backlight; | 3419 | v = 702 - 9 * val; |
3710 | data = v >> 8; | 3420 | data = v >> 8; |
3711 | i2c_write(gspca_dev, 0xca, &data, 1); | 3421 | i2c_write(gspca_dev, 0xca, &data, 1); |
3712 | data = v; | 3422 | data = v; |
@@ -3833,14 +3543,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3833 | /* case SENSOR_POxxxx: */ | 3543 | /* case SENSOR_POxxxx: */ |
3834 | usb_exchange(gspca_dev, poxxxx_init_common); | 3544 | usb_exchange(gspca_dev, poxxxx_init_common); |
3835 | setgamma(gspca_dev); | 3545 | setgamma(gspca_dev); |
3836 | setbacklight(gspca_dev); | 3546 | v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler); |
3837 | setbrightness(gspca_dev); | ||
3838 | setcontrast(gspca_dev); | ||
3839 | setcolors(gspca_dev); | ||
3840 | setsharpness(gspca_dev); | ||
3841 | setautogain(gspca_dev); | ||
3842 | setexposure(gspca_dev); | ||
3843 | setgain(gspca_dev); | ||
3844 | usb_exchange(gspca_dev, poxxxx_init_start_3); | 3547 | usb_exchange(gspca_dev, poxxxx_init_start_3); |
3845 | if (mode) | 3548 | if (mode) |
3846 | init = poxxxx_initQVGA; | 3549 | init = poxxxx_initQVGA; |
@@ -3873,8 +3576,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3873 | break; | 3576 | break; |
3874 | } | 3577 | } |
3875 | msleep(100); | 3578 | msleep(100); |
3876 | sethvflip(gspca_dev); | 3579 | v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler); |
3877 | setlightfreq(gspca_dev); | ||
3878 | } | 3580 | } |
3879 | switch (sd->sensor) { | 3581 | switch (sd->sensor) { |
3880 | case SENSOR_OV7670: | 3582 | case SENSOR_OV7670: |
@@ -3960,233 +3662,152 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
3960 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 3662 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
3961 | } | 3663 | } |
3962 | 3664 | ||
3963 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 3665 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
3964 | { | ||
3965 | struct sd *sd = (struct sd *) gspca_dev; | ||
3966 | |||
3967 | sd->brightness = val; | ||
3968 | if (gspca_dev->streaming) | ||
3969 | setbrightness(gspca_dev); | ||
3970 | return gspca_dev->usb_err; | ||
3971 | } | ||
3972 | |||
3973 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
3974 | { | ||
3975 | struct sd *sd = (struct sd *) gspca_dev; | ||
3976 | |||
3977 | *val = sd->brightness; | ||
3978 | return 0; | ||
3979 | } | ||
3980 | |||
3981 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
3982 | { | ||
3983 | struct sd *sd = (struct sd *) gspca_dev; | ||
3984 | |||
3985 | sd->contrast = val; | ||
3986 | if (gspca_dev->streaming) | ||
3987 | setcontrast(gspca_dev); | ||
3988 | return gspca_dev->usb_err; | ||
3989 | } | ||
3990 | |||
3991 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
3992 | { | ||
3993 | struct sd *sd = (struct sd *) gspca_dev; | ||
3994 | |||
3995 | *val = sd->contrast; | ||
3996 | return 0; | ||
3997 | } | ||
3998 | |||
3999 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
4000 | { | 3666 | { |
4001 | struct sd *sd = (struct sd *) gspca_dev; | 3667 | struct gspca_dev *gspca_dev = |
4002 | 3668 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | |
4003 | sd->colors = val; | 3669 | struct sd *sd = (struct sd *)gspca_dev; |
4004 | if (gspca_dev->streaming) | ||
4005 | setcolors(gspca_dev); | ||
4006 | return gspca_dev->usb_err; | ||
4007 | } | ||
4008 | |||
4009 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
4010 | { | ||
4011 | struct sd *sd = (struct sd *) gspca_dev; | ||
4012 | |||
4013 | *val = sd->colors; | ||
4014 | return 0; | ||
4015 | } | ||
4016 | |||
4017 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
4018 | { | ||
4019 | struct sd *sd = (struct sd *) gspca_dev; | ||
4020 | |||
4021 | sd->hflip = val; | ||
4022 | if (gspca_dev->streaming) | ||
4023 | sethvflip(gspca_dev); | ||
4024 | return gspca_dev->usb_err; | ||
4025 | } | ||
4026 | |||
4027 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
4028 | { | ||
4029 | struct sd *sd = (struct sd *) gspca_dev; | ||
4030 | |||
4031 | *val = sd->hflip; | ||
4032 | return 0; | ||
4033 | } | ||
4034 | |||
4035 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
4036 | { | ||
4037 | struct sd *sd = (struct sd *) gspca_dev; | ||
4038 | |||
4039 | sd->vflip = val; | ||
4040 | if (gspca_dev->streaming) | ||
4041 | sethvflip(gspca_dev); | ||
4042 | return gspca_dev->usb_err; | ||
4043 | } | ||
4044 | |||
4045 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
4046 | { | ||
4047 | struct sd *sd = (struct sd *) gspca_dev; | ||
4048 | 3670 | ||
4049 | *val = sd->vflip; | 3671 | gspca_dev->usb_err = 0; |
4050 | return 0; | ||
4051 | } | ||
4052 | 3672 | ||
4053 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | 3673 | if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) |
4054 | { | 3674 | return 0; |
4055 | struct sd *sd = (struct sd *) gspca_dev; | ||
4056 | |||
4057 | sd->lightfreq = val; | ||
4058 | if (gspca_dev->streaming) | ||
4059 | setlightfreq(gspca_dev); | ||
4060 | return gspca_dev->usb_err; | ||
4061 | } | ||
4062 | |||
4063 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
4064 | { | ||
4065 | struct sd *sd = (struct sd *) gspca_dev; | ||
4066 | |||
4067 | *val = sd->lightfreq; | ||
4068 | return 0; | ||
4069 | } | ||
4070 | |||
4071 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
4072 | { | ||
4073 | struct sd *sd = (struct sd *) gspca_dev; | ||
4074 | |||
4075 | sd->sharpness = val; | ||
4076 | if (gspca_dev->streaming) | ||
4077 | setsharpness(gspca_dev); | ||
4078 | return gspca_dev->usb_err; | ||
4079 | } | ||
4080 | |||
4081 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
4082 | { | ||
4083 | struct sd *sd = (struct sd *) gspca_dev; | ||
4084 | |||
4085 | *val = sd->sharpness; | ||
4086 | return 0; | ||
4087 | } | ||
4088 | |||
4089 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
4090 | { | ||
4091 | struct sd *sd = (struct sd *) gspca_dev; | ||
4092 | |||
4093 | sd->gain = val; | ||
4094 | if (gspca_dev->streaming) | ||
4095 | setgain(gspca_dev); | ||
4096 | return gspca_dev->usb_err; | ||
4097 | } | ||
4098 | |||
4099 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
4100 | { | ||
4101 | struct sd *sd = (struct sd *) gspca_dev; | ||
4102 | |||
4103 | *val = sd->gain; | ||
4104 | return 0; | ||
4105 | } | ||
4106 | |||
4107 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
4108 | { | ||
4109 | struct sd *sd = (struct sd *) gspca_dev; | ||
4110 | |||
4111 | sd->exposure = val; | ||
4112 | if (gspca_dev->streaming) | ||
4113 | setexposure(gspca_dev); | ||
4114 | return gspca_dev->usb_err; | ||
4115 | } | ||
4116 | |||
4117 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
4118 | { | ||
4119 | struct sd *sd = (struct sd *) gspca_dev; | ||
4120 | |||
4121 | *val = sd->exposure; | ||
4122 | return 0; | ||
4123 | } | ||
4124 | |||
4125 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
4126 | { | ||
4127 | struct sd *sd = (struct sd *) gspca_dev; | ||
4128 | |||
4129 | sd->autogain = val; | ||
4130 | if (gspca_dev->streaming) | ||
4131 | setautogain(gspca_dev); | ||
4132 | 3675 | ||
3676 | switch (ctrl->id) { | ||
3677 | case V4L2_CID_BRIGHTNESS: | ||
3678 | setbrightness(gspca_dev, ctrl->val); | ||
3679 | break; | ||
3680 | case V4L2_CID_CONTRAST: | ||
3681 | setcontrast(gspca_dev, ctrl->val); | ||
3682 | break; | ||
3683 | case V4L2_CID_SATURATION: | ||
3684 | setcolors(gspca_dev, ctrl->val); | ||
3685 | break; | ||
3686 | case V4L2_CID_HFLIP: | ||
3687 | sethvflip(gspca_dev, sd->hflip->val, sd->vflip->val); | ||
3688 | break; | ||
3689 | case V4L2_CID_SHARPNESS: | ||
3690 | setsharpness(gspca_dev, ctrl->val); | ||
3691 | break; | ||
3692 | case V4L2_CID_AUTOGAIN: | ||
3693 | setautogain(gspca_dev, ctrl->val); | ||
3694 | break; | ||
3695 | case V4L2_CID_GAIN: | ||
3696 | setgain(gspca_dev, ctrl->val); | ||
3697 | break; | ||
3698 | case V4L2_CID_EXPOSURE: | ||
3699 | setexposure(gspca_dev, ctrl->val); | ||
3700 | break; | ||
3701 | case V4L2_CID_BACKLIGHT_COMPENSATION: | ||
3702 | setbacklight(gspca_dev, ctrl->val); | ||
3703 | break; | ||
3704 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
3705 | setlightfreq(gspca_dev, ctrl->val); | ||
3706 | break; | ||
3707 | } | ||
4133 | return gspca_dev->usb_err; | 3708 | return gspca_dev->usb_err; |
4134 | } | 3709 | } |
4135 | 3710 | ||
4136 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | 3711 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
4137 | { | 3712 | .s_ctrl = sd_s_ctrl, |
4138 | struct sd *sd = (struct sd *) gspca_dev; | 3713 | }; |
4139 | |||
4140 | *val = sd->autogain; | ||
4141 | return 0; | ||
4142 | } | ||
4143 | |||
4144 | static int sd_setbacklight(struct gspca_dev *gspca_dev, __s32 val) | ||
4145 | { | ||
4146 | struct sd *sd = (struct sd *) gspca_dev; | ||
4147 | |||
4148 | sd->backlight = val; | ||
4149 | if (gspca_dev->streaming) | ||
4150 | setbacklight(gspca_dev); | ||
4151 | |||
4152 | return gspca_dev->usb_err; | ||
4153 | } | ||
4154 | 3714 | ||
4155 | static int sd_getbacklight(struct gspca_dev *gspca_dev, __s32 *val) | 3715 | static int sd_init_controls(struct gspca_dev *gspca_dev) |
4156 | { | 3716 | { |
4157 | struct sd *sd = (struct sd *) gspca_dev; | 3717 | struct sd *sd = (struct sd *)gspca_dev; |
3718 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
3719 | bool has_brightness = false; | ||
3720 | bool has_contrast = false; | ||
3721 | bool has_sat = false; | ||
3722 | bool has_hvflip = false; | ||
3723 | bool has_freq = false; | ||
3724 | bool has_backlight = false; | ||
3725 | bool has_exposure = false; | ||
3726 | bool has_autogain = false; | ||
3727 | bool has_gain = false; | ||
3728 | bool has_sharpness = false; | ||
4158 | 3729 | ||
4159 | *val = sd->backlight; | 3730 | switch (sd->sensor) { |
4160 | return 0; | 3731 | case SENSOR_HV7131R: |
4161 | } | 3732 | case SENSOR_MI0360: |
4162 | 3733 | case SENSOR_PO3130NC: | |
4163 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 3734 | break; |
4164 | struct v4l2_querymenu *menu) | 3735 | case SENSOR_MI1310_SOC: |
4165 | { | 3736 | case SENSOR_MI1320: |
4166 | static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"}; | 3737 | case SENSOR_MI1320_SOC: |
3738 | case SENSOR_OV7660: | ||
3739 | has_hvflip = true; | ||
3740 | break; | ||
3741 | case SENSOR_OV7670: | ||
3742 | has_hvflip = has_freq = true; | ||
3743 | break; | ||
3744 | case SENSOR_PO1200: | ||
3745 | has_hvflip = has_sharpness = true; | ||
3746 | break; | ||
3747 | case SENSOR_POxxxx: | ||
3748 | has_brightness = has_contrast = has_sat = has_backlight = | ||
3749 | has_exposure = has_autogain = has_gain = | ||
3750 | has_sharpness = true; | ||
3751 | break; | ||
3752 | } | ||
4167 | 3753 | ||
4168 | switch (menu->id) { | 3754 | gspca_dev->vdev.ctrl_handler = hdl; |
4169 | case V4L2_CID_POWER_LINE_FREQUENCY: | 3755 | v4l2_ctrl_handler_init(hdl, 8); |
4170 | if (menu->index >= ARRAY_SIZE(freq_nm)) | 3756 | if (has_brightness) |
4171 | break; | 3757 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, |
4172 | strcpy((char *) menu->name, freq_nm[menu->index]); | 3758 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); |
4173 | return 0; | 3759 | if (has_contrast) |
3760 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3761 | V4L2_CID_CONTRAST, 0, 255, 1, 127); | ||
3762 | if (has_sat) | ||
3763 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3764 | V4L2_CID_SATURATION, 1, 127, 1, 63); | ||
3765 | if (has_hvflip) { | ||
3766 | sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3767 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
3768 | sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3769 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
4174 | } | 3770 | } |
4175 | return -EINVAL; | 3771 | if (has_sharpness) |
3772 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3773 | V4L2_CID_SHARPNESS, -1, 2, 1, -1); | ||
3774 | if (has_freq) | ||
3775 | v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
3776 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
3777 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, | ||
3778 | V4L2_CID_POWER_LINE_FREQUENCY_50HZ); | ||
3779 | if (has_autogain) | ||
3780 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3781 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
3782 | if (has_gain) | ||
3783 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3784 | V4L2_CID_GAIN, 0, 78, 1, 0); | ||
3785 | if (has_exposure) | ||
3786 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3787 | V4L2_CID_EXPOSURE, 0, 4095, 1, 450); | ||
3788 | if (has_backlight) | ||
3789 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
3790 | V4L2_CID_BACKLIGHT_COMPENSATION, 0, 15, 1, 15); | ||
3791 | |||
3792 | if (hdl->error) { | ||
3793 | pr_err("Could not initialize controls\n"); | ||
3794 | return hdl->error; | ||
3795 | } | ||
3796 | if (sd->hflip) | ||
3797 | v4l2_ctrl_cluster(2, &sd->hflip); | ||
3798 | return 0; | ||
4176 | } | 3799 | } |
4177 | 3800 | ||
4178 | /* sub-driver description */ | 3801 | /* sub-driver description */ |
4179 | static const struct sd_desc sd_desc = { | 3802 | static const struct sd_desc sd_desc = { |
4180 | .name = MODULE_NAME, | 3803 | .name = MODULE_NAME, |
4181 | .ctrls = sd_ctrls, | 3804 | .init_controls = sd_init_controls, |
4182 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
4183 | .config = sd_config, | 3805 | .config = sd_config, |
4184 | .init = sd_init, | 3806 | .init = sd_init, |
4185 | .start = sd_start, | 3807 | .start = sd_start, |
4186 | .stopN = sd_stopN, | 3808 | .stopN = sd_stopN, |
4187 | .stop0 = sd_stop0, | 3809 | .stop0 = sd_stop0, |
4188 | .pkt_scan = sd_pkt_scan, | 3810 | .pkt_scan = sd_pkt_scan, |
4189 | .querymenu = sd_querymenu, | ||
4190 | }; | 3811 | }; |
4191 | 3812 | ||
4192 | /* -- module initialisation -- */ | 3813 | /* -- module initialisation -- */ |