diff options
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 8 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-ctrl.h | 2 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 9 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 340 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.h | 13 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 7 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | 46 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h | 1 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 42 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-main.c | 8 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 23 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 94 |
12 files changed, 567 insertions, 26 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 0764fbfffb73..203f54cd18a1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -134,13 +134,17 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) | |||
134 | 134 | ||
135 | 135 | ||
136 | /* Retrieve control's default value (any type) */ | 136 | /* Retrieve control's default value (any type) */ |
137 | int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr) | 137 | int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr) |
138 | { | 138 | { |
139 | int ret = 0; | 139 | int ret = 0; |
140 | if (!cptr) return 0; | 140 | if (!cptr) return 0; |
141 | LOCK_TAKE(cptr->hdw->big_lock); do { | 141 | LOCK_TAKE(cptr->hdw->big_lock); do { |
142 | if (cptr->info->type == pvr2_ctl_int) { | 142 | if (cptr->info->type == pvr2_ctl_int) { |
143 | ret = cptr->info->default_value; | 143 | if (cptr->info->get_def_value) { |
144 | ret = cptr->info->get_def_value(cptr, valptr); | ||
145 | } else { | ||
146 | *valptr = cptr->info->default_value; | ||
147 | } | ||
144 | } | 148 | } |
145 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | 149 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); |
146 | return ret; | 150 | return ret; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h index 0371ae6e6e4e..794ff90121c7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h | |||
@@ -49,7 +49,7 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl *); | |||
49 | int pvr2_ctrl_get_min(struct pvr2_ctrl *); | 49 | int pvr2_ctrl_get_min(struct pvr2_ctrl *); |
50 | 50 | ||
51 | /* Retrieve control's default value (any type) */ | 51 | /* Retrieve control's default value (any type) */ |
52 | int pvr2_ctrl_get_def(struct pvr2_ctrl *); | 52 | int pvr2_ctrl_get_def(struct pvr2_ctrl *, int *valptr); |
53 | 53 | ||
54 | /* Retrieve control's enumeration count (enum only) */ | 54 | /* Retrieve control's enumeration count (enum only) */ |
55 | int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); | 55 | int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 657f861593b3..de7ee7264be6 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -82,6 +82,7 @@ struct pvr2_ctl_info { | |||
82 | 82 | ||
83 | /* Control's implementation */ | 83 | /* Control's implementation */ |
84 | pvr2_ctlf_get_value get_value; /* Get its value */ | 84 | pvr2_ctlf_get_value get_value; /* Get its value */ |
85 | pvr2_ctlf_get_value get_def_value; /* Get its default value */ | ||
85 | pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */ | 86 | pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */ |
86 | pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */ | 87 | pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */ |
87 | pvr2_ctlf_set_value set_value; /* Set its value */ | 88 | pvr2_ctlf_set_value set_value; /* Set its value */ |
@@ -307,6 +308,10 @@ struct pvr2_hdw { | |||
307 | struct v4l2_tuner tuner_signal_info; | 308 | struct v4l2_tuner tuner_signal_info; |
308 | int tuner_signal_stale; | 309 | int tuner_signal_stale; |
309 | 310 | ||
311 | /* Cropping capability info */ | ||
312 | struct v4l2_cropcap cropcap_info; | ||
313 | int cropcap_stale; | ||
314 | |||
310 | /* Video standard handling */ | 315 | /* Video standard handling */ |
311 | v4l2_std_id std_mask_eeprom; // Hardware supported selections | 316 | v4l2_std_id std_mask_eeprom; // Hardware supported selections |
312 | v4l2_std_id std_mask_avail; // Which standards we may select from | 317 | v4l2_std_id std_mask_avail; // Which standards we may select from |
@@ -367,6 +372,10 @@ struct pvr2_hdw { | |||
367 | VCREATE_DATA(bass); | 372 | VCREATE_DATA(bass); |
368 | VCREATE_DATA(treble); | 373 | VCREATE_DATA(treble); |
369 | VCREATE_DATA(mute); | 374 | VCREATE_DATA(mute); |
375 | VCREATE_DATA(cropl); | ||
376 | VCREATE_DATA(cropt); | ||
377 | VCREATE_DATA(cropw); | ||
378 | VCREATE_DATA(croph); | ||
370 | VCREATE_DATA(input); | 379 | VCREATE_DATA(input); |
371 | VCREATE_DATA(audiomode); | 380 | VCREATE_DATA(audiomode); |
372 | VCREATE_DATA(res_hor); | 381 | VCREATE_DATA(res_hor); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index f051c6aa7f1f..94265bd3d926 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -298,6 +298,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | |||
298 | unsigned int timeout,int probe_fl, | 298 | unsigned int timeout,int probe_fl, |
299 | void *write_data,unsigned int write_len, | 299 | void *write_data,unsigned int write_len, |
300 | void *read_data,unsigned int read_len); | 300 | void *read_data,unsigned int read_len); |
301 | static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw); | ||
301 | 302 | ||
302 | 303 | ||
303 | static void trace_stbit(const char *name,int val) | 304 | static void trace_stbit(const char *name,int val) |
@@ -402,6 +403,194 @@ static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) | |||
402 | return 0; | 403 | return 0; |
403 | } | 404 | } |
404 | 405 | ||
406 | static int ctrl_cropl_min_get(struct pvr2_ctrl *cptr, int *left) | ||
407 | { | ||
408 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
409 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
410 | if (stat != 0) { | ||
411 | return stat; | ||
412 | } | ||
413 | *left = cap->bounds.left; | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static int ctrl_cropl_max_get(struct pvr2_ctrl *cptr, int *left) | ||
418 | { | ||
419 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
420 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
421 | if (stat != 0) { | ||
422 | return stat; | ||
423 | } | ||
424 | *left = cap->bounds.left; | ||
425 | if (cap->bounds.width > cptr->hdw->cropw_val) { | ||
426 | *left += cap->bounds.width - cptr->hdw->cropw_val; | ||
427 | } | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int ctrl_cropt_min_get(struct pvr2_ctrl *cptr, int *top) | ||
432 | { | ||
433 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
434 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
435 | if (stat != 0) { | ||
436 | return stat; | ||
437 | } | ||
438 | *top = cap->bounds.top; | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top) | ||
443 | { | ||
444 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
445 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
446 | if (stat != 0) { | ||
447 | return stat; | ||
448 | } | ||
449 | *top = cap->bounds.top; | ||
450 | if (cap->bounds.height > cptr->hdw->croph_val) { | ||
451 | *top += cap->bounds.height - cptr->hdw->croph_val; | ||
452 | } | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *val) | ||
457 | { | ||
458 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
459 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
460 | if (stat != 0) { | ||
461 | return stat; | ||
462 | } | ||
463 | *val = 0; | ||
464 | if (cap->bounds.width > cptr->hdw->cropl_val) { | ||
465 | *val = cap->bounds.width - cptr->hdw->cropl_val; | ||
466 | } | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *val) | ||
471 | { | ||
472 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
473 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
474 | if (stat != 0) { | ||
475 | return stat; | ||
476 | } | ||
477 | *val = 0; | ||
478 | if (cap->bounds.height > cptr->hdw->cropt_val) { | ||
479 | *val = cap->bounds.height - cptr->hdw->cropt_val; | ||
480 | } | ||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | static int ctrl_get_cropcapbl(struct pvr2_ctrl *cptr, int *val) | ||
485 | { | ||
486 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
487 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
488 | if (stat != 0) { | ||
489 | return stat; | ||
490 | } | ||
491 | *val = cap->bounds.left; | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static int ctrl_get_cropcapbt(struct pvr2_ctrl *cptr, int *val) | ||
496 | { | ||
497 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
498 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
499 | if (stat != 0) { | ||
500 | return stat; | ||
501 | } | ||
502 | *val = cap->bounds.top; | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int ctrl_get_cropcapbw(struct pvr2_ctrl *cptr, int *val) | ||
507 | { | ||
508 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
509 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
510 | if (stat != 0) { | ||
511 | return stat; | ||
512 | } | ||
513 | *val = cap->bounds.width; | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int ctrl_get_cropcapbh(struct pvr2_ctrl *cptr, int *val) | ||
518 | { | ||
519 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
520 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
521 | if (stat != 0) { | ||
522 | return stat; | ||
523 | } | ||
524 | *val = cap->bounds.height; | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static int ctrl_get_cropcapdl(struct pvr2_ctrl *cptr, int *val) | ||
529 | { | ||
530 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
531 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
532 | if (stat != 0) { | ||
533 | return stat; | ||
534 | } | ||
535 | *val = cap->defrect.left; | ||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static int ctrl_get_cropcapdt(struct pvr2_ctrl *cptr, int *val) | ||
540 | { | ||
541 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
542 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
543 | if (stat != 0) { | ||
544 | return stat; | ||
545 | } | ||
546 | *val = cap->defrect.top; | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int ctrl_get_cropcapdw(struct pvr2_ctrl *cptr, int *val) | ||
551 | { | ||
552 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
553 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
554 | if (stat != 0) { | ||
555 | return stat; | ||
556 | } | ||
557 | *val = cap->defrect.width; | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int ctrl_get_cropcapdh(struct pvr2_ctrl *cptr, int *val) | ||
562 | { | ||
563 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
564 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
565 | if (stat != 0) { | ||
566 | return stat; | ||
567 | } | ||
568 | *val = cap->defrect.height; | ||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static int ctrl_get_cropcappan(struct pvr2_ctrl *cptr, int *val) | ||
573 | { | ||
574 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
575 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
576 | if (stat != 0) { | ||
577 | return stat; | ||
578 | } | ||
579 | *val = cap->pixelaspect.numerator; | ||
580 | return 0; | ||
581 | } | ||
582 | |||
583 | static int ctrl_get_cropcappad(struct pvr2_ctrl *cptr, int *val) | ||
584 | { | ||
585 | struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; | ||
586 | int stat = pvr2_hdw_check_cropcap(cptr->hdw); | ||
587 | if (stat != 0) { | ||
588 | return stat; | ||
589 | } | ||
590 | *val = cap->pixelaspect.denominator; | ||
591 | return 0; | ||
592 | } | ||
593 | |||
405 | static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) | 594 | static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) |
406 | { | 595 | { |
407 | /* Actual maximum depends on the video standard in effect. */ | 596 | /* Actual maximum depends on the video standard in effect. */ |
@@ -779,6 +968,10 @@ VCREATE_FUNCS(balance) | |||
779 | VCREATE_FUNCS(bass) | 968 | VCREATE_FUNCS(bass) |
780 | VCREATE_FUNCS(treble) | 969 | VCREATE_FUNCS(treble) |
781 | VCREATE_FUNCS(mute) | 970 | VCREATE_FUNCS(mute) |
971 | VCREATE_FUNCS(cropl) | ||
972 | VCREATE_FUNCS(cropt) | ||
973 | VCREATE_FUNCS(cropw) | ||
974 | VCREATE_FUNCS(croph) | ||
782 | VCREATE_FUNCS(audiomode) | 975 | VCREATE_FUNCS(audiomode) |
783 | VCREATE_FUNCS(res_hor) | 976 | VCREATE_FUNCS(res_hor) |
784 | VCREATE_FUNCS(res_ver) | 977 | VCREATE_FUNCS(res_ver) |
@@ -849,6 +1042,72 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
849 | .default_value = 0, | 1042 | .default_value = 0, |
850 | DEFREF(mute), | 1043 | DEFREF(mute), |
851 | DEFBOOL, | 1044 | DEFBOOL, |
1045 | }, { | ||
1046 | .desc = "Capture crop left margin", | ||
1047 | .name = "crop_left", | ||
1048 | .internal_id = PVR2_CID_CROPL, | ||
1049 | .default_value = 0, | ||
1050 | DEFREF(cropl), | ||
1051 | DEFINT(-129, 340), | ||
1052 | .get_min_value = ctrl_cropl_min_get, | ||
1053 | .get_max_value = ctrl_cropl_max_get, | ||
1054 | .get_def_value = ctrl_get_cropcapdl, | ||
1055 | }, { | ||
1056 | .desc = "Capture crop top margin", | ||
1057 | .name = "crop_top", | ||
1058 | .internal_id = PVR2_CID_CROPT, | ||
1059 | .default_value = 0, | ||
1060 | DEFREF(cropt), | ||
1061 | DEFINT(-35, 544), | ||
1062 | .get_min_value = ctrl_cropt_min_get, | ||
1063 | .get_max_value = ctrl_cropt_max_get, | ||
1064 | .get_def_value = ctrl_get_cropcapdt, | ||
1065 | }, { | ||
1066 | .desc = "Capture crop width", | ||
1067 | .name = "crop_width", | ||
1068 | .internal_id = PVR2_CID_CROPW, | ||
1069 | .default_value = 720, | ||
1070 | DEFREF(cropw), | ||
1071 | .get_max_value = ctrl_cropw_max_get, | ||
1072 | .get_def_value = ctrl_get_cropcapdw, | ||
1073 | }, { | ||
1074 | .desc = "Capture crop height", | ||
1075 | .name = "crop_height", | ||
1076 | .internal_id = PVR2_CID_CROPH, | ||
1077 | .default_value = 480, | ||
1078 | DEFREF(croph), | ||
1079 | .get_max_value = ctrl_croph_max_get, | ||
1080 | .get_def_value = ctrl_get_cropcapdh, | ||
1081 | }, { | ||
1082 | .desc = "Capture capability pixel aspect numerator", | ||
1083 | .name = "cropcap_pixel_numerator", | ||
1084 | .internal_id = PVR2_CID_CROPCAPPAN, | ||
1085 | .get_value = ctrl_get_cropcappan, | ||
1086 | }, { | ||
1087 | .desc = "Capture capability pixel aspect denominator", | ||
1088 | .name = "cropcap_pixel_denominator", | ||
1089 | .internal_id = PVR2_CID_CROPCAPPAD, | ||
1090 | .get_value = ctrl_get_cropcappad, | ||
1091 | }, { | ||
1092 | .desc = "Capture capability bounds top", | ||
1093 | .name = "cropcap_bounds_top", | ||
1094 | .internal_id = PVR2_CID_CROPCAPBT, | ||
1095 | .get_value = ctrl_get_cropcapbt, | ||
1096 | }, { | ||
1097 | .desc = "Capture capability bounds left", | ||
1098 | .name = "cropcap_bounds_left", | ||
1099 | .internal_id = PVR2_CID_CROPCAPBL, | ||
1100 | .get_value = ctrl_get_cropcapbl, | ||
1101 | }, { | ||
1102 | .desc = "Capture capability bounds width", | ||
1103 | .name = "cropcap_bounds_width", | ||
1104 | .internal_id = PVR2_CID_CROPCAPBW, | ||
1105 | .get_value = ctrl_get_cropcapbw, | ||
1106 | }, { | ||
1107 | .desc = "Capture capability bounds height", | ||
1108 | .name = "cropcap_bounds_height", | ||
1109 | .internal_id = PVR2_CID_CROPCAPBH, | ||
1110 | .get_value = ctrl_get_cropcapbh, | ||
852 | },{ | 1111 | },{ |
853 | .desc = "Video Source", | 1112 | .desc = "Video Source", |
854 | .name = "input", | 1113 | .name = "input", |
@@ -1313,9 +1572,19 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1313 | if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE; | 1572 | if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE; |
1314 | memcpy(fw_ptr, fw_entry->data + fw_done, bcnt); | 1573 | memcpy(fw_ptr, fw_entry->data + fw_done, bcnt); |
1315 | /* Usbsnoop log shows that we must swap bytes... */ | 1574 | /* Usbsnoop log shows that we must swap bytes... */ |
1575 | /* Some background info: The data being swapped here is a | ||
1576 | firmware image destined for the mpeg encoder chip that | ||
1577 | lives at the other end of a USB endpoint. The encoder | ||
1578 | chip always talks in 32 bit chunks and its storage is | ||
1579 | organized into 32 bit words. However from the file | ||
1580 | system to the encoder chip everything is purely a byte | ||
1581 | stream. The firmware file's contents are always 32 bit | ||
1582 | swapped from what the encoder expects. Thus the need | ||
1583 | always exists to swap the bytes regardless of the endian | ||
1584 | type of the host processor and therefore swab32() makes | ||
1585 | the most sense. */ | ||
1316 | for (icnt = 0; icnt < bcnt/4 ; icnt++) | 1586 | for (icnt = 0; icnt < bcnt/4 ; icnt++) |
1317 | ((u32 *)fw_ptr)[icnt] = | 1587 | ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); |
1318 | ___swab32(((u32 *)fw_ptr)[icnt]); | ||
1319 | 1588 | ||
1320 | ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, | 1589 | ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, |
1321 | &actual_length, HZ); | 1590 | &actual_length, HZ); |
@@ -1905,7 +2174,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1905 | const struct usb_device_id *devid) | 2174 | const struct usb_device_id *devid) |
1906 | { | 2175 | { |
1907 | unsigned int idx,cnt1,cnt2,m; | 2176 | unsigned int idx,cnt1,cnt2,m; |
1908 | struct pvr2_hdw *hdw; | 2177 | struct pvr2_hdw *hdw = NULL; |
1909 | int valid_std_mask; | 2178 | int valid_std_mask; |
1910 | struct pvr2_ctrl *cptr; | 2179 | struct pvr2_ctrl *cptr; |
1911 | const struct pvr2_device_desc *hdw_desc; | 2180 | const struct pvr2_device_desc *hdw_desc; |
@@ -1915,6 +2184,16 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1915 | 2184 | ||
1916 | hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); | 2185 | hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); |
1917 | 2186 | ||
2187 | if (hdw_desc == NULL) { | ||
2188 | pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create:" | ||
2189 | " No device description pointer," | ||
2190 | " unable to continue."); | ||
2191 | pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type," | ||
2192 | " please contact Mike Isely <isely@pobox.com>" | ||
2193 | " to get it included in the driver\n"); | ||
2194 | goto fail; | ||
2195 | } | ||
2196 | |||
1918 | hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); | 2197 | hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); |
1919 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", | 2198 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", |
1920 | hdw,hdw_desc->description); | 2199 | hdw,hdw_desc->description); |
@@ -2072,6 +2351,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2072 | valid_std_mask; | 2351 | valid_std_mask; |
2073 | } | 2352 | } |
2074 | 2353 | ||
2354 | hdw->cropcap_stale = !0; | ||
2075 | hdw->eeprom_addr = -1; | 2355 | hdw->eeprom_addr = -1; |
2076 | hdw->unit_number = -1; | 2356 | hdw->unit_number = -1; |
2077 | hdw->v4l_minor_number_video = -1; | 2357 | hdw->v4l_minor_number_video = -1; |
@@ -2508,6 +2788,28 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | |||
2508 | /* Can't commit anything until pathway is ok. */ | 2788 | /* Can't commit anything until pathway is ok. */ |
2509 | return 0; | 2789 | return 0; |
2510 | } | 2790 | } |
2791 | /* The broadcast decoder can only scale down, so if | ||
2792 | * res_*_dirty && crop window < output format ==> enlarge crop. | ||
2793 | * | ||
2794 | * The mpeg encoder receives fields of res_hor_val dots and | ||
2795 | * res_ver_val halflines. Limits: hor<=720, ver<=576. | ||
2796 | */ | ||
2797 | if (hdw->res_hor_dirty && hdw->cropw_val < hdw->res_hor_val) { | ||
2798 | hdw->cropw_val = hdw->res_hor_val; | ||
2799 | hdw->cropw_dirty = !0; | ||
2800 | } else if (hdw->cropw_dirty) { | ||
2801 | hdw->res_hor_dirty = !0; /* must rescale */ | ||
2802 | hdw->res_hor_val = min(720, hdw->cropw_val); | ||
2803 | } | ||
2804 | if (hdw->res_ver_dirty && hdw->croph_val < hdw->res_ver_val) { | ||
2805 | hdw->croph_val = hdw->res_ver_val; | ||
2806 | hdw->croph_dirty = !0; | ||
2807 | } else if (hdw->croph_dirty) { | ||
2808 | int nvres = hdw->std_mask_cur & V4L2_STD_525_60 ? 480 : 576; | ||
2809 | hdw->res_ver_dirty = !0; | ||
2810 | hdw->res_ver_val = min(nvres, hdw->croph_val); | ||
2811 | } | ||
2812 | |||
2511 | /* If any of the below has changed, then we can't do the update | 2813 | /* If any of the below has changed, then we can't do the update |
2512 | while the pipeline is running. Pipeline must be paused first | 2814 | while the pipeline is running. Pipeline must be paused first |
2513 | and decoder -> encoder connection be made quiescent before we | 2815 | and decoder -> encoder connection be made quiescent before we |
@@ -2518,6 +2820,8 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | |||
2518 | hdw->srate_dirty || | 2820 | hdw->srate_dirty || |
2519 | hdw->res_ver_dirty || | 2821 | hdw->res_ver_dirty || |
2520 | hdw->res_hor_dirty || | 2822 | hdw->res_hor_dirty || |
2823 | hdw->cropw_dirty || | ||
2824 | hdw->croph_dirty || | ||
2521 | hdw->input_dirty || | 2825 | hdw->input_dirty || |
2522 | (hdw->active_stream_type != hdw->desired_stream_type)); | 2826 | (hdw->active_stream_type != hdw->desired_stream_type)); |
2523 | if (disruptive_change && !hdw->state_pipeline_idle) { | 2827 | if (disruptive_change && !hdw->state_pipeline_idle) { |
@@ -2587,6 +2891,9 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | |||
2587 | } | 2891 | } |
2588 | 2892 | ||
2589 | hdw->state_pipeline_config = !0; | 2893 | hdw->state_pipeline_config = !0; |
2894 | /* Hardware state may have changed in a way to cause the cropping | ||
2895 | capabilities to have changed. So mark it stale, which will | ||
2896 | cause a later re-fetch. */ | ||
2590 | trace_stbit("state_pipeline_config",hdw->state_pipeline_config); | 2897 | trace_stbit("state_pipeline_config",hdw->state_pipeline_config); |
2591 | return !0; | 2898 | return !0; |
2592 | } | 2899 | } |
@@ -2677,6 +2984,33 @@ void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw) | |||
2677 | } | 2984 | } |
2678 | 2985 | ||
2679 | 2986 | ||
2987 | static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw) | ||
2988 | { | ||
2989 | if (!hdw->cropcap_stale) { | ||
2990 | return 0; | ||
2991 | } | ||
2992 | pvr2_i2c_core_status_poll(hdw); | ||
2993 | if (hdw->cropcap_stale) { | ||
2994 | return -EIO; | ||
2995 | } | ||
2996 | return 0; | ||
2997 | } | ||
2998 | |||
2999 | |||
3000 | /* Return information about cropping capabilities */ | ||
3001 | int pvr2_hdw_get_cropcap(struct pvr2_hdw *hdw, struct v4l2_cropcap *pp) | ||
3002 | { | ||
3003 | int stat = 0; | ||
3004 | LOCK_TAKE(hdw->big_lock); | ||
3005 | stat = pvr2_hdw_check_cropcap(hdw); | ||
3006 | if (!stat) { | ||
3007 | memcpy(pp, &hdw->cropcap_info, sizeof(hdw->cropcap_info)); | ||
3008 | } | ||
3009 | LOCK_GIVE(hdw->big_lock); | ||
3010 | return stat; | ||
3011 | } | ||
3012 | |||
3013 | |||
2680 | /* Return information about the tuner */ | 3014 | /* Return information about the tuner */ |
2681 | int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) | 3015 | int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) |
2682 | { | 3016 | { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index c04956d304a7..49482d1f2b28 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
@@ -36,6 +36,16 @@ | |||
36 | #define PVR2_CID_FREQUENCY 6 | 36 | #define PVR2_CID_FREQUENCY 6 |
37 | #define PVR2_CID_HRES 7 | 37 | #define PVR2_CID_HRES 7 |
38 | #define PVR2_CID_VRES 8 | 38 | #define PVR2_CID_VRES 8 |
39 | #define PVR2_CID_CROPL 9 | ||
40 | #define PVR2_CID_CROPT 10 | ||
41 | #define PVR2_CID_CROPW 11 | ||
42 | #define PVR2_CID_CROPH 12 | ||
43 | #define PVR2_CID_CROPCAPPAN 13 | ||
44 | #define PVR2_CID_CROPCAPPAD 14 | ||
45 | #define PVR2_CID_CROPCAPBL 15 | ||
46 | #define PVR2_CID_CROPCAPBT 16 | ||
47 | #define PVR2_CID_CROPCAPBW 17 | ||
48 | #define PVR2_CID_CROPCAPBH 18 | ||
39 | 49 | ||
40 | /* Legal values for the INPUT state variable */ | 50 | /* Legal values for the INPUT state variable */ |
41 | #define PVR2_CVAL_INPUT_TV 0 | 51 | #define PVR2_CVAL_INPUT_TV 0 |
@@ -170,6 +180,9 @@ void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *); | |||
170 | /* Return information about the tuner */ | 180 | /* Return information about the tuner */ |
171 | int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *); | 181 | int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *); |
172 | 182 | ||
183 | /* Return information about cropping capabilities */ | ||
184 | int pvr2_hdw_get_cropcap(struct pvr2_hdw *, struct v4l2_cropcap *); | ||
185 | |||
173 | /* Query device and see if it thinks it is on a high-speed USB link */ | 186 | /* Query device and see if it thinks it is on a high-speed USB link */ |
174 | int pvr2_hdw_is_hsm(struct pvr2_hdw *); | 187 | int pvr2_hdw_is_hsm(struct pvr2_hdw *); |
175 | 188 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index ccdb429fc7af..94a47718e88e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | |||
@@ -37,8 +37,9 @@ | |||
37 | #define OP_VOLUME 3 | 37 | #define OP_VOLUME 3 |
38 | #define OP_FREQ 4 | 38 | #define OP_FREQ 4 |
39 | #define OP_AUDIORATE 5 | 39 | #define OP_AUDIORATE 5 |
40 | #define OP_SIZE 6 | 40 | #define OP_CROP 6 |
41 | #define OP_LOG 7 | 41 | #define OP_SIZE 7 |
42 | #define OP_LOG 8 | ||
42 | 43 | ||
43 | static const struct pvr2_i2c_op * const ops[] = { | 44 | static const struct pvr2_i2c_op * const ops[] = { |
44 | [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, | 45 | [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, |
@@ -46,6 +47,7 @@ static const struct pvr2_i2c_op * const ops[] = { | |||
46 | [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, | 47 | [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, |
47 | [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, | 48 | [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, |
48 | [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, | 49 | [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, |
50 | [OP_CROP] = &pvr2_i2c_op_v4l2_crop, | ||
49 | [OP_SIZE] = &pvr2_i2c_op_v4l2_size, | 51 | [OP_SIZE] = &pvr2_i2c_op_v4l2_size, |
50 | [OP_LOG] = &pvr2_i2c_op_v4l2_log, | 52 | [OP_LOG] = &pvr2_i2c_op_v4l2_log, |
51 | }; | 53 | }; |
@@ -59,6 +61,7 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) | |||
59 | (1 << OP_BCSH) | | 61 | (1 << OP_BCSH) | |
60 | (1 << OP_VOLUME) | | 62 | (1 << OP_VOLUME) | |
61 | (1 << OP_FREQ) | | 63 | (1 << OP_FREQ) | |
64 | (1 << OP_CROP) | | ||
62 | (1 << OP_SIZE) | | 65 | (1 << OP_SIZE) | |
63 | (1 << OP_LOG)); | 66 | (1 << OP_LOG)); |
64 | cp->status_poll = pvr2_v4l2_cmd_status_poll; | 67 | cp->status_poll = pvr2_v4l2_cmd_status_poll; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c index 55f04a0b2047..16bb11902a52 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | |||
@@ -37,6 +37,7 @@ static void set_standard(struct pvr2_hdw *hdw) | |||
37 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); | 37 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); |
38 | } | 38 | } |
39 | hdw->tuner_signal_stale = !0; | 39 | hdw->tuner_signal_stale = !0; |
40 | hdw->cropcap_stale = !0; | ||
40 | } | 41 | } |
41 | 42 | ||
42 | 43 | ||
@@ -233,6 +234,37 @@ const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { | |||
233 | }; | 234 | }; |
234 | 235 | ||
235 | 236 | ||
237 | static void set_crop(struct pvr2_hdw *hdw) | ||
238 | { | ||
239 | struct v4l2_crop crop; | ||
240 | |||
241 | memset(&crop, 0, sizeof crop); | ||
242 | crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
243 | crop.c.left = hdw->cropl_val; | ||
244 | crop.c.top = hdw->cropt_val; | ||
245 | crop.c.height = hdw->croph_val; | ||
246 | crop.c.width = hdw->cropw_val; | ||
247 | |||
248 | pvr2_trace(PVR2_TRACE_CHIPS, | ||
249 | "i2c v4l2 set_crop crop=%d:%d:%d:%d", | ||
250 | crop.c.width, crop.c.height, crop.c.left, crop.c.top); | ||
251 | |||
252 | pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop); | ||
253 | } | ||
254 | |||
255 | static int check_crop(struct pvr2_hdw *hdw) | ||
256 | { | ||
257 | return (hdw->cropl_dirty || hdw->cropt_dirty || | ||
258 | hdw->cropw_dirty || hdw->croph_dirty); | ||
259 | } | ||
260 | |||
261 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = { | ||
262 | .check = check_crop, | ||
263 | .update = set_crop, | ||
264 | .name = "v4l2_crop", | ||
265 | }; | ||
266 | |||
267 | |||
236 | static void do_log(struct pvr2_hdw *hdw) | 268 | static void do_log(struct pvr2_hdw *hdw) |
237 | { | 269 | { |
238 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); | 270 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); |
@@ -263,7 +295,19 @@ void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) | |||
263 | 295 | ||
264 | void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp) | 296 | void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp) |
265 | { | 297 | { |
266 | pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&cp->hdw->tuner_signal_info); | 298 | int stat; |
299 | struct pvr2_hdw *hdw = cp->hdw; | ||
300 | if (hdw->cropcap_stale) { | ||
301 | hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
302 | stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP, | ||
303 | &hdw->cropcap_info); | ||
304 | if (stat == 0) { | ||
305 | /* Check was successful, so the data is no | ||
306 | longer considered stale. */ | ||
307 | hdw->cropcap_stale = 0; | ||
308 | } | ||
309 | } | ||
310 | pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info); | ||
267 | } | 311 | } |
268 | 312 | ||
269 | 313 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h index 7fa38683b3b1..eb744a20610d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h | |||
@@ -29,6 +29,7 @@ extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio; | |||
29 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; | 29 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; |
30 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; | 30 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; |
31 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; | 31 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; |
32 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop; | ||
32 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; | 33 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; |
33 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode; | 34 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode; |
34 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; | 35 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index e600576a6c4b..d6a35401fefb 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | |||
@@ -827,7 +827,7 @@ static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, | |||
827 | if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { | 827 | if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { |
828 | unsigned int idx; | 828 | unsigned int idx; |
829 | unsigned long msk,sm; | 829 | unsigned long msk,sm; |
830 | int spcfl; | 830 | |
831 | bcnt = scnprintf(buf,maxlen," ["); | 831 | bcnt = scnprintf(buf,maxlen," ["); |
832 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | 832 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; |
833 | sm = 0; | 833 | sm = 0; |
@@ -891,6 +891,7 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client) | |||
891 | INIT_LIST_HEAD(&cp->list); | 891 | INIT_LIST_HEAD(&cp->list); |
892 | cp->client = client; | 892 | cp->client = client; |
893 | mutex_lock(&hdw->i2c_list_lock); do { | 893 | mutex_lock(&hdw->i2c_list_lock); do { |
894 | hdw->cropcap_stale = !0; | ||
894 | list_add_tail(&cp->list,&hdw->i2c_clients); | 895 | list_add_tail(&cp->list,&hdw->i2c_clients); |
895 | hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; | 896 | hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; |
896 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | 897 | } while (0); mutex_unlock(&hdw->i2c_list_lock); |
@@ -905,6 +906,7 @@ static int pvr2_i2c_detach_inform(struct i2c_client *client) | |||
905 | unsigned long amask = 0; | 906 | unsigned long amask = 0; |
906 | int foundfl = 0; | 907 | int foundfl = 0; |
907 | mutex_lock(&hdw->i2c_list_lock); do { | 908 | mutex_lock(&hdw->i2c_list_lock); do { |
909 | hdw->cropcap_stale = !0; | ||
908 | list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) { | 910 | list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) { |
909 | if (cp->client == client) { | 911 | if (cp->client == client) { |
910 | trace_i2c("pvr2_i2c_detach" | 912 | trace_i2c("pvr2_i2c_detach" |
@@ -946,22 +948,32 @@ static struct i2c_adapter pvr2_i2c_adap_template = { | |||
946 | .client_unregister = pvr2_i2c_detach_inform, | 948 | .client_unregister = pvr2_i2c_detach_inform, |
947 | }; | 949 | }; |
948 | 950 | ||
949 | static void do_i2c_scan(struct pvr2_hdw *hdw) | 951 | |
952 | /* Return true if device exists at given address */ | ||
953 | static int do_i2c_probe(struct pvr2_hdw *hdw, int addr) | ||
950 | { | 954 | { |
951 | struct i2c_msg msg[1]; | 955 | struct i2c_msg msg[1]; |
952 | int i,rc; | 956 | int rc; |
953 | msg[0].addr = 0; | 957 | msg[0].addr = 0; |
954 | msg[0].flags = I2C_M_RD; | 958 | msg[0].flags = I2C_M_RD; |
955 | msg[0].len = 0; | 959 | msg[0].len = 0; |
956 | msg[0].buf = NULL; | 960 | msg[0].buf = NULL; |
957 | printk("%s: i2c scan beginning\n",hdw->name); | 961 | msg[0].addr = addr; |
962 | rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg)); | ||
963 | return rc == 1; | ||
964 | } | ||
965 | |||
966 | static void do_i2c_scan(struct pvr2_hdw *hdw) | ||
967 | { | ||
968 | int i; | ||
969 | printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name); | ||
958 | for (i = 0; i < 128; i++) { | 970 | for (i = 0; i < 128; i++) { |
959 | msg[0].addr = i; | 971 | if (do_i2c_probe(hdw, i)) { |
960 | rc = i2c_transfer(&hdw->i2c_adap,msg, ARRAY_SIZE(msg)); | 972 | printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n", |
961 | if (rc != 1) continue; | 973 | hdw->name, i); |
962 | printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i); | 974 | } |
963 | } | 975 | } |
964 | printk("%s: i2c scan done.\n",hdw->name); | 976 | printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); |
965 | } | 977 | } |
966 | 978 | ||
967 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | 979 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) |
@@ -980,8 +992,6 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | |||
980 | hdw->i2c_func[0x18] = i2c_black_hole; | 992 | hdw->i2c_func[0x18] = i2c_black_hole; |
981 | } else if (ir_mode[hdw->unit_number] == 1) { | 993 | } else if (ir_mode[hdw->unit_number] == 1) { |
982 | if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { | 994 | if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { |
983 | /* This comment is present PURELY to get | ||
984 | checkpatch.pl to STFU. Lovely, eh? */ | ||
985 | hdw->i2c_func[0x18] = i2c_24xxx_ir; | 995 | hdw->i2c_func[0x18] = i2c_24xxx_ir; |
986 | } | 996 | } |
987 | } | 997 | } |
@@ -1006,6 +1016,16 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | |||
1006 | mutex_init(&hdw->i2c_list_lock); | 1016 | mutex_init(&hdw->i2c_list_lock); |
1007 | hdw->i2c_linked = !0; | 1017 | hdw->i2c_linked = !0; |
1008 | i2c_add_adapter(&hdw->i2c_adap); | 1018 | i2c_add_adapter(&hdw->i2c_adap); |
1019 | if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { | ||
1020 | /* Probe for a different type of IR receiver on this | ||
1021 | device. If present, disable the emulated IR receiver. */ | ||
1022 | if (do_i2c_probe(hdw, 0x71)) { | ||
1023 | pvr2_trace(PVR2_TRACE_INFO, | ||
1024 | "Device has newer IR hardware;" | ||
1025 | " disabling unneeded virtual IR device"); | ||
1026 | hdw->i2c_func[0x18] = NULL; | ||
1027 | } | ||
1028 | } | ||
1009 | if (i2c_scan) do_i2c_scan(hdw); | 1029 | if (i2c_scan) do_i2c_scan(hdw); |
1010 | } | 1030 | } |
1011 | 1031 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index ad0d98c2ebb4..9b3c874d96d6 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c | |||
@@ -137,9 +137,11 @@ static int __init pvr_init(void) | |||
137 | ret = usb_register(&pvr_driver); | 137 | ret = usb_register(&pvr_driver); |
138 | 138 | ||
139 | if (ret == 0) | 139 | if (ret == 0) |
140 | info(DRIVER_DESC " : " DRIVER_VERSION); | 140 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" |
141 | if (pvrusb2_debug) info("Debug mask is %d (0x%x)", | 141 | DRIVER_DESC "\n"); |
142 | pvrusb2_debug,pvrusb2_debug); | 142 | if (pvrusb2_debug) |
143 | printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n", | ||
144 | pvrusb2_debug,pvrusb2_debug); | ||
143 | 145 | ||
144 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); | 146 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); |
145 | 147 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 46a8c39ba030..733680f21317 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -65,6 +65,7 @@ struct pvr2_sysfs_ctl_item { | |||
65 | struct device_attribute attr_type; | 65 | struct device_attribute attr_type; |
66 | struct device_attribute attr_min; | 66 | struct device_attribute attr_min; |
67 | struct device_attribute attr_max; | 67 | struct device_attribute attr_max; |
68 | struct device_attribute attr_def; | ||
68 | struct device_attribute attr_enum; | 69 | struct device_attribute attr_enum; |
69 | struct device_attribute attr_bits; | 70 | struct device_attribute attr_bits; |
70 | struct device_attribute attr_val; | 71 | struct device_attribute attr_val; |
@@ -145,6 +146,23 @@ static ssize_t show_max(struct device *class_dev, | |||
145 | return scnprintf(buf, PAGE_SIZE, "%ld\n", val); | 146 | return scnprintf(buf, PAGE_SIZE, "%ld\n", val); |
146 | } | 147 | } |
147 | 148 | ||
149 | static ssize_t show_def(struct device *class_dev, | ||
150 | struct device_attribute *attr, | ||
151 | char *buf) | ||
152 | { | ||
153 | struct pvr2_sysfs_ctl_item *cip; | ||
154 | int val; | ||
155 | int ret; | ||
156 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def); | ||
157 | ret = pvr2_ctrl_get_def(cip->cptr, &val); | ||
158 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %d, stat=%d", | ||
159 | cip->chptr, cip->ctl_id, val, ret); | ||
160 | if (ret < 0) { | ||
161 | return ret; | ||
162 | } | ||
163 | return scnprintf(buf, PAGE_SIZE, "%d\n", val); | ||
164 | } | ||
165 | |||
148 | static ssize_t show_val_norm(struct device *class_dev, | 166 | static ssize_t show_val_norm(struct device *class_dev, |
149 | struct device_attribute *attr, | 167 | struct device_attribute *attr, |
150 | char *buf) | 168 | char *buf) |
@@ -320,6 +338,10 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
320 | cip->attr_max.attr.mode = S_IRUGO; | 338 | cip->attr_max.attr.mode = S_IRUGO; |
321 | cip->attr_max.show = show_max; | 339 | cip->attr_max.show = show_max; |
322 | 340 | ||
341 | cip->attr_def.attr.name = "def_val"; | ||
342 | cip->attr_def.attr.mode = S_IRUGO; | ||
343 | cip->attr_def.show = show_def; | ||
344 | |||
323 | cip->attr_val.attr.name = "cur_val"; | 345 | cip->attr_val.attr.name = "cur_val"; |
324 | cip->attr_val.attr.mode = S_IRUGO; | 346 | cip->attr_val.attr.mode = S_IRUGO; |
325 | 347 | ||
@@ -343,6 +365,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
343 | cip->attr_gen[acnt++] = &cip->attr_name.attr; | 365 | cip->attr_gen[acnt++] = &cip->attr_name.attr; |
344 | cip->attr_gen[acnt++] = &cip->attr_type.attr; | 366 | cip->attr_gen[acnt++] = &cip->attr_type.attr; |
345 | cip->attr_gen[acnt++] = &cip->attr_val.attr; | 367 | cip->attr_gen[acnt++] = &cip->attr_val.attr; |
368 | cip->attr_gen[acnt++] = &cip->attr_def.attr; | ||
346 | cip->attr_val.show = show_val_norm; | 369 | cip->attr_val.show = show_val_norm; |
347 | cip->attr_val.store = store_val_norm; | 370 | cip->attr_val.store = store_val_norm; |
348 | if (pvr2_ctrl_has_custom_symbols(cptr)) { | 371 | if (pvr2_ctrl_has_custom_symbols(cptr)) { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 00306faeac01..f048d80b77e5 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -533,7 +533,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
533 | 533 | ||
534 | lmin = pvr2_ctrl_get_min(hcp); | 534 | lmin = pvr2_ctrl_get_min(hcp); |
535 | lmax = pvr2_ctrl_get_max(hcp); | 535 | lmax = pvr2_ctrl_get_max(hcp); |
536 | ldef = pvr2_ctrl_get_def(hcp); | 536 | pvr2_ctrl_get_def(hcp, &ldef); |
537 | if (w == -1) { | 537 | if (w == -1) { |
538 | w = ldef; | 538 | w = ldef; |
539 | } else if (w < lmin) { | 539 | } else if (w < lmin) { |
@@ -543,7 +543,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
543 | } | 543 | } |
544 | lmin = pvr2_ctrl_get_min(vcp); | 544 | lmin = pvr2_ctrl_get_min(vcp); |
545 | lmax = pvr2_ctrl_get_max(vcp); | 545 | lmax = pvr2_ctrl_get_max(vcp); |
546 | ldef = pvr2_ctrl_get_def(vcp); | 546 | pvr2_ctrl_get_def(vcp, &ldef); |
547 | if (h == -1) { | 547 | if (h == -1) { |
548 | h = ldef; | 548 | h = ldef; |
549 | } else if (h < lmin) { | 549 | } else if (h < lmin) { |
@@ -604,6 +604,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
604 | case VIDIOC_QUERYCTRL: | 604 | case VIDIOC_QUERYCTRL: |
605 | { | 605 | { |
606 | struct pvr2_ctrl *cptr; | 606 | struct pvr2_ctrl *cptr; |
607 | int val; | ||
607 | struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; | 608 | struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; |
608 | ret = 0; | 609 | ret = 0; |
609 | if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { | 610 | if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { |
@@ -627,7 +628,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
627 | pvr2_ctrl_get_desc(cptr)); | 628 | pvr2_ctrl_get_desc(cptr)); |
628 | strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); | 629 | strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); |
629 | vc->flags = pvr2_ctrl_get_v4lflags(cptr); | 630 | vc->flags = pvr2_ctrl_get_v4lflags(cptr); |
630 | vc->default_value = pvr2_ctrl_get_def(cptr); | 631 | pvr2_ctrl_get_def(cptr, &val); |
632 | vc->default_value = val; | ||
631 | switch (pvr2_ctrl_get_type(cptr)) { | 633 | switch (pvr2_ctrl_get_type(cptr)) { |
632 | case pvr2_ctl_enum: | 634 | case pvr2_ctl_enum: |
633 | vc->type = V4L2_CTRL_TYPE_MENU; | 635 | vc->type = V4L2_CTRL_TYPE_MENU; |
@@ -753,6 +755,92 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
753 | break; | 755 | break; |
754 | } | 756 | } |
755 | 757 | ||
758 | case VIDIOC_CROPCAP: | ||
759 | { | ||
760 | struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg; | ||
761 | if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
762 | ret = -EINVAL; | ||
763 | break; | ||
764 | } | ||
765 | ret = pvr2_hdw_get_cropcap(hdw, cap); | ||
766 | cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */ | ||
767 | break; | ||
768 | } | ||
769 | case VIDIOC_G_CROP: | ||
770 | { | ||
771 | struct v4l2_crop *crop = (struct v4l2_crop *)arg; | ||
772 | int val = 0; | ||
773 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
774 | ret = -EINVAL; | ||
775 | break; | ||
776 | } | ||
777 | ret = pvr2_ctrl_get_value( | ||
778 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val); | ||
779 | if (ret != 0) { | ||
780 | ret = -EINVAL; | ||
781 | break; | ||
782 | } | ||
783 | crop->c.left = val; | ||
784 | ret = pvr2_ctrl_get_value( | ||
785 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val); | ||
786 | if (ret != 0) { | ||
787 | ret = -EINVAL; | ||
788 | break; | ||
789 | } | ||
790 | crop->c.top = val; | ||
791 | ret = pvr2_ctrl_get_value( | ||
792 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val); | ||
793 | if (ret != 0) { | ||
794 | ret = -EINVAL; | ||
795 | break; | ||
796 | } | ||
797 | crop->c.width = val; | ||
798 | ret = pvr2_ctrl_get_value( | ||
799 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val); | ||
800 | if (ret != 0) { | ||
801 | ret = -EINVAL; | ||
802 | break; | ||
803 | } | ||
804 | crop->c.height = val; | ||
805 | } | ||
806 | case VIDIOC_S_CROP: | ||
807 | { | ||
808 | struct v4l2_crop *crop = (struct v4l2_crop *)arg; | ||
809 | struct v4l2_cropcap cap; | ||
810 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
811 | ret = -EINVAL; | ||
812 | break; | ||
813 | } | ||
814 | cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
815 | ret = pvr2_ctrl_set_value( | ||
816 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), | ||
817 | crop->c.left); | ||
818 | if (ret != 0) { | ||
819 | ret = -EINVAL; | ||
820 | break; | ||
821 | } | ||
822 | ret = pvr2_ctrl_set_value( | ||
823 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), | ||
824 | crop->c.top); | ||
825 | if (ret != 0) { | ||
826 | ret = -EINVAL; | ||
827 | break; | ||
828 | } | ||
829 | ret = pvr2_ctrl_set_value( | ||
830 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), | ||
831 | crop->c.width); | ||
832 | if (ret != 0) { | ||
833 | ret = -EINVAL; | ||
834 | break; | ||
835 | } | ||
836 | ret = pvr2_ctrl_set_value( | ||
837 | pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), | ||
838 | crop->c.height); | ||
839 | if (ret != 0) { | ||
840 | ret = -EINVAL; | ||
841 | break; | ||
842 | } | ||
843 | } | ||
756 | case VIDIOC_LOG_STATUS: | 844 | case VIDIOC_LOG_STATUS: |
757 | { | 845 | { |
758 | pvr2_hdw_trigger_module_log(hdw); | 846 | pvr2_hdw_trigger_module_log(hdw); |