aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.h2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c340
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c46
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c42
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c23
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c94
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) */
137int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr) 137int 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 *);
49int pvr2_ctrl_get_min(struct pvr2_ctrl *); 49int 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) */
52int pvr2_ctrl_get_def(struct pvr2_ctrl *); 52int 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) */
55int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); 55int 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);
301static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw);
301 302
302 303
303static void trace_stbit(const char *name,int val) 304static 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
406static 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
417static 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
431static 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
442static 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
456static 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
470static 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
484static 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
495static 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
506static 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
517static 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
528static 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
539static 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
550static 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
561static 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
572static 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
583static 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
405static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) 594static 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)
779VCREATE_FUNCS(bass) 968VCREATE_FUNCS(bass)
780VCREATE_FUNCS(treble) 969VCREATE_FUNCS(treble)
781VCREATE_FUNCS(mute) 970VCREATE_FUNCS(mute)
971VCREATE_FUNCS(cropl)
972VCREATE_FUNCS(cropt)
973VCREATE_FUNCS(cropw)
974VCREATE_FUNCS(croph)
782VCREATE_FUNCS(audiomode) 975VCREATE_FUNCS(audiomode)
783VCREATE_FUNCS(res_hor) 976VCREATE_FUNCS(res_hor)
784VCREATE_FUNCS(res_ver) 977VCREATE_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
2987static 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 */
3001int 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 */
2681int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) 3015int 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 */
171int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *); 181int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *);
172 182
183/* Return information about cropping capabilities */
184int 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 */
174int pvr2_hdw_is_hsm(struct pvr2_hdw *); 187int 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
43static const struct pvr2_i2c_op * const ops[] = { 44static 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
237static 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
255static 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
261const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = {
262 .check = check_crop,
263 .update = set_crop,
264 .name = "v4l2_crop",
265};
266
267
236static void do_log(struct pvr2_hdw *hdw) 268static 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
264void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp) 296void 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;
29extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; 29extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
30extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; 30extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
31extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; 31extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
32extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop;
32extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; 33extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
33extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode; 34extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode;
34extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; 35extern 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
949static void do_i2c_scan(struct pvr2_hdw *hdw) 951
952/* Return true if device exists at given address */
953static 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
966static 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
967void pvr2_i2c_core_init(struct pvr2_hdw *hdw) 979void 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
149static 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
148static ssize_t show_val_norm(struct device *class_dev, 166static 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);