aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/pac7311.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2010-01-13 13:28:22 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:47 -0500
commit14799f6cf35f843806019f548e80ffa669d16102 (patch)
treed3a28b892df3eb11fa59ba78dd33d4889285f1e6 /drivers/media/video/gspca/pac7311.c
parentbe927befd091481f88c5806aa0585f25ab2ee3a1 (diff)
V4L/DVB: gspca - pac7311: Use usb_err to propagate USB errors
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/pac7311.c')
-rw-r--r--drivers/media/video/gspca/pac7311.c206
1 files changed, 81 insertions, 125 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index a9f195e6677c..ba73eb847fd1 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -258,12 +258,14 @@ static const __u8 page4_7311[] = {
258 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 258 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
259}; 259};
260 260
261static int reg_w_buf(struct gspca_dev *gspca_dev, 261static void reg_w_buf(struct gspca_dev *gspca_dev,
262 __u8 index, 262 __u8 index,
263 const char *buffer, int len) 263 const char *buffer, int len)
264{ 264{
265 int ret; 265 int ret;
266 266
267 if (gspca_dev->usb_err < 0)
268 return;
267 memcpy(gspca_dev->usb_buf, buffer, len); 269 memcpy(gspca_dev->usb_buf, buffer, len);
268 ret = usb_control_msg(gspca_dev->dev, 270 ret = usb_control_msg(gspca_dev->dev,
269 usb_sndctrlpipe(gspca_dev->dev, 0), 271 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -272,20 +274,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
272 0, /* value */ 274 0, /* value */
273 index, gspca_dev->usb_buf, len, 275 index, gspca_dev->usb_buf, len,
274 500); 276 500);
275 if (ret < 0) 277 if (ret < 0) {
276 PDEBUG(D_ERR, "reg_w_buf(): " 278 PDEBUG(D_ERR, "reg_w_buf(): "
277 "Failed to write registers to index 0x%x, error %i", 279 "Failed to write registers to index 0x%x, error %i",
278 index, ret); 280 index, ret);
279 return ret; 281 gspca_dev->usb_err = ret;
282 }
280} 283}
281 284
282 285
283static int reg_w(struct gspca_dev *gspca_dev, 286static void reg_w(struct gspca_dev *gspca_dev,
284 __u8 index, 287 __u8 index,
285 __u8 value) 288 __u8 value)
286{ 289{
287 int ret; 290 int ret;
288 291
292 if (gspca_dev->usb_err < 0)
293 return;
289 gspca_dev->usb_buf[0] = value; 294 gspca_dev->usb_buf[0] = value;
290 ret = usb_control_msg(gspca_dev->dev, 295 ret = usb_control_msg(gspca_dev->dev,
291 usb_sndctrlpipe(gspca_dev->dev, 0), 296 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -293,32 +298,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
293 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 298 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
294 0, index, gspca_dev->usb_buf, 1, 299 0, index, gspca_dev->usb_buf, 1,
295 500); 300 500);
296 if (ret < 0) 301 if (ret < 0) {
297 PDEBUG(D_ERR, "reg_w(): " 302 PDEBUG(D_ERR, "reg_w(): "
298 "Failed to write register to index 0x%x, value 0x%x, error %i", 303 "Failed to write register to index 0x%x, value 0x%x, error %i",
299 index, value, ret); 304 index, value, ret);
300 return ret; 305 gspca_dev->usb_err = ret;
306 }
301} 307}
302 308
303static int reg_w_seq(struct gspca_dev *gspca_dev, 309static void reg_w_seq(struct gspca_dev *gspca_dev,
304 const __u8 *seq, int len) 310 const __u8 *seq, int len)
305{ 311{
306 int ret = 0;
307 while (--len >= 0) { 312 while (--len >= 0) {
308 if (0 <= ret) 313 reg_w(gspca_dev, seq[0], seq[1]);
309 ret = reg_w(gspca_dev, seq[0], seq[1]);
310 seq += 2; 314 seq += 2;
311 } 315 }
312 return ret;
313} 316}
314 317
315/* load the beginning of a page */ 318/* load the beginning of a page */
316static int reg_w_page(struct gspca_dev *gspca_dev, 319static void reg_w_page(struct gspca_dev *gspca_dev,
317 const __u8 *page, int len) 320 const __u8 *page, int len)
318{ 321{
319 int index; 322 int index;
320 int ret = 0; 323 int ret = 0;
321 324
325 if (gspca_dev->usb_err < 0)
326 return;
322 for (index = 0; index < len; index++) { 327 for (index = 0; index < len; index++) {
323 if (page[index] == SKIP) /* skip this index */ 328 if (page[index] == SKIP) /* skip this index */
324 continue; 329 continue;
@@ -334,52 +339,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
334 "Failed to write register to index 0x%x, " 339 "Failed to write register to index 0x%x, "
335 "value 0x%x, error %i", 340 "value 0x%x, error %i",
336 index, page[index], ret); 341 index, page[index], ret);
342 gspca_dev->usb_err = ret;
337 break; 343 break;
338 } 344 }
339 } 345 }
340 return ret;
341} 346}
342 347
343/* output a variable sequence */ 348/* output a variable sequence */
344static int reg_w_var(struct gspca_dev *gspca_dev, 349static void reg_w_var(struct gspca_dev *gspca_dev,
345 const __u8 *seq, 350 const __u8 *seq,
346 const __u8 *page4, unsigned int page4_len) 351 const __u8 *page4, unsigned int page4_len)
347{ 352{
348 int index, len; 353 int index, len;
349 int ret = 0;
350 354
351 for (;;) { 355 for (;;) {
352 index = *seq++; 356 index = *seq++;
353 len = *seq++; 357 len = *seq++;
354 switch (len) { 358 switch (len) {
355 case END_OF_SEQUENCE: 359 case END_OF_SEQUENCE:
356 return ret; 360 return;
357 case LOAD_PAGE4: 361 case LOAD_PAGE4:
358 ret = reg_w_page(gspca_dev, page4, page4_len); 362 reg_w_page(gspca_dev, page4, page4_len);
359 break; 363 break;
360 default: 364 default:
361 if (len > USB_BUF_SZ) { 365 if (len > USB_BUF_SZ) {
362 PDEBUG(D_ERR|D_STREAM, 366 PDEBUG(D_ERR|D_STREAM,
363 "Incorrect variable sequence"); 367 "Incorrect variable sequence");
364 return -EINVAL; 368 return;
365 } 369 }
366 while (len > 0) { 370 while (len > 0) {
367 if (len < 8) { 371 if (len < 8) {
368 ret = reg_w_buf(gspca_dev, 372 reg_w_buf(gspca_dev,
369 index, seq, len); 373 index, seq, len);
370 if (ret < 0)
371 return ret;
372 seq += len; 374 seq += len;
373 break; 375 break;
374 } 376 }
375 ret = reg_w_buf(gspca_dev, index, seq, 8); 377 reg_w_buf(gspca_dev, index, seq, 8);
376 seq += 8; 378 seq += 8;
377 index += 8; 379 index += 8;
378 len -= 8; 380 len -= 8;
379 } 381 }
380 } 382 }
381 if (ret < 0)
382 return ret;
383 } 383 }
384 /* not reached */ 384 /* not reached */
385} 385}
@@ -407,46 +407,36 @@ static int sd_config(struct gspca_dev *gspca_dev,
407} 407}
408 408
409/* This function is used by pac7311 only */ 409/* This function is used by pac7311 only */
410static int setcontrast(struct gspca_dev *gspca_dev) 410static void setcontrast(struct gspca_dev *gspca_dev)
411{ 411{
412 struct sd *sd = (struct sd *) gspca_dev; 412 struct sd *sd = (struct sd *) gspca_dev;
413 int ret;
414 413
415 ret = reg_w(gspca_dev, 0xff, 0x04); 414 reg_w(gspca_dev, 0xff, 0x04);
416 if (0 <= ret) 415 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
417 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
418 /* load registers to sensor (Bit 0, auto clear) */ 416 /* load registers to sensor (Bit 0, auto clear) */
419 if (0 <= ret) 417 reg_w(gspca_dev, 0x11, 0x01);
420 ret = reg_w(gspca_dev, 0x11, 0x01);
421 return ret;
422} 418}
423 419
424static int setgain(struct gspca_dev *gspca_dev) 420static void setgain(struct gspca_dev *gspca_dev)
425{ 421{
426 struct sd *sd = (struct sd *) gspca_dev; 422 struct sd *sd = (struct sd *) gspca_dev;
427 int gain = GAIN_MAX - sd->gain; 423 int gain = GAIN_MAX - sd->gain;
428 int ret;
429 424
430 if (gain < 1) 425 if (gain < 1)
431 gain = 1; 426 gain = 1;
432 else if (gain > 245) 427 else if (gain > 245)
433 gain = 245; 428 gain = 245;
434 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 429 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
435 if (0 <= ret) 430 reg_w(gspca_dev, 0x0e, 0x00);
436 ret = reg_w(gspca_dev, 0x0e, 0x00); 431 reg_w(gspca_dev, 0x0f, gain);
437 if (0 <= ret)
438 ret = reg_w(gspca_dev, 0x0f, gain);
439 432
440 /* load registers to sensor (Bit 0, auto clear) */ 433 /* load registers to sensor (Bit 0, auto clear) */
441 if (0 <= ret) 434 reg_w(gspca_dev, 0x11, 0x01);
442 ret = reg_w(gspca_dev, 0x11, 0x01);
443 return ret;
444} 435}
445 436
446static int setexposure(struct gspca_dev *gspca_dev) 437static void setexposure(struct gspca_dev *gspca_dev)
447{ 438{
448 struct sd *sd = (struct sd *) gspca_dev; 439 struct sd *sd = (struct sd *) gspca_dev;
449 int ret;
450 __u8 reg; 440 __u8 reg;
451 441
452 /* register 2 of frame 3/4 contains the clock divider configuring the 442 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -458,93 +448,72 @@ static int setexposure(struct gspca_dev *gspca_dev)
458 else if (reg > 63) 448 else if (reg > 63)
459 reg = 63; 449 reg = 63;
460 450
461 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 451 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
462 if (0 <= ret) 452 reg_w(gspca_dev, 0x02, reg);
463 ret = reg_w(gspca_dev, 0x02, reg); 453
464 /* Page 1 register 8 must always be 0x08 except when not in 454 /* Page 1 register 8 must always be 0x08 except when not in
465 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ 455 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
466 if (0 <= ret) 456 reg_w(gspca_dev, 0xff, 0x01);
467 ret = reg_w(gspca_dev, 0xff, 0x01);
468 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && 457 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
469 reg <= 3) { 458 reg <= 3) {
470 if (0 <= ret) 459 reg_w(gspca_dev, 0x08, 0x09);
471 ret = reg_w(gspca_dev, 0x08, 0x09);
472 } else { 460 } else {
473 if (0 <= ret) 461 reg_w(gspca_dev, 0x08, 0x08);
474 ret = reg_w(gspca_dev, 0x08, 0x08);
475 } 462 }
476 463
477 /* load registers to sensor (Bit 0, auto clear) */ 464 /* load registers to sensor (Bit 0, auto clear) */
478 if (0 <= ret) 465 reg_w(gspca_dev, 0x11, 0x01);
479 ret = reg_w(gspca_dev, 0x11, 0x01);
480 return ret;
481} 466}
482 467
483static int sethvflip(struct gspca_dev *gspca_dev) 468static void sethvflip(struct gspca_dev *gspca_dev)
484{ 469{
485 struct sd *sd = (struct sd *) gspca_dev; 470 struct sd *sd = (struct sd *) gspca_dev;
486 int ret;
487 __u8 data; 471 __u8 data;
488 472
489 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 473 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
490 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); 474 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
491 if (0 <= ret) 475 reg_w(gspca_dev, 0x21, data);
492 ret = reg_w(gspca_dev, 0x21, data); 476
493 /* load registers to sensor (Bit 0, auto clear) */ 477 /* load registers to sensor (Bit 0, auto clear) */
494 if (0 <= ret) 478 reg_w(gspca_dev, 0x11, 0x01);
495 ret = reg_w(gspca_dev, 0x11, 0x01);
496 return ret;
497} 479}
498 480
499/* this function is called at probe and resume time for pac7311 */ 481/* this function is called at probe and resume time for pac7311 */
500static int sd_init(struct gspca_dev *gspca_dev) 482static int sd_init(struct gspca_dev *gspca_dev)
501{ 483{
502 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); 484 reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
485 return gspca_dev->usb_err;
503} 486}
504 487
505static int sd_start(struct gspca_dev *gspca_dev) 488static int sd_start(struct gspca_dev *gspca_dev)
506{ 489{
507 struct sd *sd = (struct sd *) gspca_dev; 490 struct sd *sd = (struct sd *) gspca_dev;
508 int ret;
509 491
510 sd->sof_read = 0; 492 sd->sof_read = 0;
511 493
512 ret = reg_w_var(gspca_dev, start_7311, 494 reg_w_var(gspca_dev, start_7311,
513 page4_7311, sizeof(page4_7311)); 495 page4_7311, sizeof(page4_7311));
514 if (0 <= ret) 496 setcontrast(gspca_dev);
515 ret = setcontrast(gspca_dev); 497 setgain(gspca_dev);
516 if (0 <= ret) 498 setexposure(gspca_dev);
517 ret = setgain(gspca_dev); 499 sethvflip(gspca_dev);
518 if (0 <= ret)
519 ret = setexposure(gspca_dev);
520 if (0 <= ret)
521 ret = sethvflip(gspca_dev);
522 500
523 /* set correct resolution */ 501 /* set correct resolution */
524 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 502 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
525 case 2: /* 160x120 pac7311 */ 503 case 2: /* 160x120 pac7311 */
526 if (0 <= ret) 504 reg_w(gspca_dev, 0xff, 0x01);
527 ret = reg_w(gspca_dev, 0xff, 0x01); 505 reg_w(gspca_dev, 0x17, 0x20);
528 if (0 <= ret) 506 reg_w(gspca_dev, 0x87, 0x10);
529 ret = reg_w(gspca_dev, 0x17, 0x20);
530 if (0 <= ret)
531 ret = reg_w(gspca_dev, 0x87, 0x10);
532 break; 507 break;
533 case 1: /* 320x240 pac7311 */ 508 case 1: /* 320x240 pac7311 */
534 if (0 <= ret) 509 reg_w(gspca_dev, 0xff, 0x01);
535 ret = reg_w(gspca_dev, 0xff, 0x01); 510 reg_w(gspca_dev, 0x17, 0x30);
536 if (0 <= ret) 511 reg_w(gspca_dev, 0x87, 0x11);
537 ret = reg_w(gspca_dev, 0x17, 0x30);
538 if (0 <= ret)
539 ret = reg_w(gspca_dev, 0x87, 0x11);
540 break; 512 break;
541 case 0: /* 640x480 */ 513 case 0: /* 640x480 */
542 if (0 <= ret) 514 reg_w(gspca_dev, 0xff, 0x01);
543 ret = reg_w(gspca_dev, 0xff, 0x01); 515 reg_w(gspca_dev, 0x17, 0x00);
544 if (0 <= ret) 516 reg_w(gspca_dev, 0x87, 0x12);
545 ret = reg_w(gspca_dev, 0x17, 0x00);
546 if (0 <= ret)
547 ret = reg_w(gspca_dev, 0x87, 0x12);
548 break; 517 break;
549 } 518 }
550 519
@@ -553,37 +522,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
553 atomic_set(&sd->avg_lum, -1); 522 atomic_set(&sd->avg_lum, -1);
554 523
555 /* start stream */ 524 /* start stream */
556 if (0 <= ret) 525 reg_w(gspca_dev, 0xff, 0x01);
557 ret = reg_w(gspca_dev, 0xff, 0x01); 526 reg_w(gspca_dev, 0x78, 0x05);
558 if (0 <= ret)
559 ret = reg_w(gspca_dev, 0x78, 0x05);
560 527
561 return ret; 528 return gspca_dev->usb_err;
562} 529}
563 530
564static void sd_stopN(struct gspca_dev *gspca_dev) 531static void sd_stopN(struct gspca_dev *gspca_dev)
565{ 532{
566 int ret; 533 reg_w(gspca_dev, 0xff, 0x04);
567 534 reg_w(gspca_dev, 0x27, 0x80);
568 ret = reg_w(gspca_dev, 0xff, 0x04); 535 reg_w(gspca_dev, 0x28, 0xca);
569 if (0 <= ret) 536 reg_w(gspca_dev, 0x29, 0x53);
570 ret = reg_w(gspca_dev, 0x27, 0x80); 537 reg_w(gspca_dev, 0x2a, 0x0e);
571 if (0 <= ret) 538 reg_w(gspca_dev, 0xff, 0x01);
572 ret = reg_w(gspca_dev, 0x28, 0xca); 539 reg_w(gspca_dev, 0x3e, 0x20);
573 if (0 <= ret) 540 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
574 ret = reg_w(gspca_dev, 0x29, 0x53); 541 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
575 if (0 <= ret) 542 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
576 ret = reg_w(gspca_dev, 0x2a, 0x0e);
577 if (0 <= ret)
578 ret = reg_w(gspca_dev, 0xff, 0x01);
579 if (0 <= ret)
580 ret = reg_w(gspca_dev, 0x3e, 0x20);
581 if (0 <= ret)
582 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
583 if (0 <= ret)
584 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
585 if (0 <= ret)
586 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
587} 543}
588 544
589/* called on streamoff with alt 0 and on disconnect for 7311 */ 545/* called on streamoff with alt 0 and on disconnect for 7311 */
@@ -728,7 +684,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
728 if (gspca_dev->streaming) { 684 if (gspca_dev->streaming) {
729 setcontrast(gspca_dev); 685 setcontrast(gspca_dev);
730 } 686 }
731 return 0; 687 return gspca_dev->usb_err;
732} 688}
733 689
734static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 690static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -746,7 +702,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
746 sd->gain = val; 702 sd->gain = val;
747 if (gspca_dev->streaming) 703 if (gspca_dev->streaming)
748 setgain(gspca_dev); 704 setgain(gspca_dev);
749 return 0; 705 return gspca_dev->usb_err;
750} 706}
751 707
752static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 708static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -764,7 +720,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
764 sd->exposure = val; 720 sd->exposure = val;
765 if (gspca_dev->streaming) 721 if (gspca_dev->streaming)
766 setexposure(gspca_dev); 722 setexposure(gspca_dev);
767 return 0; 723 return gspca_dev->usb_err;
768} 724}
769 725
770static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 726static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -795,7 +751,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
795 } 751 }
796 } 752 }
797 753
798 return 0; 754 return gspca_dev->usb_err;
799} 755}
800 756
801static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 757static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -813,7 +769,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
813 sd->hflip = val; 769 sd->hflip = val;
814 if (gspca_dev->streaming) 770 if (gspca_dev->streaming)
815 sethvflip(gspca_dev); 771 sethvflip(gspca_dev);
816 return 0; 772 return gspca_dev->usb_err;
817} 773}
818 774
819static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 775static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -831,7 +787,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
831 sd->vflip = val; 787 sd->vflip = val;
832 if (gspca_dev->streaming) 788 if (gspca_dev->streaming)
833 sethvflip(gspca_dev); 789 sethvflip(gspca_dev);
834 return 0; 790 return gspca_dev->usb_err;
835} 791}
836 792
837static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 793static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)