aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt8xx/bttv-driver.c
diff options
context:
space:
mode:
authorMichael Schimek <mschimek@gmx.at>2007-01-18 14:17:39 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-02-21 10:34:36 -0500
commite5bd0260e7d3d806e66c12859f50733dca43bbcf (patch)
tree7a726da52b8155357a08e4feb7e0e79084673fa0 /drivers/media/video/bt8xx/bttv-driver.c
parent13071f0a58f285eee81f63c917078bb2a48cf51e (diff)
V4L/DVB (5077): Bttv cropping support
Adds the missing VIDIOC_CROPCAP, G_CROP and S_CROP ioctls, permitting applications to capture or overlay a subsection of the picture or to extend the capture window beyond active video, into the VBI area and the horizontal blanking. VBI capturing can start and end on any line, including the picture area, and apps can capture different lines of each field and single fields. For compatibility with existing applications, the open() function resets the cropping and VBI capturing parameters and a VIDIOC_S_CROP call is necessary to actually enable cropping. Regrettably in PAL-M, PAL-N, PAL-Nc and NTSC-JP mode the maximum image width will increase from 640 and 768 to 747 and 923 pixels respectively. Like the VBI changes however, this should only affect applications which depend on former driver limitations, such as never getting more than 640 pixels regardless of the requested width. Also, new freedoms require additional checks for conflicts and some applications may not expect an EBUSY error from the VIDIOC_QBUF and VIDIOCMCAPTURE ioctls. These errors should be rare though. So far, the patch has been tested on a UP machine with a bt878 in PAL- BGHI and NTSC-M mode using xawtv, tvtime, mplayer/mencoder, zapping/ libzvbi and these tools: http://zapping.sf.net/bttv-crop-test.tar.bz2 I'd be grateful about comments or bug reports. Signed-off-by: Michael H. Schimek <mschimek@gmx.at> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-driver.c')
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c891
1 files changed, 764 insertions, 127 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];
64static unsigned int irq_debug; 68static unsigned int irq_debug;
65static unsigned int gbuffers = 8; 69static unsigned int gbuffers = 8;
66static unsigned int gbufsize = 0x208000; 70static unsigned int gbufsize = 0x208000;
71static unsigned int reset_crop = 1;
67 72
68static int video_nr = -1; 73static int video_nr = -1;
69static int radio_nr = -1; 74static int radio_nr = -1;
@@ -103,6 +108,7 @@ module_param(radio_nr, int, 0444);
103module_param(vbi_nr, int, 0444); 108module_param(vbi_nr, int, 0444);
104module_param(gbuffers, int, 0444); 109module_param(gbuffers, int, 0444);
105module_param(gbufsize, int, 0444); 110module_param(gbufsize, int, 0444);
111module_param(reset_crop, int, 0444);
106 112
107module_param(v4l2, int, 0644); 113module_param(v4l2, int, 0644);
108module_param(bigendian, int, 0644); 114module_param(bigendian, int, 0644);
@@ -129,6 +135,8 @@ MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
129MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); 135MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
130MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); 136MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
131MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); 137MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
138MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default "
139 "is 1 (yes) for compatibility with older applications");
132MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)"); 140MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
133MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); 141MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
134MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); 142MODULE_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
195const struct bttv_tvnorm bttv_tvnorms[] = { 230const 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};
343static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); 450static 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
681static 821static
682int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit) 822int 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
702static 873static
@@ -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. */
886static void
887disclaim_vbi_lines(struct bttv *btv)
888{
889 btv->vbi_end = 0;
890}
891
892/* Call with btv->lock down. */
893static void
894disclaim_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
714static 914static
715void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits) 915void 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
1242static void
1243bttv_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
1264static void
1265bttv_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. */
1033static int 1272static int
1034set_tvnorm(struct bttv *btv, unsigned int norm) 1273set_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. */
1060static void 1315static void
1061set_input(struct bttv *btv, unsigned int input) 1316set_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
1942static 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. */
2248static void
2249bttv_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. */
2295static int
2296limit_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. */
2409static int
2410verify_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
2148static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, 2642static 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
2968static int bttv_ioctl(struct inode *inode, struct file *file, 3563static 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 */