diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-06 08:28:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 08:38:56 -0400 |
commit | 98684298f9ed89554cdaa4afe2554fca8276d1e9 (patch) | |
tree | ed5d660a42b3cf758217445fb25aca40ded1e45a | |
parent | d67a1adaea29da942291145fa3964a453e017274 (diff) |
[media] gspca_mars: 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/mars.c | 292 |
1 files changed, 126 insertions, 166 deletions
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index b0231465afae..2950347b8265 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
@@ -30,22 +30,20 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
30 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); | 30 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); |
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | 32 | ||
33 | /* controls */ | ||
34 | enum e_ctrl { | ||
35 | BRIGHTNESS, | ||
36 | COLORS, | ||
37 | GAMMA, | ||
38 | SHARPNESS, | ||
39 | ILLUM_TOP, | ||
40 | ILLUM_BOT, | ||
41 | NCTRLS /* number of controls */ | ||
42 | }; | ||
43 | |||
44 | /* specific webcam descriptor */ | 33 | /* specific webcam descriptor */ |
45 | struct sd { | 34 | struct sd { |
46 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 35 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
47 | 36 | ||
48 | struct gspca_ctrl ctrls[NCTRLS]; | 37 | struct v4l2_ctrl_handler ctrl_handler; |
38 | struct v4l2_ctrl *brightness; | ||
39 | struct v4l2_ctrl *saturation; | ||
40 | struct v4l2_ctrl *sharpness; | ||
41 | struct v4l2_ctrl *gamma; | ||
42 | struct { /* illuminator control cluster */ | ||
43 | struct v4l2_ctrl *illum_top; | ||
44 | struct v4l2_ctrl *illum_bottom; | ||
45 | }; | ||
46 | struct v4l2_ctrl *jpegqual; | ||
49 | 47 | ||
50 | u8 quality; | 48 | u8 quality; |
51 | #define QUALITY_MIN 40 | 49 | #define QUALITY_MIN 40 |
@@ -56,89 +54,10 @@ struct sd { | |||
56 | }; | 54 | }; |
57 | 55 | ||
58 | /* V4L2 controls supported by the driver */ | 56 | /* V4L2 controls supported by the driver */ |
59 | static void setbrightness(struct gspca_dev *gspca_dev); | 57 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val); |
60 | static void setcolors(struct gspca_dev *gspca_dev); | 58 | static void setcolors(struct gspca_dev *gspca_dev, s32 val); |
61 | static void setgamma(struct gspca_dev *gspca_dev); | 59 | static void setgamma(struct gspca_dev *gspca_dev, s32 val); |
62 | static void setsharpness(struct gspca_dev *gspca_dev); | 60 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val); |
63 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val); | ||
65 | |||
66 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
67 | [BRIGHTNESS] = { | ||
68 | { | ||
69 | .id = V4L2_CID_BRIGHTNESS, | ||
70 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
71 | .name = "Brightness", | ||
72 | .minimum = 0, | ||
73 | .maximum = 30, | ||
74 | .step = 1, | ||
75 | .default_value = 15, | ||
76 | }, | ||
77 | .set_control = setbrightness | ||
78 | }, | ||
79 | [COLORS] = { | ||
80 | { | ||
81 | .id = V4L2_CID_SATURATION, | ||
82 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
83 | .name = "Color", | ||
84 | .minimum = 1, | ||
85 | .maximum = 255, | ||
86 | .step = 1, | ||
87 | .default_value = 200, | ||
88 | }, | ||
89 | .set_control = setcolors | ||
90 | }, | ||
91 | [GAMMA] = { | ||
92 | { | ||
93 | .id = V4L2_CID_GAMMA, | ||
94 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
95 | .name = "Gamma", | ||
96 | .minimum = 0, | ||
97 | .maximum = 3, | ||
98 | .step = 1, | ||
99 | .default_value = 1, | ||
100 | }, | ||
101 | .set_control = setgamma | ||
102 | }, | ||
103 | [SHARPNESS] = { | ||
104 | { | ||
105 | .id = V4L2_CID_SHARPNESS, | ||
106 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
107 | .name = "Sharpness", | ||
108 | .minimum = 0, | ||
109 | .maximum = 2, | ||
110 | .step = 1, | ||
111 | .default_value = 1, | ||
112 | }, | ||
113 | .set_control = setsharpness | ||
114 | }, | ||
115 | [ILLUM_TOP] = { | ||
116 | { | ||
117 | .id = V4L2_CID_ILLUMINATORS_1, | ||
118 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
119 | .name = "Top illuminator", | ||
120 | .minimum = 0, | ||
121 | .maximum = 1, | ||
122 | .step = 1, | ||
123 | .default_value = 0, | ||
124 | .flags = V4L2_CTRL_FLAG_UPDATE, | ||
125 | }, | ||
126 | .set = sd_setilluminator1 | ||
127 | }, | ||
128 | [ILLUM_BOT] = { | ||
129 | { | ||
130 | .id = V4L2_CID_ILLUMINATORS_2, | ||
131 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
132 | .name = "Bottom illuminator", | ||
133 | .minimum = 0, | ||
134 | .maximum = 1, | ||
135 | .step = 1, | ||
136 | .default_value = 0, | ||
137 | .flags = V4L2_CTRL_FLAG_UPDATE, | ||
138 | }, | ||
139 | .set = sd_setilluminator2 | ||
140 | }, | ||
141 | }; | ||
142 | 61 | ||
143 | static const struct v4l2_pix_format vga_mode[] = { | 62 | static const struct v4l2_pix_format vga_mode[] = { |
144 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 63 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
@@ -198,59 +117,129 @@ static void mi_w(struct gspca_dev *gspca_dev, | |||
198 | reg_w(gspca_dev, 4); | 117 | reg_w(gspca_dev, 4); |
199 | } | 118 | } |
200 | 119 | ||
201 | static void setbrightness(struct gspca_dev *gspca_dev) | 120 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
202 | { | 121 | { |
203 | struct sd *sd = (struct sd *) gspca_dev; | ||
204 | |||
205 | gspca_dev->usb_buf[0] = 0x61; | 122 | gspca_dev->usb_buf[0] = 0x61; |
206 | gspca_dev->usb_buf[1] = sd->ctrls[BRIGHTNESS].val; | 123 | gspca_dev->usb_buf[1] = val; |
207 | reg_w(gspca_dev, 2); | 124 | reg_w(gspca_dev, 2); |
208 | } | 125 | } |
209 | 126 | ||
210 | static void setcolors(struct gspca_dev *gspca_dev) | 127 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
211 | { | 128 | { |
212 | struct sd *sd = (struct sd *) gspca_dev; | ||
213 | s16 val; | ||
214 | |||
215 | val = sd->ctrls[COLORS].val; | ||
216 | gspca_dev->usb_buf[0] = 0x5f; | 129 | gspca_dev->usb_buf[0] = 0x5f; |
217 | gspca_dev->usb_buf[1] = val << 3; | 130 | gspca_dev->usb_buf[1] = val << 3; |
218 | gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04; | 131 | gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04; |
219 | reg_w(gspca_dev, 3); | 132 | reg_w(gspca_dev, 3); |
220 | } | 133 | } |
221 | 134 | ||
222 | static void setgamma(struct gspca_dev *gspca_dev) | 135 | static void setgamma(struct gspca_dev *gspca_dev, s32 val) |
223 | { | 136 | { |
224 | struct sd *sd = (struct sd *) gspca_dev; | ||
225 | |||
226 | gspca_dev->usb_buf[0] = 0x06; | 137 | gspca_dev->usb_buf[0] = 0x06; |
227 | gspca_dev->usb_buf[1] = sd->ctrls[GAMMA].val * 0x40; | 138 | gspca_dev->usb_buf[1] = val * 0x40; |
228 | reg_w(gspca_dev, 2); | 139 | reg_w(gspca_dev, 2); |
229 | } | 140 | } |
230 | 141 | ||
231 | static void setsharpness(struct gspca_dev *gspca_dev) | 142 | static void setsharpness(struct gspca_dev *gspca_dev, s32 val) |
232 | { | 143 | { |
233 | struct sd *sd = (struct sd *) gspca_dev; | ||
234 | |||
235 | gspca_dev->usb_buf[0] = 0x67; | 144 | gspca_dev->usb_buf[0] = 0x67; |
236 | gspca_dev->usb_buf[1] = sd->ctrls[SHARPNESS].val * 4 + 3; | 145 | gspca_dev->usb_buf[1] = val * 4 + 3; |
237 | reg_w(gspca_dev, 2); | 146 | reg_w(gspca_dev, 2); |
238 | } | 147 | } |
239 | 148 | ||
240 | static void setilluminators(struct gspca_dev *gspca_dev) | 149 | static void setilluminators(struct gspca_dev *gspca_dev, bool top, bool bottom) |
241 | { | 150 | { |
242 | struct sd *sd = (struct sd *) gspca_dev; | 151 | /* both are off if not streaming */ |
243 | |||
244 | gspca_dev->usb_buf[0] = 0x22; | 152 | gspca_dev->usb_buf[0] = 0x22; |
245 | if (sd->ctrls[ILLUM_TOP].val) | 153 | if (top) |
246 | gspca_dev->usb_buf[1] = 0x76; | 154 | gspca_dev->usb_buf[1] = 0x76; |
247 | else if (sd->ctrls[ILLUM_BOT].val) | 155 | else if (bottom) |
248 | gspca_dev->usb_buf[1] = 0x7a; | 156 | gspca_dev->usb_buf[1] = 0x7a; |
249 | else | 157 | else |
250 | gspca_dev->usb_buf[1] = 0x7e; | 158 | gspca_dev->usb_buf[1] = 0x7e; |
251 | reg_w(gspca_dev, 2); | 159 | reg_w(gspca_dev, 2); |
252 | } | 160 | } |
253 | 161 | ||
162 | static int mars_s_ctrl(struct v4l2_ctrl *ctrl) | ||
163 | { | ||
164 | struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler); | ||
165 | struct gspca_dev *gspca_dev = &sd->gspca_dev; | ||
166 | |||
167 | gspca_dev->usb_err = 0; | ||
168 | |||
169 | if (ctrl->id == V4L2_CID_ILLUMINATORS_1) { | ||
170 | /* only one can be on at a time */ | ||
171 | if (ctrl->is_new && ctrl->val) | ||
172 | sd->illum_bottom->val = 0; | ||
173 | if (sd->illum_bottom->is_new && sd->illum_bottom->val) | ||
174 | sd->illum_top->val = 0; | ||
175 | } | ||
176 | |||
177 | if (!gspca_dev->streaming) | ||
178 | return 0; | ||
179 | |||
180 | switch (ctrl->id) { | ||
181 | case V4L2_CID_BRIGHTNESS: | ||
182 | setbrightness(&sd->gspca_dev, ctrl->val); | ||
183 | break; | ||
184 | case V4L2_CID_SATURATION: | ||
185 | setcolors(&sd->gspca_dev, ctrl->val); | ||
186 | break; | ||
187 | case V4L2_CID_GAMMA: | ||
188 | setgamma(&sd->gspca_dev, ctrl->val); | ||
189 | break; | ||
190 | case V4L2_CID_ILLUMINATORS_1: | ||
191 | setilluminators(&sd->gspca_dev, sd->illum_top->val, | ||
192 | sd->illum_bottom->val); | ||
193 | break; | ||
194 | case V4L2_CID_SHARPNESS: | ||
195 | setsharpness(&sd->gspca_dev, ctrl->val); | ||
196 | break; | ||
197 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: | ||
198 | jpeg_set_qual(sd->jpeg_hdr, ctrl->val); | ||
199 | break; | ||
200 | default: | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | return gspca_dev->usb_err; | ||
204 | } | ||
205 | |||
206 | static const struct v4l2_ctrl_ops mars_ctrl_ops = { | ||
207 | .s_ctrl = mars_s_ctrl, | ||
208 | }; | ||
209 | |||
210 | /* this function is called at probe time */ | ||
211 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
212 | { | ||
213 | struct sd *sd = (struct sd *) gspca_dev; | ||
214 | struct v4l2_ctrl_handler *hdl = &sd->ctrl_handler; | ||
215 | |||
216 | gspca_dev->vdev.ctrl_handler = hdl; | ||
217 | v4l2_ctrl_handler_init(hdl, 7); | ||
218 | sd->brightness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
219 | V4L2_CID_BRIGHTNESS, 0, 30, 1, 15); | ||
220 | sd->saturation = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
221 | V4L2_CID_SATURATION, 0, 255, 1, 200); | ||
222 | sd->gamma = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
223 | V4L2_CID_GAMMA, 0, 3, 1, 1); | ||
224 | sd->sharpness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
225 | V4L2_CID_SHARPNESS, 0, 2, 1, 1); | ||
226 | sd->illum_top = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
227 | V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); | ||
228 | sd->illum_top->flags |= V4L2_CTRL_FLAG_UPDATE; | ||
229 | sd->illum_bottom = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
230 | V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); | ||
231 | sd->illum_bottom->flags |= V4L2_CTRL_FLAG_UPDATE; | ||
232 | sd->jpegqual = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, | ||
233 | V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
234 | QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); | ||
235 | if (hdl->error) { | ||
236 | pr_err("Could not initialize controls\n"); | ||
237 | return hdl->error; | ||
238 | } | ||
239 | v4l2_ctrl_cluster(2, &sd->illum_top); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
254 | /* this function is called at probe time */ | 243 | /* this function is called at probe time */ |
255 | static int sd_config(struct gspca_dev *gspca_dev, | 244 | static int sd_config(struct gspca_dev *gspca_dev, |
256 | const struct usb_device_id *id) | 245 | const struct usb_device_id *id) |
@@ -261,7 +250,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
261 | cam = &gspca_dev->cam; | 250 | cam = &gspca_dev->cam; |
262 | cam->cam_mode = vga_mode; | 251 | cam->cam_mode = vga_mode; |
263 | cam->nmodes = ARRAY_SIZE(vga_mode); | 252 | cam->nmodes = ARRAY_SIZE(vga_mode); |
264 | cam->ctrls = sd->ctrls; | ||
265 | sd->quality = QUALITY_DEF; | 253 | sd->quality = QUALITY_DEF; |
266 | return 0; | 254 | return 0; |
267 | } | 255 | } |
@@ -269,7 +257,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
269 | /* this function is called at probe and resume time */ | 257 | /* this function is called at probe and resume time */ |
270 | static int sd_init(struct gspca_dev *gspca_dev) | 258 | static int sd_init(struct gspca_dev *gspca_dev) |
271 | { | 259 | { |
272 | gspca_dev->ctrl_inac = (1 << ILLUM_TOP) | (1 << ILLUM_BOT); | ||
273 | return 0; | 260 | return 0; |
274 | } | 261 | } |
275 | 262 | ||
@@ -282,7 +269,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
282 | /* create the JPEG header */ | 269 | /* create the JPEG header */ |
283 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 270 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
284 | 0x21); /* JPEG 422 */ | 271 | 0x21); /* JPEG 422 */ |
285 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 272 | jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); |
286 | 273 | ||
287 | data = gspca_dev->usb_buf; | 274 | data = gspca_dev->usb_buf; |
288 | 275 | ||
@@ -301,7 +288,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
301 | data[5] = 0x30; /* reg 4, MI, PAS5101 : | 288 | data[5] = 0x30; /* reg 4, MI, PAS5101 : |
302 | * 0x30 for 24mhz , 0x28 for 12mhz */ | 289 | * 0x30 for 24mhz , 0x28 for 12mhz */ |
303 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ | 290 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ |
304 | data[7] = sd->ctrls[GAMMA].val * 0x40; /* reg 0x06: gamma */ | 291 | data[7] = v4l2_ctrl_g_ctrl(sd->gamma) * 0x40; /* reg 0x06: gamma */ |
305 | data[8] = 0x01; /* reg 7, V start - was 0x03 */ | 292 | data[8] = 0x01; /* reg 7, V start - was 0x03 */ |
306 | /* if (h_size == 320 ) */ | 293 | /* if (h_size == 320 ) */ |
307 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ | 294 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ |
@@ -333,16 +320,16 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
333 | /* reg 0x5f/0x60 (LE) = saturation */ | 320 | /* reg 0x5f/0x60 (LE) = saturation */ |
334 | /* h (60): xxxx x100 | 321 | /* h (60): xxxx x100 |
335 | * l (5f): xxxx x000 */ | 322 | * l (5f): xxxx x000 */ |
336 | data[2] = sd->ctrls[COLORS].val << 3; | 323 | data[2] = v4l2_ctrl_g_ctrl(sd->saturation) << 3; |
337 | data[3] = ((sd->ctrls[COLORS].val >> 2) & 0xf8) | 0x04; | 324 | data[3] = ((v4l2_ctrl_g_ctrl(sd->saturation) >> 2) & 0xf8) | 0x04; |
338 | data[4] = sd->ctrls[BRIGHTNESS].val; /* reg 0x61 = brightness */ | 325 | data[4] = v4l2_ctrl_g_ctrl(sd->brightness); /* reg 0x61 = brightness */ |
339 | data[5] = 0x00; | 326 | data[5] = 0x00; |
340 | 327 | ||
341 | reg_w(gspca_dev, 6); | 328 | reg_w(gspca_dev, 6); |
342 | 329 | ||
343 | data[0] = 0x67; | 330 | data[0] = 0x67; |
344 | /*jfm: from win trace*/ | 331 | /*jfm: from win trace*/ |
345 | data[1] = sd->ctrls[SHARPNESS].val * 4 + 3; | 332 | data[1] = v4l2_ctrl_g_ctrl(sd->sharpness) * 4 + 3; |
346 | data[2] = 0x14; | 333 | data[2] = 0x14; |
347 | reg_w(gspca_dev, 3); | 334 | reg_w(gspca_dev, 3); |
348 | 335 | ||
@@ -365,7 +352,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
365 | data[1] = 0x4d; /* ISOC transferring enable... */ | 352 | data[1] = 0x4d; /* ISOC transferring enable... */ |
366 | reg_w(gspca_dev, 2); | 353 | reg_w(gspca_dev, 2); |
367 | 354 | ||
368 | gspca_dev->ctrl_inac = 0; /* activate the illuminator controls */ | 355 | setilluminators(gspca_dev, v4l2_ctrl_g_ctrl(sd->illum_top), |
356 | v4l2_ctrl_g_ctrl(sd->illum_bottom)); | ||
357 | |||
369 | return gspca_dev->usb_err; | 358 | return gspca_dev->usb_err; |
370 | } | 359 | } |
371 | 360 | ||
@@ -373,11 +362,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
373 | { | 362 | { |
374 | struct sd *sd = (struct sd *) gspca_dev; | 363 | struct sd *sd = (struct sd *) gspca_dev; |
375 | 364 | ||
376 | gspca_dev->ctrl_inac = (1 << ILLUM_TOP) | (1 << ILLUM_BOT); | 365 | if (v4l2_ctrl_g_ctrl(sd->illum_top) || |
377 | if (sd->ctrls[ILLUM_TOP].val || sd->ctrls[ILLUM_BOT].val) { | 366 | v4l2_ctrl_g_ctrl(sd->illum_bottom)) { |
378 | sd->ctrls[ILLUM_TOP].val = 0; | 367 | setilluminators(gspca_dev, false, false); |
379 | sd->ctrls[ILLUM_BOT].val = 0; | ||
380 | setilluminators(gspca_dev); | ||
381 | msleep(20); | 368 | msleep(20); |
382 | } | 369 | } |
383 | 370 | ||
@@ -424,43 +411,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
424 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 411 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
425 | } | 412 | } |
426 | 413 | ||
427 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val) | ||
428 | { | ||
429 | struct sd *sd = (struct sd *) gspca_dev; | ||
430 | |||
431 | /* only one illuminator may be on */ | ||
432 | sd->ctrls[ILLUM_TOP].val = val; | ||
433 | if (val) | ||
434 | sd->ctrls[ILLUM_BOT].val = 0; | ||
435 | setilluminators(gspca_dev); | ||
436 | return gspca_dev->usb_err; | ||
437 | } | ||
438 | |||
439 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val) | ||
440 | { | ||
441 | struct sd *sd = (struct sd *) gspca_dev; | ||
442 | |||
443 | /* only one illuminator may be on */ | ||
444 | sd->ctrls[ILLUM_BOT].val = val; | ||
445 | if (val) | ||
446 | sd->ctrls[ILLUM_TOP].val = 0; | ||
447 | setilluminators(gspca_dev); | ||
448 | return gspca_dev->usb_err; | ||
449 | } | ||
450 | |||
451 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 414 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, |
452 | struct v4l2_jpegcompression *jcomp) | 415 | struct v4l2_jpegcompression *jcomp) |
453 | { | 416 | { |
454 | struct sd *sd = (struct sd *) gspca_dev; | 417 | struct sd *sd = (struct sd *) gspca_dev; |
418 | int ret; | ||
455 | 419 | ||
456 | if (jcomp->quality < QUALITY_MIN) | 420 | ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); |
457 | sd->quality = QUALITY_MIN; | 421 | if (ret) |
458 | else if (jcomp->quality > QUALITY_MAX) | 422 | return ret; |
459 | sd->quality = QUALITY_MAX; | 423 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); |
460 | else | ||
461 | sd->quality = jcomp->quality; | ||
462 | if (gspca_dev->streaming) | ||
463 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
464 | return 0; | 424 | return 0; |
465 | } | 425 | } |
466 | 426 | ||
@@ -470,7 +430,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
470 | struct sd *sd = (struct sd *) gspca_dev; | 430 | struct sd *sd = (struct sd *) gspca_dev; |
471 | 431 | ||
472 | memset(jcomp, 0, sizeof *jcomp); | 432 | memset(jcomp, 0, sizeof *jcomp); |
473 | jcomp->quality = sd->quality; | 433 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); |
474 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 434 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT |
475 | | V4L2_JPEG_MARKER_DQT; | 435 | | V4L2_JPEG_MARKER_DQT; |
476 | return 0; | 436 | return 0; |
@@ -479,10 +439,9 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
479 | /* sub-driver description */ | 439 | /* sub-driver description */ |
480 | static const struct sd_desc sd_desc = { | 440 | static const struct sd_desc sd_desc = { |
481 | .name = MODULE_NAME, | 441 | .name = MODULE_NAME, |
482 | .ctrls = sd_ctrls, | ||
483 | .nctrls = NCTRLS, | ||
484 | .config = sd_config, | 442 | .config = sd_config, |
485 | .init = sd_init, | 443 | .init = sd_init, |
444 | .init_controls = sd_init_controls, | ||
486 | .start = sd_start, | 445 | .start = sd_start, |
487 | .stopN = sd_stopN, | 446 | .stopN = sd_stopN, |
488 | .pkt_scan = sd_pkt_scan, | 447 | .pkt_scan = sd_pkt_scan, |
@@ -513,6 +472,7 @@ static struct usb_driver sd_driver = { | |||
513 | #ifdef CONFIG_PM | 472 | #ifdef CONFIG_PM |
514 | .suspend = gspca_suspend, | 473 | .suspend = gspca_suspend, |
515 | .resume = gspca_resume, | 474 | .resume = gspca_resume, |
475 | .reset_resume = gspca_resume, | ||
516 | #endif | 476 | #endif |
517 | }; | 477 | }; |
518 | 478 | ||