aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-16 07:38:34 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 17:31:45 -0400
commit74dec797143ea2624f829758ef2fb92f7c470a2d (patch)
tree3f68e223b5a5d6fd5da3c0ea03cb2cf4cb0e5fd0
parentdf0df1accaf5a5a36901ad4019dd22b59ab8974d (diff)
[media] stk014: 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/stk014.c194
1 files changed, 76 insertions, 118 deletions
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 4ae7cc8f463a..247365c2a519 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -29,22 +29,11 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
29MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); 29MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31 31
32/* controls */
33enum e_ctrl {
34 BRIGHTNESS,
35 CONTRAST,
36 COLORS,
37 LIGHTFREQ,
38 NCTRLS /* number of controls */
39};
40
41/* specific webcam descriptor */ 32/* specific webcam descriptor */
42struct sd { 33struct sd {
43 struct gspca_dev gspca_dev; /* !! must be the first item */ 34 struct gspca_dev gspca_dev; /* !! must be the first item */
44 35
45 struct gspca_ctrl ctrls[NCTRLS]; 36 struct v4l2_ctrl *jpegqual;
46
47 u8 quality;
48#define QUALITY_MIN 70 37#define QUALITY_MIN 70
49#define QUALITY_MAX 95 38#define QUALITY_MAX 95
50#define QUALITY_DEF 88 39#define QUALITY_DEF 88
@@ -52,63 +41,6 @@ struct sd {
52 u8 jpeg_hdr[JPEG_HDR_SZ]; 41 u8 jpeg_hdr[JPEG_HDR_SZ];
53}; 42};
54 43
55/* V4L2 controls supported by the driver */
56static void setbrightness(struct gspca_dev *gspca_dev);
57static void setcontrast(struct gspca_dev *gspca_dev);
58static void setcolors(struct gspca_dev *gspca_dev);
59static void setlightfreq(struct gspca_dev *gspca_dev);
60
61static const struct ctrl sd_ctrls[NCTRLS] = {
62[BRIGHTNESS] = {
63 {
64 .id = V4L2_CID_BRIGHTNESS,
65 .type = V4L2_CTRL_TYPE_INTEGER,
66 .name = "Brightness",
67 .minimum = 0,
68 .maximum = 255,
69 .step = 1,
70 .default_value = 127,
71 },
72 .set_control = setbrightness
73 },
74[CONTRAST] = {
75 {
76 .id = V4L2_CID_CONTRAST,
77 .type = V4L2_CTRL_TYPE_INTEGER,
78 .name = "Contrast",
79 .minimum = 0,
80 .maximum = 255,
81 .step = 1,
82 .default_value = 127,
83 },
84 .set_control = setcontrast
85 },
86[COLORS] = {
87 {
88 .id = V4L2_CID_SATURATION,
89 .type = V4L2_CTRL_TYPE_INTEGER,
90 .name = "Color",
91 .minimum = 0,
92 .maximum = 255,
93 .step = 1,
94 .default_value = 127,
95 },
96 .set_control = setcolors
97 },
98[LIGHTFREQ] = {
99 {
100 .id = V4L2_CID_POWER_LINE_FREQUENCY,
101 .type = V4L2_CTRL_TYPE_MENU,
102 .name = "Light frequency filter",
103 .minimum = 1,
104 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
105 .step = 1,
106 .default_value = 1,
107 },
108 .set_control = setlightfreq
109 },
110};
111
112static const struct v4l2_pix_format vga_mode[] = { 44static const struct v4l2_pix_format vga_mode[] = {
113 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 45 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
114 .bytesperline = 320, 46 .bytesperline = 320,
@@ -255,41 +187,36 @@ static void set_par(struct gspca_dev *gspca_dev,
255 snd_val(gspca_dev, 0x003f08, parval); 187 snd_val(gspca_dev, 0x003f08, parval);
256} 188}
257 189
258static void setbrightness(struct gspca_dev *gspca_dev) 190static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
259{ 191{
260 struct sd *sd = (struct sd *) gspca_dev;
261 int parval; 192 int parval;
262 193
263 parval = 0x06000000 /* whiteness */ 194 parval = 0x06000000 /* whiteness */
264 + (sd->ctrls[BRIGHTNESS].val << 16); 195 + (val << 16);
265 set_par(gspca_dev, parval); 196 set_par(gspca_dev, parval);
266} 197}
267 198
268static void setcontrast(struct gspca_dev *gspca_dev) 199static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
269{ 200{
270 struct sd *sd = (struct sd *) gspca_dev;
271 int parval; 201 int parval;
272 202
273 parval = 0x07000000 /* contrast */ 203 parval = 0x07000000 /* contrast */
274 + (sd->ctrls[CONTRAST].val << 16); 204 + (val << 16);
275 set_par(gspca_dev, parval); 205 set_par(gspca_dev, parval);
276} 206}
277 207
278static void setcolors(struct gspca_dev *gspca_dev) 208static void setcolors(struct gspca_dev *gspca_dev, s32 val)
279{ 209{
280 struct sd *sd = (struct sd *) gspca_dev;
281 int parval; 210 int parval;
282 211
283 parval = 0x08000000 /* saturation */ 212 parval = 0x08000000 /* saturation */
284 + (sd->ctrls[COLORS].val << 16); 213 + (val << 16);
285 set_par(gspca_dev, parval); 214 set_par(gspca_dev, parval);
286} 215}
287 216
288static void setlightfreq(struct gspca_dev *gspca_dev) 217static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
289{ 218{
290 struct sd *sd = (struct sd *) gspca_dev; 219 set_par(gspca_dev, val == 1
291
292 set_par(gspca_dev, sd->ctrls[LIGHTFREQ].val == 1
293 ? 0x33640000 /* 50 Hz */ 220 ? 0x33640000 /* 50 Hz */
294 : 0x33780000); /* 60 Hz */ 221 : 0x33780000); /* 60 Hz */
295} 222}
@@ -298,12 +225,8 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
298static int sd_config(struct gspca_dev *gspca_dev, 225static int sd_config(struct gspca_dev *gspca_dev,
299 const struct usb_device_id *id) 226 const struct usb_device_id *id)
300{ 227{
301 struct sd *sd = (struct sd *) gspca_dev;
302
303 gspca_dev->cam.cam_mode = vga_mode; 228 gspca_dev->cam.cam_mode = vga_mode;
304 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); 229 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
305 gspca_dev->cam.ctrls = sd->ctrls;
306 sd->quality = QUALITY_DEF;
307 return 0; 230 return 0;
308} 231}
309 232
@@ -333,7 +256,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
333 /* create the JPEG header */ 256 /* create the JPEG header */
334 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 257 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
335 0x22); /* JPEG 411 */ 258 0x22); /* JPEG 411 */
336 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
337 259
338 /* work on alternate 1 */ 260 /* work on alternate 1 */
339 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); 261 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
@@ -365,14 +287,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
365 reg_w(gspca_dev, 0x0640, 0); 287 reg_w(gspca_dev, 0x0640, 0);
366 reg_w(gspca_dev, 0x0650, 0); 288 reg_w(gspca_dev, 0x0650, 0);
367 reg_w(gspca_dev, 0x0660, 0); 289 reg_w(gspca_dev, 0x0660, 0);
368 setbrightness(gspca_dev); /* whiteness */ 290 v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler);
369 setcontrast(gspca_dev); /* contrast */
370 setcolors(gspca_dev); /* saturation */
371 set_par(gspca_dev, 0x09800000); /* Red ? */ 291 set_par(gspca_dev, 0x09800000); /* Red ? */
372 set_par(gspca_dev, 0x0a800000); /* Green ? */ 292 set_par(gspca_dev, 0x0a800000); /* Green ? */
373 set_par(gspca_dev, 0x0b800000); /* Blue ? */ 293 set_par(gspca_dev, 0x0b800000); /* Blue ? */
374 set_par(gspca_dev, 0x0d030000); /* Gamma ? */ 294 set_par(gspca_dev, 0x0d030000); /* Gamma ? */
375 setlightfreq(gspca_dev);
376 295
377 /* start the video flow */ 296 /* start the video flow */
378 set_par(gspca_dev, 0x01000000); 297 set_par(gspca_dev, 0x01000000);
@@ -435,34 +354,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
435 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 354 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
436} 355}
437 356
438static int sd_querymenu(struct gspca_dev *gspca_dev,
439 struct v4l2_querymenu *menu)
440{
441 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
442
443 switch (menu->id) {
444 case V4L2_CID_POWER_LINE_FREQUENCY:
445 if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
446 break;
447 strcpy((char *) menu->name, freq_nm[menu->index]);
448 return 0;
449 }
450 return -EINVAL;
451}
452
453static int sd_set_jcomp(struct gspca_dev *gspca_dev, 357static int sd_set_jcomp(struct gspca_dev *gspca_dev,
454 struct v4l2_jpegcompression *jcomp) 358 struct v4l2_jpegcompression *jcomp)
455{ 359{
456 struct sd *sd = (struct sd *) gspca_dev; 360 struct sd *sd = (struct sd *) gspca_dev;
457 361
458 if (jcomp->quality < QUALITY_MIN) 362 v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
459 sd->quality = QUALITY_MIN;
460 else if (jcomp->quality > QUALITY_MAX)
461 sd->quality = QUALITY_MAX;
462 else
463 sd->quality = jcomp->quality;
464 if (gspca_dev->streaming)
465 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
466 return gspca_dev->usb_err; 363 return gspca_dev->usb_err;
467} 364}
468 365
@@ -472,23 +369,84 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
472 struct sd *sd = (struct sd *) gspca_dev; 369 struct sd *sd = (struct sd *) gspca_dev;
473 370
474 memset(jcomp, 0, sizeof *jcomp); 371 memset(jcomp, 0, sizeof *jcomp);
475 jcomp->quality = sd->quality; 372 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
476 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 373 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
477 | V4L2_JPEG_MARKER_DQT; 374 | V4L2_JPEG_MARKER_DQT;
478 return 0; 375 return 0;
479} 376}
480 377
378static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
379{
380 struct gspca_dev *gspca_dev =
381 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
382 struct sd *sd = (struct sd *)gspca_dev;
383
384 gspca_dev->usb_err = 0;
385
386 if (!gspca_dev->streaming)
387 return 0;
388
389 switch (ctrl->id) {
390 case V4L2_CID_BRIGHTNESS:
391 setbrightness(gspca_dev, ctrl->val);
392 break;
393 case V4L2_CID_CONTRAST:
394 setcontrast(gspca_dev, ctrl->val);
395 break;
396 case V4L2_CID_SATURATION:
397 setcolors(gspca_dev, ctrl->val);
398 break;
399 case V4L2_CID_POWER_LINE_FREQUENCY:
400 setlightfreq(gspca_dev, ctrl->val);
401 break;
402 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
403 jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
404 break;
405 }
406 return gspca_dev->usb_err;
407}
408
409static const struct v4l2_ctrl_ops sd_ctrl_ops = {
410 .s_ctrl = sd_s_ctrl,
411};
412
413static int sd_init_controls(struct gspca_dev *gspca_dev)
414{
415 struct sd *sd = (struct sd *)gspca_dev;
416 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
417
418 gspca_dev->vdev.ctrl_handler = hdl;
419 v4l2_ctrl_handler_init(hdl, 5);
420 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
421 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
422 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
423 V4L2_CID_CONTRAST, 0, 255, 1, 127);
424 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
425 V4L2_CID_SATURATION, 0, 255, 1, 127);
426 v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
427 V4L2_CID_POWER_LINE_FREQUENCY,
428 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
429 V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
430 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
431 V4L2_CID_JPEG_COMPRESSION_QUALITY,
432 QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
433
434 if (hdl->error) {
435 pr_err("Could not initialize controls\n");
436 return hdl->error;
437 }
438 return 0;
439}
440
481/* sub-driver description */ 441/* sub-driver description */
482static const struct sd_desc sd_desc = { 442static const struct sd_desc sd_desc = {
483 .name = MODULE_NAME, 443 .name = MODULE_NAME,
484 .ctrls = sd_ctrls,
485 .nctrls = NCTRLS,
486 .config = sd_config, 444 .config = sd_config,
487 .init = sd_init, 445 .init = sd_init,
446 .init_controls = sd_init_controls,
488 .start = sd_start, 447 .start = sd_start,
489 .stopN = sd_stopN, 448 .stopN = sd_stopN,
490 .pkt_scan = sd_pkt_scan, 449 .pkt_scan = sd_pkt_scan,
491 .querymenu = sd_querymenu,
492 .get_jcomp = sd_get_jcomp, 450 .get_jcomp = sd_get_jcomp,
493 .set_jcomp = sd_set_jcomp, 451 .set_jcomp = sd_set_jcomp,
494}; 452};