aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-04-27 10:40:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-07 15:13:50 -0400
commita5340ce50092e5458e1da489e06bc55398a76315 (patch)
treedeb16ca6e733e6c3c11b0b04d519203d9da1c602 /drivers
parentc894d26c5a89a241b10e2e8058ac12eb8f251252 (diff)
[media] gspca_pac7311: Switch to new gspca control mechanism
Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/pac7311.c240
1 files changed, 57 insertions, 183 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 4efa110e6932..d4c6ad2f1156 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -50,20 +50,26 @@
50 50
51#include <linux/input.h> 51#include <linux/input.h>
52#include "gspca.h" 52#include "gspca.h"
53/* Include pac common sof detection functions */
54#include "pac_common.h"
53 55
54MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 56MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
55MODULE_DESCRIPTION("Pixart PAC7311"); 57MODULE_DESCRIPTION("Pixart PAC7311");
56MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
57 59
60enum e_ctrl {
61 CONTRAST,
62 GAIN,
63 EXPOSURE,
64 AUTOGAIN,
65 HFLIP,
66 VFLIP,
67 NCTRLS /* number of controls */
68};
69
58struct sd { 70struct sd {
59 struct gspca_dev gspca_dev; /* !! must be the first item */ 71 struct gspca_dev gspca_dev; /* !! must be the first item */
60 72 struct gspca_ctrl ctrls[NCTRLS];
61 unsigned char contrast;
62 unsigned char gain;
63 unsigned char exposure;
64 unsigned char autogain;
65 __u8 hflip;
66 __u8 vflip;
67 73
68 u8 sof_read; 74 u8 sof_read;
69 u8 autogain_ignore_frames; 75 u8 autogain_ignore_frames;
@@ -72,68 +78,52 @@ struct sd {
72}; 78};
73 79
74/* V4L2 controls supported by the driver */ 80/* V4L2 controls supported by the driver */
75static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 81static void setcontrast(struct gspca_dev *gspca_dev);
76static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 82static void setgain(struct gspca_dev *gspca_dev);
77static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 83static void setexposure(struct gspca_dev *gspca_dev);
78static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 84static void setautogain(struct gspca_dev *gspca_dev);
79static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 85static void sethvflip(struct gspca_dev *gspca_dev);
80static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
87 86
88static const struct ctrl sd_ctrls[] = { 87static const struct ctrl sd_ctrls[] = {
89 { 88[CONTRAST] = {
90 { 89 {
91 .id = V4L2_CID_CONTRAST, 90 .id = V4L2_CID_CONTRAST,
92 .type = V4L2_CTRL_TYPE_INTEGER, 91 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Contrast", 92 .name = "Contrast",
94 .minimum = 0, 93 .minimum = 0,
95#define CONTRAST_MAX 15 94 .maximum = 15,
96 .maximum = CONTRAST_MAX,
97 .step = 1, 95 .step = 1,
98#define CONTRAST_DEF 7 96 .default_value = 7,
99 .default_value = CONTRAST_DEF,
100 }, 97 },
101 .set = sd_setcontrast, 98 .set_control = setcontrast
102 .get = sd_getcontrast,
103 }, 99 },
104 { 100[GAIN] = {
105 { 101 {
106 .id = V4L2_CID_GAIN, 102 .id = V4L2_CID_GAIN,
107 .type = V4L2_CTRL_TYPE_INTEGER, 103 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Gain", 104 .name = "Gain",
109 .minimum = 0, 105 .minimum = 0,
110#define GAIN_MAX 244 106 .maximum = 244,
111 .maximum = GAIN_MAX,
112 .step = 1, 107 .step = 1,
113#define GAIN_DEF 122 108 .default_value = 122,
114#define GAIN_KNEE GAIN_MAX /* Gain seems to cause little noise on the 7311 */ 109#define GAIN_KNEE 244 /* Gain seems to cause little noise on the 7311 */
115 .default_value = GAIN_DEF,
116 }, 110 },
117 .set = sd_setgain, 111 .set_control = setgain,
118 .get = sd_getgain,
119 }, 112 },
120 { 113[EXPOSURE] = {
121 { 114 {
122 .id = V4L2_CID_EXPOSURE, 115 .id = V4L2_CID_EXPOSURE,
123 .type = V4L2_CTRL_TYPE_INTEGER, 116 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Exposure", 117 .name = "Exposure",
125 .minimum = 2, 118 .minimum = 2,
126#define EXPOSURE_MAX 63 119 .maximum = 63,
127 .maximum = EXPOSURE_MAX,
128 .step = 1, 120 .step = 1,
129#define EXPOSURE_DEF 2 /* 30 fps */ 121 .default_value = 2, /* 30 fps */
130#define EXPOSURE_KNEE 6 /* 10 fps */ 122#define EXPOSURE_KNEE 6 /* 10 fps */
131 .default_value = EXPOSURE_DEF,
132 }, 123 },
133 .set = sd_setexposure, 124 .set_control = setexposure,
134 .get = sd_getexposure,
135 }, 125 },
136 { 126[AUTOGAIN] = {
137 { 127 {
138 .id = V4L2_CID_AUTOGAIN, 128 .id = V4L2_CID_AUTOGAIN,
139 .type = V4L2_CTRL_TYPE_BOOLEAN, 129 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -141,13 +131,11 @@ static const struct ctrl sd_ctrls[] = {
141 .minimum = 0, 131 .minimum = 0,
142 .maximum = 1, 132 .maximum = 1,
143 .step = 1, 133 .step = 1,
144#define AUTOGAIN_DEF 1 134 .default_value = 1,
145 .default_value = AUTOGAIN_DEF,
146 }, 135 },
147 .set = sd_setautogain, 136 .set_control = setautogain,
148 .get = sd_getautogain,
149 }, 137 },
150 { 138[HFLIP] = {
151 { 139 {
152 .id = V4L2_CID_HFLIP, 140 .id = V4L2_CID_HFLIP,
153 .type = V4L2_CTRL_TYPE_BOOLEAN, 141 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -155,13 +143,11 @@ static const struct ctrl sd_ctrls[] = {
155 .minimum = 0, 143 .minimum = 0,
156 .maximum = 1, 144 .maximum = 1,
157 .step = 1, 145 .step = 1,
158#define HFLIP_DEF 0 146 .default_value = 0,
159 .default_value = HFLIP_DEF,
160 }, 147 },
161 .set = sd_sethflip, 148 .set_control = sethvflip,
162 .get = sd_gethflip,
163 }, 149 },
164 { 150[VFLIP] = {
165 { 151 {
166 .id = V4L2_CID_VFLIP, 152 .id = V4L2_CID_VFLIP,
167 .type = V4L2_CTRL_TYPE_BOOLEAN, 153 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -169,11 +155,9 @@ static const struct ctrl sd_ctrls[] = {
169 .minimum = 0, 155 .minimum = 0,
170 .maximum = 1, 156 .maximum = 1,
171 .step = 1, 157 .step = 1,
172#define VFLIP_DEF 0 158 .default_value = 0,
173 .default_value = VFLIP_DEF,
174 }, 159 },
175 .set = sd_setvflip, 160 .set_control = sethvflip,
176 .get = sd_getvflip,
177 }, 161 },
178}; 162};
179 163
@@ -379,19 +363,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
379 const struct usb_device_id *id) 363 const struct usb_device_id *id)
380{ 364{
381 struct sd *sd = (struct sd *) gspca_dev; 365 struct sd *sd = (struct sd *) gspca_dev;
382 struct cam *cam; 366 struct cam *cam = &gspca_dev->cam;
383
384 cam = &gspca_dev->cam;
385 367
386 cam->cam_mode = vga_mode; 368 cam->cam_mode = vga_mode;
387 cam->nmodes = ARRAY_SIZE(vga_mode); 369 cam->nmodes = ARRAY_SIZE(vga_mode);
388 370
389 sd->contrast = CONTRAST_DEF; 371 gspca_dev->cam.ctrls = sd->ctrls;
390 sd->gain = GAIN_DEF; 372
391 sd->exposure = EXPOSURE_DEF;
392 sd->autogain = AUTOGAIN_DEF;
393 sd->hflip = HFLIP_DEF;
394 sd->vflip = VFLIP_DEF;
395 return 0; 373 return 0;
396} 374}
397 375
@@ -400,7 +378,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
400 struct sd *sd = (struct sd *) gspca_dev; 378 struct sd *sd = (struct sd *) gspca_dev;
401 379
402 reg_w(gspca_dev, 0xff, 0x04); 380 reg_w(gspca_dev, 0xff, 0x04);
403 reg_w(gspca_dev, 0x10, sd->contrast); 381 reg_w(gspca_dev, 0x10, sd->ctrls[CONTRAST].val);
404 /* load registers to sensor (Bit 0, auto clear) */ 382 /* load registers to sensor (Bit 0, auto clear) */
405 reg_w(gspca_dev, 0x11, 0x01); 383 reg_w(gspca_dev, 0x11, 0x01);
406} 384}
@@ -411,7 +389,7 @@ static void setgain(struct gspca_dev *gspca_dev)
411 389
412 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 390 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
413 reg_w(gspca_dev, 0x0e, 0x00); 391 reg_w(gspca_dev, 0x0e, 0x00);
414 reg_w(gspca_dev, 0x0f, GAIN_MAX - sd->gain + 1); 392 reg_w(gspca_dev, 0x0f, sd->ctrls[GAIN].max - sd->ctrls[GAIN].val + 1);
415 393
416 /* load registers to sensor (Bit 0, auto clear) */ 394 /* load registers to sensor (Bit 0, auto clear) */
417 reg_w(gspca_dev, 0x11, 0x01); 395 reg_w(gspca_dev, 0x11, 0x01);
@@ -422,7 +400,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
422 struct sd *sd = (struct sd *) gspca_dev; 400 struct sd *sd = (struct sd *) gspca_dev;
423 401
424 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 402 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
425 reg_w(gspca_dev, 0x02, sd->exposure); 403 reg_w(gspca_dev, 0x02, sd->ctrls[EXPOSURE].val);
426 404
427 /* load registers to sensor (Bit 0, auto clear) */ 405 /* load registers to sensor (Bit 0, auto clear) */
428 reg_w(gspca_dev, 0x11, 0x01); 406 reg_w(gspca_dev, 0x11, 0x01);
@@ -431,7 +409,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
431 640x480 mode and page 4 reg 2 <= 3 then it must be 9 */ 409 640x480 mode and page 4 reg 2 <= 3 then it must be 9 */
432 reg_w(gspca_dev, 0xff, 0x01); 410 reg_w(gspca_dev, 0xff, 0x01);
433 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && 411 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
434 sd->exposure <= 3) { 412 sd->ctrls[EXPOSURE].val <= 3) {
435 reg_w(gspca_dev, 0x08, 0x09); 413 reg_w(gspca_dev, 0x08, 0x09);
436 } else { 414 } else {
437 reg_w(gspca_dev, 0x08, 0x08); 415 reg_w(gspca_dev, 0x08, 0x08);
@@ -447,7 +425,8 @@ static void sethvflip(struct gspca_dev *gspca_dev)
447 __u8 data; 425 __u8 data;
448 426
449 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 427 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
450 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); 428 data = (sd->ctrls[HFLIP].val ? 0x04 : 0x00) |
429 (sd->ctrls[VFLIP].val ? 0x08 : 0x00);
451 reg_w(gspca_dev, 0x21, data); 430 reg_w(gspca_dev, 0x21, data);
452 431
453 /* load registers to sensor (Bit 0, auto clear) */ 432 /* load registers to sensor (Bit 0, auto clear) */
@@ -518,8 +497,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
518 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ 497 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
519} 498}
520 499
521/* Include pac common sof detection functions */ 500#define WANT_REGULAR_AUTOGAIN
522#include "pac_common.h" 501#include "autogain_functions.h"
523 502
524static void do_autogain(struct gspca_dev *gspca_dev) 503static void do_autogain(struct gspca_dev *gspca_dev)
525{ 504{
@@ -527,7 +506,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
527 int avg_lum = atomic_read(&sd->avg_lum); 506 int avg_lum = atomic_read(&sd->avg_lum);
528 int desired_lum, deadzone; 507 int desired_lum, deadzone;
529 508
530 if (avg_lum == -1) 509 if (sd->ctrls[AUTOGAIN].val == 0 || avg_lum == -1)
531 return; 510 return;
532 511
533 desired_lum = 200; 512 desired_lum = 200;
@@ -535,7 +514,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
535 514
536 if (sd->autogain_ignore_frames > 0) 515 if (sd->autogain_ignore_frames > 0)
537 sd->autogain_ignore_frames--; 516 sd->autogain_ignore_frames--;
538 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 517 else if (auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
539 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) 518 deadzone, GAIN_KNEE, EXPOSURE_KNEE))
540 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 519 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
541} 520}
@@ -640,72 +619,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
640 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 619 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
641} 620}
642 621
643static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 622static void setautogain(struct gspca_dev *gspca_dev)
644{
645 struct sd *sd = (struct sd *) gspca_dev;
646
647 sd->contrast = val;
648 if (gspca_dev->streaming)
649 setcontrast(gspca_dev);
650 return gspca_dev->usb_err;
651}
652
653static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
654{
655 struct sd *sd = (struct sd *) gspca_dev;
656
657 *val = sd->contrast;
658 return 0;
659}
660
661static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
662{
663 struct sd *sd = (struct sd *) gspca_dev;
664
665 sd->gain = val;
666 if (gspca_dev->streaming)
667 setgain(gspca_dev);
668 return gspca_dev->usb_err;
669}
670
671static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
672{
673 struct sd *sd = (struct sd *) gspca_dev;
674
675 *val = sd->gain;
676 return 0;
677}
678
679static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
680{
681 struct sd *sd = (struct sd *) gspca_dev;
682
683 sd->exposure = val;
684 if (gspca_dev->streaming)
685 setexposure(gspca_dev);
686 return gspca_dev->usb_err;
687}
688
689static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
690{ 623{
691 struct sd *sd = (struct sd *) gspca_dev; 624 struct sd *sd = (struct sd *) gspca_dev;
692 625
693 *val = sd->exposure; 626 if (sd->ctrls[AUTOGAIN].val) {
694 return 0; 627 sd->ctrls[EXPOSURE].val = 2;
695} 628 sd->ctrls[GAIN].val = 122;
696
697static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
698{
699 struct sd *sd = (struct sd *) gspca_dev;
700
701 sd->autogain = val;
702 /* when switching to autogain set defaults to make sure
703 we are on a valid point of the autogain gain /
704 exposure knee graph, and give this change time to
705 take effect before doing autogain. */
706 if (sd->autogain) {
707 sd->exposure = EXPOSURE_DEF;
708 sd->gain = GAIN_DEF;
709 if (gspca_dev->streaming) { 629 if (gspca_dev->streaming) {
710 sd->autogain_ignore_frames = 630 sd->autogain_ignore_frames =
711 PAC_AUTOGAIN_IGNORE_FRAMES; 631 PAC_AUTOGAIN_IGNORE_FRAMES;
@@ -713,52 +633,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
713 setgain(gspca_dev); 633 setgain(gspca_dev);
714 } 634 }
715 } 635 }
716
717 return gspca_dev->usb_err;
718}
719
720static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
721{
722 struct sd *sd = (struct sd *) gspca_dev;
723
724 *val = sd->autogain;
725 return 0;
726}
727
728static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
729{
730 struct sd *sd = (struct sd *) gspca_dev;
731
732 sd->hflip = val;
733 if (gspca_dev->streaming)
734 sethvflip(gspca_dev);
735 return gspca_dev->usb_err;
736}
737
738static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
739{
740 struct sd *sd = (struct sd *) gspca_dev;
741
742 *val = sd->hflip;
743 return 0;
744}
745
746static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
747{
748 struct sd *sd = (struct sd *) gspca_dev;
749
750 sd->vflip = val;
751 if (gspca_dev->streaming)
752 sethvflip(gspca_dev);
753 return gspca_dev->usb_err;
754}
755
756static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
757{
758 struct sd *sd = (struct sd *) gspca_dev;
759
760 *val = sd->vflip;
761 return 0;
762} 636}
763 637
764#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 638#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)