94 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
96 #include <linux/input.h>
102 #define PAC7302_GAIN_DEFAULT 15
103 #define PAC7302_GAIN_KNEE 42
104 #define PAC7302_EXPOSURE_DEFAULT 66
105 #define PAC7302_EXPOSURE_KNEE 133
107 MODULE_AUTHOR(
"Jean-Francois Moine <http://moinejf.free.fr>, "
129 #define FL_HFLIP 0x01
130 #define FL_VFLIP 0x02
141 .sizeimage = 640 * 480 * 3 / 8 + 590,
146 #define LOAD_PAGE3 255
147 #define END_OF_SEQUENCE 0
149 static const u8 init_7302[] = {
156 static const u8 start_7302[] = {
159 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
160 0x00, 0x00, 0x00, 0x00,
161 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
162 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
163 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
167 0x3a, 3, 0x14, 0xff, 0x5a,
168 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
171 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
173 0x6e, 3, 0x08, 0x06, 0x00,
174 0x72, 3, 0x00, 0xff, 0x00,
175 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
176 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
177 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
178 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
183 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
185 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
189 0x12, 3, 0x02, 0x00, 0x01,
191 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
193 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
195 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
196 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
197 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
200 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
201 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
210 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
212 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
213 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
222 static const u8 page3_7302[] = {
223 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
224 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
225 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
227 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
228 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
229 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
230 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
232 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
233 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
237 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
238 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
239 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
255 usb_sndctrlpipe(gspca_dev->
dev, 0),
259 index, gspca_dev->
usb_buf, len,
262 pr_err(
"reg_w_buf failed i: %02x error %d\n",
269 static void reg_w(
struct gspca_dev *gspca_dev,
279 usb_sndctrlpipe(gspca_dev->
dev, 0),
282 0, index, gspca_dev->
usb_buf, 1,
285 pr_err(
"reg_w() failed i: %02x v: %02x error %d\n",
291 static void reg_w_seq(
struct gspca_dev *gspca_dev,
292 const u8 *seq,
int len)
295 reg_w(gspca_dev, seq[0], seq[1]);
301 static void reg_w_page(
struct gspca_dev *gspca_dev,
309 for (index = 0; index < len; index++) {
310 if (page[index] ==
SKIP)
314 usb_sndctrlpipe(gspca_dev->
dev, 0),
317 0, index, gspca_dev->
usb_buf, 1,
320 pr_err(
"reg_w_page() failed i: %02x v: %02x error %d\n",
321 index, page[index], ret);
329 static void reg_w_var(
struct gspca_dev *gspca_dev,
331 const u8 *page3,
unsigned int page3_len)
342 reg_w_page(gspca_dev, page3, page3_len);
348 "Incorrect variable sequence");
359 reg_w_buf(gspca_dev, index, seq, 8);
370 static int sd_config(
struct gspca_dev *gspca_dev,
373 struct sd *
sd = (
struct sd *) gspca_dev;
376 cam = &gspca_dev->
cam;
381 sd->
flags =
id->driver_info;
385 static void setbrightcont(
struct gspca_dev *gspca_dev)
387 struct sd *
sd = (
struct sd *) gspca_dev;
389 static const u8 max[10] =
390 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
393 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
396 reg_w(gspca_dev, 0xff, 0x00);
397 for (i = 0; i < 10; i++) {
406 reg_w(gspca_dev, 0xa2 + i, v);
408 reg_w(gspca_dev, 0xdc, 0x01);
411 static void setcolors(
struct gspca_dev *gspca_dev)
413 struct sd *sd = (
struct sd *) gspca_dev;
415 static const int a[9] =
416 {217, -212, 0, -101, 170, -67, -38, -315, 355};
417 static const int b[9] =
418 {19, 106, 0, 19, 106, 1, 19, 106, 1};
420 reg_w(gspca_dev, 0xff, 0x03);
421 reg_w(gspca_dev, 0x11, 0x01);
422 reg_w(gspca_dev, 0xff, 0x00);
423 for (i = 0; i < 9; i++) {
426 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
427 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
429 reg_w(gspca_dev, 0xdc, 0x01);
432 static void setwhitebalance(
struct gspca_dev *gspca_dev)
434 struct sd *sd = (
struct sd *) gspca_dev;
436 reg_w(gspca_dev, 0xff, 0x00);
439 reg_w(gspca_dev, 0xdc, 0x01);
442 static void setredbalance(
struct gspca_dev *gspca_dev)
444 struct sd *sd = (
struct sd *) gspca_dev;
446 reg_w(gspca_dev, 0xff, 0x00);
449 reg_w(gspca_dev, 0xdc, 0x01);
452 static void setbluebalance(
struct gspca_dev *gspca_dev)
454 struct sd *sd = (
struct sd *) gspca_dev;
456 reg_w(gspca_dev, 0xff, 0x00);
459 reg_w(gspca_dev, 0xdc, 0x01);
462 static void setgain(
struct gspca_dev *gspca_dev)
466 if (gspca_dev->
gain->val < 32) {
467 reg10 = gspca_dev->
gain->val;
471 reg12 = gspca_dev->
gain->val - 31;
474 reg_w(gspca_dev, 0xff, 0x03);
475 reg_w(gspca_dev, 0x10, reg10);
476 reg_w(gspca_dev, 0x12, reg12);
479 reg_w(gspca_dev, 0x11, 0x01);
482 static void setexposure(
struct gspca_dev *gspca_dev)
492 clockdiv = (90 * gspca_dev->
exposure->val + 1999) / 2000;
502 else if (clockdiv > 63)
510 if (clockdiv < 6 || clockdiv > 12)
511 clockdiv = ((clockdiv + 2) / 3) * 3;
517 exposure = (gspca_dev->
exposure->val * 45 * 448) / (1000 * clockdiv);
521 reg_w(gspca_dev, 0xff, 0x03);
522 reg_w(gspca_dev, 0x02, clockdiv);
523 reg_w(gspca_dev, 0x0e, exposure & 0xff);
524 reg_w(gspca_dev, 0x0f, exposure >> 8);
527 reg_w(gspca_dev, 0x11, 0x01);
530 static void sethvflip(
struct gspca_dev *gspca_dev)
532 struct sd *sd = (
struct sd *) gspca_dev;
535 hflip = sd->
hflip->val;
538 vflip = sd->
vflip->val;
542 reg_w(gspca_dev, 0xff, 0x03);
543 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
544 reg_w(gspca_dev, 0x21, data);
547 reg_w(gspca_dev, 0x11, 0x01);
550 static void setsharpness(
struct gspca_dev *gspca_dev)
552 struct sd *sd = (
struct sd *) gspca_dev;
554 reg_w(gspca_dev, 0xff, 0x00);
555 reg_w(gspca_dev, 0xb6, sd->
sharpness->val);
557 reg_w(gspca_dev, 0xdc, 0x01);
561 static int sd_init(
struct gspca_dev *gspca_dev)
563 reg_w_seq(gspca_dev, init_7302,
sizeof(init_7302)/2);
569 struct gspca_dev *gspca_dev =
571 struct sd *sd = (
struct sd *)gspca_dev;
590 setbrightcont(gspca_dev);
593 setcolors(gspca_dev);
596 setwhitebalance(gspca_dev);
599 setredbalance(gspca_dev);
602 setbluebalance(gspca_dev);
606 setexposure(gspca_dev);
611 sethvflip(gspca_dev);
614 setsharpness(gspca_dev);
627 static int sd_init_controls(
struct gspca_dev *gspca_dev)
629 struct sd *sd = (
struct sd *) gspca_dev;
632 gspca_dev->
vdev.ctrl_handler = hdl;
668 pr_err(
"Could not initialize controls\n");
679 static int sd_start(
struct gspca_dev *gspca_dev)
681 struct sd *sd = (
struct sd *) gspca_dev;
683 reg_w_var(gspca_dev, start_7302,
684 page3_7302,
sizeof(page3_7302));
691 reg_w(gspca_dev, 0xff, 0x01);
692 reg_w(gspca_dev, 0x78, 0x01);
697 static void sd_stopN(
struct gspca_dev *gspca_dev)
701 reg_w(gspca_dev, 0xff, 0x01);
702 reg_w(gspca_dev, 0x78, 0x00);
706 static void sd_stop0(
struct gspca_dev *gspca_dev)
710 reg_w(gspca_dev, 0xff, 0x01);
711 reg_w(gspca_dev, 0x78, 0x40);
714 static void do_autogain(
struct gspca_dev *gspca_dev)
716 struct sd *sd = (
struct sd *) gspca_dev;
719 const int deadzone = 30;
738 static const u8 jpeg_header[] = {
762 static void sd_pkt_scan(
struct gspca_dev *gspca_dev,
766 struct sd *sd = (
struct sd *) gspca_dev;
770 sof = pac_find_sof(&sd->
sof_read, data, len);
772 int n, lum_offset, footer_length;
780 lum_offset = 61 +
sizeof pac_sof_marker;
784 n = (sof -
data) - (footer_length +
sizeof pac_sof_marker);
792 image = gspca_dev->
image;
794 && image[gspca_dev->
image_len - 2] == 0xff
795 && image[gspca_dev->
image_len - 1] == 0xd9)
806 data[-lum_offset + 1]);
811 jpeg_header,
sizeof jpeg_header);
816 #ifdef CONFIG_VIDEO_ADV_DEBUG
817 static int sd_dbg_s_register(
struct gspca_dev *gspca_dev,
828 reg->
match.addr == 0 &&
829 (reg->
reg < 0x000000ff) &&
830 (reg->
val <= 0x000000ff)
842 reg_w(gspca_dev, 0xff, 0x00);
843 reg_w(gspca_dev, index, value);
845 reg_w(gspca_dev, 0xdc, 0x01);
850 static int sd_chip_ident(
struct gspca_dev *gspca_dev,
856 chip->
match.addr == 0) {
865 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
866 static int sd_int_pkt_scan(
struct gspca_dev *gspca_dev,
876 if ((data0 == 0x00 && data1 == 0x11) ||
877 (data0 == 0x22 && data1 == 0x33) ||
878 (data0 == 0x44 && data1 == 0x55) ||
879 (data0 == 0x66 && data1 == 0x77) ||
880 (data0 == 0x88 && data1 == 0x99) ||
881 (data0 == 0xaa && data1 == 0xbb) ||
882 (data0 == 0xcc && data1 == 0xdd) ||
883 (data0 == 0xee && data1 == 0xff)) {
884 input_report_key(gspca_dev->input_dev,
KEY_CAMERA, 1);
885 input_sync(gspca_dev->input_dev);
886 input_report_key(gspca_dev->input_dev,
KEY_CAMERA, 0);
887 input_sync(gspca_dev->input_dev);
898 .
name = KBUILD_MODNAME,
901 .init_controls = sd_init_controls,
905 .pkt_scan = sd_pkt_scan,
906 .dq_callback = do_autogain,
907 #ifdef CONFIG_VIDEO_ADV_DEBUG
908 .set_register = sd_dbg_s_register,
909 .get_chip_ident = sd_chip_ident,
911 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
912 .int_pkt_scan = sd_int_pkt_scan,
918 {USB_DEVICE(0x06f8, 0x3009)},
919 {USB_DEVICE(0x06f8, 0x301b)},
920 {USB_DEVICE(0x093a, 0x2620)},
921 {USB_DEVICE(0x093a, 0x2621)},
922 {USB_DEVICE(0x093a, 0x2622), .driver_info =
FL_VFLIP},
923 {USB_DEVICE(0x093a, 0x2624), .driver_info =
FL_VFLIP},
924 {USB_DEVICE(0x093a, 0x2625)},
925 {USB_DEVICE(0x093a, 0x2626)},
926 {USB_DEVICE(0x093a, 0x2627), .driver_info =
FL_VFLIP},
927 {USB_DEVICE(0x093a, 0x2628)},
928 {USB_DEVICE(0x093a, 0x2629), .driver_info =
FL_VFLIP},
929 {USB_DEVICE(0x093a, 0x262a)},
930 {USB_DEVICE(0x093a, 0x262c)},
931 {USB_DEVICE(0x145f, 0x013c)},
932 {USB_DEVICE(0x1ae7, 0x2001)},
945 static struct usb_driver sd_driver = {
946 .name = KBUILD_MODNAME,
947 .id_table = device_table,
951 .suspend = gspca_suspend,
952 .resume = gspca_resume,
953 .reset_resume = gspca_resume,