aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/pac7311.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/pac7311.c')
-rw-r--r--drivers/media/video/gspca/pac7311.c251
1 files changed, 118 insertions, 133 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 42cfcdfd8f4f..44fed9686729 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -51,6 +51,7 @@
51 51
52#define MODULE_NAME "pac7311" 52#define MODULE_NAME "pac7311"
53 53
54#include <linux/input.h>
54#include "gspca.h" 55#include "gspca.h"
55 56
56MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 57MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
@@ -88,7 +89,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 90static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
90 91
91static struct ctrl sd_ctrls[] = { 92static const struct ctrl sd_ctrls[] = {
92/* This control is for both the 7302 and the 7311 */ 93/* This control is for both the 7302 and the 7311 */
93 { 94 {
94 { 95 {
@@ -200,7 +201,6 @@ static const struct v4l2_pix_format vga_mode[] = {
200 .priv = 0}, 201 .priv = 0},
201}; 202};
202 203
203#define LOAD_PAGE3 255
204#define LOAD_PAGE4 254 204#define LOAD_PAGE4 254
205#define END_OF_SEQUENCE 0 205#define END_OF_SEQUENCE 0
206 206
@@ -259,12 +259,14 @@ static const __u8 page4_7311[] = {
259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
260}; 260};
261 261
262static int reg_w_buf(struct gspca_dev *gspca_dev, 262static void reg_w_buf(struct gspca_dev *gspca_dev,
263 __u8 index, 263 __u8 index,
264 const char *buffer, int len) 264 const char *buffer, int len)
265{ 265{
266 int ret; 266 int ret;
267 267
268 if (gspca_dev->usb_err < 0)
269 return;
268 memcpy(gspca_dev->usb_buf, buffer, len); 270 memcpy(gspca_dev->usb_buf, buffer, len);
269 ret = usb_control_msg(gspca_dev->dev, 271 ret = usb_control_msg(gspca_dev->dev,
270 usb_sndctrlpipe(gspca_dev->dev, 0), 272 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -273,20 +275,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
273 0, /* value */ 275 0, /* value */
274 index, gspca_dev->usb_buf, len, 276 index, gspca_dev->usb_buf, len,
275 500); 277 500);
276 if (ret < 0) 278 if (ret < 0) {
277 PDEBUG(D_ERR, "reg_w_buf(): " 279 PDEBUG(D_ERR, "reg_w_buf(): "
278 "Failed to write registers to index 0x%x, error %i", 280 "Failed to write registers to index 0x%x, error %i",
279 index, ret); 281 index, ret);
280 return ret; 282 gspca_dev->usb_err = ret;
283 }
281} 284}
282 285
283 286
284static int reg_w(struct gspca_dev *gspca_dev, 287static void reg_w(struct gspca_dev *gspca_dev,
285 __u8 index, 288 __u8 index,
286 __u8 value) 289 __u8 value)
287{ 290{
288 int ret; 291 int ret;
289 292
293 if (gspca_dev->usb_err < 0)
294 return;
290 gspca_dev->usb_buf[0] = value; 295 gspca_dev->usb_buf[0] = value;
291 ret = usb_control_msg(gspca_dev->dev, 296 ret = usb_control_msg(gspca_dev->dev,
292 usb_sndctrlpipe(gspca_dev->dev, 0), 297 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -294,32 +299,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
294 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 299 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
295 0, index, gspca_dev->usb_buf, 1, 300 0, index, gspca_dev->usb_buf, 1,
296 500); 301 500);
297 if (ret < 0) 302 if (ret < 0) {
298 PDEBUG(D_ERR, "reg_w(): " 303 PDEBUG(D_ERR, "reg_w(): "
299 "Failed to write register to index 0x%x, value 0x%x, error %i", 304 "Failed to write register to index 0x%x, value 0x%x, error %i",
300 index, value, ret); 305 index, value, ret);
301 return ret; 306 gspca_dev->usb_err = ret;
307 }
302} 308}
303 309
304static int reg_w_seq(struct gspca_dev *gspca_dev, 310static void reg_w_seq(struct gspca_dev *gspca_dev,
305 const __u8 *seq, int len) 311 const __u8 *seq, int len)
306{ 312{
307 int ret = 0;
308 while (--len >= 0) { 313 while (--len >= 0) {
309 if (0 <= ret) 314 reg_w(gspca_dev, seq[0], seq[1]);
310 ret = reg_w(gspca_dev, seq[0], seq[1]);
311 seq += 2; 315 seq += 2;
312 } 316 }
313 return ret;
314} 317}
315 318
316/* load the beginning of a page */ 319/* load the beginning of a page */
317static int reg_w_page(struct gspca_dev *gspca_dev, 320static void reg_w_page(struct gspca_dev *gspca_dev,
318 const __u8 *page, int len) 321 const __u8 *page, int len)
319{ 322{
320 int index; 323 int index;
321 int ret = 0; 324 int ret = 0;
322 325
326 if (gspca_dev->usb_err < 0)
327 return;
323 for (index = 0; index < len; index++) { 328 for (index = 0; index < len; index++) {
324 if (page[index] == SKIP) /* skip this index */ 329 if (page[index] == SKIP) /* skip this index */
325 continue; 330 continue;
@@ -335,56 +340,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
335 "Failed to write register to index 0x%x, " 340 "Failed to write register to index 0x%x, "
336 "value 0x%x, error %i", 341 "value 0x%x, error %i",
337 index, page[index], ret); 342 index, page[index], ret);
343 gspca_dev->usb_err = ret;
338 break; 344 break;
339 } 345 }
340 } 346 }
341 return ret;
342} 347}
343 348
344/* output a variable sequence */ 349/* output a variable sequence */
345static int reg_w_var(struct gspca_dev *gspca_dev, 350static void reg_w_var(struct gspca_dev *gspca_dev,
346 const __u8 *seq, 351 const __u8 *seq,
347 const __u8 *page3, unsigned int page3_len,
348 const __u8 *page4, unsigned int page4_len) 352 const __u8 *page4, unsigned int page4_len)
349{ 353{
350 int index, len; 354 int index, len;
351 int ret = 0;
352 355
353 for (;;) { 356 for (;;) {
354 index = *seq++; 357 index = *seq++;
355 len = *seq++; 358 len = *seq++;
356 switch (len) { 359 switch (len) {
357 case END_OF_SEQUENCE: 360 case END_OF_SEQUENCE:
358 return ret; 361 return;
359 case LOAD_PAGE4: 362 case LOAD_PAGE4:
360 ret = reg_w_page(gspca_dev, page4, page4_len); 363 reg_w_page(gspca_dev, page4, page4_len);
361 break;
362 case LOAD_PAGE3:
363 ret = reg_w_page(gspca_dev, page3, page3_len);
364 break; 364 break;
365 default: 365 default:
366 if (len > USB_BUF_SZ) { 366 if (len > USB_BUF_SZ) {
367 PDEBUG(D_ERR|D_STREAM, 367 PDEBUG(D_ERR|D_STREAM,
368 "Incorrect variable sequence"); 368 "Incorrect variable sequence");
369 return -EINVAL; 369 return;
370 } 370 }
371 while (len > 0) { 371 while (len > 0) {
372 if (len < 8) { 372 if (len < 8) {
373 ret = reg_w_buf(gspca_dev, 373 reg_w_buf(gspca_dev,
374 index, seq, len); 374 index, seq, len);
375 if (ret < 0)
376 return ret;
377 seq += len; 375 seq += len;
378 break; 376 break;
379 } 377 }
380 ret = reg_w_buf(gspca_dev, index, seq, 8); 378 reg_w_buf(gspca_dev, index, seq, 8);
381 seq += 8; 379 seq += 8;
382 index += 8; 380 index += 8;
383 len -= 8; 381 len -= 8;
384 } 382 }
385 } 383 }
386 if (ret < 0)
387 return ret;
388 } 384 }
389 /* not reached */ 385 /* not reached */
390} 386}
@@ -412,46 +408,36 @@ static int sd_config(struct gspca_dev *gspca_dev,
412} 408}
413 409
414/* This function is used by pac7311 only */ 410/* This function is used by pac7311 only */
415static int setcontrast(struct gspca_dev *gspca_dev) 411static void setcontrast(struct gspca_dev *gspca_dev)
416{ 412{
417 struct sd *sd = (struct sd *) gspca_dev; 413 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
419 414
420 ret = reg_w(gspca_dev, 0xff, 0x04); 415 reg_w(gspca_dev, 0xff, 0x04);
421 if (0 <= ret) 416 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
422 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
423 /* load registers to sensor (Bit 0, auto clear) */ 417 /* load registers to sensor (Bit 0, auto clear) */
424 if (0 <= ret) 418 reg_w(gspca_dev, 0x11, 0x01);
425 ret = reg_w(gspca_dev, 0x11, 0x01);
426 return ret;
427} 419}
428 420
429static int setgain(struct gspca_dev *gspca_dev) 421static void setgain(struct gspca_dev *gspca_dev)
430{ 422{
431 struct sd *sd = (struct sd *) gspca_dev; 423 struct sd *sd = (struct sd *) gspca_dev;
432 int gain = GAIN_MAX - sd->gain; 424 int gain = GAIN_MAX - sd->gain;
433 int ret;
434 425
435 if (gain < 1) 426 if (gain < 1)
436 gain = 1; 427 gain = 1;
437 else if (gain > 245) 428 else if (gain > 245)
438 gain = 245; 429 gain = 245;
439 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 430 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
440 if (0 <= ret) 431 reg_w(gspca_dev, 0x0e, 0x00);
441 ret = reg_w(gspca_dev, 0x0e, 0x00); 432 reg_w(gspca_dev, 0x0f, gain);
442 if (0 <= ret)
443 ret = reg_w(gspca_dev, 0x0f, gain);
444 433
445 /* load registers to sensor (Bit 0, auto clear) */ 434 /* load registers to sensor (Bit 0, auto clear) */
446 if (0 <= ret) 435 reg_w(gspca_dev, 0x11, 0x01);
447 ret = reg_w(gspca_dev, 0x11, 0x01);
448 return ret;
449} 436}
450 437
451static int setexposure(struct gspca_dev *gspca_dev) 438static void setexposure(struct gspca_dev *gspca_dev)
452{ 439{
453 struct sd *sd = (struct sd *) gspca_dev; 440 struct sd *sd = (struct sd *) gspca_dev;
454 int ret;
455 __u8 reg; 441 __u8 reg;
456 442
457 /* register 2 of frame 3/4 contains the clock divider configuring the 443 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -463,94 +449,72 @@ static int setexposure(struct gspca_dev *gspca_dev)
463 else if (reg > 63) 449 else if (reg > 63)
464 reg = 63; 450 reg = 63;
465 451
466 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 452 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
467 if (0 <= ret) 453 reg_w(gspca_dev, 0x02, reg);
468 ret = reg_w(gspca_dev, 0x02, reg); 454
469 /* Page 1 register 8 must always be 0x08 except when not in 455 /* Page 1 register 8 must always be 0x08 except when not in
470 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ 456 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
471 if (0 <= ret) 457 reg_w(gspca_dev, 0xff, 0x01);
472 ret = reg_w(gspca_dev, 0xff, 0x01);
473 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && 458 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
474 reg <= 3) { 459 reg <= 3) {
475 if (0 <= ret) 460 reg_w(gspca_dev, 0x08, 0x09);
476 ret = reg_w(gspca_dev, 0x08, 0x09);
477 } else { 461 } else {
478 if (0 <= ret) 462 reg_w(gspca_dev, 0x08, 0x08);
479 ret = reg_w(gspca_dev, 0x08, 0x08);
480 } 463 }
481 464
482 /* load registers to sensor (Bit 0, auto clear) */ 465 /* load registers to sensor (Bit 0, auto clear) */
483 if (0 <= ret) 466 reg_w(gspca_dev, 0x11, 0x01);
484 ret = reg_w(gspca_dev, 0x11, 0x01);
485 return ret;
486} 467}
487 468
488static int sethvflip(struct gspca_dev *gspca_dev) 469static void sethvflip(struct gspca_dev *gspca_dev)
489{ 470{
490 struct sd *sd = (struct sd *) gspca_dev; 471 struct sd *sd = (struct sd *) gspca_dev;
491 int ret;
492 __u8 data; 472 __u8 data;
493 473
494 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 474 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
495 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); 475 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
496 if (0 <= ret) 476 reg_w(gspca_dev, 0x21, data);
497 ret = reg_w(gspca_dev, 0x21, data); 477
498 /* load registers to sensor (Bit 0, auto clear) */ 478 /* load registers to sensor (Bit 0, auto clear) */
499 if (0 <= ret) 479 reg_w(gspca_dev, 0x11, 0x01);
500 ret = reg_w(gspca_dev, 0x11, 0x01);
501 return ret;
502} 480}
503 481
504/* this function is called at probe and resume time for pac7311 */ 482/* this function is called at probe and resume time for pac7311 */
505static int sd_init(struct gspca_dev *gspca_dev) 483static int sd_init(struct gspca_dev *gspca_dev)
506{ 484{
507 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); 485 reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
486 return gspca_dev->usb_err;
508} 487}
509 488
510static int sd_start(struct gspca_dev *gspca_dev) 489static int sd_start(struct gspca_dev *gspca_dev)
511{ 490{
512 struct sd *sd = (struct sd *) gspca_dev; 491 struct sd *sd = (struct sd *) gspca_dev;
513 int ret;
514 492
515 sd->sof_read = 0; 493 sd->sof_read = 0;
516 494
517 ret = reg_w_var(gspca_dev, start_7311, 495 reg_w_var(gspca_dev, start_7311,
518 NULL, 0,
519 page4_7311, sizeof(page4_7311)); 496 page4_7311, sizeof(page4_7311));
520 if (0 <= ret) 497 setcontrast(gspca_dev);
521 ret = setcontrast(gspca_dev); 498 setgain(gspca_dev);
522 if (0 <= ret) 499 setexposure(gspca_dev);
523 ret = setgain(gspca_dev); 500 sethvflip(gspca_dev);
524 if (0 <= ret)
525 ret = setexposure(gspca_dev);
526 if (0 <= ret)
527 ret = sethvflip(gspca_dev);
528 501
529 /* set correct resolution */ 502 /* set correct resolution */
530 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 503 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
531 case 2: /* 160x120 pac7311 */ 504 case 2: /* 160x120 pac7311 */
532 if (0 <= ret) 505 reg_w(gspca_dev, 0xff, 0x01);
533 ret = reg_w(gspca_dev, 0xff, 0x01); 506 reg_w(gspca_dev, 0x17, 0x20);
534 if (0 <= ret) 507 reg_w(gspca_dev, 0x87, 0x10);
535 ret = reg_w(gspca_dev, 0x17, 0x20);
536 if (0 <= ret)
537 ret = reg_w(gspca_dev, 0x87, 0x10);
538 break; 508 break;
539 case 1: /* 320x240 pac7311 */ 509 case 1: /* 320x240 pac7311 */
540 if (0 <= ret) 510 reg_w(gspca_dev, 0xff, 0x01);
541 ret = reg_w(gspca_dev, 0xff, 0x01); 511 reg_w(gspca_dev, 0x17, 0x30);
542 if (0 <= ret) 512 reg_w(gspca_dev, 0x87, 0x11);
543 ret = reg_w(gspca_dev, 0x17, 0x30);
544 if (0 <= ret)
545 ret = reg_w(gspca_dev, 0x87, 0x11);
546 break; 513 break;
547 case 0: /* 640x480 */ 514 case 0: /* 640x480 */
548 if (0 <= ret) 515 reg_w(gspca_dev, 0xff, 0x01);
549 ret = reg_w(gspca_dev, 0xff, 0x01); 516 reg_w(gspca_dev, 0x17, 0x00);
550 if (0 <= ret) 517 reg_w(gspca_dev, 0x87, 0x12);
551 ret = reg_w(gspca_dev, 0x17, 0x00);
552 if (0 <= ret)
553 ret = reg_w(gspca_dev, 0x87, 0x12);
554 break; 518 break;
555 } 519 }
556 520
@@ -559,37 +523,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
559 atomic_set(&sd->avg_lum, -1); 523 atomic_set(&sd->avg_lum, -1);
560 524
561 /* start stream */ 525 /* start stream */
562 if (0 <= ret) 526 reg_w(gspca_dev, 0xff, 0x01);
563 ret = reg_w(gspca_dev, 0xff, 0x01); 527 reg_w(gspca_dev, 0x78, 0x05);
564 if (0 <= ret)
565 ret = reg_w(gspca_dev, 0x78, 0x05);
566 528
567 return ret; 529 return gspca_dev->usb_err;
568} 530}
569 531
570static void sd_stopN(struct gspca_dev *gspca_dev) 532static void sd_stopN(struct gspca_dev *gspca_dev)
571{ 533{
572 int ret; 534 reg_w(gspca_dev, 0xff, 0x04);
573 535 reg_w(gspca_dev, 0x27, 0x80);
574 ret = reg_w(gspca_dev, 0xff, 0x04); 536 reg_w(gspca_dev, 0x28, 0xca);
575 if (0 <= ret) 537 reg_w(gspca_dev, 0x29, 0x53);
576 ret = reg_w(gspca_dev, 0x27, 0x80); 538 reg_w(gspca_dev, 0x2a, 0x0e);
577 if (0 <= ret) 539 reg_w(gspca_dev, 0xff, 0x01);
578 ret = reg_w(gspca_dev, 0x28, 0xca); 540 reg_w(gspca_dev, 0x3e, 0x20);
579 if (0 <= ret) 541 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
580 ret = reg_w(gspca_dev, 0x29, 0x53); 542 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
581 if (0 <= ret) 543 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
582 ret = reg_w(gspca_dev, 0x2a, 0x0e);
583 if (0 <= ret)
584 ret = reg_w(gspca_dev, 0xff, 0x01);
585 if (0 <= ret)
586 ret = reg_w(gspca_dev, 0x3e, 0x20);
587 if (0 <= ret)
588 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
589 if (0 <= ret)
590 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
591 if (0 <= ret)
592 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
593} 544}
594 545
595/* called on streamoff with alt 0 and on disconnect for 7311 */ 546/* called on streamoff with alt 0 and on disconnect for 7311 */
@@ -734,7 +685,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
734 if (gspca_dev->streaming) { 685 if (gspca_dev->streaming) {
735 setcontrast(gspca_dev); 686 setcontrast(gspca_dev);
736 } 687 }
737 return 0; 688 return gspca_dev->usb_err;
738} 689}
739 690
740static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 691static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -752,7 +703,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
752 sd->gain = val; 703 sd->gain = val;
753 if (gspca_dev->streaming) 704 if (gspca_dev->streaming)
754 setgain(gspca_dev); 705 setgain(gspca_dev);
755 return 0; 706 return gspca_dev->usb_err;
756} 707}
757 708
758static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 709static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -770,7 +721,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
770 sd->exposure = val; 721 sd->exposure = val;
771 if (gspca_dev->streaming) 722 if (gspca_dev->streaming)
772 setexposure(gspca_dev); 723 setexposure(gspca_dev);
773 return 0; 724 return gspca_dev->usb_err;
774} 725}
775 726
776static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 727static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -801,7 +752,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
801 } 752 }
802 } 753 }
803 754
804 return 0; 755 return gspca_dev->usb_err;
805} 756}
806 757
807static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 758static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -819,7 +770,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
819 sd->hflip = val; 770 sd->hflip = val;
820 if (gspca_dev->streaming) 771 if (gspca_dev->streaming)
821 sethvflip(gspca_dev); 772 sethvflip(gspca_dev);
822 return 0; 773 return gspca_dev->usb_err;
823} 774}
824 775
825static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 776static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -837,7 +788,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
837 sd->vflip = val; 788 sd->vflip = val;
838 if (gspca_dev->streaming) 789 if (gspca_dev->streaming)
839 sethvflip(gspca_dev); 790 sethvflip(gspca_dev);
840 return 0; 791 return gspca_dev->usb_err;
841} 792}
842 793
843static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 794static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -848,8 +799,39 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
848 return 0; 799 return 0;
849} 800}
850 801
802#ifdef CONFIG_INPUT
803static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
804 u8 *data, /* interrupt packet data */
805 int len) /* interrupt packet length */
806{
807 int ret = -EINVAL;
808 u8 data0, data1;
809
810 if (len == 2) {
811 data0 = data[0];
812 data1 = data[1];
813 if ((data0 == 0x00 && data1 == 0x11) ||
814 (data0 == 0x22 && data1 == 0x33) ||
815 (data0 == 0x44 && data1 == 0x55) ||
816 (data0 == 0x66 && data1 == 0x77) ||
817 (data0 == 0x88 && data1 == 0x99) ||
818 (data0 == 0xaa && data1 == 0xbb) ||
819 (data0 == 0xcc && data1 == 0xdd) ||
820 (data0 == 0xee && data1 == 0xff)) {
821 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
822 input_sync(gspca_dev->input_dev);
823 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
824 input_sync(gspca_dev->input_dev);
825 ret = 0;
826 }
827 }
828
829 return ret;
830}
831#endif
832
851/* sub-driver description for pac7311 */ 833/* sub-driver description for pac7311 */
852static struct sd_desc sd_desc = { 834static const struct sd_desc sd_desc = {
853 .name = MODULE_NAME, 835 .name = MODULE_NAME,
854 .ctrls = sd_ctrls, 836 .ctrls = sd_ctrls,
855 .nctrls = ARRAY_SIZE(sd_ctrls), 837 .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -860,6 +842,9 @@ static struct sd_desc sd_desc = {
860 .stop0 = sd_stop0, 842 .stop0 = sd_stop0,
861 .pkt_scan = sd_pkt_scan, 843 .pkt_scan = sd_pkt_scan,
862 .dq_callback = do_autogain, 844 .dq_callback = do_autogain,
845#ifdef CONFIG_INPUT
846 .int_pkt_scan = sd_int_pkt_scan,
847#endif
863}; 848};
864 849
865/* -- module initialisation -- */ 850/* -- module initialisation -- */