diff options
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 891 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-risc.c | 171 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-vbi.c | 366 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttvp.h | 88 |
4 files changed, 1278 insertions, 238 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 41fd09d7d11e..50dfad47ccff 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -9,6 +9,10 @@ | |||
9 | some v4l2 code lines are taken from Justin's bttv2 driver which is | 9 | some v4l2 code lines are taken from Justin's bttv2 driver which is |
10 | (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za> | 10 | (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za> |
11 | 11 | ||
12 | Cropping and overscan support | ||
13 | Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> | ||
14 | Sponsored by OPQ Systems AB | ||
15 | |||
12 | This program is free software; you can redistribute it and/or modify | 16 | This program is free software; you can redistribute it and/or modify |
13 | it under the terms of the GNU General Public License as published by | 17 | it under the terms of the GNU General Public License as published by |
14 | the Free Software Foundation; either version 2 of the License, or | 18 | the Free Software Foundation; either version 2 of the License, or |
@@ -64,6 +68,7 @@ static unsigned int radio[BTTV_MAX]; | |||
64 | static unsigned int irq_debug; | 68 | static unsigned int irq_debug; |
65 | static unsigned int gbuffers = 8; | 69 | static unsigned int gbuffers = 8; |
66 | static unsigned int gbufsize = 0x208000; | 70 | static unsigned int gbufsize = 0x208000; |
71 | static unsigned int reset_crop = 1; | ||
67 | 72 | ||
68 | static int video_nr = -1; | 73 | static int video_nr = -1; |
69 | static int radio_nr = -1; | 74 | static int radio_nr = -1; |
@@ -103,6 +108,7 @@ module_param(radio_nr, int, 0444); | |||
103 | module_param(vbi_nr, int, 0444); | 108 | module_param(vbi_nr, int, 0444); |
104 | module_param(gbuffers, int, 0444); | 109 | module_param(gbuffers, int, 0444); |
105 | module_param(gbufsize, int, 0444); | 110 | module_param(gbufsize, int, 0444); |
111 | module_param(reset_crop, int, 0444); | ||
106 | 112 | ||
107 | module_param(v4l2, int, 0644); | 113 | module_param(v4l2, int, 0644); |
108 | module_param(bigendian, int, 0644); | 114 | module_param(bigendian, int, 0644); |
@@ -129,6 +135,8 @@ MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)"); | |||
129 | MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); | 135 | MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); |
130 | MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); | 136 | MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); |
131 | MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); | 137 | MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); |
138 | MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default " | ||
139 | "is 1 (yes) for compatibility with older applications"); | ||
132 | MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)"); | 140 | MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)"); |
133 | MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); | 141 | MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); |
134 | MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); | 142 | MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); |
@@ -192,6 +200,33 @@ static u8 SRAM_Table[][60] = | |||
192 | } | 200 | } |
193 | }; | 201 | }; |
194 | 202 | ||
203 | /* minhdelayx1 first video pixel we can capture on a line and | ||
204 | hdelayx1 start of active video, both relative to rising edge of | ||
205 | /HRESET pulse (0H) in 1 / fCLKx1. | ||
206 | swidth width of active video and | ||
207 | totalwidth total line width, both in 1 / fCLKx1. | ||
208 | sqwidth total line width in square pixels. | ||
209 | vdelay start of active video in 2 * field lines relative to | ||
210 | trailing edge of /VRESET pulse (VDELAY register). | ||
211 | sheight height of active video in 2 * field lines. | ||
212 | videostart0 ITU-R frame line number of the line corresponding | ||
213 | to vdelay in the first field. */ | ||
214 | #define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \ | ||
215 | vdelay, sheight, videostart0) \ | ||
216 | .cropcap.bounds.left = minhdelayx1, \ | ||
217 | /* * 2 because vertically we count field lines times two, */ \ | ||
218 | /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \ | ||
219 | .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \ | ||
220 | /* 4 is a safety margin at the end of the line. */ \ | ||
221 | .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \ | ||
222 | .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY, \ | ||
223 | .cropcap.defrect.left = hdelayx1, \ | ||
224 | .cropcap.defrect.top = (videostart0) * 2, \ | ||
225 | .cropcap.defrect.width = swidth, \ | ||
226 | .cropcap.defrect.height = sheight, \ | ||
227 | .cropcap.pixelaspect.numerator = totalwidth, \ | ||
228 | .cropcap.pixelaspect.denominator = sqwidth, | ||
229 | |||
195 | const struct bttv_tvnorm bttv_tvnorms[] = { | 230 | const struct bttv_tvnorm bttv_tvnorms[] = { |
196 | /* PAL-BDGHI */ | 231 | /* PAL-BDGHI */ |
197 | /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ | 232 | /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ |
@@ -210,11 +245,26 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
210 | .hdelayx1 = 186, | 245 | .hdelayx1 = 186, |
211 | .hactivex1 = 924, | 246 | .hactivex1 = 924, |
212 | .vdelay = 0x20, | 247 | .vdelay = 0x20, |
213 | .vbipack = 255, | 248 | .vbipack = 255, /* min (2048 / 4, 0x1ff) & 0xff */ |
214 | .sram = 0, | 249 | .sram = 0, |
215 | /* ITU-R frame line number of the first VBI line | 250 | /* ITU-R frame line number of the first VBI line |
216 | we can capture, of the first and second field. */ | 251 | we can capture, of the first and second field. |
217 | .vbistart = { 7,320 }, | 252 | The last line is determined by cropcap.bounds. */ |
253 | .vbistart = { 7, 320 }, | ||
254 | CROPCAP(/* minhdelayx1 */ 68, | ||
255 | /* hdelayx1 */ 186, | ||
256 | /* Should be (768 * 1135 + 944 / 2) / 944. | ||
257 | cropcap.defrect is used for image width | ||
258 | checks, so we keep the old value 924. */ | ||
259 | /* swidth */ 924, | ||
260 | /* totalwidth */ 1135, | ||
261 | /* sqwidth */ 944, | ||
262 | /* vdelay */ 0x20, | ||
263 | /* sheight */ 576, | ||
264 | /* videostart0 */ 23) | ||
265 | /* bt878 (and bt848?) can capture another | ||
266 | line below active video. */ | ||
267 | .cropcap.bounds.height = (576 + 2) + 0x20 - 2, | ||
218 | },{ | 268 | },{ |
219 | .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, | 269 | .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, |
220 | .name = "NTSC", | 270 | .name = "NTSC", |
@@ -229,9 +279,18 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
229 | .hdelayx1 = 128, | 279 | .hdelayx1 = 128, |
230 | .hactivex1 = 910, | 280 | .hactivex1 = 910, |
231 | .vdelay = 0x1a, | 281 | .vdelay = 0x1a, |
232 | .vbipack = 144, | 282 | .vbipack = 144, /* min (1600 / 4, 0x1ff) & 0xff */ |
233 | .sram = 1, | 283 | .sram = 1, |
234 | .vbistart = { 10, 273 }, | 284 | .vbistart = { 10, 273 }, |
285 | CROPCAP(/* minhdelayx1 */ 68, | ||
286 | /* hdelayx1 */ 128, | ||
287 | /* Should be (640 * 910 + 780 / 2) / 780? */ | ||
288 | /* swidth */ 768, | ||
289 | /* totalwidth */ 910, | ||
290 | /* sqwidth */ 780, | ||
291 | /* vdelay */ 0x1a, | ||
292 | /* sheight */ 480, | ||
293 | /* videostart0 */ 23) | ||
235 | },{ | 294 | },{ |
236 | .v4l2_id = V4L2_STD_SECAM, | 295 | .v4l2_id = V4L2_STD_SECAM, |
237 | .name = "SECAM", | 296 | .name = "SECAM", |
@@ -249,6 +308,14 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
249 | .vbipack = 255, | 308 | .vbipack = 255, |
250 | .sram = 0, /* like PAL, correct? */ | 309 | .sram = 0, /* like PAL, correct? */ |
251 | .vbistart = { 7, 320 }, | 310 | .vbistart = { 7, 320 }, |
311 | CROPCAP(/* minhdelayx1 */ 68, | ||
312 | /* hdelayx1 */ 186, | ||
313 | /* swidth */ 924, | ||
314 | /* totalwidth */ 1135, | ||
315 | /* sqwidth */ 944, | ||
316 | /* vdelay */ 0x20, | ||
317 | /* sheight */ 576, | ||
318 | /* videostart0 */ 23) | ||
252 | },{ | 319 | },{ |
253 | .v4l2_id = V4L2_STD_PAL_Nc, | 320 | .v4l2_id = V4L2_STD_PAL_Nc, |
254 | .name = "PAL-Nc", | 321 | .name = "PAL-Nc", |
@@ -266,6 +333,14 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
266 | .vbipack = 144, | 333 | .vbipack = 144, |
267 | .sram = -1, | 334 | .sram = -1, |
268 | .vbistart = { 7, 320 }, | 335 | .vbistart = { 7, 320 }, |
336 | CROPCAP(/* minhdelayx1 */ 68, | ||
337 | /* hdelayx1 */ 130, | ||
338 | /* swidth */ (640 * 910 + 780 / 2) / 780, | ||
339 | /* totalwidth */ 910, | ||
340 | /* sqwidth */ 780, | ||
341 | /* vdelay */ 0x1a, | ||
342 | /* sheight */ 576, | ||
343 | /* videostart0 */ 23) | ||
269 | },{ | 344 | },{ |
270 | .v4l2_id = V4L2_STD_PAL_M, | 345 | .v4l2_id = V4L2_STD_PAL_M, |
271 | .name = "PAL-M", | 346 | .name = "PAL-M", |
@@ -283,6 +358,14 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
283 | .vbipack = 144, | 358 | .vbipack = 144, |
284 | .sram = -1, | 359 | .sram = -1, |
285 | .vbistart = { 10, 273 }, | 360 | .vbistart = { 10, 273 }, |
361 | CROPCAP(/* minhdelayx1 */ 68, | ||
362 | /* hdelayx1 */ 135, | ||
363 | /* swidth */ (640 * 910 + 780 / 2) / 780, | ||
364 | /* totalwidth */ 910, | ||
365 | /* sqwidth */ 780, | ||
366 | /* vdelay */ 0x1a, | ||
367 | /* sheight */ 480, | ||
368 | /* videostart0 */ 23) | ||
286 | },{ | 369 | },{ |
287 | .v4l2_id = V4L2_STD_PAL_N, | 370 | .v4l2_id = V4L2_STD_PAL_N, |
288 | .name = "PAL-N", | 371 | .name = "PAL-N", |
@@ -299,7 +382,15 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
299 | .vdelay = 0x20, | 382 | .vdelay = 0x20, |
300 | .vbipack = 144, | 383 | .vbipack = 144, |
301 | .sram = -1, | 384 | .sram = -1, |
302 | .vbistart = { 7, 320}, | 385 | .vbistart = { 7, 320 }, |
386 | CROPCAP(/* minhdelayx1 */ 68, | ||
387 | /* hdelayx1 */ 186, | ||
388 | /* swidth */ (768 * 1135 + 944 / 2) / 944, | ||
389 | /* totalwidth */ 1135, | ||
390 | /* sqwidth */ 944, | ||
391 | /* vdelay */ 0x20, | ||
392 | /* sheight */ 576, | ||
393 | /* videostart0 */ 23) | ||
303 | },{ | 394 | },{ |
304 | .v4l2_id = V4L2_STD_NTSC_M_JP, | 395 | .v4l2_id = V4L2_STD_NTSC_M_JP, |
305 | .name = "NTSC-JP", | 396 | .name = "NTSC-JP", |
@@ -316,7 +407,15 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
316 | .vdelay = 0x16, | 407 | .vdelay = 0x16, |
317 | .vbipack = 144, | 408 | .vbipack = 144, |
318 | .sram = -1, | 409 | .sram = -1, |
319 | .vbistart = {10, 273}, | 410 | .vbistart = { 10, 273 }, |
411 | CROPCAP(/* minhdelayx1 */ 68, | ||
412 | /* hdelayx1 */ 135, | ||
413 | /* swidth */ (640 * 910 + 780 / 2) / 780, | ||
414 | /* totalwidth */ 910, | ||
415 | /* sqwidth */ 780, | ||
416 | /* vdelay */ 0x16, | ||
417 | /* sheight */ 480, | ||
418 | /* videostart0 */ 23) | ||
320 | },{ | 419 | },{ |
321 | /* that one hopefully works with the strange timing | 420 | /* that one hopefully works with the strange timing |
322 | * which video recorders produce when playing a NTSC | 421 | * which video recorders produce when playing a NTSC |
@@ -338,6 +437,14 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
338 | .vtotal = 524, | 437 | .vtotal = 524, |
339 | .sram = -1, | 438 | .sram = -1, |
340 | .vbistart = { 10, 273 }, | 439 | .vbistart = { 10, 273 }, |
440 | CROPCAP(/* minhdelayx1 */ 68, | ||
441 | /* hdelayx1 */ 186, | ||
442 | /* swidth */ 924, | ||
443 | /* totalwidth */ 1135, | ||
444 | /* sqwidth */ 944, | ||
445 | /* vdelay */ 0x1a, | ||
446 | /* sheight */ 480, | ||
447 | /* videostart0 */ 23) | ||
341 | } | 448 | } |
342 | }; | 449 | }; |
343 | static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); | 450 | static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); |
@@ -678,25 +785,89 @@ static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); | |||
678 | /* ----------------------------------------------------------------------- */ | 785 | /* ----------------------------------------------------------------------- */ |
679 | /* resource management */ | 786 | /* resource management */ |
680 | 787 | ||
788 | /* | ||
789 | RESOURCE_ allocated by freed by | ||
790 | |||
791 | VIDEO_READ bttv_read 1) bttv_read 2) | ||
792 | |||
793 | VIDEO_STREAM VIDIOC_STREAMON VIDIOC_STREAMOFF | ||
794 | VIDIOC_QBUF 1) bttv_release | ||
795 | VIDIOCMCAPTURE 1) | ||
796 | |||
797 | OVERLAY VIDIOCCAPTURE on VIDIOCCAPTURE off | ||
798 | VIDIOC_OVERLAY on VIDIOC_OVERLAY off | ||
799 | 3) bttv_release | ||
800 | |||
801 | VBI VIDIOC_STREAMON VIDIOC_STREAMOFF | ||
802 | VIDIOC_QBUF 1) bttv_release | ||
803 | bttv_read, bttv_poll 1) 4) | ||
804 | |||
805 | 1) The resource must be allocated when we enter buffer prepare functions | ||
806 | and remain allocated while buffers are in the DMA queue. | ||
807 | 2) This is a single frame read. | ||
808 | 3) VIDIOC_S_FBUF and VIDIOC_S_FMT (OVERLAY) still work when | ||
809 | RESOURCE_OVERLAY is allocated. | ||
810 | 4) This is a continuous read, implies VIDIOC_STREAMON. | ||
811 | |||
812 | Note this driver permits video input and standard changes regardless if | ||
813 | resources are allocated. | ||
814 | */ | ||
815 | |||
816 | #define VBI_RESOURCES (RESOURCE_VBI) | ||
817 | #define VIDEO_RESOURCES (RESOURCE_VIDEO_READ | \ | ||
818 | RESOURCE_VIDEO_STREAM | \ | ||
819 | RESOURCE_OVERLAY) | ||
820 | |||
681 | static | 821 | static |
682 | int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit) | 822 | int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit) |
683 | { | 823 | { |
824 | int xbits; /* mutual exclusive resources */ | ||
825 | |||
684 | if (fh->resources & bit) | 826 | if (fh->resources & bit) |
685 | /* have it already allocated */ | 827 | /* have it already allocated */ |
686 | return 1; | 828 | return 1; |
687 | 829 | ||
830 | xbits = bit; | ||
831 | if (bit & (RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM)) | ||
832 | xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; | ||
833 | |||
688 | /* is it free? */ | 834 | /* is it free? */ |
689 | mutex_lock(&btv->reslock); | 835 | mutex_lock(&btv->lock); |
690 | if (btv->resources & bit) { | 836 | if (btv->resources & xbits) { |
691 | /* no, someone else uses it */ | 837 | /* no, someone else uses it */ |
692 | mutex_unlock(&btv->reslock); | 838 | goto fail; |
693 | return 0; | 839 | } |
840 | |||
841 | if ((bit & VIDEO_RESOURCES) | ||
842 | && 0 == (btv->resources & VIDEO_RESOURCES)) { | ||
843 | /* Do crop - use current, don't - use default parameters. */ | ||
844 | __s32 top = btv->crop[!!fh->do_crop].rect.top; | ||
845 | |||
846 | if (btv->vbi_end > top) | ||
847 | goto fail; | ||
848 | |||
849 | /* We cannot capture the same line as video and VBI data. | ||
850 | Claim scan lines crop[].rect.top to bottom. */ | ||
851 | btv->crop_start = top; | ||
852 | } else if (bit & VBI_RESOURCES) { | ||
853 | __s32 end = fh->vbi_fmt.end; | ||
854 | |||
855 | if (end > btv->crop_start) | ||
856 | goto fail; | ||
857 | |||
858 | /* Claim scan lines above fh->vbi_fmt.end. */ | ||
859 | btv->vbi_end = end; | ||
694 | } | 860 | } |
861 | |||
695 | /* it's free, grab it */ | 862 | /* it's free, grab it */ |
696 | fh->resources |= bit; | 863 | fh->resources |= bit; |
697 | btv->resources |= bit; | 864 | btv->resources |= bit; |
698 | mutex_unlock(&btv->reslock); | 865 | mutex_unlock(&btv->lock); |
699 | return 1; | 866 | return 1; |
867 | |||
868 | fail: | ||
869 | mutex_unlock(&btv->lock); | ||
870 | return 0; | ||
700 | } | 871 | } |
701 | 872 | ||
702 | static | 873 | static |
@@ -711,6 +882,35 @@ int locked_btres(struct bttv *btv, int bit) | |||
711 | return (btv->resources & bit); | 882 | return (btv->resources & bit); |
712 | } | 883 | } |
713 | 884 | ||
885 | /* Call with btv->lock down. */ | ||
886 | static void | ||
887 | disclaim_vbi_lines(struct bttv *btv) | ||
888 | { | ||
889 | btv->vbi_end = 0; | ||
890 | } | ||
891 | |||
892 | /* Call with btv->lock down. */ | ||
893 | static void | ||
894 | disclaim_video_lines(struct bttv *btv) | ||
895 | { | ||
896 | const struct bttv_tvnorm *tvnorm; | ||
897 | u8 crop; | ||
898 | |||
899 | tvnorm = &bttv_tvnorms[btv->tvnorm]; | ||
900 | btv->crop_start = tvnorm->cropcap.bounds.top | ||
901 | + tvnorm->cropcap.bounds.height; | ||
902 | |||
903 | /* VBI capturing ends at VDELAY, start of video capturing, no | ||
904 | matter how many lines the VBI RISC program expects. When video | ||
905 | capturing is off, it shall no longer "preempt" VBI capturing, | ||
906 | so we set VDELAY to maximum. */ | ||
907 | crop = btread(BT848_E_CROP) | 0xc0; | ||
908 | btwrite(crop, BT848_E_CROP); | ||
909 | btwrite(0xfe, BT848_E_VDELAY_LO); | ||
910 | btwrite(crop, BT848_O_CROP); | ||
911 | btwrite(0xfe, BT848_O_VDELAY_LO); | ||
912 | } | ||
913 | |||
714 | static | 914 | static |
715 | void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits) | 915 | void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits) |
716 | { | 916 | { |
@@ -718,10 +918,19 @@ void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits) | |||
718 | /* trying to free ressources not allocated by us ... */ | 918 | /* trying to free ressources not allocated by us ... */ |
719 | printk("bttv: BUG! (btres)\n"); | 919 | printk("bttv: BUG! (btres)\n"); |
720 | } | 920 | } |
721 | mutex_lock(&btv->reslock); | 921 | mutex_lock(&btv->lock); |
722 | fh->resources &= ~bits; | 922 | fh->resources &= ~bits; |
723 | btv->resources &= ~bits; | 923 | btv->resources &= ~bits; |
724 | mutex_unlock(&btv->reslock); | 924 | |
925 | bits = btv->resources; | ||
926 | |||
927 | if (0 == (bits & VIDEO_RESOURCES)) | ||
928 | disclaim_video_lines(btv); | ||
929 | |||
930 | if (0 == (bits & VBI_RESOURCES)) | ||
931 | disclaim_vbi_lines(btv); | ||
932 | |||
933 | mutex_unlock(&btv->lock); | ||
725 | } | 934 | } |
726 | 935 | ||
727 | /* ----------------------------------------------------------------------- */ | 936 | /* ----------------------------------------------------------------------- */ |
@@ -1030,6 +1239,36 @@ i2c_vidiocschan(struct bttv *btv) | |||
1030 | bttv_tda9880_setnorm(btv,btv->tvnorm); | 1239 | bttv_tda9880_setnorm(btv,btv->tvnorm); |
1031 | } | 1240 | } |
1032 | 1241 | ||
1242 | static void | ||
1243 | bttv_crop_calc_limits(struct bttv_crop *c) | ||
1244 | { | ||
1245 | /* Scale factor min. 1:1, max. 16:1. Min. image size | ||
1246 | 48 x 32. Scaled width must be a multiple of 4. */ | ||
1247 | |||
1248 | if (1) { | ||
1249 | /* For bug compatibility with VIDIOCGCAP and image | ||
1250 | size checks in earlier driver versions. */ | ||
1251 | c->min_scaled_width = 48; | ||
1252 | c->min_scaled_height = 32; | ||
1253 | } else { | ||
1254 | c->min_scaled_width = | ||
1255 | (max(48, c->rect.width >> 4) + 3) & ~3; | ||
1256 | c->min_scaled_height = | ||
1257 | max(32, c->rect.height >> 4); | ||
1258 | } | ||
1259 | |||
1260 | c->max_scaled_width = c->rect.width & ~3; | ||
1261 | c->max_scaled_height = c->rect.height; | ||
1262 | } | ||
1263 | |||
1264 | static void | ||
1265 | bttv_crop_reset(struct bttv_crop *c, int norm) | ||
1266 | { | ||
1267 | c->rect = bttv_tvnorms[norm].cropcap.defrect; | ||
1268 | bttv_crop_calc_limits(c); | ||
1269 | } | ||
1270 | |||
1271 | /* Call with btv->lock down. */ | ||
1033 | static int | 1272 | static int |
1034 | set_tvnorm(struct bttv *btv, unsigned int norm) | 1273 | set_tvnorm(struct bttv *btv, unsigned int norm) |
1035 | { | 1274 | { |
@@ -1038,9 +1277,24 @@ set_tvnorm(struct bttv *btv, unsigned int norm) | |||
1038 | if (norm < 0 || norm >= BTTV_TVNORMS) | 1277 | if (norm < 0 || norm >= BTTV_TVNORMS) |
1039 | return -EINVAL; | 1278 | return -EINVAL; |
1040 | 1279 | ||
1041 | btv->tvnorm = norm; | ||
1042 | tvnorm = &bttv_tvnorms[norm]; | 1280 | tvnorm = &bttv_tvnorms[norm]; |
1043 | 1281 | ||
1282 | if (btv->tvnorm < 0 || | ||
1283 | btv->tvnorm >= BTTV_TVNORMS || | ||
1284 | 0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, | ||
1285 | &tvnorm->cropcap, | ||
1286 | sizeof (tvnorm->cropcap))) { | ||
1287 | bttv_crop_reset(&btv->crop[0], norm); | ||
1288 | btv->crop[1] = btv->crop[0]; /* current = default */ | ||
1289 | |||
1290 | if (0 == (btv->resources & VIDEO_RESOURCES)) { | ||
1291 | btv->crop_start = tvnorm->cropcap.bounds.top | ||
1292 | + tvnorm->cropcap.bounds.height; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | btv->tvnorm = norm; | ||
1297 | |||
1044 | btwrite(tvnorm->adelay, BT848_ADELAY); | 1298 | btwrite(tvnorm->adelay, BT848_ADELAY); |
1045 | btwrite(tvnorm->bdelay, BT848_BDELAY); | 1299 | btwrite(tvnorm->bdelay, BT848_BDELAY); |
1046 | btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), | 1300 | btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), |
@@ -1057,6 +1311,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) | |||
1057 | return 0; | 1311 | return 0; |
1058 | } | 1312 | } |
1059 | 1313 | ||
1314 | /* Call with btv->lock down. */ | ||
1060 | static void | 1315 | static void |
1061 | set_input(struct bttv *btv, unsigned int input) | 1316 | set_input(struct bttv *btv, unsigned int input) |
1062 | { | 1317 | { |
@@ -1459,13 +1714,13 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, | |||
1459 | btv->loop_irq |= 1; | 1714 | btv->loop_irq |= 1; |
1460 | bttv_set_dma(btv, 0x03); | 1715 | bttv_set_dma(btv, 0x03); |
1461 | spin_unlock_irqrestore(&btv->s_lock,flags); | 1716 | spin_unlock_irqrestore(&btv->s_lock,flags); |
1462 | if (NULL == new) | ||
1463 | free_btres(btv,fh,RESOURCE_OVERLAY); | ||
1464 | if (NULL != old) { | 1717 | if (NULL != old) { |
1465 | dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state); | 1718 | dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state); |
1466 | bttv_dma_free(&fh->cap,btv, old); | 1719 | bttv_dma_free(&fh->cap,btv, old); |
1467 | kfree(old); | 1720 | kfree(old); |
1468 | } | 1721 | } |
1722 | if (NULL == new) | ||
1723 | free_btres(btv,fh,RESOURCE_OVERLAY); | ||
1469 | dprintk("switch_overlay: done\n"); | 1724 | dprintk("switch_overlay: done\n"); |
1470 | return retval; | 1725 | return retval; |
1471 | } | 1726 | } |
@@ -1479,7 +1734,10 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, | |||
1479 | unsigned int width, unsigned int height, | 1734 | unsigned int width, unsigned int height, |
1480 | enum v4l2_field field) | 1735 | enum v4l2_field field) |
1481 | { | 1736 | { |
1737 | struct bttv_fh *fh = q->priv_data; | ||
1482 | int redo_dma_risc = 0; | 1738 | int redo_dma_risc = 0; |
1739 | struct bttv_crop c; | ||
1740 | int norm; | ||
1483 | int rc; | 1741 | int rc; |
1484 | 1742 | ||
1485 | /* check settings */ | 1743 | /* check settings */ |
@@ -1491,12 +1749,52 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, | |||
1491 | if (width*height > buf->vb.bsize) | 1749 | if (width*height > buf->vb.bsize) |
1492 | return -EINVAL; | 1750 | return -EINVAL; |
1493 | buf->vb.size = buf->vb.bsize; | 1751 | buf->vb.size = buf->vb.bsize; |
1752 | |||
1753 | /* Make sure tvnorm and vbi_end remain consistent | ||
1754 | until we're done. */ | ||
1755 | mutex_lock(&btv->lock); | ||
1756 | |||
1757 | norm = btv->tvnorm; | ||
1758 | |||
1759 | /* In this mode capturing always starts at defrect.top | ||
1760 | (default VDELAY), ignoring cropping parameters. */ | ||
1761 | if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { | ||
1762 | mutex_unlock(&btv->lock); | ||
1763 | return -EINVAL; | ||
1764 | } | ||
1765 | |||
1766 | mutex_unlock(&btv->lock); | ||
1767 | |||
1768 | c.rect = bttv_tvnorms[norm].cropcap.defrect; | ||
1494 | } else { | 1769 | } else { |
1495 | if (width < 48 || | 1770 | mutex_lock(&btv->lock); |
1496 | height < 32 || | 1771 | |
1497 | width > bttv_tvnorms[btv->tvnorm].swidth || | 1772 | norm = btv->tvnorm; |
1498 | height > bttv_tvnorms[btv->tvnorm].sheight) | 1773 | c = btv->crop[!!fh->do_crop]; |
1774 | |||
1775 | mutex_unlock(&btv->lock); | ||
1776 | |||
1777 | if (width < c.min_scaled_width || | ||
1778 | width > c.max_scaled_width || | ||
1779 | height < c.min_scaled_height) | ||
1499 | return -EINVAL; | 1780 | return -EINVAL; |
1781 | |||
1782 | switch (field) { | ||
1783 | case V4L2_FIELD_TOP: | ||
1784 | case V4L2_FIELD_BOTTOM: | ||
1785 | case V4L2_FIELD_ALTERNATE: | ||
1786 | /* btv->crop counts frame lines. Max. scale | ||
1787 | factor is 16:1 for frames, 8:1 for fields. */ | ||
1788 | if (height * 2 > c.max_scaled_height) | ||
1789 | return -EINVAL; | ||
1790 | break; | ||
1791 | |||
1792 | default: | ||
1793 | if (height > c.max_scaled_height) | ||
1794 | return -EINVAL; | ||
1795 | break; | ||
1796 | } | ||
1797 | |||
1500 | buf->vb.size = (width * height * fmt->depth) >> 3; | 1798 | buf->vb.size = (width * height * fmt->depth) >> 3; |
1501 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 1799 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
1502 | return -EINVAL; | 1800 | return -EINVAL; |
@@ -1505,12 +1803,17 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, | |||
1505 | /* alloc + fill struct bttv_buffer (if changed) */ | 1803 | /* alloc + fill struct bttv_buffer (if changed) */ |
1506 | if (buf->vb.width != width || buf->vb.height != height || | 1804 | if (buf->vb.width != width || buf->vb.height != height || |
1507 | buf->vb.field != field || | 1805 | buf->vb.field != field || |
1508 | buf->tvnorm != btv->tvnorm || buf->fmt != fmt) { | 1806 | buf->tvnorm != norm || buf->fmt != fmt || |
1807 | buf->crop.top != c.rect.top || | ||
1808 | buf->crop.left != c.rect.left || | ||
1809 | buf->crop.width != c.rect.width || | ||
1810 | buf->crop.height != c.rect.height) { | ||
1509 | buf->vb.width = width; | 1811 | buf->vb.width = width; |
1510 | buf->vb.height = height; | 1812 | buf->vb.height = height; |
1511 | buf->vb.field = field; | 1813 | buf->vb.field = field; |
1512 | buf->tvnorm = btv->tvnorm; | 1814 | buf->tvnorm = norm; |
1513 | buf->fmt = fmt; | 1815 | buf->fmt = fmt; |
1816 | buf->crop = c.rect; | ||
1514 | redo_dma_risc = 1; | 1817 | redo_dma_risc = 1; |
1515 | } | 1818 | } |
1516 | 1819 | ||
@@ -1939,11 +2242,179 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1939 | return 0; | 2242 | return 0; |
1940 | } | 2243 | } |
1941 | 2244 | ||
1942 | static int verify_window(const struct bttv_tvnorm *tvn, | 2245 | /* Given cropping boundaries b and the scaled width and height of a |
1943 | struct v4l2_window *win, int fixup) | 2246 | single field or frame, which must not exceed hardware limits, this |
2247 | function adjusts the cropping parameters c. */ | ||
2248 | static void | ||
2249 | bttv_crop_adjust (struct bttv_crop * c, | ||
2250 | const struct v4l2_rect * b, | ||
2251 | __s32 width, | ||
2252 | __s32 height, | ||
2253 | enum v4l2_field field) | ||
2254 | { | ||
2255 | __s32 frame_height = height << !V4L2_FIELD_HAS_BOTH(field); | ||
2256 | __s32 max_left; | ||
2257 | __s32 max_top; | ||
2258 | |||
2259 | if (width < c->min_scaled_width) { | ||
2260 | /* Max. hor. scale factor 16:1. */ | ||
2261 | c->rect.width = width * 16; | ||
2262 | } else if (width > c->max_scaled_width) { | ||
2263 | /* Min. hor. scale factor 1:1. */ | ||
2264 | c->rect.width = width; | ||
2265 | |||
2266 | max_left = b->left + b->width - width; | ||
2267 | max_left = min(max_left, (__s32) MAX_HDELAY); | ||
2268 | if (c->rect.left > max_left) | ||
2269 | c->rect.left = max_left; | ||
2270 | } | ||
2271 | |||
2272 | if (height < c->min_scaled_height) { | ||
2273 | /* Max. vert. scale factor 16:1, single fields 8:1. */ | ||
2274 | c->rect.height = height * 16; | ||
2275 | } else if (frame_height > c->max_scaled_height) { | ||
2276 | /* Min. vert. scale factor 1:1. | ||
2277 | Top and height count field lines times two. */ | ||
2278 | c->rect.height = (frame_height + 1) & ~1; | ||
2279 | |||
2280 | max_top = b->top + b->height - c->rect.height; | ||
2281 | if (c->rect.top > max_top) | ||
2282 | c->rect.top = max_top; | ||
2283 | } | ||
2284 | |||
2285 | bttv_crop_calc_limits(c); | ||
2286 | } | ||
2287 | |||
2288 | /* Returns an error if scaling to a frame or single field with the given | ||
2289 | width and height is not possible with the current cropping parameters | ||
2290 | and width aligned according to width_mask. If adjust_size is TRUE the | ||
2291 | function may adjust the width and/or height instead, rounding width | ||
2292 | to (width + width_bias) & width_mask. If adjust_crop is TRUE it may | ||
2293 | also adjust the current cropping parameters to get closer to the | ||
2294 | desired image size. */ | ||
2295 | static int | ||
2296 | limit_scaled_size (struct bttv_fh * fh, | ||
2297 | __s32 * width, | ||
2298 | __s32 * height, | ||
2299 | enum v4l2_field field, | ||
2300 | unsigned int width_mask, | ||
2301 | unsigned int width_bias, | ||
2302 | int adjust_size, | ||
2303 | int adjust_crop) | ||
2304 | { | ||
2305 | struct bttv *btv = fh->btv; | ||
2306 | const struct v4l2_rect *b; | ||
2307 | struct bttv_crop *c; | ||
2308 | __s32 min_width; | ||
2309 | __s32 min_height; | ||
2310 | __s32 max_width; | ||
2311 | __s32 max_height; | ||
2312 | int rc; | ||
2313 | |||
2314 | BUG_ON((int) width_mask >= 0 || | ||
2315 | width_bias >= (unsigned int) -width_mask); | ||
2316 | |||
2317 | /* Make sure tvnorm, vbi_end and the current cropping parameters | ||
2318 | remain consistent until we're done. */ | ||
2319 | mutex_lock(&btv->lock); | ||
2320 | |||
2321 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; | ||
2322 | |||
2323 | /* Do crop - use current, don't - use default parameters. */ | ||
2324 | c = &btv->crop[!!fh->do_crop]; | ||
2325 | |||
2326 | if (fh->do_crop | ||
2327 | && adjust_size | ||
2328 | && adjust_crop | ||
2329 | && !locked_btres(btv, VIDEO_RESOURCES)) { | ||
2330 | min_width = 48; | ||
2331 | min_height = 32; | ||
2332 | |||
2333 | /* We cannot scale up. When the scaled image is larger | ||
2334 | than crop.rect we adjust the crop.rect as required | ||
2335 | by the V4L2 spec, hence cropcap.bounds are our limit. */ | ||
2336 | max_width = min(b->width, (__s32) MAX_HACTIVE); | ||
2337 | max_height = b->height; | ||
2338 | |||
2339 | /* We cannot capture the same line as video and VBI data. | ||
2340 | Note btv->vbi_end is really a minimum, see | ||
2341 | bttv_vbi_try_fmt(). */ | ||
2342 | if (btv->vbi_end > b->top) { | ||
2343 | max_height -= btv->vbi_end - b->top; | ||
2344 | rc = -EBUSY; | ||
2345 | if (min_height > max_height) | ||
2346 | goto fail; | ||
2347 | } | ||
2348 | } else { | ||
2349 | rc = -EBUSY; | ||
2350 | if (btv->vbi_end > c->rect.top) | ||
2351 | goto fail; | ||
2352 | |||
2353 | min_width = c->min_scaled_width; | ||
2354 | min_height = c->min_scaled_height; | ||
2355 | max_width = c->max_scaled_width; | ||
2356 | max_height = c->max_scaled_height; | ||
2357 | |||
2358 | adjust_crop = 0; | ||
2359 | } | ||
2360 | |||
2361 | min_width = (min_width - width_mask - 1) & width_mask; | ||
2362 | max_width = max_width & width_mask; | ||
2363 | |||
2364 | /* Max. scale factor is 16:1 for frames, 8:1 for fields. */ | ||
2365 | min_height = min_height; | ||
2366 | /* Min. scale factor is 1:1. */ | ||
2367 | max_height >>= !V4L2_FIELD_HAS_BOTH(field); | ||
2368 | |||
2369 | if (adjust_size) { | ||
2370 | *width = clamp(*width, min_width, max_width); | ||
2371 | *height = clamp(*height, min_height, max_height); | ||
2372 | |||
2373 | /* Round after clamping to avoid overflow. */ | ||
2374 | *width = (*width + width_bias) & width_mask; | ||
2375 | |||
2376 | if (adjust_crop) { | ||
2377 | bttv_crop_adjust(c, b, *width, *height, field); | ||
2378 | |||
2379 | if (btv->vbi_end > c->rect.top) { | ||
2380 | /* Move the crop window out of the way. */ | ||
2381 | c->rect.top = btv->vbi_end; | ||
2382 | } | ||
2383 | } | ||
2384 | } else { | ||
2385 | rc = -EINVAL; | ||
2386 | if (*width < min_width || | ||
2387 | *height < min_height || | ||
2388 | *width > max_width || | ||
2389 | *height > max_height || | ||
2390 | 0 != (*width & ~width_mask)) | ||
2391 | goto fail; | ||
2392 | } | ||
2393 | |||
2394 | rc = 0; /* success */ | ||
2395 | |||
2396 | fail: | ||
2397 | mutex_unlock(&btv->lock); | ||
2398 | |||
2399 | return rc; | ||
2400 | } | ||
2401 | |||
2402 | /* Returns an error if the given overlay window dimensions are not | ||
2403 | possible with the current cropping parameters. If adjust_size is | ||
2404 | TRUE the function may adjust the window width and/or height | ||
2405 | instead, however it always rounds the horizontal position and | ||
2406 | width as btcx_align() does. If adjust_crop is TRUE the function | ||
2407 | may also adjust the current cropping parameters to get closer | ||
2408 | to the desired window size. */ | ||
2409 | static int | ||
2410 | verify_window (struct bttv_fh * fh, | ||
2411 | struct v4l2_window * win, | ||
2412 | int adjust_size, | ||
2413 | int adjust_crop) | ||
1944 | { | 2414 | { |
1945 | enum v4l2_field field; | 2415 | enum v4l2_field field; |
1946 | int maxw, maxh; | 2416 | unsigned int width_mask; |
2417 | int rc; | ||
1947 | 2418 | ||
1948 | if (win->w.width < 48 || win->w.height < 32) | 2419 | if (win->w.width < 48 || win->w.height < 32) |
1949 | return -EINVAL; | 2420 | return -EINVAL; |
@@ -1951,32 +2422,52 @@ static int verify_window(const struct bttv_tvnorm *tvn, | |||
1951 | return -EINVAL; | 2422 | return -EINVAL; |
1952 | 2423 | ||
1953 | field = win->field; | 2424 | field = win->field; |
1954 | maxw = tvn->swidth; | ||
1955 | maxh = tvn->sheight; | ||
1956 | 2425 | ||
1957 | if (V4L2_FIELD_ANY == field) { | 2426 | if (V4L2_FIELD_ANY == field) { |
1958 | field = (win->w.height > maxh/2) | 2427 | __s32 height2; |
2428 | |||
2429 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; | ||
2430 | field = (win->w.height > height2) | ||
1959 | ? V4L2_FIELD_INTERLACED | 2431 | ? V4L2_FIELD_INTERLACED |
1960 | : V4L2_FIELD_TOP; | 2432 | : V4L2_FIELD_TOP; |
1961 | } | 2433 | } |
1962 | switch (field) { | 2434 | switch (field) { |
1963 | case V4L2_FIELD_TOP: | 2435 | case V4L2_FIELD_TOP: |
1964 | case V4L2_FIELD_BOTTOM: | 2436 | case V4L2_FIELD_BOTTOM: |
1965 | maxh = maxh / 2; | ||
1966 | break; | ||
1967 | case V4L2_FIELD_INTERLACED: | 2437 | case V4L2_FIELD_INTERLACED: |
1968 | break; | 2438 | break; |
1969 | default: | 2439 | default: |
1970 | return -EINVAL; | 2440 | return -EINVAL; |
1971 | } | 2441 | } |
1972 | 2442 | ||
1973 | if (!fixup && (win->w.width > maxw || win->w.height > maxh)) | 2443 | /* 4-byte alignment. */ |
2444 | if (NULL == fh->ovfmt) | ||
1974 | return -EINVAL; | 2445 | return -EINVAL; |
2446 | width_mask = ~0; | ||
2447 | switch (fh->ovfmt->depth) { | ||
2448 | case 8: | ||
2449 | case 24: | ||
2450 | width_mask = ~3; | ||
2451 | break; | ||
2452 | case 16: | ||
2453 | width_mask = ~1; | ||
2454 | break; | ||
2455 | case 32: | ||
2456 | break; | ||
2457 | default: | ||
2458 | BUG(); | ||
2459 | } | ||
2460 | |||
2461 | win->w.width -= win->w.left & ~width_mask; | ||
2462 | win->w.left = (win->w.left - width_mask - 1) & width_mask; | ||
2463 | |||
2464 | rc = limit_scaled_size(fh, &win->w.width, &win->w.height, | ||
2465 | field, width_mask, | ||
2466 | /* width_bias: round down */ 0, | ||
2467 | adjust_size, adjust_crop); | ||
2468 | if (0 != rc) | ||
2469 | return rc; | ||
1975 | 2470 | ||
1976 | if (win->w.width > maxw) | ||
1977 | win->w.width = maxw; | ||
1978 | if (win->w.height > maxh) | ||
1979 | win->w.height = maxh; | ||
1980 | win->field = field; | 2471 | win->field = field; |
1981 | return 0; | 2472 | return 0; |
1982 | } | 2473 | } |
@@ -1991,7 +2482,9 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
1991 | return -EINVAL; | 2482 | return -EINVAL; |
1992 | if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) | 2483 | if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) |
1993 | return -EINVAL; | 2484 | return -EINVAL; |
1994 | retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup); | 2485 | retval = verify_window(fh, win, |
2486 | /* adjust_size */ fixup, | ||
2487 | /* adjust_crop */ fixup); | ||
1995 | if (0 != retval) | 2488 | if (0 != retval) |
1996 | return retval; | 2489 | return retval; |
1997 | 2490 | ||
@@ -2048,6 +2541,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
2048 | struct bttv_buffer *new; | 2541 | struct bttv_buffer *new; |
2049 | 2542 | ||
2050 | new = videobuf_alloc(sizeof(*new)); | 2543 | new = videobuf_alloc(sizeof(*new)); |
2544 | new->crop = btv->crop[!!fh->do_crop].rect; | ||
2051 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2545 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2052 | retval = bttv_switch_overlay(btv,fh,new); | 2546 | retval = bttv_switch_overlay(btv,fh,new); |
2053 | } | 2547 | } |
@@ -2080,7 +2574,7 @@ static int bttv_resource(struct bttv_fh *fh) | |||
2080 | 2574 | ||
2081 | switch (fh->type) { | 2575 | switch (fh->type) { |
2082 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 2576 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
2083 | res = RESOURCE_VIDEO; | 2577 | res = RESOURCE_VIDEO_STREAM; |
2084 | break; | 2578 | break; |
2085 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 2579 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
2086 | res = RESOURCE_VBI; | 2580 | res = RESOURCE_VBI; |
@@ -2138,7 +2632,7 @@ static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f) | |||
2138 | f->fmt.win.field = fh->ov.field; | 2632 | f->fmt.win.field = fh->ov.field; |
2139 | return 0; | 2633 | return 0; |
2140 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 2634 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
2141 | bttv_vbi_get_fmt(fh,f); | 2635 | bttv_vbi_get_fmt(fh, &f->fmt.vbi); |
2142 | return 0; | 2636 | return 0; |
2143 | default: | 2637 | default: |
2144 | return -EINVAL; | 2638 | return -EINVAL; |
@@ -2146,35 +2640,35 @@ static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f) | |||
2146 | } | 2640 | } |
2147 | 2641 | ||
2148 | static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, | 2642 | static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, |
2149 | struct v4l2_format *f) | 2643 | struct v4l2_format *f, int adjust_crop) |
2150 | { | 2644 | { |
2151 | switch (f->type) { | 2645 | switch (f->type) { |
2152 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 2646 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
2153 | { | 2647 | { |
2154 | const struct bttv_format *fmt; | 2648 | const struct bttv_format *fmt; |
2155 | enum v4l2_field field; | 2649 | enum v4l2_field field; |
2156 | unsigned int maxw,maxh; | 2650 | __s32 width, height; |
2651 | int rc; | ||
2157 | 2652 | ||
2158 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 2653 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
2159 | if (NULL == fmt) | 2654 | if (NULL == fmt) |
2160 | return -EINVAL; | 2655 | return -EINVAL; |
2161 | 2656 | ||
2162 | /* fixup format */ | ||
2163 | maxw = bttv_tvnorms[btv->tvnorm].swidth; | ||
2164 | maxh = bttv_tvnorms[btv->tvnorm].sheight; | ||
2165 | field = f->fmt.pix.field; | 2657 | field = f->fmt.pix.field; |
2166 | if (V4L2_FIELD_ANY == field) | 2658 | if (V4L2_FIELD_ANY == field) { |
2167 | field = (f->fmt.pix.height > maxh/2) | 2659 | __s32 height2; |
2660 | |||
2661 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; | ||
2662 | field = (f->fmt.pix.height > height2) | ||
2168 | ? V4L2_FIELD_INTERLACED | 2663 | ? V4L2_FIELD_INTERLACED |
2169 | : V4L2_FIELD_BOTTOM; | 2664 | : V4L2_FIELD_BOTTOM; |
2665 | } | ||
2170 | if (V4L2_FIELD_SEQ_BT == field) | 2666 | if (V4L2_FIELD_SEQ_BT == field) |
2171 | field = V4L2_FIELD_SEQ_TB; | 2667 | field = V4L2_FIELD_SEQ_TB; |
2172 | switch (field) { | 2668 | switch (field) { |
2173 | case V4L2_FIELD_TOP: | 2669 | case V4L2_FIELD_TOP: |
2174 | case V4L2_FIELD_BOTTOM: | 2670 | case V4L2_FIELD_BOTTOM: |
2175 | case V4L2_FIELD_ALTERNATE: | 2671 | case V4L2_FIELD_ALTERNATE: |
2176 | maxh = maxh/2; | ||
2177 | break; | ||
2178 | case V4L2_FIELD_INTERLACED: | 2672 | case V4L2_FIELD_INTERLACED: |
2179 | break; | 2673 | break; |
2180 | case V4L2_FIELD_SEQ_TB: | 2674 | case V4L2_FIELD_SEQ_TB: |
@@ -2185,28 +2679,29 @@ static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
2185 | return -EINVAL; | 2679 | return -EINVAL; |
2186 | } | 2680 | } |
2187 | 2681 | ||
2682 | width = f->fmt.pix.width; | ||
2683 | height = f->fmt.pix.height; | ||
2684 | |||
2685 | rc = limit_scaled_size(fh, &width, &height, field, | ||
2686 | /* width_mask: 4 pixels */ ~3, | ||
2687 | /* width_bias: nearest */ 2, | ||
2688 | /* adjust_size */ 1, | ||
2689 | adjust_crop); | ||
2690 | if (0 != rc) | ||
2691 | return rc; | ||
2692 | |||
2188 | /* update data for the application */ | 2693 | /* update data for the application */ |
2189 | f->fmt.pix.field = field; | 2694 | f->fmt.pix.field = field; |
2190 | if (f->fmt.pix.width < 48) | 2695 | pix_format_set_size(&f->fmt.pix, fmt, width, height); |
2191 | f->fmt.pix.width = 48; | ||
2192 | if (f->fmt.pix.height < 32) | ||
2193 | f->fmt.pix.height = 32; | ||
2194 | if (f->fmt.pix.width > maxw) | ||
2195 | f->fmt.pix.width = maxw; | ||
2196 | if (f->fmt.pix.height > maxh) | ||
2197 | f->fmt.pix.height = maxh; | ||
2198 | pix_format_set_size (&f->fmt.pix, fmt, | ||
2199 | f->fmt.pix.width & ~3, | ||
2200 | f->fmt.pix.height); | ||
2201 | 2696 | ||
2202 | return 0; | 2697 | return 0; |
2203 | } | 2698 | } |
2204 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 2699 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
2205 | return verify_window(&bttv_tvnorms[btv->tvnorm], | 2700 | return verify_window(fh, &f->fmt.win, |
2206 | &f->fmt.win, 1); | 2701 | /* adjust_size */ 1, |
2702 | /* adjust_crop */ 0); | ||
2207 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 2703 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
2208 | bttv_vbi_try_fmt(fh,f); | 2704 | return bttv_vbi_try_fmt(fh, &f->fmt.vbi); |
2209 | return 0; | ||
2210 | default: | 2705 | default: |
2211 | return -EINVAL; | 2706 | return -EINVAL; |
2212 | } | 2707 | } |
@@ -2225,7 +2720,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
2225 | retval = bttv_switch_type(fh,f->type); | 2720 | retval = bttv_switch_type(fh,f->type); |
2226 | if (0 != retval) | 2721 | if (0 != retval) |
2227 | return retval; | 2722 | return retval; |
2228 | retval = bttv_try_fmt(fh,btv,f); | 2723 | retval = bttv_try_fmt(fh,btv,f, /* adjust_crop */ 1); |
2229 | if (0 != retval) | 2724 | if (0 != retval) |
2230 | return retval; | 2725 | return retval; |
2231 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 2726 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
@@ -2254,12 +2749,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
2254 | retval = bttv_switch_type(fh,f->type); | 2749 | retval = bttv_switch_type(fh,f->type); |
2255 | if (0 != retval) | 2750 | if (0 != retval) |
2256 | return retval; | 2751 | return retval; |
2257 | if (locked_btres(fh->btv, RESOURCE_VBI)) | 2752 | return bttv_vbi_set_fmt(fh, &f->fmt.vbi); |
2258 | return -EBUSY; | ||
2259 | bttv_vbi_try_fmt(fh,f); | ||
2260 | bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); | ||
2261 | bttv_vbi_get_fmt(fh,f); | ||
2262 | return 0; | ||
2263 | default: | 2753 | default: |
2264 | return -EINVAL; | 2754 | return -EINVAL; |
2265 | } | 2755 | } |
@@ -2517,6 +3007,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2517 | if (*on) { | 3007 | if (*on) { |
2518 | fh->ov.tvnorm = btv->tvnorm; | 3008 | fh->ov.tvnorm = btv->tvnorm; |
2519 | new = videobuf_alloc(sizeof(*new)); | 3009 | new = videobuf_alloc(sizeof(*new)); |
3010 | new->crop = btv->crop[!!fh->do_crop].rect; | ||
2520 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 3011 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2521 | } else { | 3012 | } else { |
2522 | new = NULL; | 3013 | new = NULL; |
@@ -2551,10 +3042,16 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2551 | struct video_mmap *vm = arg; | 3042 | struct video_mmap *vm = arg; |
2552 | struct bttv_buffer *buf; | 3043 | struct bttv_buffer *buf; |
2553 | enum v4l2_field field; | 3044 | enum v4l2_field field; |
3045 | __s32 height2; | ||
3046 | int res; | ||
2554 | 3047 | ||
2555 | if (vm->frame >= VIDEO_MAX_FRAME) | 3048 | if (vm->frame >= VIDEO_MAX_FRAME) |
2556 | return -EINVAL; | 3049 | return -EINVAL; |
2557 | 3050 | ||
3051 | res = bttv_resource(fh); | ||
3052 | if (!check_alloc_btres(btv, fh, res)) | ||
3053 | return -EBUSY; | ||
3054 | |||
2558 | mutex_lock(&fh->cap.lock); | 3055 | mutex_lock(&fh->cap.lock); |
2559 | retval = -EINVAL; | 3056 | retval = -EINVAL; |
2560 | buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame]; | 3057 | buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame]; |
@@ -2566,7 +3063,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2566 | buf->vb.state == STATE_ACTIVE) | 3063 | buf->vb.state == STATE_ACTIVE) |
2567 | goto fh_unlock_and_return; | 3064 | goto fh_unlock_and_return; |
2568 | 3065 | ||
2569 | field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2) | 3066 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; |
3067 | field = (vm->height > height2) | ||
2570 | ? V4L2_FIELD_INTERLACED | 3068 | ? V4L2_FIELD_INTERLACED |
2571 | : V4L2_FIELD_BOTTOM; | 3069 | : V4L2_FIELD_BOTTOM; |
2572 | retval = bttv_prepare_buffer(&fh->cap,btv,buf, | 3070 | retval = bttv_prepare_buffer(&fh->cap,btv,buf, |
@@ -2613,54 +3111,17 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2613 | } | 3111 | } |
2614 | 3112 | ||
2615 | case VIDIOCGVBIFMT: | 3113 | case VIDIOCGVBIFMT: |
2616 | { | ||
2617 | struct vbi_format *fmt = (void *) arg; | ||
2618 | struct v4l2_format fmt2; | ||
2619 | |||
2620 | if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) { | 3114 | if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) { |
2621 | retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); | 3115 | retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); |
2622 | if (0 != retval) | 3116 | if (0 != retval) |
2623 | return retval; | 3117 | return retval; |
2624 | } | 3118 | } |
2625 | bttv_vbi_get_fmt(fh, &fmt2); | ||
2626 | |||
2627 | memset(fmt,0,sizeof(*fmt)); | ||
2628 | fmt->sampling_rate = fmt2.fmt.vbi.sampling_rate; | ||
2629 | fmt->samples_per_line = fmt2.fmt.vbi.samples_per_line; | ||
2630 | fmt->sample_format = VIDEO_PALETTE_RAW; | ||
2631 | fmt->start[0] = fmt2.fmt.vbi.start[0]; | ||
2632 | fmt->count[0] = fmt2.fmt.vbi.count[0]; | ||
2633 | fmt->start[1] = fmt2.fmt.vbi.start[1]; | ||
2634 | fmt->count[1] = fmt2.fmt.vbi.count[1]; | ||
2635 | if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC) | ||
2636 | fmt->flags |= VBI_UNSYNC; | ||
2637 | if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED) | ||
2638 | fmt->flags |= VBI_INTERLACED; | ||
2639 | return 0; | ||
2640 | } | ||
2641 | case VIDIOCSVBIFMT: | ||
2642 | { | ||
2643 | struct vbi_format *fmt = (void *) arg; | ||
2644 | struct v4l2_format fmt2; | ||
2645 | 3119 | ||
2646 | retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); | 3120 | /* fall through */ |
2647 | if (0 != retval) | ||
2648 | return retval; | ||
2649 | bttv_vbi_get_fmt(fh, &fmt2); | ||
2650 | |||
2651 | if (fmt->sampling_rate != fmt2.fmt.vbi.sampling_rate || | ||
2652 | fmt->samples_per_line != fmt2.fmt.vbi.samples_per_line || | ||
2653 | fmt->sample_format != VIDEO_PALETTE_RAW || | ||
2654 | fmt->start[0] != fmt2.fmt.vbi.start[0] || | ||
2655 | fmt->start[1] != fmt2.fmt.vbi.start[1] || | ||
2656 | fmt->count[0] != fmt->count[1] || | ||
2657 | fmt->count[0] < 1 || | ||
2658 | fmt->count[0] > 32 /* VBI_MAXLINES */) | ||
2659 | return -EINVAL; | ||
2660 | 3121 | ||
2661 | bttv_vbi_setlines(fh,btv,fmt->count[0]); | 3122 | case VIDIOCSVBIFMT: |
2662 | return 0; | 3123 | return v4l_compat_translate_ioctl(inode, file, cmd, |
2663 | } | 3124 | arg, bttv_do_ioctl); |
2664 | 3125 | ||
2665 | case BTTV_VERSION: | 3126 | case BTTV_VERSION: |
2666 | case VIDIOCGFREQ: | 3127 | case VIDIOCGFREQ: |
@@ -2753,7 +3214,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2753 | case VIDIOC_TRY_FMT: | 3214 | case VIDIOC_TRY_FMT: |
2754 | { | 3215 | { |
2755 | struct v4l2_format *f = arg; | 3216 | struct v4l2_format *f = arg; |
2756 | return bttv_try_fmt(fh,btv,f); | 3217 | return bttv_try_fmt(fh,btv,f, /* adjust_crop */ 0); |
2757 | } | 3218 | } |
2758 | case VIDIOC_G_FMT: | 3219 | case VIDIOC_G_FMT: |
2759 | { | 3220 | { |
@@ -2792,16 +3253,23 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2792 | if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) | 3253 | if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) |
2793 | return -EINVAL; | 3254 | return -EINVAL; |
2794 | 3255 | ||
2795 | mutex_lock(&fh->cap.lock); | ||
2796 | retval = -EINVAL; | 3256 | retval = -EINVAL; |
2797 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | 3257 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { |
2798 | if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth) | 3258 | __s32 width = fb->fmt.width; |
2799 | goto fh_unlock_and_return; | 3259 | __s32 height = fb->fmt.height; |
2800 | if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight) | 3260 | |
2801 | goto fh_unlock_and_return; | 3261 | retval = limit_scaled_size(fh, &width, &height, |
3262 | V4L2_FIELD_INTERLACED, | ||
3263 | /* width_mask */ ~3, | ||
3264 | /* width_bias */ 2, | ||
3265 | /* adjust_size */ 0, | ||
3266 | /* adjust_crop */ 0); | ||
3267 | if (0 != retval) | ||
3268 | return retval; | ||
2802 | } | 3269 | } |
2803 | 3270 | ||
2804 | /* ok, accept it */ | 3271 | /* ok, accept it */ |
3272 | mutex_lock(&fh->cap.lock); | ||
2805 | btv->fbuf.base = fb->base; | 3273 | btv->fbuf.base = fb->base; |
2806 | btv->fbuf.fmt.width = fb->fmt.width; | 3274 | btv->fbuf.fmt.width = fb->fmt.width; |
2807 | btv->fbuf.fmt.height = fb->fmt.height; | 3275 | btv->fbuf.fmt.height = fb->fmt.height; |
@@ -2828,6 +3296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2828 | struct bttv_buffer *new; | 3296 | struct bttv_buffer *new; |
2829 | 3297 | ||
2830 | new = videobuf_alloc(sizeof(*new)); | 3298 | new = videobuf_alloc(sizeof(*new)); |
3299 | new->crop = btv->crop[!!fh->do_crop].rect; | ||
2831 | bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new); | 3300 | bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new); |
2832 | retval = bttv_switch_overlay(btv,fh,new); | 3301 | retval = bttv_switch_overlay(btv,fh,new); |
2833 | } | 3302 | } |
@@ -2843,7 +3312,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2843 | return videobuf_querybuf(bttv_queue(fh),arg); | 3312 | return videobuf_querybuf(bttv_queue(fh),arg); |
2844 | 3313 | ||
2845 | case VIDIOC_QBUF: | 3314 | case VIDIOC_QBUF: |
3315 | { | ||
3316 | int res = bttv_resource(fh); | ||
3317 | |||
3318 | if (!check_alloc_btres(btv, fh, res)) | ||
3319 | return -EBUSY; | ||
2846 | return videobuf_qbuf(bttv_queue(fh),arg); | 3320 | return videobuf_qbuf(bttv_queue(fh),arg); |
3321 | } | ||
2847 | 3322 | ||
2848 | case VIDIOC_DQBUF: | 3323 | case VIDIOC_DQBUF: |
2849 | return videobuf_dqbuf(bttv_queue(fh),arg, | 3324 | return videobuf_dqbuf(bttv_queue(fh),arg, |
@@ -2942,6 +3417,122 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2942 | return v4l2_prio_change(&btv->prio, &fh->prio, *prio); | 3417 | return v4l2_prio_change(&btv->prio, &fh->prio, *prio); |
2943 | } | 3418 | } |
2944 | 3419 | ||
3420 | case VIDIOC_CROPCAP: | ||
3421 | { | ||
3422 | struct v4l2_cropcap *cap = arg; | ||
3423 | enum v4l2_buf_type type; | ||
3424 | |||
3425 | type = cap->type; | ||
3426 | |||
3427 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
3428 | type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
3429 | return -EINVAL; | ||
3430 | |||
3431 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | ||
3432 | cap->type = type; | ||
3433 | |||
3434 | return 0; | ||
3435 | } | ||
3436 | case VIDIOC_G_CROP: | ||
3437 | { | ||
3438 | struct v4l2_crop * crop = arg; | ||
3439 | |||
3440 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
3441 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
3442 | return -EINVAL; | ||
3443 | |||
3444 | /* No fh->do_crop = 1; because btv->crop[1] may be | ||
3445 | inconsistent with fh->width or fh->height and apps | ||
3446 | do not expect a change here. */ | ||
3447 | |||
3448 | crop->c = btv->crop[!!fh->do_crop].rect; | ||
3449 | |||
3450 | return 0; | ||
3451 | } | ||
3452 | case VIDIOC_S_CROP: | ||
3453 | { | ||
3454 | struct v4l2_crop *crop = arg; | ||
3455 | const struct v4l2_rect *b; | ||
3456 | struct bttv_crop c; | ||
3457 | __s32 b_left; | ||
3458 | __s32 b_top; | ||
3459 | __s32 b_right; | ||
3460 | __s32 b_bottom; | ||
3461 | |||
3462 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
3463 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
3464 | return -EINVAL; | ||
3465 | |||
3466 | retval = v4l2_prio_check(&btv->prio,&fh->prio); | ||
3467 | if (0 != retval) | ||
3468 | return retval; | ||
3469 | |||
3470 | /* Make sure tvnorm, vbi_end and the current cropping | ||
3471 | parameters remain consistent until we're done. Note | ||
3472 | read() may change vbi_end in check_alloc_btres(). */ | ||
3473 | mutex_lock(&btv->lock); | ||
3474 | |||
3475 | retval = -EBUSY; | ||
3476 | |||
3477 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) | ||
3478 | goto btv_unlock_and_return; | ||
3479 | |||
3480 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; | ||
3481 | |||
3482 | b_left = b->left; | ||
3483 | b_right = b_left + b->width; | ||
3484 | b_bottom = b->top + b->height; | ||
3485 | |||
3486 | b_top = max(b->top, btv->vbi_end); | ||
3487 | if (b_top + 32 >= b_bottom) | ||
3488 | goto btv_unlock_and_return; | ||
3489 | |||
3490 | /* Min. scaled size 48 x 32. */ | ||
3491 | c.rect.left = clamp(crop->c.left, b_left, b_right - 48); | ||
3492 | c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY); | ||
3493 | |||
3494 | c.rect.width = clamp(crop->c.width, | ||
3495 | 48, b_right - c.rect.left); | ||
3496 | |||
3497 | c.rect.top = clamp(crop->c.top, b_top, b_bottom - 32); | ||
3498 | /* Top and height must be a multiple of two. */ | ||
3499 | c.rect.top = (c.rect.top + 1) & ~1; | ||
3500 | |||
3501 | c.rect.height = clamp(crop->c.height, | ||
3502 | 32, b_bottom - c.rect.top); | ||
3503 | c.rect.height = (c.rect.height + 1) & ~1; | ||
3504 | |||
3505 | bttv_crop_calc_limits(&c); | ||
3506 | |||
3507 | btv->crop[1] = c; | ||
3508 | |||
3509 | mutex_unlock(&btv->lock); | ||
3510 | |||
3511 | fh->do_crop = 1; | ||
3512 | |||
3513 | mutex_lock(&fh->cap.lock); | ||
3514 | |||
3515 | if (fh->width < c.min_scaled_width) { | ||
3516 | fh->width = c.min_scaled_width; | ||
3517 | btv->init.width = c.min_scaled_width; | ||
3518 | } else if (fh->width > c.max_scaled_width) { | ||
3519 | fh->width = c.max_scaled_width; | ||
3520 | btv->init.width = c.max_scaled_width; | ||
3521 | } | ||
3522 | |||
3523 | if (fh->height < c.min_scaled_height) { | ||
3524 | fh->height = c.min_scaled_height; | ||
3525 | btv->init.height = c.min_scaled_height; | ||
3526 | } else if (fh->height > c.max_scaled_height) { | ||
3527 | fh->height = c.max_scaled_height; | ||
3528 | btv->init.height = c.max_scaled_height; | ||
3529 | } | ||
3530 | |||
3531 | mutex_unlock(&fh->cap.lock); | ||
3532 | |||
3533 | return 0; | ||
3534 | } | ||
3535 | |||
2945 | case VIDIOC_ENUMSTD: | 3536 | case VIDIOC_ENUMSTD: |
2946 | case VIDIOC_G_STD: | 3537 | case VIDIOC_G_STD: |
2947 | case VIDIOC_S_STD: | 3538 | case VIDIOC_S_STD: |
@@ -2963,6 +3554,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2963 | fh_unlock_and_return: | 3554 | fh_unlock_and_return: |
2964 | mutex_unlock(&fh->cap.lock); | 3555 | mutex_unlock(&fh->cap.lock); |
2965 | return retval; | 3556 | return retval; |
3557 | |||
3558 | btv_unlock_and_return: | ||
3559 | mutex_unlock(&btv->lock); | ||
3560 | return retval; | ||
2966 | } | 3561 | } |
2967 | 3562 | ||
2968 | static int bttv_ioctl(struct inode *inode, struct file *file, | 3563 | static int bttv_ioctl(struct inode *inode, struct file *file, |
@@ -2972,8 +3567,26 @@ static int bttv_ioctl(struct inode *inode, struct file *file, | |||
2972 | 3567 | ||
2973 | switch (cmd) { | 3568 | switch (cmd) { |
2974 | case BTTV_VBISIZE: | 3569 | case BTTV_VBISIZE: |
3570 | { | ||
3571 | const struct bttv_tvnorm *tvnorm; | ||
3572 | |||
3573 | tvnorm = fh->vbi_fmt.tvnorm; | ||
3574 | |||
3575 | if (fh->vbi_fmt.fmt.start[0] != tvnorm->vbistart[0] || | ||
3576 | fh->vbi_fmt.fmt.start[1] != tvnorm->vbistart[1] || | ||
3577 | fh->vbi_fmt.fmt.count[0] != fh->vbi_fmt.fmt.count[1]) { | ||
3578 | /* BTTV_VBISIZE cannot express these parameters, | ||
3579 | however open() resets the paramters to defaults | ||
3580 | and apps shouldn't call BTTV_VBISIZE after | ||
3581 | VIDIOC_S_FMT. */ | ||
3582 | return -EINVAL; | ||
3583 | } | ||
3584 | |||
2975 | bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); | 3585 | bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); |
2976 | return fh->lines * 2 * 2048; | 3586 | return (fh->vbi_fmt.fmt.count[0] * 2 |
3587 | * fh->vbi_fmt.fmt.samples_per_line); | ||
3588 | } | ||
3589 | |||
2977 | default: | 3590 | default: |
2978 | return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl); | 3591 | return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl); |
2979 | } | 3592 | } |
@@ -2992,10 +3605,14 @@ static ssize_t bttv_read(struct file *file, char __user *data, | |||
2992 | 3605 | ||
2993 | switch (fh->type) { | 3606 | switch (fh->type) { |
2994 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 3607 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
2995 | if (locked_btres(fh->btv,RESOURCE_VIDEO)) | 3608 | if (!check_alloc_btres(fh->btv, fh, RESOURCE_VIDEO_READ)) { |
3609 | /* VIDEO_READ in use by another fh, | ||
3610 | or VIDEO_STREAM by any fh. */ | ||
2996 | return -EBUSY; | 3611 | return -EBUSY; |
3612 | } | ||
2997 | retval = videobuf_read_one(&fh->cap, data, count, ppos, | 3613 | retval = videobuf_read_one(&fh->cap, data, count, ppos, |
2998 | file->f_flags & O_NONBLOCK); | 3614 | file->f_flags & O_NONBLOCK); |
3615 | free_btres(fh->btv, fh, RESOURCE_VIDEO_READ); | ||
2999 | break; | 3616 | break; |
3000 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 3617 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
3001 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) | 3618 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) |
@@ -3021,7 +3638,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3021 | return videobuf_poll_stream(file, &fh->vbi, wait); | 3638 | return videobuf_poll_stream(file, &fh->vbi, wait); |
3022 | } | 3639 | } |
3023 | 3640 | ||
3024 | if (check_btres(fh,RESOURCE_VIDEO)) { | 3641 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { |
3025 | /* streaming capture */ | 3642 | /* streaming capture */ |
3026 | if (list_empty(&fh->cap.stream)) | 3643 | if (list_empty(&fh->cap.stream)) |
3027 | return POLLERR; | 3644 | return POLLERR; |
@@ -3031,7 +3648,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3031 | mutex_lock(&fh->cap.lock); | 3648 | mutex_lock(&fh->cap.lock); |
3032 | if (NULL == fh->cap.read_buf) { | 3649 | if (NULL == fh->cap.read_buf) { |
3033 | /* need to capture a new frame */ | 3650 | /* need to capture a new frame */ |
3034 | if (locked_btres(fh->btv,RESOURCE_VIDEO)) { | 3651 | if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) { |
3035 | mutex_unlock(&fh->cap.lock); | 3652 | mutex_unlock(&fh->cap.lock); |
3036 | return POLLERR; | 3653 | return POLLERR; |
3037 | } | 3654 | } |
@@ -3117,8 +3734,23 @@ static int bttv_open(struct inode *inode, struct file *file) | |||
3117 | i2c_vidiocschan(btv); | 3734 | i2c_vidiocschan(btv); |
3118 | 3735 | ||
3119 | btv->users++; | 3736 | btv->users++; |
3120 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) | 3737 | |
3121 | bttv_vbi_setlines(fh,btv,16); | 3738 | /* The V4L2 spec requires one global set of cropping parameters |
3739 | which only change on request. These are stored in btv->crop[1]. | ||
3740 | However for compatibility with V4L apps and cropping unaware | ||
3741 | V4L2 apps we now reset the cropping parameters as seen through | ||
3742 | this fh, which is to say VIDIOC_G_CROP and scaling limit checks | ||
3743 | will use btv->crop[0], the default cropping parameters for the | ||
3744 | current video standard, and VIDIOC_S_FMT will not implicitely | ||
3745 | change the cropping parameters until VIDIOC_S_CROP has been | ||
3746 | called. */ | ||
3747 | fh->do_crop = !reset_crop; /* module parameter */ | ||
3748 | |||
3749 | /* Likewise there should be one global set of VBI capture | ||
3750 | parameters, but for compatibility with V4L apps and earlier | ||
3751 | driver versions each fh has its own parameters. */ | ||
3752 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); | ||
3753 | |||
3122 | bttv_field_count(btv); | 3754 | bttv_field_count(btv); |
3123 | return 0; | 3755 | return 0; |
3124 | } | 3756 | } |
@@ -3133,14 +3765,17 @@ static int bttv_release(struct inode *inode, struct file *file) | |||
3133 | bttv_switch_overlay(btv,fh,NULL); | 3765 | bttv_switch_overlay(btv,fh,NULL); |
3134 | 3766 | ||
3135 | /* stop video capture */ | 3767 | /* stop video capture */ |
3136 | if (check_btres(fh, RESOURCE_VIDEO)) { | 3768 | if (check_btres(fh, RESOURCE_VIDEO_STREAM)) { |
3137 | videobuf_streamoff(&fh->cap); | 3769 | videobuf_streamoff(&fh->cap); |
3138 | free_btres(btv,fh,RESOURCE_VIDEO); | 3770 | free_btres(btv,fh,RESOURCE_VIDEO_STREAM); |
3139 | } | 3771 | } |
3140 | if (fh->cap.read_buf) { | 3772 | if (fh->cap.read_buf) { |
3141 | buffer_release(&fh->cap,fh->cap.read_buf); | 3773 | buffer_release(&fh->cap,fh->cap.read_buf); |
3142 | kfree(fh->cap.read_buf); | 3774 | kfree(fh->cap.read_buf); |
3143 | } | 3775 | } |
3776 | if (check_btres(fh, RESOURCE_VIDEO_READ)) { | ||
3777 | free_btres(btv, fh, RESOURCE_VIDEO_READ); | ||
3778 | } | ||
3144 | 3779 | ||
3145 | /* stop vbi capture */ | 3780 | /* stop vbi capture */ |
3146 | if (check_btres(fh, RESOURCE_VBI)) { | 3781 | if (check_btres(fh, RESOURCE_VBI)) { |
@@ -3997,7 +4632,6 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3997 | 4632 | ||
3998 | /* initialize structs / fill in defaults */ | 4633 | /* initialize structs / fill in defaults */ |
3999 | mutex_init(&btv->lock); | 4634 | mutex_init(&btv->lock); |
4000 | mutex_init(&btv->reslock); | ||
4001 | spin_lock_init(&btv->s_lock); | 4635 | spin_lock_init(&btv->s_lock); |
4002 | spin_lock_init(&btv->gpio_lock); | 4636 | spin_lock_init(&btv->gpio_lock); |
4003 | init_waitqueue_head(&btv->gpioq); | 4637 | init_waitqueue_head(&btv->gpioq); |
@@ -4095,7 +4729,6 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4095 | btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24); | 4729 | btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24); |
4096 | btv->init.width = 320; | 4730 | btv->init.width = 320; |
4097 | btv->init.height = 240; | 4731 | btv->init.height = 240; |
4098 | btv->init.lines = 16; | ||
4099 | btv->input = 0; | 4732 | btv->input = 0; |
4100 | 4733 | ||
4101 | /* initialize hardware */ | 4734 | /* initialize hardware */ |
@@ -4130,6 +4763,10 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4130 | bt848_sat(btv,32768); | 4763 | bt848_sat(btv,32768); |
4131 | audio_mute(btv, 1); | 4764 | audio_mute(btv, 1); |
4132 | set_input(btv,0); | 4765 | set_input(btv,0); |
4766 | bttv_crop_reset(&btv->crop[0], btv->tvnorm); | ||
4767 | btv->crop[1] = btv->crop[0]; /* current = default */ | ||
4768 | disclaim_vbi_lines(btv); | ||
4769 | disclaim_video_lines(btv); | ||
4133 | } | 4770 | } |
4134 | 4771 | ||
4135 | /* add subdevices */ | 4772 | /* add subdevices */ |
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index afcfe71e3792..e7104d9cb4bd 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c | |||
@@ -43,7 +43,8 @@ int | |||
43 | bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | 43 | bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, |
44 | struct scatterlist *sglist, | 44 | struct scatterlist *sglist, |
45 | unsigned int offset, unsigned int bpl, | 45 | unsigned int offset, unsigned int bpl, |
46 | unsigned int padding, unsigned int lines) | 46 | unsigned int padding, unsigned int skip_lines, |
47 | unsigned int store_lines) | ||
47 | { | 48 | { |
48 | u32 instructions,line,todo; | 49 | u32 instructions,line,todo; |
49 | struct scatterlist *sg; | 50 | struct scatterlist *sg; |
@@ -54,9 +55,11 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | |||
54 | one write per scan line + sync + jump (all 2 dwords). padding | 55 | one write per scan line + sync + jump (all 2 dwords). padding |
55 | can cause next bpl to start close to a page border. First DMA | 56 | can cause next bpl to start close to a page border. First DMA |
56 | region may be smaller than PAGE_SIZE */ | 57 | region may be smaller than PAGE_SIZE */ |
57 | instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines; | 58 | instructions = skip_lines * 4; |
58 | instructions += 2; | 59 | instructions += (1 + ((bpl + padding) * store_lines) |
59 | if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) | 60 | / PAGE_SIZE + store_lines) * 8; |
61 | instructions += 2 * 8; | ||
62 | if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0) | ||
60 | return rc; | 63 | return rc; |
61 | 64 | ||
62 | /* sync instruction */ | 65 | /* sync instruction */ |
@@ -64,11 +67,16 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | |||
64 | *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); | 67 | *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); |
65 | *(rp++) = cpu_to_le32(0); | 68 | *(rp++) = cpu_to_le32(0); |
66 | 69 | ||
70 | while (skip_lines-- > 0) { | ||
71 | *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL | | ||
72 | BT848_RISC_EOL | bpl); | ||
73 | } | ||
74 | |||
67 | /* scan lines */ | 75 | /* scan lines */ |
68 | sg = sglist; | 76 | sg = sglist; |
69 | for (line = 0; line < lines; line++) { | 77 | for (line = 0; line < store_lines; line++) { |
70 | if ((btv->opt_vcr_hack) && | 78 | if ((btv->opt_vcr_hack) && |
71 | (line >= (lines - VCR_HACK_LINES))) | 79 | (line >= (store_lines - VCR_HACK_LINES))) |
72 | continue; | 80 | continue; |
73 | while (offset && offset >= sg_dma_len(sg)) { | 81 | while (offset && offset >= sg_dma_len(sg)) { |
74 | offset -= sg_dma_len(sg); | 82 | offset -= sg_dma_len(sg); |
@@ -130,7 +138,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, | |||
130 | /* estimate risc mem: worst case is one write per page border + | 138 | /* estimate risc mem: worst case is one write per page border + |
131 | one write per scan line (5 dwords) | 139 | one write per scan line (5 dwords) |
132 | plus sync + jump (2 dwords) */ | 140 | plus sync + jump (2 dwords) */ |
133 | instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines; | 141 | instructions = ((3 + (ybpl + ypadding) * ylines * 2) |
142 | / PAGE_SIZE) + ylines; | ||
134 | instructions += 2; | 143 | instructions += 2; |
135 | if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0) | 144 | if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0) |
136 | return rc; | 145 | return rc; |
@@ -317,10 +326,10 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, | |||
317 | /* ---------------------------------------------------------- */ | 326 | /* ---------------------------------------------------------- */ |
318 | 327 | ||
319 | static void | 328 | static void |
320 | bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, | 329 | bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo, |
321 | int width, int height, int interleaved, int norm) | 330 | int width, int height, int interleaved, |
331 | const struct bttv_tvnorm *tvnorm) | ||
322 | { | 332 | { |
323 | const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; | ||
324 | u32 xsf, sr; | 333 | u32 xsf, sr; |
325 | int vdelay; | 334 | int vdelay; |
326 | 335 | ||
@@ -361,6 +370,62 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, | |||
361 | } | 370 | } |
362 | 371 | ||
363 | static void | 372 | static void |
373 | bttv_calc_geo (struct bttv * btv, | ||
374 | struct bttv_geometry * geo, | ||
375 | unsigned int width, | ||
376 | unsigned int height, | ||
377 | int both_fields, | ||
378 | const struct bttv_tvnorm * tvnorm, | ||
379 | const struct v4l2_rect * crop) | ||
380 | { | ||
381 | unsigned int c_width; | ||
382 | unsigned int c_height; | ||
383 | u32 sr; | ||
384 | |||
385 | if ((crop->left == tvnorm->cropcap.defrect.left | ||
386 | && crop->top == tvnorm->cropcap.defrect.top | ||
387 | && crop->width == tvnorm->cropcap.defrect.width | ||
388 | && crop->height == tvnorm->cropcap.defrect.height | ||
389 | && width <= tvnorm->swidth /* see PAL-Nc et al */) | ||
390 | || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) { | ||
391 | bttv_calc_geo_old(btv, geo, width, height, | ||
392 | both_fields, tvnorm); | ||
393 | return; | ||
394 | } | ||
395 | |||
396 | /* For bug compatibility the image size checks permit scale | ||
397 | factors > 16. See bttv_crop_calc_limits(). */ | ||
398 | c_width = min((unsigned int) crop->width, width * 16); | ||
399 | c_height = min((unsigned int) crop->height, height * 16); | ||
400 | |||
401 | geo->width = width; | ||
402 | geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096; | ||
403 | /* Even to store Cb first, odd for Cr. */ | ||
404 | geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1; | ||
405 | |||
406 | geo->sheight = c_height; | ||
407 | geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY; | ||
408 | sr = c_height >> !both_fields; | ||
409 | sr = (sr * 512U + (height >> 1)) / height - 512; | ||
410 | geo->vscale = (0x10000UL - sr) & 0x1fff; | ||
411 | geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0; | ||
412 | geo->vtotal = tvnorm->vtotal; | ||
413 | |||
414 | geo->crop = (((geo->width >> 8) & 0x03) | | ||
415 | ((geo->hdelay >> 6) & 0x0c) | | ||
416 | ((geo->sheight >> 4) & 0x30) | | ||
417 | ((geo->vdelay >> 2) & 0xc0)); | ||
418 | |||
419 | if (btv->opt_combfilter) { | ||
420 | geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); | ||
421 | geo->comb = (width < 769) ? 1 : 0; | ||
422 | } else { | ||
423 | geo->vtc = 0; | ||
424 | geo->comb = 0; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | static void | ||
364 | bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) | 429 | bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) |
365 | { | 430 | { |
366 | int off = odd ? 0x80 : 0x00; | 431 | int off = odd ? 0x80 : 0x00; |
@@ -522,16 +587,51 @@ int | |||
522 | bttv_buffer_activate_vbi(struct bttv *btv, | 587 | bttv_buffer_activate_vbi(struct bttv *btv, |
523 | struct bttv_buffer *vbi) | 588 | struct bttv_buffer *vbi) |
524 | { | 589 | { |
525 | /* vbi capture */ | 590 | struct btcx_riscmem *top; |
591 | struct btcx_riscmem *bottom; | ||
592 | int top_irq_flags; | ||
593 | int bottom_irq_flags; | ||
594 | |||
595 | top = NULL; | ||
596 | bottom = NULL; | ||
597 | top_irq_flags = 0; | ||
598 | bottom_irq_flags = 0; | ||
599 | |||
526 | if (vbi) { | 600 | if (vbi) { |
601 | unsigned int crop, vdelay; | ||
602 | |||
527 | vbi->vb.state = STATE_ACTIVE; | 603 | vbi->vb.state = STATE_ACTIVE; |
528 | list_del(&vbi->vb.queue); | 604 | list_del(&vbi->vb.queue); |
529 | bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0); | 605 | |
530 | bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4); | 606 | /* VDELAY is start of video, end of VBI capturing. */ |
531 | } else { | 607 | crop = btread(BT848_E_CROP); |
532 | bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0); | 608 | vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2); |
533 | bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0); | 609 | |
610 | if (vbi->geo.vdelay > vdelay) { | ||
611 | vdelay = vbi->geo.vdelay & 0xfe; | ||
612 | crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0); | ||
613 | |||
614 | btwrite(vdelay, BT848_E_VDELAY_LO); | ||
615 | btwrite(crop, BT848_E_CROP); | ||
616 | btwrite(vdelay, BT848_O_VDELAY_LO); | ||
617 | btwrite(crop, BT848_O_CROP); | ||
618 | } | ||
619 | |||
620 | if (vbi->vbi_count[0] > 0) { | ||
621 | top = &vbi->top; | ||
622 | top_irq_flags = 4; | ||
623 | } | ||
624 | |||
625 | if (vbi->vbi_count[1] > 0) { | ||
626 | top_irq_flags = 0; | ||
627 | bottom = &vbi->bottom; | ||
628 | bottom_irq_flags = 4; | ||
629 | } | ||
534 | } | 630 | } |
631 | |||
632 | bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags); | ||
633 | bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags); | ||
634 | |||
535 | return 0; | 635 | return 0; |
536 | } | 636 | } |
537 | 637 | ||
@@ -611,28 +711,31 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) | |||
611 | int bpf = bpl * (buf->vb.height >> 1); | 711 | int bpf = bpl * (buf->vb.height >> 1); |
612 | 712 | ||
613 | bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height, | 713 | bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height, |
614 | V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm); | 714 | V4L2_FIELD_HAS_BOTH(buf->vb.field), |
715 | tvnorm,&buf->crop); | ||
615 | 716 | ||
616 | switch (buf->vb.field) { | 717 | switch (buf->vb.field) { |
617 | case V4L2_FIELD_TOP: | 718 | case V4L2_FIELD_TOP: |
618 | bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, | 719 | bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, |
619 | 0,bpl,0,buf->vb.height); | 720 | /* offset */ 0,bpl, |
721 | /* padding */ 0,/* skip_lines */ 0, | ||
722 | buf->vb.height); | ||
620 | break; | 723 | break; |
621 | case V4L2_FIELD_BOTTOM: | 724 | case V4L2_FIELD_BOTTOM: |
622 | bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, | 725 | bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, |
623 | 0,bpl,0,buf->vb.height); | 726 | 0,bpl,0,0,buf->vb.height); |
624 | break; | 727 | break; |
625 | case V4L2_FIELD_INTERLACED: | 728 | case V4L2_FIELD_INTERLACED: |
626 | bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, | 729 | bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, |
627 | 0,bpl,bpl,buf->vb.height >> 1); | 730 | 0,bpl,bpl,0,buf->vb.height >> 1); |
628 | bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, | 731 | bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, |
629 | bpl,bpl,bpl,buf->vb.height >> 1); | 732 | bpl,bpl,bpl,0,buf->vb.height >> 1); |
630 | break; | 733 | break; |
631 | case V4L2_FIELD_SEQ_TB: | 734 | case V4L2_FIELD_SEQ_TB: |
632 | bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, | 735 | bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, |
633 | 0,bpl,0,buf->vb.height >> 1); | 736 | 0,bpl,0,0,buf->vb.height >> 1); |
634 | bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, | 737 | bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, |
635 | bpf,bpl,0,buf->vb.height >> 1); | 738 | bpf,bpl,0,0,buf->vb.height >> 1); |
636 | break; | 739 | break; |
637 | default: | 740 | default: |
638 | BUG(); | 741 | BUG(); |
@@ -662,7 +765,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) | |||
662 | switch (buf->vb.field) { | 765 | switch (buf->vb.field) { |
663 | case V4L2_FIELD_TOP: | 766 | case V4L2_FIELD_TOP: |
664 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, | 767 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, |
665 | buf->vb.height,0,buf->tvnorm); | 768 | buf->vb.height,/* both_fields */ 0, |
769 | tvnorm,&buf->crop); | ||
666 | bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist, | 770 | bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist, |
667 | 0,buf->vb.width,0,buf->vb.height, | 771 | 0,buf->vb.width,0,buf->vb.height, |
668 | uoffset,voffset,buf->fmt->hshift, | 772 | uoffset,voffset,buf->fmt->hshift, |
@@ -670,7 +774,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) | |||
670 | break; | 774 | break; |
671 | case V4L2_FIELD_BOTTOM: | 775 | case V4L2_FIELD_BOTTOM: |
672 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, | 776 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, |
673 | buf->vb.height,0,buf->tvnorm); | 777 | buf->vb.height,0, |
778 | tvnorm,&buf->crop); | ||
674 | bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist, | 779 | bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist, |
675 | 0,buf->vb.width,0,buf->vb.height, | 780 | 0,buf->vb.width,0,buf->vb.height, |
676 | uoffset,voffset,buf->fmt->hshift, | 781 | uoffset,voffset,buf->fmt->hshift, |
@@ -678,7 +783,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) | |||
678 | break; | 783 | break; |
679 | case V4L2_FIELD_INTERLACED: | 784 | case V4L2_FIELD_INTERLACED: |
680 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, | 785 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, |
681 | buf->vb.height,1,buf->tvnorm); | 786 | buf->vb.height,1, |
787 | tvnorm,&buf->crop); | ||
682 | lines = buf->vb.height >> 1; | 788 | lines = buf->vb.height >> 1; |
683 | ypadding = buf->vb.width; | 789 | ypadding = buf->vb.width; |
684 | cpadding = buf->vb.width >> buf->fmt->hshift; | 790 | cpadding = buf->vb.width >> buf->fmt->hshift; |
@@ -700,7 +806,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) | |||
700 | break; | 806 | break; |
701 | case V4L2_FIELD_SEQ_TB: | 807 | case V4L2_FIELD_SEQ_TB: |
702 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, | 808 | bttv_calc_geo(btv,&buf->geo,buf->vb.width, |
703 | buf->vb.height,1,buf->tvnorm); | 809 | buf->vb.height,1, |
810 | tvnorm,&buf->crop); | ||
704 | lines = buf->vb.height >> 1; | 811 | lines = buf->vb.height >> 1; |
705 | ypadding = buf->vb.width; | 812 | ypadding = buf->vb.width; |
706 | cpadding = buf->vb.width >> buf->fmt->hshift; | 813 | cpadding = buf->vb.width >> buf->fmt->hshift; |
@@ -731,11 +838,12 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) | |||
731 | /* build risc code */ | 838 | /* build risc code */ |
732 | buf->vb.field = V4L2_FIELD_SEQ_TB; | 839 | buf->vb.field = V4L2_FIELD_SEQ_TB; |
733 | bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight, | 840 | bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight, |
734 | 1,buf->tvnorm); | 841 | 1,tvnorm,&buf->crop); |
735 | bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, | 842 | bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, |
736 | 0, RAW_BPL, 0, RAW_LINES); | 843 | /* offset */ 0, RAW_BPL, /* padding */ 0, |
844 | /* skip_lines */ 0, RAW_LINES); | ||
737 | bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, | 845 | bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, |
738 | buf->vb.size/2 , RAW_BPL, 0, RAW_LINES); | 846 | buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES); |
739 | } | 847 | } |
740 | 848 | ||
741 | /* copy format info */ | 849 | /* copy format info */ |
@@ -761,7 +869,8 @@ bttv_overlay_risc(struct bttv *btv, | |||
761 | 869 | ||
762 | /* calculate geometry */ | 870 | /* calculate geometry */ |
763 | bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height, | 871 | bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height, |
764 | V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm); | 872 | V4L2_FIELD_HAS_BOTH(ov->field), |
873 | &bttv_tvnorms[ov->tvnorm],&buf->crop); | ||
765 | 874 | ||
766 | /* build risc code */ | 875 | /* build risc code */ |
767 | switch (ov->field) { | 876 | switch (ov->field) { |
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 6fc6b0260056..754f66bfdf46 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c | |||
@@ -5,6 +5,9 @@ | |||
5 | 5 | ||
6 | (c) 2002 Gerd Knorr <kraxel@bytesex.org> | 6 | (c) 2002 Gerd Knorr <kraxel@bytesex.org> |
7 | 7 | ||
8 | Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> | ||
9 | Sponsored by OPQ Systems AB | ||
10 | |||
8 | This program is free software; you can redistribute it and/or modify | 11 | This program is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by | 12 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2 of the License, or | 13 | the Free Software Foundation; either version 2 of the License, or |
@@ -41,8 +44,15 @@ | |||
41 | to be about 244. */ | 44 | to be about 244. */ |
42 | #define VBI_OFFSET 244 | 45 | #define VBI_OFFSET 244 |
43 | 46 | ||
47 | /* 2048 for compatibility with earlier driver versions. The driver | ||
48 | really stores 1024 + tvnorm->vbipack * 4 samples per line in the | ||
49 | buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI | ||
50 | is 0x1FF DWORDs) and VBI read()s store a frame counter in the last | ||
51 | four bytes of the VBI image. */ | ||
52 | #define VBI_BPL 2048 | ||
53 | |||
54 | /* Compatibility. */ | ||
44 | #define VBI_DEFLINES 16 | 55 | #define VBI_DEFLINES 16 |
45 | #define VBI_MAXLINES 32 | ||
46 | 56 | ||
47 | static unsigned int vbibufs = 4; | 57 | static unsigned int vbibufs = 4; |
48 | static unsigned int vbi_debug = 0; | 58 | static unsigned int vbi_debug = 0; |
@@ -58,21 +68,12 @@ MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)"); | |||
58 | #define dprintk(fmt, arg...) if (vbi_debug) \ | 68 | #define dprintk(fmt, arg...) if (vbi_debug) \ |
59 | printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) | 69 | printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) |
60 | 70 | ||
71 | #define IMAGE_SIZE(fmt) \ | ||
72 | (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line) | ||
73 | |||
61 | /* ----------------------------------------------------------------------- */ | 74 | /* ----------------------------------------------------------------------- */ |
62 | /* vbi risc code + mm */ | 75 | /* vbi risc code + mm */ |
63 | 76 | ||
64 | static int | ||
65 | vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines) | ||
66 | { | ||
67 | int bpl = 2048; | ||
68 | |||
69 | bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, | ||
70 | 0, bpl-4, 4, lines); | ||
71 | bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, | ||
72 | lines * bpl, bpl-4, 4, lines); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int vbi_buffer_setup(struct videobuf_queue *q, | 77 | static int vbi_buffer_setup(struct videobuf_queue *q, |
77 | unsigned int *count, unsigned int *size) | 78 | unsigned int *count, unsigned int *size) |
78 | { | 79 | { |
@@ -81,8 +82,16 @@ static int vbi_buffer_setup(struct videobuf_queue *q, | |||
81 | 82 | ||
82 | if (0 == *count) | 83 | if (0 == *count) |
83 | *count = vbibufs; | 84 | *count = vbibufs; |
84 | *size = fh->lines * 2 * 2048; | 85 | |
85 | dprintk("setup: lines=%d\n",fh->lines); | 86 | *size = IMAGE_SIZE(&fh->vbi_fmt.fmt); |
87 | |||
88 | dprintk("setup: samples=%u start=%d,%d count=%u,%u\n", | ||
89 | fh->vbi_fmt.fmt.samples_per_line, | ||
90 | fh->vbi_fmt.fmt.start[0], | ||
91 | fh->vbi_fmt.fmt.start[1], | ||
92 | fh->vbi_fmt.fmt.count[0], | ||
93 | fh->vbi_fmt.fmt.count[1]); | ||
94 | |||
86 | return 0; | 95 | return 0; |
87 | } | 96 | } |
88 | 97 | ||
@@ -93,18 +102,93 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, | |||
93 | struct bttv_fh *fh = q->priv_data; | 102 | struct bttv_fh *fh = q->priv_data; |
94 | struct bttv *btv = fh->btv; | 103 | struct bttv *btv = fh->btv; |
95 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | 104 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); |
105 | const struct bttv_tvnorm *tvnorm; | ||
106 | unsigned int skip_lines0, skip_lines1, min_vdelay; | ||
107 | int redo_dma_risc; | ||
96 | int rc; | 108 | int rc; |
97 | 109 | ||
98 | buf->vb.size = fh->lines * 2 * 2048; | 110 | buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt); |
99 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 111 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
100 | return -EINVAL; | 112 | return -EINVAL; |
101 | 113 | ||
114 | tvnorm = fh->vbi_fmt.tvnorm; | ||
115 | |||
116 | /* There's no VBI_VDELAY register, RISC must skip the lines | ||
117 | we don't want. With default parameters we skip zero lines | ||
118 | as earlier driver versions did. The driver permits video | ||
119 | standard changes while capturing, so we use vbi_fmt.tvnorm | ||
120 | instead of btv->tvnorm to skip zero lines after video | ||
121 | standard changes as well. */ | ||
122 | |||
123 | skip_lines0 = 0; | ||
124 | skip_lines1 = 0; | ||
125 | |||
126 | if (fh->vbi_fmt.fmt.count[0] > 0) | ||
127 | skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0] | ||
128 | - tvnorm->vbistart[0])); | ||
129 | if (fh->vbi_fmt.fmt.count[1] > 0) | ||
130 | skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1] | ||
131 | - tvnorm->vbistart[1])); | ||
132 | |||
133 | redo_dma_risc = 0; | ||
134 | |||
135 | if (buf->vbi_skip[0] != skip_lines0 || | ||
136 | buf->vbi_skip[1] != skip_lines1 || | ||
137 | buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] || | ||
138 | buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) { | ||
139 | buf->vbi_skip[0] = skip_lines0; | ||
140 | buf->vbi_skip[1] = skip_lines1; | ||
141 | buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0]; | ||
142 | buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1]; | ||
143 | redo_dma_risc = 1; | ||
144 | } | ||
145 | |||
102 | if (STATE_NEEDS_INIT == buf->vb.state) { | 146 | if (STATE_NEEDS_INIT == buf->vb.state) { |
147 | redo_dma_risc = 1; | ||
103 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) | 148 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) |
104 | goto fail; | 149 | goto fail; |
105 | if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) | ||
106 | goto fail; | ||
107 | } | 150 | } |
151 | |||
152 | if (redo_dma_risc) { | ||
153 | unsigned int bpl, padding, offset; | ||
154 | |||
155 | bpl = 2044; /* max. vbipack */ | ||
156 | padding = VBI_BPL - bpl; | ||
157 | |||
158 | if (fh->vbi_fmt.fmt.count[0] > 0) { | ||
159 | rc = bttv_risc_packed(btv, &buf->top, | ||
160 | buf->vb.dma.sglist, | ||
161 | /* offset */ 0, bpl, | ||
162 | padding, skip_lines0, | ||
163 | fh->vbi_fmt.fmt.count[0]); | ||
164 | if (0 != rc) | ||
165 | goto fail; | ||
166 | } | ||
167 | |||
168 | if (fh->vbi_fmt.fmt.count[1] > 0) { | ||
169 | offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL; | ||
170 | |||
171 | rc = bttv_risc_packed(btv, &buf->bottom, | ||
172 | buf->vb.dma.sglist, | ||
173 | offset, bpl, | ||
174 | padding, skip_lines1, | ||
175 | fh->vbi_fmt.fmt.count[1]); | ||
176 | if (0 != rc) | ||
177 | goto fail; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* VBI capturing ends at VDELAY, start of video capturing, | ||
182 | no matter where the RISC program ends. VDELAY minimum is 2, | ||
183 | bounds.top is the corresponding first field line number | ||
184 | times two. VDELAY counts half field lines. */ | ||
185 | min_vdelay = MIN_VDELAY; | ||
186 | if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top) | ||
187 | min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top; | ||
188 | |||
189 | /* For bttv_buffer_activate_vbi(). */ | ||
190 | buf->geo.vdelay = min_vdelay; | ||
191 | |||
108 | buf->vb.state = STATE_PREPARED; | 192 | buf->vb.state = STATE_PREPARED; |
109 | buf->vb.field = field; | 193 | buf->vb.field = field; |
110 | dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", | 194 | dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", |
@@ -152,69 +236,215 @@ struct videobuf_queue_ops bttv_vbi_qops = { | |||
152 | 236 | ||
153 | /* ----------------------------------------------------------------------- */ | 237 | /* ----------------------------------------------------------------------- */ |
154 | 238 | ||
155 | void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) | 239 | static int |
240 | try_fmt (struct v4l2_vbi_format * f, | ||
241 | const struct bttv_tvnorm * tvnorm, | ||
242 | __s32 crop_start) | ||
156 | { | 243 | { |
157 | int vdelay; | 244 | __s32 min_start, max_start, max_end, f2_offset; |
158 | 245 | unsigned int i; | |
159 | if (lines < 1) | 246 | |
160 | lines = 1; | 247 | /* For compatibility with earlier driver versions we must pretend |
161 | if (lines > VBI_MAXLINES) | 248 | the VBI and video capture window may overlap. In reality RISC |
162 | lines = VBI_MAXLINES; | 249 | magic aborts VBI capturing at the first line of video capturing, |
163 | fh->lines = lines; | 250 | leaving the rest of the buffer unchanged, usually all zero. |
164 | 251 | VBI capturing must always start before video capturing. >> 1 | |
165 | vdelay = btread(BT848_E_VDELAY_LO); | 252 | because cropping counts field lines times two. */ |
166 | if (vdelay < lines*2) { | 253 | min_start = tvnorm->vbistart[0]; |
167 | vdelay = lines*2; | 254 | max_start = (crop_start >> 1) - 1; |
168 | btwrite(vdelay,BT848_E_VDELAY_LO); | 255 | max_end = (tvnorm->cropcap.bounds.top |
169 | btwrite(vdelay,BT848_O_VDELAY_LO); | 256 | + tvnorm->cropcap.bounds.height) >> 1; |
257 | |||
258 | if (min_start > max_start) | ||
259 | return -EBUSY; | ||
260 | |||
261 | BUG_ON(max_start >= max_end); | ||
262 | |||
263 | f->sampling_rate = tvnorm->Fsc; | ||
264 | f->samples_per_line = VBI_BPL; | ||
265 | f->sample_format = V4L2_PIX_FMT_GREY; | ||
266 | f->offset = VBI_OFFSET; | ||
267 | |||
268 | f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0]; | ||
269 | |||
270 | for (i = 0; i < 2; ++i) { | ||
271 | if (0 == f->count[i]) { | ||
272 | /* No data from this field. We leave f->start[i] | ||
273 | alone because VIDIOCSVBIFMT is w/o and EINVALs | ||
274 | when a driver does not support exactly the | ||
275 | requested parameters. */ | ||
276 | } else { | ||
277 | s64 start, count; | ||
278 | |||
279 | start = clamp(f->start[i], min_start, max_start); | ||
280 | /* s64 to prevent overflow. */ | ||
281 | count = (s64) f->start[i] + f->count[i] - start; | ||
282 | f->start[i] = start; | ||
283 | f->count[i] = clamp(count, (s64) 1, | ||
284 | max_end - start); | ||
285 | } | ||
286 | |||
287 | min_start += f2_offset; | ||
288 | max_start += f2_offset; | ||
289 | max_end += f2_offset; | ||
170 | } | 290 | } |
291 | |||
292 | if (0 == (f->count[0] | f->count[1])) { | ||
293 | /* As in earlier driver versions. */ | ||
294 | f->start[0] = tvnorm->vbistart[0]; | ||
295 | f->start[1] = tvnorm->vbistart[1]; | ||
296 | f->count[0] = 1; | ||
297 | f->count[1] = 1; | ||
298 | } | ||
299 | |||
300 | f->flags = 0; | ||
301 | |||
302 | f->reserved[0] = 0; | ||
303 | f->reserved[1] = 0; | ||
304 | |||
305 | return 0; | ||
171 | } | 306 | } |
172 | 307 | ||
173 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 308 | int |
309 | bttv_vbi_try_fmt (struct bttv_fh * fh, | ||
310 | struct v4l2_vbi_format * f) | ||
174 | { | 311 | { |
312 | struct bttv *btv = fh->btv; | ||
175 | const struct bttv_tvnorm *tvnorm; | 313 | const struct bttv_tvnorm *tvnorm; |
176 | s64 count0,count1,count; | 314 | __s32 crop_start; |
177 | 315 | ||
178 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | 316 | mutex_lock(&btv->lock); |
179 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 317 | |
180 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | 318 | tvnorm = &bttv_tvnorms[btv->tvnorm]; |
181 | f->fmt.vbi.samples_per_line = 2048; | 319 | crop_start = btv->crop_start; |
182 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 320 | |
183 | f->fmt.vbi.offset = VBI_OFFSET; | 321 | mutex_unlock(&btv->lock); |
184 | f->fmt.vbi.flags = 0; | 322 | |
185 | 323 | return try_fmt(f, tvnorm, crop_start); | |
186 | /* s64 to prevent overflow. */ | ||
187 | count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0] | ||
188 | - tvnorm->vbistart[0]; | ||
189 | count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1] | ||
190 | - tvnorm->vbistart[1]; | ||
191 | count = clamp (max (count0, count1), (s64) 1, (s64) VBI_MAXLINES); | ||
192 | |||
193 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | ||
194 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | ||
195 | f->fmt.vbi.count[0] = count; | ||
196 | f->fmt.vbi.count[1] = count; | ||
197 | |||
198 | f->fmt.vbi.reserved[0] = 0; | ||
199 | f->fmt.vbi.reserved[1] = 0; | ||
200 | } | 324 | } |
201 | 325 | ||
202 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 326 | int |
327 | bttv_vbi_set_fmt (struct bttv_fh * fh, | ||
328 | struct v4l2_vbi_format * f) | ||
203 | { | 329 | { |
330 | struct bttv *btv = fh->btv; | ||
204 | const struct bttv_tvnorm *tvnorm; | 331 | const struct bttv_tvnorm *tvnorm; |
332 | __s32 start1, end; | ||
333 | int rc; | ||
334 | |||
335 | mutex_lock(&btv->lock); | ||
336 | |||
337 | rc = -EBUSY; | ||
338 | if (fh->resources & RESOURCE_VBI) | ||
339 | goto fail; | ||
340 | |||
341 | tvnorm = &bttv_tvnorms[btv->tvnorm]; | ||
342 | |||
343 | rc = try_fmt(f, tvnorm, btv->crop_start); | ||
344 | if (0 != rc) | ||
345 | goto fail; | ||
346 | |||
347 | start1 = f->start[1] - tvnorm->vbistart[1] + tvnorm->vbistart[0]; | ||
348 | |||
349 | /* First possible line of video capturing. Should be | ||
350 | max(f->start[0] + f->count[0], start1 + f->count[1]) * 2 | ||
351 | when capturing both fields. But for compatibility we must | ||
352 | pretend the VBI and video capture window may overlap, | ||
353 | so end = start + 1, the lowest possible value, times two | ||
354 | because vbi_fmt.end counts field lines times two. */ | ||
355 | end = max(f->start[0], start1) * 2 + 2; | ||
356 | |||
357 | mutex_lock(&fh->vbi.lock); | ||
358 | |||
359 | fh->vbi_fmt.fmt = *f; | ||
360 | fh->vbi_fmt.tvnorm = tvnorm; | ||
361 | fh->vbi_fmt.end = end; | ||
362 | |||
363 | mutex_unlock(&fh->vbi.lock); | ||
364 | |||
365 | rc = 0; | ||
366 | |||
367 | fail: | ||
368 | mutex_unlock(&btv->lock); | ||
369 | |||
370 | return rc; | ||
371 | } | ||
372 | |||
373 | void | ||
374 | bttv_vbi_get_fmt (struct bttv_fh * fh, | ||
375 | struct v4l2_vbi_format * f) | ||
376 | { | ||
377 | const struct bttv_tvnorm *tvnorm; | ||
378 | |||
379 | *f = fh->vbi_fmt.fmt; | ||
205 | 380 | ||
206 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | 381 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; |
207 | memset(f,0,sizeof(*f)); | 382 | |
208 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 383 | if (tvnorm != fh->vbi_fmt.tvnorm) { |
209 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | 384 | __s32 max_end; |
210 | f->fmt.vbi.samples_per_line = 2048; | 385 | unsigned int i; |
211 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 386 | |
212 | f->fmt.vbi.offset = VBI_OFFSET; | 387 | /* As in vbi_buffer_prepare() this imitates the |
213 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | 388 | behaviour of earlier driver versions after video |
214 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | 389 | standard changes, with default parameters anyway. */ |
215 | f->fmt.vbi.count[0] = fh->lines; | 390 | |
216 | f->fmt.vbi.count[1] = fh->lines; | 391 | max_end = (tvnorm->cropcap.bounds.top |
217 | f->fmt.vbi.flags = 0; | 392 | + tvnorm->cropcap.bounds.height) >> 1; |
393 | |||
394 | f->sampling_rate = tvnorm->Fsc; | ||
395 | |||
396 | for (i = 0; i < 2; ++i) { | ||
397 | __s32 new_start; | ||
398 | |||
399 | new_start = f->start[i] | ||
400 | + tvnorm->vbistart[i] | ||
401 | - fh->vbi_fmt.tvnorm->vbistart[i]; | ||
402 | |||
403 | f->start[i] = min(new_start, max_end - 1); | ||
404 | f->count[i] = min((__s32) f->count[i], | ||
405 | max_end - f->start[i]); | ||
406 | |||
407 | max_end += tvnorm->vbistart[1] | ||
408 | - tvnorm->vbistart[0]; | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | |||
413 | void | ||
414 | bttv_vbi_fmt_reset (struct bttv_vbi_fmt * f, | ||
415 | int norm) | ||
416 | { | ||
417 | const struct bttv_tvnorm *tvnorm; | ||
418 | unsigned int real_samples_per_line; | ||
419 | unsigned int real_count; | ||
420 | |||
421 | tvnorm = &bttv_tvnorms[norm]; | ||
422 | |||
423 | f->fmt.sampling_rate = tvnorm->Fsc; | ||
424 | f->fmt.samples_per_line = VBI_BPL; | ||
425 | f->fmt.sample_format = V4L2_PIX_FMT_GREY; | ||
426 | f->fmt.offset = VBI_OFFSET; | ||
427 | f->fmt.start[0] = tvnorm->vbistart[0]; | ||
428 | f->fmt.start[1] = tvnorm->vbistart[1]; | ||
429 | f->fmt.count[0] = VBI_DEFLINES; | ||
430 | f->fmt.count[1] = VBI_DEFLINES; | ||
431 | f->fmt.flags = 0; | ||
432 | f->fmt.reserved[0] = 0; | ||
433 | f->fmt.reserved[1] = 0; | ||
434 | |||
435 | /* For compatibility the buffer size must be 2 * VBI_DEFLINES * | ||
436 | VBI_BPL regardless of the current video standard. */ | ||
437 | real_samples_per_line = 1024 + tvnorm->vbipack * 4; | ||
438 | real_count = ((tvnorm->cropcap.defrect.top >> 1) | ||
439 | - tvnorm->vbistart[0]); | ||
440 | |||
441 | BUG_ON(real_samples_per_line > VBI_BPL); | ||
442 | BUG_ON(real_count > VBI_DEFLINES); | ||
443 | |||
444 | f->tvnorm = tvnorm; | ||
445 | |||
446 | /* See bttv_vbi_fmt_set(). */ | ||
447 | f->end = tvnorm->vbistart[0] * 2 + 2; | ||
218 | } | 448 | } |
219 | 449 | ||
220 | /* ----------------------------------------------------------------------- */ | 450 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 3802cafc9e41..ad79b8d53430 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define _BTTVP_H_ | 26 | #define _BTTVP_H_ |
27 | 27 | ||
28 | #include <linux/version.h> | 28 | #include <linux/version.h> |
29 | #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) | 29 | #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,17) |
30 | 30 | ||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
@@ -66,14 +66,22 @@ | |||
66 | #define RISC_SLOT_LOOP 14 | 66 | #define RISC_SLOT_LOOP 14 |
67 | 67 | ||
68 | #define RESOURCE_OVERLAY 1 | 68 | #define RESOURCE_OVERLAY 1 |
69 | #define RESOURCE_VIDEO 2 | 69 | #define RESOURCE_VIDEO_STREAM 2 |
70 | #define RESOURCE_VBI 4 | 70 | #define RESOURCE_VBI 4 |
71 | #define RESOURCE_VIDEO_READ 8 | ||
71 | 72 | ||
72 | #define RAW_LINES 640 | 73 | #define RAW_LINES 640 |
73 | #define RAW_BPL 1024 | 74 | #define RAW_BPL 1024 |
74 | 75 | ||
75 | #define UNSET (-1U) | 76 | #define UNSET (-1U) |
76 | 77 | ||
78 | /* Min. value in VDELAY register. */ | ||
79 | #define MIN_VDELAY 2 | ||
80 | /* Even to get Cb first, odd for Cr. */ | ||
81 | #define MAX_HDELAY (0x3FF & -2) | ||
82 | /* Limits scaled width, which must be a multiple of 4. */ | ||
83 | #define MAX_HACTIVE (0x3FF & -4) | ||
84 | |||
77 | #define clamp(x, low, high) min (max (low, x), high) | 85 | #define clamp(x, low, high) min (max (low, x), high) |
78 | 86 | ||
79 | /* ---------------------------------------------------------- */ | 87 | /* ---------------------------------------------------------- */ |
@@ -92,8 +100,13 @@ struct bttv_tvnorm { | |||
92 | u16 vtotal; | 100 | u16 vtotal; |
93 | int sram; | 101 | int sram; |
94 | /* ITU-R frame line number of the first VBI line we can | 102 | /* ITU-R frame line number of the first VBI line we can |
95 | capture, of the first and second field. */ | 103 | capture, of the first and second field. The last possible line |
104 | is determined by cropcap.bounds. */ | ||
96 | u16 vbistart[2]; | 105 | u16 vbistart[2]; |
106 | /* Horizontally this counts fCLKx1 samples following the leading | ||
107 | edge of the horizontal sync pulse, vertically ITU-R frame line | ||
108 | numbers of the first field times two (2, 4, 6, ... 524 or 624). */ | ||
109 | struct v4l2_cropcap cropcap; | ||
97 | }; | 110 | }; |
98 | extern const struct bttv_tvnorm bttv_tvnorms[]; | 111 | extern const struct bttv_tvnorm bttv_tvnorms[]; |
99 | 112 | ||
@@ -128,6 +141,9 @@ struct bttv_buffer { | |||
128 | struct bttv_geometry geo; | 141 | struct bttv_geometry geo; |
129 | struct btcx_riscmem top; | 142 | struct btcx_riscmem top; |
130 | struct btcx_riscmem bottom; | 143 | struct btcx_riscmem bottom; |
144 | struct v4l2_rect crop; | ||
145 | unsigned int vbi_skip[2]; | ||
146 | unsigned int vbi_count[2]; | ||
131 | }; | 147 | }; |
132 | 148 | ||
133 | struct bttv_buffer_set { | 149 | struct bttv_buffer_set { |
@@ -146,6 +162,34 @@ struct bttv_overlay { | |||
146 | int setup_ok; | 162 | int setup_ok; |
147 | }; | 163 | }; |
148 | 164 | ||
165 | struct bttv_vbi_fmt { | ||
166 | struct v4l2_vbi_format fmt; | ||
167 | |||
168 | /* fmt.start[] and count[] refer to this video standard. */ | ||
169 | const struct bttv_tvnorm *tvnorm; | ||
170 | |||
171 | /* Earliest possible start of video capturing with this | ||
172 | v4l2_vbi_format, in struct bttv_crop.rect units. */ | ||
173 | __s32 end; | ||
174 | }; | ||
175 | |||
176 | /* bttv-vbi.c */ | ||
177 | void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm); | ||
178 | |||
179 | struct bttv_crop { | ||
180 | /* A cropping rectangle in struct bttv_tvnorm.cropcap units. */ | ||
181 | struct v4l2_rect rect; | ||
182 | |||
183 | /* Scaled image size limits with this crop rect. Divide | ||
184 | max_height, but not min_height, by two when capturing | ||
185 | single fields. See also bttv_crop_reset() and | ||
186 | bttv_crop_adjust() in bttv-driver.c. */ | ||
187 | __s32 min_scaled_width; | ||
188 | __s32 min_scaled_height; | ||
189 | __s32 max_scaled_width; | ||
190 | __s32 max_scaled_height; | ||
191 | }; | ||
192 | |||
149 | struct bttv_fh { | 193 | struct bttv_fh { |
150 | struct bttv *btv; | 194 | struct bttv *btv; |
151 | int resources; | 195 | int resources; |
@@ -160,13 +204,19 @@ struct bttv_fh { | |||
160 | int width; | 204 | int width; |
161 | int height; | 205 | int height; |
162 | 206 | ||
163 | /* current settings */ | 207 | /* video overlay */ |
164 | const struct bttv_format *ovfmt; | 208 | const struct bttv_format *ovfmt; |
165 | struct bttv_overlay ov; | 209 | struct bttv_overlay ov; |
166 | 210 | ||
167 | /* video overlay */ | 211 | /* Application called VIDIOC_S_CROP. */ |
212 | int do_crop; | ||
213 | |||
214 | /* vbi capture */ | ||
168 | struct videobuf_queue vbi; | 215 | struct videobuf_queue vbi; |
169 | int lines; | 216 | /* Current VBI capture window as seen through this fh (cannot |
217 | be global for compatibility with earlier drivers). Protected | ||
218 | by struct bttv.lock and struct bttv_fh.vbi.lock. */ | ||
219 | struct bttv_vbi_fmt vbi_fmt; | ||
170 | }; | 220 | }; |
171 | 221 | ||
172 | /* ---------------------------------------------------------- */ | 222 | /* ---------------------------------------------------------- */ |
@@ -176,7 +226,8 @@ struct bttv_fh { | |||
176 | int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | 226 | int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, |
177 | struct scatterlist *sglist, | 227 | struct scatterlist *sglist, |
178 | unsigned int offset, unsigned int bpl, | 228 | unsigned int offset, unsigned int bpl, |
179 | unsigned int pitch, unsigned int lines); | 229 | unsigned int pitch, unsigned int skip_lines, |
230 | unsigned int store_lines); | ||
180 | 231 | ||
181 | /* control dma register + risc main loop */ | 232 | /* control dma register + risc main loop */ |
182 | void bttv_set_dma(struct bttv *btv, int override); | 233 | void bttv_set_dma(struct bttv *btv, int override); |
@@ -202,9 +253,9 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, | |||
202 | /* ---------------------------------------------------------- */ | 253 | /* ---------------------------------------------------------- */ |
203 | /* bttv-vbi.c */ | 254 | /* bttv-vbi.c */ |
204 | 255 | ||
205 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f); | 256 | int bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); |
206 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f); | 257 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); |
207 | void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines); | 258 | int bttv_vbi_set_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); |
208 | 259 | ||
209 | extern struct videobuf_queue_ops bttv_vbi_qops; | 260 | extern struct videobuf_queue_ops bttv_vbi_qops; |
210 | 261 | ||
@@ -233,7 +284,6 @@ extern int fini_bttv_i2c(struct bttv *btv); | |||
233 | #define d2printk if (bttv_debug >= 2) printk | 284 | #define d2printk if (bttv_debug >= 2) printk |
234 | 285 | ||
235 | #define BTTV_MAX_FBUF 0x208000 | 286 | #define BTTV_MAX_FBUF 0x208000 |
236 | #define VBIBUF_SIZE (2048*VBI_MAXLINES*2) | ||
237 | #define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ | 287 | #define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ |
238 | #define BTTV_FREE_IDLE (HZ) /* one second */ | 288 | #define BTTV_FREE_IDLE (HZ) /* one second */ |
239 | 289 | ||
@@ -314,7 +364,6 @@ struct bttv { | |||
314 | spinlock_t s_lock; | 364 | spinlock_t s_lock; |
315 | struct mutex lock; | 365 | struct mutex lock; |
316 | int resources; | 366 | int resources; |
317 | struct mutex reslock; | ||
318 | #ifdef VIDIOC_G_PRIORITY | 367 | #ifdef VIDIOC_G_PRIORITY |
319 | struct v4l2_prio_state prio; | 368 | struct v4l2_prio_state prio; |
320 | #endif | 369 | #endif |
@@ -384,6 +433,21 @@ struct bttv { | |||
384 | 433 | ||
385 | unsigned int users; | 434 | unsigned int users; |
386 | struct bttv_fh init; | 435 | struct bttv_fh init; |
436 | |||
437 | /* Default (0) and current (1) video capturing and overlay | ||
438 | cropping parameters in bttv_tvnorm.cropcap units. Protected | ||
439 | by bttv.lock. */ | ||
440 | struct bttv_crop crop[2]; | ||
441 | |||
442 | /* Earliest possible start of video capturing in | ||
443 | bttv_tvnorm.cropcap line units. Set by check_alloc_btres() | ||
444 | and free_btres(). Protected by bttv.lock. */ | ||
445 | __s32 vbi_end; | ||
446 | |||
447 | /* Latest possible end of VBI capturing (= crop[x].rect.top when | ||
448 | VIDEO_RESOURCES are locked). Set by check_alloc_btres() | ||
449 | and free_btres(). Protected by bttv.lock. */ | ||
450 | __s32 crop_start; | ||
387 | }; | 451 | }; |
388 | 452 | ||
389 | /* our devices */ | 453 | /* our devices */ |