diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 17:03:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 17:03:59 -0400 |
commit | cf2fa66055d718ae13e62451bb546505f63906a2 (patch) | |
tree | e206d3f04e74a34e9aa88d21af6c26eea21d4121 /drivers/media/video/pvrusb2/pvrusb2-hdw.c | |
parent | 4501a466f28788485604ee42641d7a5fe7258d16 (diff) | |
parent | 57f51dbc45f65f7ee1e8c8f77200bb8000e3e271 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (313 commits)
V4L/DVB (9186): Added support for Prof 7300 DVB-S/S2 cards
V4L/DVB (9185): S2API: Ensure we have a reasonable ROLLOFF default
V4L/DVB (9184): cx24116: Change the default SNR units back to percentage by default.
V4L/DVB (9183): S2API: Return error of the caller provides 0 commands.
V4L/DVB (9182): S2API: Added support for DTV_HIERARCHY
V4L/DVB (9181): S2API: Add support fot DTV_GUARD_INTERVAL and DTV_TRANSMISSION_MODE
V4L/DVB (9180): S2API: Added support for DTV_CODE_RATE_HP/LP
V4L/DVB (9179): S2API: frontend.h cleanup
V4L/DVB (9178): cx24116: Add module parameter to return SNR as ESNO.
V4L/DVB (9177): S2API: Change _8PSK / _16APSK to PSK_8 and APSK_16
V4L/DVB (9176): Add support for DvbWorld USB cards with STV0288 demodulator.
V4L/DVB (9175): Remove NULL pointer in stb6000 driver.
V4L/DVB (9174): Allow custom inittab for ST STV0288 demodulator.
V4L/DVB (9173): S2API: Remove the hardcoded command limit during validation
V4L/DVB (9172): S2API: Bugfix related to DVB-S / DVB-S2 tuning for the legacy API.
V4L/DVB (9171): S2API: Stop an OOPS if illegal commands are dumped in S2API.
V4L/DVB (9170): cx24116: Sanity checking to data input via S2API to the cx24116 demod.
V4L/DVB (9169): uvcvideo: Support two new Bison Electronics webcams.
V4L/DVB (9168): Add support for MSI TV@nywhere Plus remote
V4L/DVB: v4l2-dev: remove duplicated #include
...
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 340 |
1 files changed, 337 insertions, 3 deletions
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 | { |