aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-09-03 15:47:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-03 17:36:29 -0400
commit49b57dba2f6425e9b42874b4dec2433b335fa69c (patch)
tree36654b65fc2ff12ce5db8fe7c3dcebcbb1b0e5c1 /drivers
parentd2d16e9084ee44088974c3312b803d54dd9b46d7 (diff)
V4L/DVB (8664): gspca: The bridge/sensor of the webcam 093a:2621 is a PAC 7302.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/pac7311.c418
1 files changed, 294 insertions, 124 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 96cd7f644adf..034c00d6c0ab 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -44,6 +44,10 @@ struct sd {
44 char tosof; /* number of bytes before next start of frame */ 44 char tosof; /* number of bytes before next start of frame */
45 signed char ag_cnt; 45 signed char ag_cnt;
46#define AG_CNT_START 13 46#define AG_CNT_START 13
47
48 __u8 sensor;
49#define SENSOR_PAC7302 0
50#define SENSOR_PAC7311 1
47}; 51};
48 52
49/* V4L2 controls supported by the driver */ 53/* V4L2 controls supported by the driver */
@@ -206,9 +210,158 @@ static const __u8 pac7311_jpeg_header[] = {
206 0x11, 0x00, 0x3f, 0x00 210 0x11, 0x00, 0x3f, 0x00
207}; 211};
208 212
213/* pac 7302 */
214static const __u8 probe_7302[] = {
215/* index,value */
216 0xff, 0x01, /* page 1 */
217 0x78, 0x00, /* deactivate */
218 0xff, 0x01,
219 0x78, 0x40, /* led off */
220};
221static const __u8 start_7302[] = {
222/* index, len, [value]* */
223 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
224 0x00, 0x00, 0x00, 0x00,
225 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
226 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
227 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
228 0x26, 2, 0xaa, 0xaa,
229 0x2e, 1, 0x31,
230 0x38, 1, 0x01,
231 0x3a, 3, 0x14, 0xff, 0x5a,
232 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
233 0x00, 0x54, 0x11,
234 0x55, 1, 0x00,
235 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
236 0x6b, 1, 0x00,
237 0x6e, 3, 0x08, 0x06, 0x00,
238 0x72, 3, 0x00, 0xff, 0x00,
239 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
240 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
241 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
242 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
243 0xd2, 0xeb,
244 0xaf, 1, 0x02,
245 0xb5, 2, 0x08, 0x08,
246 0xb8, 2, 0x08, 0x88,
247 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
248 0xcc, 1, 0x00,
249 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
250 0xc1, 0xd7, 0xec,
251 0xdc, 1, 0x01,
252 0xff, 1, 0x01,
253 0x12, 3, 0x02, 0x00, 0x01,
254 0x3e, 2, 0x00, 0x00,
255 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
256 0x7c, 1, 0x00,
257 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
258 0x02, 0x00,
259 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
260 0xc8, 17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
261 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
262 0x01,
263 0xdb, 2, 0x00, 0x01,
264 0xde, 8, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
265 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
266 0xeb, 1, 0x00,
267 0xff, 1, 0x02,
268 0x22, 1, 0x00,
269 0xff, 1, 0x03,
270 0x00, 255, /* load the page 3 */
271 0x11, 1, 0x01,
272 0xff, 1, 0x02,
273 0x13, 1, 0x00,
274 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
275 0x27, 2, 0x14, 0x0c,
276 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
277 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
278 0x6e, 1, 0x08,
279 0xff, 1, 0x03,
280 0x78, 1, 0x00,
281 0, 0 /* end of sequence */
282};
283
284/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
285static const __u8 page3_7302[] = {
286 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
287 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
288 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
290 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
291 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
292 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
293 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
296 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
300 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
301 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
302 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
305 0x00
306};
307
308/* pac 7311 */
309static const __u8 probe_7311[] = {
310 0x78, 0x40, /* Bit_0=start stream, Bit_7=LED */
311 0x78, 0x40, /* Bit_0=start stream, Bit_7=LED */
312 0x78, 0x44, /* Bit_0=start stream, Bit_7=LED */
313 0xff, 0x04,
314 0x27, 0x80,
315 0x28, 0xca,
316 0x29, 0x53,
317 0x2a, 0x0e,
318 0xff, 0x01,
319 0x3e, 0x20,
320};
321
322static const __u8 start_7311[] = {
323/* index, len, [value]* */
324 0xff, 1, 0x01,
325 0x02, 53, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
326 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
327 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
328 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00,
331 0x3e, 52, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
332 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
333 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
334 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
335 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
336 0xd0, 0xff,
337 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
338 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
339 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
340 0x18, 0x20,
341 0x96, 3, 0x01, 0x08, 0x04,
342 0xa0, 4, 0x44, 0x44, 0x44, 0x04,
343 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
344 0x3f, 0x00, 0x0a, 0x01, 0x00,
345 0xff, 1, 0x04,
346 0x00, 254, /* load the page 4 */
347 0x11, 1, 0x01,
348 0, 0 /* end of sequence */
349};
350
351/* page 4 - the value 0xaa says skip the index - see reg_w_page() */
352static const __u8 page4_7311[] = {
353 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
354 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
355 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
357 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x01,
358 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
359 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
360};
361
209static void reg_w_buf(struct gspca_dev *gspca_dev, 362static void reg_w_buf(struct gspca_dev *gspca_dev,
210 __u16 index, 363 __u8 index,
211 const char *buffer, __u16 len) 364 const char *buffer, int len)
212{ 365{
213 memcpy(gspca_dev->usb_buf, buffer, len); 366 memcpy(gspca_dev->usb_buf, buffer, len);
214 usb_control_msg(gspca_dev->dev, 367 usb_control_msg(gspca_dev->dev,
@@ -221,7 +374,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
221} 374}
222 375
223static __u8 reg_r(struct gspca_dev *gspca_dev, 376static __u8 reg_r(struct gspca_dev *gspca_dev,
224 __u16 index) 377 __u8 index)
225{ 378{
226 usb_control_msg(gspca_dev->dev, 379 usb_control_msg(gspca_dev->dev,
227 usb_rcvctrlpipe(gspca_dev->dev, 0), 380 usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -234,7 +387,7 @@ static __u8 reg_r(struct gspca_dev *gspca_dev,
234} 387}
235 388
236static void reg_w(struct gspca_dev *gspca_dev, 389static void reg_w(struct gspca_dev *gspca_dev,
237 __u16 index, 390 __u8 index,
238 __u8 value) 391 __u8 value)
239{ 392{
240 gspca_dev->usb_buf[0] = value; 393 gspca_dev->usb_buf[0] = value;
@@ -246,6 +399,74 @@ static void reg_w(struct gspca_dev *gspca_dev,
246 500); 399 500);
247} 400}
248 401
402static void reg_w_seq(struct gspca_dev *gspca_dev,
403 const __u8 *seq, int len)
404{
405 while (--len >= 0) {
406 reg_w(gspca_dev, seq[0], seq[1]);
407 seq += 2;
408 }
409}
410
411/* load the beginning of a page */
412static void reg_w_page(struct gspca_dev *gspca_dev,
413 const __u8 *page, int len)
414{
415 int index;
416
417 for (index = 0; index < len; index++) {
418 if (page[index] == 0xaa) /* skip this index */
419 continue;
420 gspca_dev->usb_buf[0] = page[index];
421 usb_control_msg(gspca_dev->dev,
422 usb_sndctrlpipe(gspca_dev->dev, 0),
423 0, /* request */
424 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
425 0, index, gspca_dev->usb_buf, 1,
426 500);
427 }
428}
429
430/* output a variable sequence */
431static void reg_w_var(struct gspca_dev *gspca_dev,
432 const __u8 *seq)
433{
434 int index, len;
435
436 for (;;) {
437 index = *seq++;
438 len = *seq++;
439 switch (len) {
440 case 0:
441 return;
442 case 254:
443 reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
444 break;
445 case 255:
446 reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
447 break;
448 default:
449 if (len > 32) {
450 PDEBUG(D_ERR|D_STREAM,
451 "Incorrect variable sequence");
452 return;
453 }
454 while (len > 0) {
455 if (len < 8) {
456 reg_w_buf(gspca_dev, index, seq, len);
457 seq += len;
458 break;
459 }
460 reg_w_buf(gspca_dev, index, seq, 8);
461 seq += 8;
462 index += 8;
463 len -= 8;
464 }
465 }
466 }
467 /* not reached */
468}
469
249/* this function is called at probe time */ 470/* this function is called at probe time */
250static int sd_config(struct gspca_dev *gspca_dev, 471static int sd_config(struct gspca_dev *gspca_dev,
251 const struct usb_device_id *id) 472 const struct usb_device_id *id)
@@ -253,22 +474,23 @@ static int sd_config(struct gspca_dev *gspca_dev,
253 struct sd *sd = (struct sd *) gspca_dev; 474 struct sd *sd = (struct sd *) gspca_dev;
254 struct cam *cam; 475 struct cam *cam;
255 476
256 PDEBUG(D_CONF, "Find Sensor PAC7311");
257 reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
258 reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
259 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
260 reg_w(gspca_dev, 0xff, 0x04);
261 reg_w(gspca_dev, 0x27, 0x80);
262 reg_w(gspca_dev, 0x28, 0xca);
263 reg_w(gspca_dev, 0x29, 0x53);
264 reg_w(gspca_dev, 0x2a, 0x0e);
265 reg_w(gspca_dev, 0xff, 0x01);
266 reg_w(gspca_dev, 0x3e, 0x20);
267
268 cam = &gspca_dev->cam; 477 cam = &gspca_dev->cam;
269 cam->epaddr = 0x05; 478 cam->epaddr = 0x05;
270 cam->cam_mode = vga_mode; 479
271 cam->nmodes = ARRAY_SIZE(vga_mode); 480 sd->sensor = id->driver_info;
481 if (sd->sensor == SENSOR_PAC7302) {
482 PDEBUG(D_CONF, "Find Sensor PAC7302");
483 reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302);
484
485 cam->cam_mode = &vga_mode[2]; /* only 640x480 */
486 cam->nmodes = 1;
487 } else {
488 PDEBUG(D_CONF, "Find Sensor PAC7311");
489 reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302);
490
491 cam->cam_mode = vga_mode;
492 cam->nmodes = ARRAY_SIZE(vga_mode);
493 }
272 494
273 sd->brightness = BRIGHTNESS_DEF; 495 sd->brightness = BRIGHTNESS_DEF;
274 sd->contrast = CONTRAST_DEF; 496 sd->contrast = CONTRAST_DEF;
@@ -283,10 +505,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
283 struct sd *sd = (struct sd *) gspca_dev; 505 struct sd *sd = (struct sd *) gspca_dev;
284 int brightness; 506 int brightness;
285 507
508 if (sd->sensor == SENSOR_PAC7302)
509 return;
286/*jfm: inverted?*/ 510/*jfm: inverted?*/
287 brightness = BRIGHTNESS_MAX - sd->brightness; 511 brightness = BRIGHTNESS_MAX - sd->brightness;
288 reg_w(gspca_dev, 0xff, 0x04); 512 reg_w(gspca_dev, 0xff, 0x04);
289/* reg_w(gspca_dev, 0x0e, 0x00); */
290 reg_w(gspca_dev, 0x0f, brightness); 513 reg_w(gspca_dev, 0x0f, brightness);
291 /* load registers to sensor (Bit 0, auto clear) */ 514 /* load registers to sensor (Bit 0, auto clear) */
292 reg_w(gspca_dev, 0x11, 0x01); 515 reg_w(gspca_dev, 0x11, 0x01);
@@ -297,6 +520,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
297{ 520{
298 struct sd *sd = (struct sd *) gspca_dev; 521 struct sd *sd = (struct sd *) gspca_dev;
299 522
523 if (sd->sensor == SENSOR_PAC7302)
524 return;
300 reg_w(gspca_dev, 0xff, 0x01); 525 reg_w(gspca_dev, 0xff, 0x01);
301 reg_w(gspca_dev, 0x80, sd->contrast); 526 reg_w(gspca_dev, 0x80, sd->contrast);
302 /* load registers to sensor (Bit 0, auto clear) */ 527 /* load registers to sensor (Bit 0, auto clear) */
@@ -308,6 +533,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
308{ 533{
309 struct sd *sd = (struct sd *) gspca_dev; 534 struct sd *sd = (struct sd *) gspca_dev;
310 535
536 if (sd->sensor == SENSOR_PAC7302)
537 return;
311 reg_w(gspca_dev, 0xff, 0x01); 538 reg_w(gspca_dev, 0xff, 0x01);
312 reg_w(gspca_dev, 0x10, sd->colors); 539 reg_w(gspca_dev, 0x10, sd->colors);
313 /* load registers to sensor (Bit 0, auto clear) */ 540 /* load registers to sensor (Bit 0, auto clear) */
@@ -340,75 +567,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
340 567
341 sd->ffnb = 0; 568 sd->ffnb = 0;
342 sd->tosof = 0; 569 sd->tosof = 0;
343 reg_w(gspca_dev, 0xff, 0x01);
344 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
345 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
346 reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8);
347 reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8);
348 reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8);
349 reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3);
350 reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8);
351 reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8);
352 reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8);
353 reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8);
354 reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8);
355 reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2);
356 reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6);
357 reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8);
358 reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8);
359 reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2);
360 reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3);
361 reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4);
362 reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8);
363 reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5);
364 570
365 reg_w(gspca_dev, 0xff, 0x04); 571 if (sd->sensor == SENSOR_PAC7302)
366 reg_w(gspca_dev, 0x02, 0x04); 572 reg_w_var(gspca_dev, start_7302);
367 reg_w(gspca_dev, 0x03, 0x54); 573 else
368 reg_w(gspca_dev, 0x04, 0x07); 574 reg_w_var(gspca_dev, start_7311);
369 reg_w(gspca_dev, 0x05, 0x2b); 575
370 reg_w(gspca_dev, 0x06, 0x09);
371 reg_w(gspca_dev, 0x07, 0x0f);
372 reg_w(gspca_dev, 0x08, 0x09);
373 reg_w(gspca_dev, 0x09, 0x00);
374 reg_w(gspca_dev, 0x0c, 0x07);
375 reg_w(gspca_dev, 0x0d, 0x00);
376 reg_w(gspca_dev, 0x0e, 0x00);
377 reg_w(gspca_dev, 0x0f, 0x62);
378 reg_w(gspca_dev, 0x10, 0x08);
379 reg_w(gspca_dev, 0x12, 0x07);
380 reg_w(gspca_dev, 0x13, 0x00);
381 reg_w(gspca_dev, 0x14, 0x00);
382 reg_w(gspca_dev, 0x15, 0x00);
383 reg_w(gspca_dev, 0x16, 0x00);
384 reg_w(gspca_dev, 0x17, 0x00);
385 reg_w(gspca_dev, 0x18, 0x00);
386 reg_w(gspca_dev, 0x19, 0x00);
387 reg_w(gspca_dev, 0x1a, 0x00);
388 reg_w(gspca_dev, 0x1b, 0x03);
389 reg_w(gspca_dev, 0x1c, 0xa0);
390 reg_w(gspca_dev, 0x1d, 0x01);
391 reg_w(gspca_dev, 0x1e, 0xf4);
392 reg_w(gspca_dev, 0x21, 0x00);
393 reg_w(gspca_dev, 0x22, 0x08);
394 reg_w(gspca_dev, 0x24, 0x03);
395 reg_w(gspca_dev, 0x26, 0x00);
396 reg_w(gspca_dev, 0x27, 0x01);
397 reg_w(gspca_dev, 0x28, 0xca);
398 reg_w(gspca_dev, 0x29, 0x10);
399 reg_w(gspca_dev, 0x2a, 0x06);
400 reg_w(gspca_dev, 0x2b, 0x78);
401 reg_w(gspca_dev, 0x2c, 0x00);
402 reg_w(gspca_dev, 0x2d, 0x00);
403 reg_w(gspca_dev, 0x2e, 0x00);
404 reg_w(gspca_dev, 0x2f, 0x00);
405 reg_w(gspca_dev, 0x30, 0x23);
406 reg_w(gspca_dev, 0x31, 0x28);
407 reg_w(gspca_dev, 0x32, 0x04);
408 reg_w(gspca_dev, 0x33, 0x11);
409 reg_w(gspca_dev, 0x34, 0x00);
410 reg_w(gspca_dev, 0x35, 0x00);
411 reg_w(gspca_dev, 0x11, 0x01);
412 setcontrast(gspca_dev); 576 setcontrast(gspca_dev);
413 setbrightness(gspca_dev); 577 setbrightness(gspca_dev);
414 setcolors(gspca_dev); 578 setcolors(gspca_dev);
@@ -416,7 +580,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
416 580
417 /* set correct resolution */ 581 /* set correct resolution */
418 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 582 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
419 case 2: /* 160x120 */ 583 case 2: /* 160x120 pac7311 */
420 reg_w(gspca_dev, 0xff, 0x04); 584 reg_w(gspca_dev, 0xff, 0x04);
421 reg_w(gspca_dev, 0x02, 0x03); 585 reg_w(gspca_dev, 0x02, 0x03);
422 reg_w(gspca_dev, 0xff, 0x01); 586 reg_w(gspca_dev, 0xff, 0x01);
@@ -426,7 +590,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
426/* reg_w(gspca_dev, 0x80, 0x69); */ 590/* reg_w(gspca_dev, 0x80, 0x69); */
427 reg_w(gspca_dev, 0x87, 0x10); 591 reg_w(gspca_dev, 0x87, 0x10);
428 break; 592 break;
429 case 1: /* 320x240 */ 593 case 1: /* 320x240 pac7311 */
430 reg_w(gspca_dev, 0xff, 0x04); 594 reg_w(gspca_dev, 0xff, 0x04);
431 reg_w(gspca_dev, 0x02, 0x03); 595 reg_w(gspca_dev, 0x02, 0x03);
432 reg_w(gspca_dev, 0xff, 0x01); 596 reg_w(gspca_dev, 0xff, 0x01);
@@ -436,6 +600,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
436 reg_w(gspca_dev, 0x87, 0x11); 600 reg_w(gspca_dev, 0x87, 0x11);
437 break; 601 break;
438 case 0: /* 640x480 */ 602 case 0: /* 640x480 */
603 if (sd->sensor == SENSOR_PAC7302)
604 break;
439 reg_w(gspca_dev, 0xff, 0x04); 605 reg_w(gspca_dev, 0xff, 0x04);
440 reg_w(gspca_dev, 0x02, 0x03); 606 reg_w(gspca_dev, 0x02, 0x03);
441 reg_w(gspca_dev, 0xff, 0x01); 607 reg_w(gspca_dev, 0xff, 0x01);
@@ -448,12 +614,25 @@ static void sd_start(struct gspca_dev *gspca_dev)
448 614
449 /* start stream */ 615 /* start stream */
450 reg_w(gspca_dev, 0xff, 0x01); 616 reg_w(gspca_dev, 0xff, 0x01);
451 reg_w(gspca_dev, 0x78, 0x04); 617 if (sd->sensor == SENSOR_PAC7302) {
452 reg_w(gspca_dev, 0x78, 0x05); 618 reg_w(gspca_dev, 0x78, 0x01);
619 reg_w(gspca_dev, 0xff, 0x01);
620 reg_w(gspca_dev, 0x78, 0x01);
621 } else {
622 reg_w(gspca_dev, 0x78, 0x04);
623 reg_w(gspca_dev, 0x78, 0x05);
624 }
453} 625}
454 626
455static void sd_stopN(struct gspca_dev *gspca_dev) 627static void sd_stopN(struct gspca_dev *gspca_dev)
456{ 628{
629 struct sd *sd = (struct sd *) gspca_dev;
630
631 if (sd->sensor == SENSOR_PAC7302) {
632 reg_w(gspca_dev, 0x78, 0x00);
633 reg_w(gspca_dev, 0x78, 0x00);
634 return;
635 }
457 reg_w(gspca_dev, 0xff, 0x04); 636 reg_w(gspca_dev, 0xff, 0x04);
458 reg_w(gspca_dev, 0x27, 0x80); 637 reg_w(gspca_dev, 0x27, 0x80);
459 reg_w(gspca_dev, 0x28, 0xca); 638 reg_w(gspca_dev, 0x28, 0xca);
@@ -468,21 +647,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
468 647
469static void sd_stop0(struct gspca_dev *gspca_dev) 648static void sd_stop0(struct gspca_dev *gspca_dev)
470{ 649{
650 struct sd *sd = (struct sd *) gspca_dev;
651
652 if (sd->sensor == SENSOR_PAC7302) {
653 reg_w(gspca_dev, 0xff, 0x01);
654 reg_w(gspca_dev, 0x78, 0x40);
655 }
471} 656}
472 657
473/* this function is called at close time */ 658/* this function is called at close time */
474static void sd_close(struct gspca_dev *gspca_dev) 659static void sd_close(struct gspca_dev *gspca_dev)
475{ 660{
476 reg_w(gspca_dev, 0xff, 0x04);
477 reg_w(gspca_dev, 0x27, 0x80);
478 reg_w(gspca_dev, 0x28, 0xca);
479 reg_w(gspca_dev, 0x29, 0x53);
480 reg_w(gspca_dev, 0x2a, 0x0e);
481 reg_w(gspca_dev, 0xff, 0x01);
482 reg_w(gspca_dev, 0x3e, 0x20);
483 reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
484 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
485 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
486} 661}
487 662
488static void do_autogain(struct gspca_dev *gspca_dev) 663static void do_autogain(struct gspca_dev *gspca_dev)
@@ -509,10 +684,17 @@ static void do_autogain(struct gspca_dev *gspca_dev)
509 else if (Gbright < 4) 684 else if (Gbright < 4)
510 Gbright = 4; 685 Gbright = 4;
511 PDEBUG(D_FRAM, "gbright %d", Gbright); 686 PDEBUG(D_FRAM, "gbright %d", Gbright);
512 reg_w(gspca_dev, 0xff, 0x04); 687 if (sd->sensor == SENSOR_PAC7302) {
513 reg_w(gspca_dev, 0x0f, Gbright); 688 reg_w(gspca_dev, 0xff, 0x03);
514 /* load registers to sensor (Bit 0, auto clear) */ 689 reg_w(gspca_dev, 0x10, Gbright);
515 reg_w(gspca_dev, 0x11, 0x01); 690 /* load registers to sensor (Bit 0, auto clear) */
691 reg_w(gspca_dev, 0x11, 0x01);
692 } else {
693 reg_w(gspca_dev, 0xff, 0x04);
694 reg_w(gspca_dev, 0x0f, Gbright);
695 /* load registers to sensor (Bit 0, auto clear) */
696 reg_w(gspca_dev, 0x11, 0x01);
697 }
516 } 698 }
517} 699}
518 700
@@ -636,15 +818,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
636 } 818 }
637} 819}
638 820
639static void getbrightness(struct gspca_dev *gspca_dev)
640{
641/* sd->brightness = reg_r(gspca_dev, 0x08);
642 return sd->brightness; */
643/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */
644}
645
646
647
648static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 821static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
649{ 822{
650 struct sd *sd = (struct sd *) gspca_dev; 823 struct sd *sd = (struct sd *) gspca_dev;
@@ -659,7 +832,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
659{ 832{
660 struct sd *sd = (struct sd *) gspca_dev; 833 struct sd *sd = (struct sd *) gspca_dev;
661 834
662 getbrightness(gspca_dev);
663 *val = sd->brightness; 835 *val = sd->brightness;
664 return 0; 836 return 0;
665} 837}
@@ -678,7 +850,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
678{ 850{
679 struct sd *sd = (struct sd *) gspca_dev; 851 struct sd *sd = (struct sd *) gspca_dev;
680 852
681/* getcontrast(gspca_dev); */
682 *val = sd->contrast; 853 *val = sd->contrast;
683 return 0; 854 return 0;
684} 855}
@@ -697,7 +868,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
697{ 868{
698 struct sd *sd = (struct sd *) gspca_dev; 869 struct sd *sd = (struct sd *) gspca_dev;
699 870
700/* getcolors(gspca_dev); */
701 *val = sd->colors; 871 *val = sd->colors;
702 return 0; 872 return 0;
703} 873}
@@ -737,13 +907,13 @@ static struct sd_desc sd_desc = {
737 907
738/* -- module initialisation -- */ 908/* -- module initialisation -- */
739static __devinitdata struct usb_device_id device_table[] = { 909static __devinitdata struct usb_device_id device_table[] = {
740 {USB_DEVICE(0x093a, 0x2600)}, 910 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
741 {USB_DEVICE(0x093a, 0x2601)}, 911 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
742 {USB_DEVICE(0x093a, 0x2603)}, 912 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
743 {USB_DEVICE(0x093a, 0x2608)}, 913 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
744 {USB_DEVICE(0x093a, 0x260e)}, 914 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
745 {USB_DEVICE(0x093a, 0x260f)}, 915 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
746 {USB_DEVICE(0x093a, 0x2621)}, 916 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
747 {} 917 {}
748}; 918};
749MODULE_DEVICE_TABLE(usb, device_table); 919MODULE_DEVICE_TABLE(usb, device_table);