aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/se401.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/se401.c')
-rw-r--r--drivers/media/video/gspca/se401.c774
1 files changed, 774 insertions, 0 deletions
diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c
new file mode 100644
index 00000000000..4c283c24c75
--- /dev/null
+++ b/drivers/media/video/gspca/se401.c
@@ -0,0 +1,774 @@
1/*
2 * GSPCA Endpoints (formerly known as AOX) se401 USB Camera sub Driver
3 *
4 * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
5 *
6 * Based on the v4l1 se401 driver which is:
7 *
8 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#define MODULE_NAME "se401"
27
28#define BULK_SIZE 4096
29#define PACKET_SIZE 1024
30#define READ_REQ_SIZE 64
31#define MAX_MODES ((READ_REQ_SIZE - 6) / 4)
32/* The se401 compression algorithm uses a fixed quant factor, which
33 can be configured by setting the high nibble of the SE401_OPERATINGMODE
34 feature. This needs to exactly match what is in libv4l! */
35#define SE401_QUANT_FACT 8
36
37#include <linux/input.h>
38#include <linux/slab.h>
39#include "gspca.h"
40#include "se401.h"
41
42MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
43MODULE_DESCRIPTION("Endpoints se401");
44MODULE_LICENSE("GPL");
45
46/* controls */
47enum e_ctrl {
48 BRIGHTNESS,
49 GAIN,
50 EXPOSURE,
51 FREQ,
52 NCTRL /* number of controls */
53};
54
55/* exposure change state machine states */
56enum {
57 EXPO_CHANGED,
58 EXPO_DROP_FRAME,
59 EXPO_NO_CHANGE,
60};
61
62/* specific webcam descriptor */
63struct sd {
64 struct gspca_dev gspca_dev; /* !! must be the first item */
65 struct gspca_ctrl ctrls[NCTRL];
66 struct v4l2_pix_format fmts[MAX_MODES];
67 int pixels_read;
68 int packet_read;
69 u8 packet[PACKET_SIZE];
70 u8 restart_stream;
71 u8 button_state;
72 u8 resetlevel;
73 u8 resetlevel_frame_count;
74 int resetlevel_adjust_dir;
75 int expo_change_state;
76};
77
78static void setbrightness(struct gspca_dev *gspca_dev);
79static void setgain(struct gspca_dev *gspca_dev);
80static void setexposure(struct gspca_dev *gspca_dev);
81
82static const struct ctrl sd_ctrls[NCTRL] = {
83[BRIGHTNESS] = {
84 {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "Brightness",
88 .minimum = 0,
89 .maximum = 255,
90 .step = 1,
91 .default_value = 15,
92 },
93 .set_control = setbrightness
94 },
95[GAIN] = {
96 {
97 .id = V4L2_CID_GAIN,
98 .type = V4L2_CTRL_TYPE_INTEGER,
99 .name = "Gain",
100 .minimum = 0,
101 .maximum = 50, /* Really 63 but > 50 is not pretty */
102 .step = 1,
103 .default_value = 25,
104 },
105 .set_control = setgain
106 },
107[EXPOSURE] = {
108 {
109 .id = V4L2_CID_EXPOSURE,
110 .type = V4L2_CTRL_TYPE_INTEGER,
111 .name = "Exposure",
112 .minimum = 0,
113 .maximum = 32767,
114 .step = 1,
115 .default_value = 15000,
116 },
117 .set_control = setexposure
118 },
119[FREQ] = {
120 {
121 .id = V4L2_CID_POWER_LINE_FREQUENCY,
122 .type = V4L2_CTRL_TYPE_MENU,
123 .name = "Light frequency filter",
124 .minimum = 0,
125 .maximum = 2,
126 .step = 1,
127 .default_value = 0,
128 },
129 .set_control = setexposure
130 },
131};
132
133static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value,
134 int silent)
135{
136 int err;
137
138 if (gspca_dev->usb_err < 0)
139 return;
140
141 err = usb_control_msg(gspca_dev->dev,
142 usb_sndctrlpipe(gspca_dev->dev, 0), req,
143 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
144 value, 0, NULL, 0, 1000);
145 if (err < 0) {
146 if (!silent)
147 err("write req failed req %#04x val %#04x error %d",
148 req, value, err);
149 gspca_dev->usb_err = err;
150 }
151}
152
153static void se401_read_req(struct gspca_dev *gspca_dev, u16 req, int silent)
154{
155 int err;
156
157 if (gspca_dev->usb_err < 0)
158 return;
159
160 if (USB_BUF_SZ < READ_REQ_SIZE) {
161 err("USB_BUF_SZ too small!!");
162 gspca_dev->usb_err = -ENOBUFS;
163 return;
164 }
165
166 err = usb_control_msg(gspca_dev->dev,
167 usb_rcvctrlpipe(gspca_dev->dev, 0), req,
168 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
169 0, 0, gspca_dev->usb_buf, READ_REQ_SIZE, 1000);
170 if (err < 0) {
171 if (!silent)
172 err("read req failed req %#04x error %d", req, err);
173 gspca_dev->usb_err = err;
174 }
175}
176
177static void se401_set_feature(struct gspca_dev *gspca_dev,
178 u16 selector, u16 param)
179{
180 int err;
181
182 if (gspca_dev->usb_err < 0)
183 return;
184
185 err = usb_control_msg(gspca_dev->dev,
186 usb_sndctrlpipe(gspca_dev->dev, 0),
187 SE401_REQ_SET_EXT_FEATURE,
188 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
189 param, selector, NULL, 0, 1000);
190 if (err < 0) {
191 err("set feature failed sel %#04x param %#04x error %d",
192 selector, param, err);
193 gspca_dev->usb_err = err;
194 }
195}
196
197static int se401_get_feature(struct gspca_dev *gspca_dev, u16 selector)
198{
199 int err;
200
201 if (gspca_dev->usb_err < 0)
202 return gspca_dev->usb_err;
203
204 if (USB_BUF_SZ < 2) {
205 err("USB_BUF_SZ too small!!");
206 gspca_dev->usb_err = -ENOBUFS;
207 return gspca_dev->usb_err;
208 }
209
210 err = usb_control_msg(gspca_dev->dev,
211 usb_rcvctrlpipe(gspca_dev->dev, 0),
212 SE401_REQ_GET_EXT_FEATURE,
213 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
214 0, selector, gspca_dev->usb_buf, 2, 1000);
215 if (err < 0) {
216 err("get feature failed sel %#04x error %d", selector, err);
217 gspca_dev->usb_err = err;
218 return err;
219 }
220 return gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
221}
222
223static void setbrightness(struct gspca_dev *gspca_dev)
224{
225 struct sd *sd = (struct sd *) gspca_dev;
226
227 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS))
228 return;
229
230 /* HDG: this does not seem to do anything on my cam */
231 se401_write_req(gspca_dev, SE401_REQ_SET_BRT,
232 sd->ctrls[BRIGHTNESS].val, 0);
233}
234
235static void setgain(struct gspca_dev *gspca_dev)
236{
237 struct sd *sd = (struct sd *) gspca_dev;
238 u16 gain = 63 - sd->ctrls[GAIN].val;
239
240 /* red color gain */
241 se401_set_feature(gspca_dev, HV7131_REG_ARCG, gain);
242 /* green color gain */
243 se401_set_feature(gspca_dev, HV7131_REG_AGCG, gain);
244 /* blue color gain */
245 se401_set_feature(gspca_dev, HV7131_REG_ABCG, gain);
246}
247
248static void setexposure(struct gspca_dev *gspca_dev)
249{
250 struct sd *sd = (struct sd *) gspca_dev;
251 int integration = sd->ctrls[EXPOSURE].val << 6;
252 u8 expose_h, expose_m, expose_l;
253
254 /* Do this before the set_feature calls, for proper timing wrt
255 the interrupt driven pkt_scan. Note we may still race but that
256 is not a big issue, the expo change state machine is merely for
257 avoiding underexposed frames getting send out, if one sneaks
258 through so be it */
259 sd->expo_change_state = EXPO_CHANGED;
260
261 if (sd->ctrls[FREQ].val == V4L2_CID_POWER_LINE_FREQUENCY_50HZ)
262 integration = integration - integration % 106667;
263 if (sd->ctrls[FREQ].val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ)
264 integration = integration - integration % 88889;
265
266 expose_h = (integration >> 16);
267 expose_m = (integration >> 8);
268 expose_l = integration;
269
270 /* integration time low */
271 se401_set_feature(gspca_dev, HV7131_REG_TITL, expose_l);
272 /* integration time mid */
273 se401_set_feature(gspca_dev, HV7131_REG_TITM, expose_m);
274 /* integration time high */
275 se401_set_feature(gspca_dev, HV7131_REG_TITU, expose_h);
276}
277
278static int sd_config(struct gspca_dev *gspca_dev,
279 const struct usb_device_id *id)
280{
281 struct sd *sd = (struct sd *)gspca_dev;
282 struct cam *cam = &gspca_dev->cam;
283 u8 *cd = gspca_dev->usb_buf;
284 int i, j, n;
285 int widths[MAX_MODES], heights[MAX_MODES];
286
287 /* Read the camera descriptor */
288 se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 1);
289 if (gspca_dev->usb_err) {
290 /* Sometimes after being idle for a while the se401 won't
291 respond and needs a good kicking */
292 usb_reset_device(gspca_dev->dev);
293 gspca_dev->usb_err = 0;
294 se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0);
295 }
296
297 /* Some cameras start with their LED on */
298 se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 0, 0);
299 if (gspca_dev->usb_err)
300 return gspca_dev->usb_err;
301
302 if (cd[1] != 0x41) {
303 err("Wrong descriptor type");
304 return -ENODEV;
305 }
306
307 if (!(cd[2] & SE401_FORMAT_BAYER)) {
308 err("Bayer format not supported!");
309 return -ENODEV;
310 }
311
312 if (cd[3])
313 info("ExtraFeatures: %d", cd[3]);
314
315 n = cd[4] | (cd[5] << 8);
316 if (n > MAX_MODES) {
317 err("Too many frame sizes");
318 return -ENODEV;
319 }
320
321 for (i = 0; i < n ; i++) {
322 widths[i] = cd[6 + i * 4 + 0] | (cd[6 + i * 4 + 1] << 8);
323 heights[i] = cd[6 + i * 4 + 2] | (cd[6 + i * 4 + 3] << 8);
324 }
325
326 for (i = 0; i < n ; i++) {
327 sd->fmts[i].width = widths[i];
328 sd->fmts[i].height = heights[i];
329 sd->fmts[i].field = V4L2_FIELD_NONE;
330 sd->fmts[i].colorspace = V4L2_COLORSPACE_SRGB;
331 sd->fmts[i].priv = 1;
332
333 /* janggu compression only works for 1/4th or 1/16th res */
334 for (j = 0; j < n; j++) {
335 if (widths[j] / 2 == widths[i] &&
336 heights[j] / 2 == heights[i]) {
337 sd->fmts[i].priv = 2;
338 break;
339 }
340 }
341 /* 1/16th if available too is better then 1/4th, because
342 we then use a larger area of the sensor */
343 for (j = 0; j < n; j++) {
344 if (widths[j] / 4 == widths[i] &&
345 heights[j] / 4 == heights[i]) {
346 sd->fmts[i].priv = 4;
347 break;
348 }
349 }
350
351 if (sd->fmts[i].priv == 1) {
352 /* Not a 1/4th or 1/16th res, use bayer */
353 sd->fmts[i].pixelformat = V4L2_PIX_FMT_SBGGR8;
354 sd->fmts[i].bytesperline = widths[i];
355 sd->fmts[i].sizeimage = widths[i] * heights[i];
356 info("Frame size: %dx%d bayer", widths[i], heights[i]);
357 } else {
358 /* Found a match use janggu compression */
359 sd->fmts[i].pixelformat = V4L2_PIX_FMT_SE401;
360 sd->fmts[i].bytesperline = 0;
361 sd->fmts[i].sizeimage = widths[i] * heights[i] * 3;
362 info("Frame size: %dx%d 1/%dth janggu",
363 widths[i], heights[i],
364 sd->fmts[i].priv * sd->fmts[i].priv);
365 }
366 }
367
368 cam->cam_mode = sd->fmts;
369 cam->nmodes = n;
370 cam->bulk = 1;
371 cam->bulk_size = BULK_SIZE;
372 cam->bulk_nurbs = 4;
373 cam->ctrls = sd->ctrls;
374 gspca_dev->nbalt = 1; /* Ignore the bogus isoc alt settings */
375 sd->resetlevel = 0x2d; /* Set initial resetlevel */
376
377 /* See if the camera supports brightness */
378 se401_read_req(gspca_dev, SE401_REQ_GET_BRT, 1);
379 if (gspca_dev->usb_err) {
380 gspca_dev->ctrl_dis = (1 << BRIGHTNESS);
381 gspca_dev->usb_err = 0;
382 }
383
384 return 0;
385}
386
387/* this function is called at probe and resume time */
388static int sd_init(struct gspca_dev *gspca_dev)
389{
390 return 0;
391}
392
393/* -- start the camera -- */
394static int sd_start(struct gspca_dev *gspca_dev)
395{
396 struct sd *sd = (struct sd *)gspca_dev;
397 int mult = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
398 int mode = 0;
399
400 se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 1, 1);
401 if (gspca_dev->usb_err) {
402 /* Sometimes after being idle for a while the se401 won't
403 respond and needs a good kicking */
404 usb_reset_device(gspca_dev->dev);
405 gspca_dev->usb_err = 0;
406 se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 1, 0);
407 }
408 se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 1, 0);
409
410 se401_set_feature(gspca_dev, HV7131_REG_MODE_B, 0x05);
411
412 /* set size + mode */
413 se401_write_req(gspca_dev, SE401_REQ_SET_WIDTH,
414 gspca_dev->width * mult, 0);
415 se401_write_req(gspca_dev, SE401_REQ_SET_HEIGHT,
416 gspca_dev->height * mult, 0);
417 /*
418 * HDG: disabled this as it does not seem to do anything
419 * se401_write_req(gspca_dev, SE401_REQ_SET_OUTPUT_MODE,
420 * SE401_FORMAT_BAYER, 0);
421 */
422
423 switch (mult) {
424 case 1: /* Raw bayer */
425 mode = 0x03; break;
426 case 2: /* 1/4th janggu */
427 mode = SE401_QUANT_FACT << 4; break;
428 case 4: /* 1/16th janggu */
429 mode = (SE401_QUANT_FACT << 4) | 0x02; break;
430 }
431 se401_set_feature(gspca_dev, SE401_OPERATINGMODE, mode);
432
433 setbrightness(gspca_dev);
434 setgain(gspca_dev);
435 setexposure(gspca_dev);
436 se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel);
437
438 sd->packet_read = 0;
439 sd->pixels_read = 0;
440 sd->restart_stream = 0;
441 sd->resetlevel_frame_count = 0;
442 sd->resetlevel_adjust_dir = 0;
443 sd->expo_change_state = EXPO_NO_CHANGE;
444
445 se401_write_req(gspca_dev, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, 0);
446
447 return gspca_dev->usb_err;
448}
449
450static void sd_stopN(struct gspca_dev *gspca_dev)
451{
452 se401_write_req(gspca_dev, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, 0);
453 se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 0, 0);
454 se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 0, 0);
455}
456
457static void sd_dq_callback(struct gspca_dev *gspca_dev)
458{
459 struct sd *sd = (struct sd *)gspca_dev;
460 unsigned int ahrc, alrc;
461 int oldreset, adjust_dir;
462
463 /* Restart the stream if requested do so by pkt_scan */
464 if (sd->restart_stream) {
465 sd_stopN(gspca_dev);
466 sd_start(gspca_dev);
467 sd->restart_stream = 0;
468 }
469
470 /* Automatically adjust sensor reset level
471 Hyundai have some really nice docs about this and other sensor
472 related stuff on their homepage: www.hei.co.kr */
473 sd->resetlevel_frame_count++;
474 if (sd->resetlevel_frame_count < 20)
475 return;
476
477 /* For some reason this normally read-only register doesn't get reset
478 to zero after reading them just once... */
479 se401_get_feature(gspca_dev, HV7131_REG_HIREFNOH);
480 se401_get_feature(gspca_dev, HV7131_REG_HIREFNOL);
481 se401_get_feature(gspca_dev, HV7131_REG_LOREFNOH);
482 se401_get_feature(gspca_dev, HV7131_REG_LOREFNOL);
483 ahrc = 256*se401_get_feature(gspca_dev, HV7131_REG_HIREFNOH) +
484 se401_get_feature(gspca_dev, HV7131_REG_HIREFNOL);
485 alrc = 256*se401_get_feature(gspca_dev, HV7131_REG_LOREFNOH) +
486 se401_get_feature(gspca_dev, HV7131_REG_LOREFNOL);
487
488 /* Not an exact science, but it seems to work pretty well... */
489 oldreset = sd->resetlevel;
490 if (alrc > 10) {
491 while (alrc >= 10 && sd->resetlevel < 63) {
492 sd->resetlevel++;
493 alrc /= 2;
494 }
495 } else if (ahrc > 20) {
496 while (ahrc >= 20 && sd->resetlevel > 0) {
497 sd->resetlevel--;
498 ahrc /= 2;
499 }
500 }
501 /* Detect ping-pong-ing and halve adjustment to avoid overshoot */
502 if (sd->resetlevel > oldreset)
503 adjust_dir = 1;
504 else
505 adjust_dir = -1;
506 if (sd->resetlevel_adjust_dir &&
507 sd->resetlevel_adjust_dir != adjust_dir)
508 sd->resetlevel = oldreset + (sd->resetlevel - oldreset) / 2;
509
510 if (sd->resetlevel != oldreset) {
511 sd->resetlevel_adjust_dir = adjust_dir;
512 se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel);
513 }
514
515 sd->resetlevel_frame_count = 0;
516}
517
518static void sd_complete_frame(struct gspca_dev *gspca_dev, u8 *data, int len)
519{
520 struct sd *sd = (struct sd *)gspca_dev;
521
522 switch (sd->expo_change_state) {
523 case EXPO_CHANGED:
524 /* The exposure was changed while this frame
525 was being send, so this frame is ok */
526 sd->expo_change_state = EXPO_DROP_FRAME;
527 break;
528 case EXPO_DROP_FRAME:
529 /* The exposure was changed while this frame
530 was being captured, drop it! */
531 gspca_dev->last_packet_type = DISCARD_PACKET;
532 sd->expo_change_state = EXPO_NO_CHANGE;
533 break;
534 case EXPO_NO_CHANGE:
535 break;
536 }
537 gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
538}
539
540static void sd_pkt_scan_janggu(struct gspca_dev *gspca_dev, u8 *data, int len)
541{
542 struct sd *sd = (struct sd *)gspca_dev;
543 int imagesize = gspca_dev->width * gspca_dev->height;
544 int i, plen, bits, pixels, info, count;
545
546 if (sd->restart_stream)
547 return;
548
549 /* Sometimes a 1024 bytes garbage bulk packet is send between frames */
550 if (gspca_dev->last_packet_type == LAST_PACKET && len == 1024) {
551 gspca_dev->last_packet_type = DISCARD_PACKET;
552 return;
553 }
554
555 i = 0;
556 while (i < len) {
557 /* Read header if not already be present from prev bulk pkt */
558 if (sd->packet_read < 4) {
559 count = 4 - sd->packet_read;
560 if (count > len - i)
561 count = len - i;
562 memcpy(&sd->packet[sd->packet_read], &data[i], count);
563 sd->packet_read += count;
564 i += count;
565 if (sd->packet_read < 4)
566 break;
567 }
568 bits = sd->packet[3] + (sd->packet[2] << 8);
569 pixels = sd->packet[1] + ((sd->packet[0] & 0x3f) << 8);
570 info = (sd->packet[0] & 0xc0) >> 6;
571 plen = ((bits + 47) >> 4) << 1;
572 /* Sanity checks */
573 if (plen > 1024) {
574 err("invalid packet len %d restarting stream", plen);
575 goto error;
576 }
577 if (info == 3) {
578 err("unknown frame info value restarting stream");
579 goto error;
580 }
581
582 /* Read (remainder of) packet contents */
583 count = plen - sd->packet_read;
584 if (count > len - i)
585 count = len - i;
586 memcpy(&sd->packet[sd->packet_read], &data[i], count);
587 sd->packet_read += count;
588 i += count;
589 if (sd->packet_read < plen)
590 break;
591
592 sd->pixels_read += pixels;
593 sd->packet_read = 0;
594
595 switch (info) {
596 case 0: /* Frame data */
597 gspca_frame_add(gspca_dev, INTER_PACKET, sd->packet,
598 plen);
599 break;
600 case 1: /* EOF */
601 if (sd->pixels_read != imagesize) {
602 err("frame size %d expected %d",
603 sd->pixels_read, imagesize);
604 goto error;
605 }
606 sd_complete_frame(gspca_dev, sd->packet, plen);
607 return; /* Discard the rest of the bulk packet !! */
608 case 2: /* SOF */
609 gspca_frame_add(gspca_dev, FIRST_PACKET, sd->packet,
610 plen);
611 sd->pixels_read = pixels;
612 break;
613 }
614 }
615 return;
616
617error:
618 sd->restart_stream = 1;
619 /* Give userspace a 0 bytes frame, so our dq callback gets
620 called and it can restart the stream */
621 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
622 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
623}
624
625static void sd_pkt_scan_bayer(struct gspca_dev *gspca_dev, u8 *data, int len)
626{
627 struct cam *cam = &gspca_dev->cam;
628 int imagesize = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
629
630 if (gspca_dev->image_len == 0) {
631 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
632 return;
633 }
634
635 if (gspca_dev->image_len + len >= imagesize) {
636 sd_complete_frame(gspca_dev, data, len);
637 return;
638 }
639
640 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
641}
642
643static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len)
644{
645 int mult = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
646
647 if (len == 0)
648 return;
649
650 if (mult == 1) /* mult == 1 means raw bayer */
651 sd_pkt_scan_bayer(gspca_dev, data, len);
652 else
653 sd_pkt_scan_janggu(gspca_dev, data, len);
654}
655
656static int sd_querymenu(struct gspca_dev *gspca_dev,
657 struct v4l2_querymenu *menu)
658{
659 switch (menu->id) {
660 case V4L2_CID_POWER_LINE_FREQUENCY:
661 switch (menu->index) {
662 case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
663 strcpy((char *) menu->name, "NoFliker");
664 return 0;
665 case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
666 strcpy((char *) menu->name, "50 Hz");
667 return 0;
668 case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
669 strcpy((char *) menu->name, "60 Hz");
670 return 0;
671 }
672 break;
673 }
674 return -EINVAL;
675}
676
677#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
678static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len)
679{
680 struct sd *sd = (struct sd *)gspca_dev;
681 u8 state;
682
683 if (len != 2)
684 return -EINVAL;
685
686 switch (data[0]) {
687 case 0:
688 case 1:
689 state = data[0];
690 break;
691 default:
692 return -EINVAL;
693 }
694 if (sd->button_state != state) {
695 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
696 input_sync(gspca_dev->input_dev);
697 sd->button_state = state;
698 }
699
700 return 0;
701}
702#endif
703
704/* sub-driver description */
705static const struct sd_desc sd_desc = {
706 .name = MODULE_NAME,
707 .ctrls = sd_ctrls,
708 .nctrls = ARRAY_SIZE(sd_ctrls),
709 .config = sd_config,
710 .init = sd_init,
711 .start = sd_start,
712 .stopN = sd_stopN,
713 .dq_callback = sd_dq_callback,
714 .pkt_scan = sd_pkt_scan,
715 .querymenu = sd_querymenu,
716#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
717 .int_pkt_scan = sd_int_pkt_scan,
718#endif
719};
720
721/* -- module initialisation -- */
722static const struct usb_device_id device_table[] = {
723 {USB_DEVICE(0x03e8, 0x0004)}, /* Endpoints/Aox SE401 */
724 {USB_DEVICE(0x0471, 0x030b)}, /* Philips PCVC665K */
725 {USB_DEVICE(0x047d, 0x5001)}, /* Kensington 67014 */
726 {USB_DEVICE(0x047d, 0x5002)}, /* Kensington 6701(5/7) */
727 {USB_DEVICE(0x047d, 0x5003)}, /* Kensington 67016 */
728 {}
729};
730MODULE_DEVICE_TABLE(usb, device_table);
731
732/* -- device connect -- */
733static int sd_probe(struct usb_interface *intf,
734 const struct usb_device_id *id)
735{
736 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
737 THIS_MODULE);
738}
739
740static int sd_pre_reset(struct usb_interface *intf)
741{
742 return 0;
743}
744
745static int sd_post_reset(struct usb_interface *intf)
746{
747 return 0;
748}
749
750static struct usb_driver sd_driver = {
751 .name = MODULE_NAME,
752 .id_table = device_table,
753 .probe = sd_probe,
754 .disconnect = gspca_disconnect,
755#ifdef CONFIG_PM
756 .suspend = gspca_suspend,
757 .resume = gspca_resume,
758#endif
759 .pre_reset = sd_pre_reset,
760 .post_reset = sd_post_reset,
761};
762
763/* -- module insert / remove -- */
764static int __init sd_mod_init(void)
765{
766 return usb_register(&sd_driver);
767}
768static void __exit sd_mod_exit(void)
769{
770 usb_deregister(&sd_driver);
771}
772
773module_init(sd_mod_init);
774module_exit(sd_mod_exit);