diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-04-27 10:40:28 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-07 15:13:50 -0400 |
commit | a5340ce50092e5458e1da489e06bc55398a76315 (patch) | |
tree | deb16ca6e733e6c3c11b0b04d519203d9da1c602 /drivers | |
parent | c894d26c5a89a241b10e2e8058ac12eb8f251252 (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.c | 240 |
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 | ||
54 | MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); | 56 | MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); |
55 | MODULE_DESCRIPTION("Pixart PAC7311"); | 57 | MODULE_DESCRIPTION("Pixart PAC7311"); |
56 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
57 | 59 | ||
60 | enum e_ctrl { | ||
61 | CONTRAST, | ||
62 | GAIN, | ||
63 | EXPOSURE, | ||
64 | AUTOGAIN, | ||
65 | HFLIP, | ||
66 | VFLIP, | ||
67 | NCTRLS /* number of controls */ | ||
68 | }; | ||
69 | |||
58 | struct sd { | 70 | struct 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 */ |
75 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 81 | static void setcontrast(struct gspca_dev *gspca_dev); |
76 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 82 | static void setgain(struct gspca_dev *gspca_dev); |
77 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 83 | static void setexposure(struct gspca_dev *gspca_dev); |
78 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 84 | static void setautogain(struct gspca_dev *gspca_dev); |
79 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | 85 | static void sethvflip(struct gspca_dev *gspca_dev); |
80 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | 86 | ||
88 | static const struct ctrl sd_ctrls[] = { | 87 | static 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 | ||
524 | static void do_autogain(struct gspca_dev *gspca_dev) | 503 | static 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 | ||
643 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | 622 | static 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 | |||
653 | static 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 | |||
661 | static 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 | |||
671 | static 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 | |||
679 | static 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 | |||
689 | static 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 | |||
697 | static 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 | |||
720 | static 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 | |||
728 | static 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 | |||
738 | static 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 | |||
746 | static 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 | |||
756 | static 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) |