1/* 2 * 3 * device driver for philips saa7134 based TV cards 4 * video4linux video interface 5 * 6 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 7 * 8 * 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 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23#include <linux/init.h> 24#include <linux/list.h> 25#include <linux/module.h> 26#include <linux/moduleparam.h> 27#include <linux/kernel.h> 28#include <linux/slab.h> 29#include <linux/sort.h> 30 31#include "saa7134-reg.h" 32#include "saa7134.h" 33#include <media/v4l2-common.h> 34 35#ifdef CONFIG_VIDEO_V4L1_COMPAT 36/* Include V4L1 specific functions. Should be removed soon */ 37#include <linux/videodev.h> 38#endif 39 40/* ------------------------------------------------------------------ */ 41 42static unsigned int video_debug = 0; 43static unsigned int gbuffers = 8; 44static unsigned int noninterlaced = 1; 45static unsigned int gbufsize = 720*576*4; 46static unsigned int gbufsize_max = 720*576*4; 47static char secam[] = "--"; 48module_param(video_debug, int, 0644); 49MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); 50module_param(gbuffers, int, 0444); 51MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32"); 52module_param(noninterlaced, int, 0644); 53MODULE_PARM_DESC(noninterlaced,"capture non interlaced video"); 54module_param_string(secam, secam, sizeof(secam), 0644); 55MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc"); 56 57 58#define dprintk(fmt, arg...) if (video_debug) \ 59 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) 60 61/* ------------------------------------------------------------------ */ 62/* Defines for Video Output Port Register at address 0x191 */ 63 64/* Bit 0: VIP code T bit polarity */ 65 66#define VP_T_CODE_P_NON_INVERTED 0x00 67#define VP_T_CODE_P_INVERTED 0x01 68 69/* ------------------------------------------------------------------ */ 70/* Defines for Video Output Port Register at address 0x195 */ 71 72/* Bit 2: Video output clock delay control */ 73 74#define VP_CLK_CTRL2_NOT_DELAYED 0x00 75#define VP_CLK_CTRL2_DELAYED 0x04 76 77/* Bit 1: Video output clock invert control */ 78 79#define VP_CLK_CTRL1_NON_INVERTED 0x00 80#define VP_CLK_CTRL1_INVERTED 0x02 81 82/* ------------------------------------------------------------------ */ 83/* Defines for Video Output Port Register at address 0x196 */ 84 85/* Bits 2 to 0: VSYNC pin video vertical sync type */ 86 87#define VP_VS_TYPE_MASK 0x07 88 89#define VP_VS_TYPE_OFF 0x00 90#define VP_VS_TYPE_V123 0x01 91#define VP_VS_TYPE_V_ITU 0x02 92#define VP_VS_TYPE_VGATE_L 0x03 93#define VP_VS_TYPE_RESERVED1 0x04 94#define VP_VS_TYPE_RESERVED2 0x05 95#define VP_VS_TYPE_F_ITU 0x06 96#define VP_VS_TYPE_SC_FID 0x07 97 98/* ------------------------------------------------------------------ */ 99/* data structs for video */ 100 101static int video_out[][9] = { 102 [CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 }, 103}; 104 105static struct saa7134_format formats[] = { 106 { 107 .name = "8 bpp gray", 108 .fourcc = V4L2_PIX_FMT_GREY, 109 .depth = 8, 110 .pm = 0x06, 111 },{ 112 .name = "15 bpp RGB, le", 113 .fourcc = V4L2_PIX_FMT_RGB555, 114 .depth = 16, 115 .pm = 0x13 | 0x80, 116 },{ 117 .name = "15 bpp RGB, be", 118 .fourcc = V4L2_PIX_FMT_RGB555X, 119 .depth = 16, 120 .pm = 0x13 | 0x80, 121 .bswap = 1, 122 },{ 123 .name = "16 bpp RGB, le", 124 .fourcc = V4L2_PIX_FMT_RGB565, 125 .depth = 16, 126 .pm = 0x10 | 0x80, 127 },{ 128 .name = "16 bpp RGB, be", 129 .fourcc = V4L2_PIX_FMT_RGB565X, 130 .depth = 16, 131 .pm = 0x10 | 0x80, 132 .bswap = 1, 133 },{ 134 .name = "24 bpp RGB, le", 135 .fourcc = V4L2_PIX_FMT_BGR24, 136 .depth = 24, 137 .pm = 0x11, 138 },{ 139 .name = "24 bpp RGB, be", 140 .fourcc = V4L2_PIX_FMT_RGB24, 141 .depth = 24, 142 .pm = 0x11, 143 .bswap = 1, 144 },{ 145 .name = "32 bpp RGB, le", 146 .fourcc = V4L2_PIX_FMT_BGR32, 147 .depth = 32, 148 .pm = 0x12, 149 },{ 150 .name = "32 bpp RGB, be", 151 .fourcc = V4L2_PIX_FMT_RGB32, 152 .depth = 32, 153 .pm = 0x12, 154 .bswap = 1, 155 .wswap = 1, 156 },{ 157 .name = "4:2:2 packed, YUYV", 158 .fourcc = V4L2_PIX_FMT_YUYV, 159 .depth = 16, 160 .pm = 0x00, 161 .bswap = 1, 162 .yuv = 1, 163 },{ 164 .name = "4:2:2 packed, UYVY", 165 .fourcc = V4L2_PIX_FMT_UYVY, 166 .depth = 16, 167 .pm = 0x00, 168 .yuv = 1, 169 },{ 170 .name = "4:2:2 planar, Y-Cb-Cr", 171 .fourcc = V4L2_PIX_FMT_YUV422P, 172 .depth = 16, 173 .pm = 0x09, 174 .yuv = 1, 175 .planar = 1, 176 .hshift = 1, 177 .vshift = 0, 178 },{ 179 .name = "4:2:0 planar, Y-Cb-Cr", 180 .fourcc = V4L2_PIX_FMT_YUV420, 181 .depth = 12, 182 .pm = 0x0a, 183 .yuv = 1, 184 .planar = 1, 185 .hshift = 1, 186 .vshift = 1, 187 },{ 188 .name = "4:2:0 planar, Y-Cb-Cr", 189 .fourcc = V4L2_PIX_FMT_YVU420, 190 .depth = 12, 191 .pm = 0x0a, 192 .yuv = 1, 193 .planar = 1, 194 .uvswap = 1, 195 .hshift = 1, 196 .vshift = 1, 197 } 198}; 199#define FORMATS ARRAY_SIZE(formats) 200 201#define NORM_625_50 \ 202 .h_start = 0, \ 203 .h_stop = 719, \ 204 .video_v_start = 24, \ 205 .video_v_stop = 311, \ 206 .vbi_v_start_0 = 7, \ 207 .vbi_v_stop_0 = 22, \ 208 .vbi_v_start_1 = 319, \ 209 .src_timing = 4 210 211#define NORM_525_60 \ 212 .h_start = 0, \ 213 .h_stop = 703, \ 214 .video_v_start = 23, \ 215 .video_v_stop = 262, \ 216 .vbi_v_start_0 = 10, \ 217 .vbi_v_stop_0 = 21, \ 218 .vbi_v_start_1 = 273, \ 219 .src_timing = 7 220 221static struct saa7134_tvnorm tvnorms[] = { 222 { 223 .name = "PAL", /* autodetect */ 224 .id = V4L2_STD_PAL, 225 NORM_625_50, 226 227 .sync_control = 0x18, 228 .luma_control = 0x40, 229 .chroma_ctrl1 = 0x81, 230 .chroma_gain = 0x2a, 231 .chroma_ctrl2 = 0x06, 232 .vgate_misc = 0x1c, 233 234 },{ 235 .name = "PAL-BG", 236 .id = V4L2_STD_PAL_BG, 237 NORM_625_50, 238 239 .sync_control = 0x18, 240 .luma_control = 0x40, 241 .chroma_ctrl1 = 0x81, 242 .chroma_gain = 0x2a, 243 .chroma_ctrl2 = 0x06, 244 .vgate_misc = 0x1c, 245 246 },{ 247 .name = "PAL-I", 248 .id = V4L2_STD_PAL_I, 249 NORM_625_50, 250 251 .sync_control = 0x18, 252 .luma_control = 0x40, 253 .chroma_ctrl1 = 0x81, 254 .chroma_gain = 0x2a, 255 .chroma_ctrl2 = 0x06, 256 .vgate_misc = 0x1c, 257 258 },{ 259 .name = "PAL-DK", 260 .id = V4L2_STD_PAL_DK, 261 NORM_625_50, 262 263 .sync_control = 0x18, 264 .luma_control = 0x40, 265 .chroma_ctrl1 = 0x81, 266 .chroma_gain = 0x2a, 267 .chroma_ctrl2 = 0x06, 268 .vgate_misc = 0x1c, 269 270 },{ 271 .name = "NTSC", 272 .id = V4L2_STD_NTSC, 273 NORM_525_60, 274 275 .sync_control = 0x59, 276 .luma_control = 0x40, 277 .chroma_ctrl1 = 0x89, 278 .chroma_gain = 0x2a, 279 .chroma_ctrl2 = 0x0e, 280 .vgate_misc = 0x18, 281 282 },{ 283 .name = "SECAM", 284 .id = V4L2_STD_SECAM, 285 NORM_625_50, 286 287 .sync_control = 0x18, 288 .luma_control = 0x1b, 289 .chroma_ctrl1 = 0xd1, 290 .chroma_gain = 0x80, 291 .chroma_ctrl2 = 0x00, 292 .vgate_misc = 0x1c, 293 294 },{ 295 .name = "SECAM-DK", 296 .id = V4L2_STD_SECAM_DK, 297 NORM_625_50, 298 299 .sync_control = 0x18, 300 .luma_control = 0x1b, 301 .chroma_ctrl1 = 0xd1, 302 .chroma_gain = 0x80, 303 .chroma_ctrl2 = 0x00, 304 .vgate_misc = 0x1c, 305 306 },{ 307 .name = "SECAM-L", 308 .id = V4L2_STD_SECAM_L, 309 NORM_625_50, 310 311 .sync_control = 0x18, 312 .luma_control = 0x1b, 313 .chroma_ctrl1 = 0xd1, 314 .chroma_gain = 0x80, 315 .chroma_ctrl2 = 0x00, 316 .vgate_misc = 0x1c, 317 318 },{ 319 .name = "SECAM-Lc", 320 .id = V4L2_STD_SECAM_LC, 321 NORM_625_50, 322 323 .sync_control = 0x18, 324 .luma_control = 0x1b, 325 .chroma_ctrl1 = 0xd1, 326 .chroma_gain = 0x80, 327 .chroma_ctrl2 = 0x00, 328 .vgate_misc = 0x1c, 329 330 },{ 331 .name = "PAL-M", 332 .id = V4L2_STD_PAL_M, 333 NORM_525_60, 334 335 .sync_control = 0x59, 336 .luma_control = 0x40, 337 .chroma_ctrl1 = 0xb9, 338 .chroma_gain = 0x2a, 339 .chroma_ctrl2 = 0x0e, 340 .vgate_misc = 0x18, 341 342 },{ 343 .name = "PAL-Nc", 344 .id = V4L2_STD_PAL_Nc, 345 NORM_625_50, 346 347 .sync_control = 0x18, 348 .luma_control = 0x40, 349 .chroma_ctrl1 = 0xa1, 350 .chroma_gain = 0x2a, 351 .chroma_ctrl2 = 0x06, 352 .vgate_misc = 0x1c, 353 354 },{ 355 .name = "PAL-60", 356 .id = V4L2_STD_PAL_60, 357 358 .h_start = 0, 359 .h_stop = 719, 360 .video_v_start = 23, 361 .video_v_stop = 262, 362 .vbi_v_start_0 = 10, 363 .vbi_v_stop_0 = 21, 364 .vbi_v_start_1 = 273, 365 .src_timing = 7, 366 367 .sync_control = 0x18, 368 .luma_control = 0x40, 369 .chroma_ctrl1 = 0x81, 370 .chroma_gain = 0x2a, 371 .chroma_ctrl2 = 0x06, 372 .vgate_misc = 0x1c, 373 } 374}; 375#define TVNORMS ARRAY_SIZE(tvnorms) 376 377#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0) 378#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1) 379#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2) 380#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3) 381#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4) 382 383static const struct v4l2_queryctrl no_ctrl = { 384 .name = "42", 385 .flags = V4L2_CTRL_FLAG_DISABLED, 386}; 387static const struct v4l2_queryctrl video_ctrls[] = { 388 /* --- video --- */ 389 { 390 .id = V4L2_CID_BRIGHTNESS, 391 .name = "Brightness", 392 .minimum = 0, 393 .maximum = 255, 394 .step = 1, 395 .default_value = 128, 396 .type = V4L2_CTRL_TYPE_INTEGER, 397 },{ 398 .id = V4L2_CID_CONTRAST, 399 .name = "Contrast", 400 .minimum = 0, 401 .maximum = 127, 402 .step = 1, 403 .default_value = 68, 404 .type = V4L2_CTRL_TYPE_INTEGER, 405 },{ 406 .id = V4L2_CID_SATURATION, 407 .name = "Saturation", 408 .minimum = 0, 409 .maximum = 127, 410 .step = 1, 411 .default_value = 64, 412 .type = V4L2_CTRL_TYPE_INTEGER, 413 },{ 414 .id = V4L2_CID_HUE, 415 .name = "Hue", 416 .minimum = -128, 417 .maximum = 127, 418 .step = 1, 419 .default_value = 0, 420 .type = V4L2_CTRL_TYPE_INTEGER, 421 },{ 422 .id = V4L2_CID_HFLIP, 423 .name = "Mirror", 424 .minimum = 0, 425 .maximum = 1, 426 .type = V4L2_CTRL_TYPE_BOOLEAN, 427 }, 428 /* --- audio --- */ 429 { 430 .id = V4L2_CID_AUDIO_MUTE, 431 .name = "Mute", 432 .minimum = 0, 433 .maximum = 1, 434 .type = V4L2_CTRL_TYPE_BOOLEAN, 435 },{ 436 .id = V4L2_CID_AUDIO_VOLUME, 437 .name = "Volume", 438 .minimum = -15, 439 .maximum = 15, 440 .step = 1, 441 .default_value = 0, 442 .type = V4L2_CTRL_TYPE_INTEGER, 443 }, 444 /* --- private --- */ 445 { 446 .id = V4L2_CID_PRIVATE_INVERT, 447 .name = "Invert", 448 .minimum = 0, 449 .maximum = 1, 450 .type = V4L2_CTRL_TYPE_BOOLEAN, 451 },{ 452 .id = V4L2_CID_PRIVATE_Y_ODD, 453 .name = "y offset odd field", 454 .minimum = 0, 455 .maximum = 128, 456 .default_value = 0, 457 .type = V4L2_CTRL_TYPE_INTEGER, 458 },{ 459 .id = V4L2_CID_PRIVATE_Y_EVEN, 460 .name = "y offset even field", 461 .minimum = 0, 462 .maximum = 128, 463 .default_value = 0, 464 .type = V4L2_CTRL_TYPE_INTEGER, 465 },{ 466 .id = V4L2_CID_PRIVATE_AUTOMUTE, 467 .name = "automute", 468 .minimum = 0, 469 .maximum = 1, 470 .default_value = 1, 471 .type = V4L2_CTRL_TYPE_BOOLEAN, 472 } 473}; 474static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls); 475 476static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id) 477{ 478 unsigned int i; 479 480 for (i = 0; i < CTRLS; i++) 481 if (video_ctrls[i].id == id) 482 return video_ctrls+i; 483 return NULL; 484} 485 486static struct saa7134_format* format_by_fourcc(unsigned int fourcc) 487{ 488 unsigned int i; 489 490 for (i = 0; i < FORMATS; i++) 491 if (formats[i].fourcc == fourcc) 492 return formats+i; 493 return NULL; 494} 495 496/* ----------------------------------------------------------------------- */ 497/* resource management */ 498 499static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit) 500{ 501 if (fh->resources & bit) 502 /* have it already allocated */ 503 return 1; 504 505 /* is it free? */ 506 mutex_lock(&dev->lock); 507 if (dev->resources & bit) { 508 /* no, someone else uses it */ 509 mutex_unlock(&dev->lock); 510 return 0; 511 } 512 /* it's free, grab it */ 513 fh->resources |= bit; 514 dev->resources |= bit; 515 dprintk("res: get %d\n",bit); 516 mutex_unlock(&dev->lock); 517 return 1; 518} 519 520static int res_check(struct saa7134_fh *fh, unsigned int bit) 521{ 522 return (fh->resources & bit); 523} 524 525static int res_locked(struct saa7134_dev *dev, unsigned int bit) 526{ 527 return (dev->resources & bit); 528} 529 530static 531void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) 532{ 533 BUG_ON((fh->resources & bits) != bits); 534 535 mutex_lock(&dev->lock); 536 fh->resources &= ~bits; 537 dev->resources &= ~bits; 538 dprintk("res: put %d\n",bits); 539 mutex_unlock(&dev->lock); 540} 541 542/* ------------------------------------------------------------------ */ 543 544static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) 545{ 546 int luma_control,sync_control,mux; 547 548 dprintk("set tv norm = %s\n",norm->name); 549 dev->tvnorm = norm; 550 551 mux = card_in(dev,dev->ctl_input).vmux; 552 luma_control = norm->luma_control; 553 sync_control = norm->sync_control; 554 555 if (mux > 5) 556 luma_control |= 0x80; /* svideo */ 557 if (noninterlaced || dev->nosignal) 558 sync_control |= 0x20; 559 560 /* setup cropping */ 561 dev->crop_bounds.left = norm->h_start; 562 dev->crop_defrect.left = norm->h_start; 563 dev->crop_bounds.width = norm->h_stop - norm->h_start +1; 564 dev->crop_defrect.width = norm->h_stop - norm->h_start +1; 565 566 dev->crop_bounds.top = (norm->vbi_v_stop_0+1)*2; 567 dev->crop_defrect.top = norm->video_v_start*2; 568 dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624) 569 - dev->crop_bounds.top; 570 dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2; 571 572 dev->crop_current = dev->crop_defrect; 573 574 /* setup video decoder */ 575 saa_writeb(SAA7134_INCR_DELAY, 0x08); 576 saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux); 577 saa_writeb(SAA7134_ANALOG_IN_CTRL2, 0x00); 578 579 saa_writeb(SAA7134_ANALOG_IN_CTRL3, 0x90); 580 saa_writeb(SAA7134_ANALOG_IN_CTRL4, 0x90); 581 saa_writeb(SAA7134_HSYNC_START, 0xeb); 582 saa_writeb(SAA7134_HSYNC_STOP, 0xe0); 583 saa_writeb(SAA7134_SOURCE_TIMING1, norm->src_timing); 584 585 saa_writeb(SAA7134_SYNC_CTRL, sync_control); 586 saa_writeb(SAA7134_LUMA_CTRL, luma_control); 587 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright); 588 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, dev->ctl_contrast); 589 590 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation); 591 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue); 592 saa_writeb(SAA7134_CHROMA_CTRL1, norm->chroma_ctrl1); 593 saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain); 594 595 saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2); 596 saa_writeb(SAA7134_MODE_DELAY_CTRL, 0x00); 597 598 saa_writeb(SAA7134_ANALOG_ADC, 0x01); 599 saa_writeb(SAA7134_VGATE_START, 0x11); 600 saa_writeb(SAA7134_VGATE_STOP, 0xfe); 601 saa_writeb(SAA7134_MISC_VGATE_MSB, norm->vgate_misc); 602 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40); 603 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80); 604 605 /* only tell the tuner if this is a tv input */ 606 if (card_in(dev,dev->ctl_input).tv) { 607 if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290) 608 && ((card(dev).tuner_config == 1) 609 || (card(dev).tuner_config == 2))) 610 saa7134_set_gpio(dev, 22, 5); 611 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id); 612 } 613} 614 615static void video_mux(struct saa7134_dev *dev, int input) 616{ 617 dprintk("video input = %d [%s]\n",input,card_in(dev,input).name); 618 dev->ctl_input = input; 619 set_tvnorm(dev,dev->tvnorm); 620 saa7134_tvaudio_setinput(dev,&card_in(dev,input)); 621} 622 623static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) 624{ 625 static const struct { 626 int xpsc; 627 int xacl; 628 int xc2_1; 629 int xdcg; 630 int vpfy; 631 } vals[] = { 632 /* XPSC XACL XC2_1 XDCG VPFY */ 633 { 1, 0, 0, 0, 0 }, 634 { 2, 2, 1, 2, 2 }, 635 { 3, 4, 1, 3, 2 }, 636 { 4, 8, 1, 4, 2 }, 637 { 5, 8, 1, 4, 2 }, 638 { 6, 8, 1, 4, 3 }, 639 { 7, 8, 1, 4, 3 }, 640 { 8, 15, 0, 4, 3 }, 641 { 9, 15, 0, 4, 3 }, 642 { 10, 16, 1, 5, 3 }, 643 }; 644 static const int count = ARRAY_SIZE(vals); 645 int i; 646 647 for (i = 0; i < count; i++) 648 if (vals[i].xpsc == prescale) 649 break; 650 if (i == count) 651 return; 652 653 saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc); 654 saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl); 655 saa_writeb(SAA7134_LEVEL_CTRL(task), 656 (vals[i].xc2_1 << 3) | (vals[i].xdcg)); 657 saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f, 658 (vals[i].vpfy << 2) | vals[i].vpfy); 659} 660 661static void set_v_scale(struct saa7134_dev *dev, int task, int yscale) 662{ 663 int val,mirror; 664 665 saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale & 0xff); 666 saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8); 667 668 mirror = (dev->ctl_mirror) ? 0x02 : 0x00; 669 if (yscale < 2048) { 670 /* LPI */ 671 dprintk("yscale LPI yscale=%d\n",yscale); 672 saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror); 673 saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40); 674 saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40); 675 } else { 676 /* ACM */ 677 val = 0x40 * 1024 / yscale; 678 dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val); 679 saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror); 680 saa_writeb(SAA7134_LUMA_CONTRAST(task), val); 681 saa_writeb(SAA7134_CHROMA_SATURATION(task), val); 682 } 683 saa_writeb(SAA7134_LUMA_BRIGHT(task), 0x80); 684} 685 686static void set_size(struct saa7134_dev *dev, int task, 687 int width, int height, int interlace) 688{ 689 int prescale,xscale,yscale,y_even,y_odd; 690 int h_start, h_stop, v_start, v_stop; 691 int div = interlace ? 2 : 1; 692 693 /* setup video scaler */ 694 h_start = dev->crop_current.left; 695 v_start = dev->crop_current.top/2; 696 h_stop = (dev->crop_current.left + dev->crop_current.width -1); 697 v_stop = (dev->crop_current.top + dev->crop_current.height -1)/2; 698 699 saa_writeb(SAA7134_VIDEO_H_START1(task), h_start & 0xff); 700 saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8); 701 saa_writeb(SAA7134_VIDEO_H_STOP1(task), h_stop & 0xff); 702 saa_writeb(SAA7134_VIDEO_H_STOP2(task), h_stop >> 8); 703 saa_writeb(SAA7134_VIDEO_V_START1(task), v_start & 0xff); 704 saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8); 705 saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff); 706 saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8); 707 708 prescale = dev->crop_current.width / width; 709 if (0 == prescale) 710 prescale = 1; 711 xscale = 1024 * dev->crop_current.width / prescale / width; 712 yscale = 512 * div * dev->crop_current.height / height; 713 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); 714 set_h_prescale(dev,task,prescale); 715 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); 716 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); 717 set_v_scale(dev,task,yscale); 718 719 saa_writeb(SAA7134_VIDEO_PIXELS1(task), width & 0xff); 720 saa_writeb(SAA7134_VIDEO_PIXELS2(task), width >> 8); 721 saa_writeb(SAA7134_VIDEO_LINES1(task), height/div & 0xff); 722 saa_writeb(SAA7134_VIDEO_LINES2(task), height/div >> 8); 723 724 /* deinterlace y offsets */ 725 y_odd = dev->ctl_y_odd; 726 y_even = dev->ctl_y_even; 727 saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd); 728 saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even); 729 saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd); 730 saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even); 731} 732 733/* ------------------------------------------------------------------ */ 734 735struct cliplist { 736 __u16 position; 737 __u8 enable; 738 __u8 disable; 739}; 740 741static void set_cliplist(struct saa7134_dev *dev, int reg, 742 struct cliplist *cl, int entries, char *name) 743{ 744 __u8 winbits = 0; 745 int i; 746 747 for (i = 0; i < entries; i++) { 748 winbits |= cl[i].enable; 749 winbits &= ~cl[i].disable; 750 if (i < 15 && cl[i].position == cl[i+1].position) 751 continue; 752 saa_writeb(reg + 0, winbits); 753 saa_writeb(reg + 2, cl[i].position & 0xff); 754 saa_writeb(reg + 3, cl[i].position >> 8); 755 dprintk("clip: %s winbits=%02x pos=%d\n", 756 name,winbits,cl[i].position); 757 reg += 8; 758 } 759 for (; reg < 0x400; reg += 8) { 760 saa_writeb(reg+ 0, 0); 761 saa_writeb(reg + 1, 0); 762 saa_writeb(reg + 2, 0); 763 saa_writeb(reg + 3, 0); 764 } 765} 766 767static int clip_range(int val) 768{ 769 if (val < 0) 770 val = 0; 771 return val; 772} 773 774/* Sort into smallest position first order */ 775static int cliplist_cmp(const void *a, const void *b) 776{ 777 const struct cliplist *cla = a; 778 const struct cliplist *clb = b; 779 if (cla->position < clb->position) 780 return -1; 781 if (cla->position > clb->position) 782 return 1; 783 return 0; 784} 785 786static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips, 787 int nclips, int interlace) 788{ 789 struct cliplist col[16], row[16]; 790 int cols = 0, rows = 0, i; 791 int div = interlace ? 2 : 1; 792 793 memset(col, 0, sizeof(col)); 794 memset(row, 0, sizeof(row)); 795 for (i = 0; i < nclips && i < 8; i++) { 796 col[cols].position = clip_range(clips[i].c.left); 797 col[cols].enable = (1 << i); 798 cols++; 799 col[cols].position = clip_range(clips[i].c.left+clips[i].c.width); 800 col[cols].disable = (1 << i); 801 cols++; 802 row[rows].position = clip_range(clips[i].c.top / div); 803 row[rows].enable = (1 << i); 804 rows++; 805 row[rows].position = clip_range((clips[i].c.top + clips[i].c.height) 806 / div); 807 row[rows].disable = (1 << i); 808 rows++; 809 } 810 sort(col, cols, sizeof col[0], cliplist_cmp, NULL); 811 sort(row, rows, sizeof row[0], cliplist_cmp, NULL); 812 set_cliplist(dev,0x380,col,cols,"cols"); 813 set_cliplist(dev,0x384,row,rows,"rows"); 814 return 0; 815} 816 817static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win) 818{ 819 enum v4l2_field field; 820 int maxw, maxh; 821 822 if (NULL == dev->ovbuf.base) 823 return -EINVAL; 824 if (NULL == dev->ovfmt) 825 return -EINVAL; 826 if (win->w.width < 48 || win->w.height < 32) 827 return -EINVAL; 828 if (win->clipcount > 2048) 829 return -EINVAL; 830 831 field = win->field; 832 maxw = dev->crop_current.width; 833 maxh = dev->crop_current.height; 834 835 if (V4L2_FIELD_ANY == field) { 836 field = (win->w.height > maxh/2) 837 ? V4L2_FIELD_INTERLACED 838 : V4L2_FIELD_TOP; 839 } 840 switch (field) { 841 case V4L2_FIELD_TOP: 842 case V4L2_FIELD_BOTTOM: 843 maxh = maxh / 2; 844 break; 845 case V4L2_FIELD_INTERLACED: 846 break; 847 default: 848 return -EINVAL; 849 } 850 851 win->field = field; 852 if (win->w.width > maxw) 853 win->w.width = maxw; 854 if (win->w.height > maxh) 855 win->w.height = maxh; 856 return 0; 857} 858 859static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh) 860{ 861 unsigned long base,control,bpl; 862 int err; 863 864 err = verify_preview(dev,&fh->win); 865 if (0 != err) 866 return err; 867 868 dev->ovfield = fh->win.field; 869 dprintk("start_preview %dx%d+%d+%d %s field=%s\n", 870 fh->win.w.width,fh->win.w.height, 871 fh->win.w.left,fh->win.w.top, 872 dev->ovfmt->name,v4l2_field_names[dev->ovfield]); 873 874 /* setup window + clipping */ 875 set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height, 876 V4L2_FIELD_HAS_BOTH(dev->ovfield)); 877 setup_clipping(dev,fh->clips,fh->nclips, 878 V4L2_FIELD_HAS_BOTH(dev->ovfield)); 879 if (dev->ovfmt->yuv) 880 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03); 881 else 882 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01); 883 saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20); 884 885 /* dma: setup channel 1 (= Video Task B) */ 886 base = (unsigned long)dev->ovbuf.base; 887 base += dev->ovbuf.fmt.bytesperline * fh->win.w.top; 888 base += dev->ovfmt->depth/8 * fh->win.w.left; 889 bpl = dev->ovbuf.fmt.bytesperline; 890 control = SAA7134_RS_CONTROL_BURST_16; 891 if (dev->ovfmt->bswap) 892 control |= SAA7134_RS_CONTROL_BSWAP; 893 if (dev->ovfmt->wswap) 894 control |= SAA7134_RS_CONTROL_WSWAP; 895 if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) { 896 saa_writel(SAA7134_RS_BA1(1),base); 897 saa_writel(SAA7134_RS_BA2(1),base+bpl); 898 saa_writel(SAA7134_RS_PITCH(1),bpl*2); 899 saa_writel(SAA7134_RS_CONTROL(1),control); 900 } else { 901 saa_writel(SAA7134_RS_BA1(1),base); 902 saa_writel(SAA7134_RS_BA2(1),base); 903 saa_writel(SAA7134_RS_PITCH(1),bpl); 904 saa_writel(SAA7134_RS_CONTROL(1),control); 905 } 906 907 /* start dma */ 908 dev->ovenable = 1; 909 saa7134_set_dmabits(dev); 910 911 return 0; 912} 913 914static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh) 915{ 916 dev->ovenable = 0; 917 saa7134_set_dmabits(dev); 918 return 0; 919} 920 921/* ------------------------------------------------------------------ */ 922 923static int buffer_activate(struct saa7134_dev *dev, 924 struct saa7134_buf *buf, 925 struct saa7134_buf *next) 926{ 927 unsigned long base,control,bpl; 928 unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ 929 930 dprintk("buffer_activate buf=%p\n",buf); 931 buf->vb.state = STATE_ACTIVE; 932 buf->top_seen = 0; 933 934 set_size(dev,TASK_A,buf->vb.width,buf->vb.height, 935 V4L2_FIELD_HAS_BOTH(buf->vb.field)); 936 if (buf->fmt->yuv) 937 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03); 938 else 939 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01); 940 saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm); 941 942 /* DMA: setup channel 0 (= Video Task A0) */ 943 base = saa7134_buffer_base(buf); 944 if (buf->fmt->planar) 945 bpl = buf->vb.width; 946 else 947 bpl = (buf->vb.width * buf->fmt->depth) / 8; 948 control = SAA7134_RS_CONTROL_BURST_16 | 949 SAA7134_RS_CONTROL_ME | 950 (buf->pt->dma >> 12); 951 if (buf->fmt->bswap) 952 control |= SAA7134_RS_CONTROL_BSWAP; 953 if (buf->fmt->wswap) 954 control |= SAA7134_RS_CONTROL_WSWAP; 955 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) { 956 /* interlaced */ 957 saa_writel(SAA7134_RS_BA1(0),base); 958 saa_writel(SAA7134_RS_BA2(0),base+bpl); 959 saa_writel(SAA7134_RS_PITCH(0),bpl*2); 960 } else { 961 /* non-interlaced */ 962 saa_writel(SAA7134_RS_BA1(0),base); 963 saa_writel(SAA7134_RS_BA2(0),base); 964 saa_writel(SAA7134_RS_PITCH(0),bpl); 965 } 966 saa_writel(SAA7134_RS_CONTROL(0),control); 967 968 if (buf->fmt->planar) { 969 /* DMA: setup channel 4+5 (= planar task A) */ 970 bpl_uv = bpl >> buf->fmt->hshift; 971 lines_uv = buf->vb.height >> buf->fmt->vshift; 972 base2 = base + bpl * buf->vb.height; 973 base3 = base2 + bpl_uv * lines_uv; 974 if (buf->fmt->uvswap) 975 tmp = base2, base2 = base3, base3 = tmp; 976 dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n", 977 bpl_uv,lines_uv,base2,base3); 978 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) { 979 /* interlaced */ 980 saa_writel(SAA7134_RS_BA1(4),base2); 981 saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv); 982 saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2); 983 saa_writel(SAA7134_RS_BA1(5),base3); 984 saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv); 985 saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2); 986 } else { 987 /* non-interlaced */ 988 saa_writel(SAA7134_RS_BA1(4),base2); 989 saa_writel(SAA7134_RS_BA2(4),base2); 990 saa_writel(SAA7134_RS_PITCH(4),bpl_uv); 991 saa_writel(SAA7134_RS_BA1(5),base3); 992 saa_writel(SAA7134_RS_BA2(5),base3); 993 saa_writel(SAA7134_RS_PITCH(5),bpl_uv); 994 } 995 saa_writel(SAA7134_RS_CONTROL(4),control); 996 saa_writel(SAA7134_RS_CONTROL(5),control); 997 } 998 999 /* start DMA */ 1000 saa7134_set_dmabits(dev); 1001 mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT); 1002 return 0; 1003} 1004 1005static int buffer_prepare(struct videobuf_queue *q, 1006 struct videobuf_buffer *vb, 1007 enum v4l2_field field) 1008{ 1009 struct saa7134_fh *fh = q->priv_data; 1010 struct saa7134_dev *dev = fh->dev; 1011 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 1012 unsigned int size; 1013 int err; 1014 1015 /* sanity checks */ 1016 if (NULL == fh->fmt) 1017 return -EINVAL; 1018 if (fh->width < 48 || 1019 fh->height < 32 || 1020 fh->width/4 > dev->crop_current.width || 1021 fh->height/4 > dev->crop_current.height || 1022 fh->width > dev->crop_bounds.width || 1023 fh->height > dev->crop_bounds.height) 1024 return -EINVAL; 1025 size = (fh->width * fh->height * fh->fmt->depth) >> 3; 1026 if (0 != buf->vb.baddr && buf->vb.bsize < size) 1027 return -EINVAL; 1028 1029 dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n", 1030 vb->i,fh->width,fh->height,size,v4l2_field_names[field], 1031 fh->fmt->name); 1032 if (buf->vb.width != fh->width || 1033 buf->vb.height != fh->height || 1034 buf->vb.size != size || 1035 buf->vb.field != field || 1036 buf->fmt != fh->fmt) { 1037 saa7134_dma_free(q,buf); 1038 } 1039 1040 if (STATE_NEEDS_INIT == buf->vb.state) { 1041 buf->vb.width = fh->width; 1042 buf->vb.height = fh->height; 1043 buf->vb.size = size; 1044 buf->vb.field = field; 1045 buf->fmt = fh->fmt; 1046 buf->pt = &fh->pt_cap; 1047 1048 err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); 1049 if (err) 1050 goto oops; 1051 err = saa7134_pgtable_build(dev->pci,buf->pt, 1052 buf->vb.dma.sglist, 1053 buf->vb.dma.sglen, 1054 saa7134_buffer_startpage(buf)); 1055 if (err) 1056 goto oops; 1057 } 1058 buf->vb.state = STATE_PREPARED; 1059 buf->activate = buffer_activate; 1060 return 0; 1061 1062 oops: 1063 saa7134_dma_free(q,buf); 1064 return err; 1065} 1066 1067static int 1068buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 1069{ 1070 struct saa7134_fh *fh = q->priv_data; 1071 1072 *size = fh->fmt->depth * fh->width * fh->height >> 3; 1073 if (0 == *count) 1074 *count = gbuffers; 1075 *count = saa7134_buffer_count(*size,*count); 1076 return 0; 1077} 1078 1079static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 1080{ 1081 struct saa7134_fh *fh = q->priv_data; 1082 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 1083 1084 saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf); 1085} 1086 1087static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 1088{ 1089 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 1090 1091 saa7134_dma_free(q,buf); 1092} 1093 1094static struct videobuf_queue_ops video_qops = { 1095 .buf_setup = buffer_setup, 1096 .buf_prepare = buffer_prepare, 1097 .buf_queue = buffer_queue, 1098 .buf_release = buffer_release, 1099}; 1100 1101/* ------------------------------------------------------------------ */ 1102 1103static int get_control(struct saa7134_dev *dev, struct v4l2_control *c) 1104{ 1105 const struct v4l2_queryctrl* ctrl; 1106 1107 ctrl = ctrl_by_id(c->id); 1108 if (NULL == ctrl) 1109 return -EINVAL; 1110 switch (c->id) { 1111 case V4L2_CID_BRIGHTNESS: 1112 c->value = dev->ctl_bright; 1113 break; 1114 case V4L2_CID_HUE: 1115 c->value = dev->ctl_hue; 1116 break; 1117 case V4L2_CID_CONTRAST: 1118 c->value = dev->ctl_contrast; 1119 break; 1120 case V4L2_CID_SATURATION: 1121 c->value = dev->ctl_saturation; 1122 break; 1123 case V4L2_CID_AUDIO_MUTE: 1124 c->value = dev->ctl_mute; 1125 break; 1126 case V4L2_CID_AUDIO_VOLUME: 1127 c->value = dev->ctl_volume; 1128 break; 1129 case V4L2_CID_PRIVATE_INVERT: 1130 c->value = dev->ctl_invert; 1131 break; 1132 case V4L2_CID_HFLIP: 1133 c->value = dev->ctl_mirror; 1134 break; 1135 case V4L2_CID_PRIVATE_Y_EVEN: 1136 c->value = dev->ctl_y_even; 1137 break; 1138 case V4L2_CID_PRIVATE_Y_ODD: 1139 c->value = dev->ctl_y_odd; 1140 break; 1141 case V4L2_CID_PRIVATE_AUTOMUTE: 1142 c->value = dev->ctl_automute; 1143 break; 1144 default: 1145 return -EINVAL; 1146 } 1147 return 0; 1148} 1149 1150static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, 1151 struct v4l2_control *c) 1152{ 1153 const struct v4l2_queryctrl* ctrl; 1154 unsigned long flags; 1155 int restart_overlay = 0; 1156 1157 ctrl = ctrl_by_id(c->id); 1158 if (NULL == ctrl) 1159 return -EINVAL; 1160 dprintk("set_control name=%s val=%d\n",ctrl->name,c->value); 1161 switch (ctrl->type) { 1162 case V4L2_CTRL_TYPE_BOOLEAN: 1163 case V4L2_CTRL_TYPE_MENU: 1164 case V4L2_CTRL_TYPE_INTEGER: 1165 if (c->value < ctrl->minimum) 1166 c->value = ctrl->minimum; 1167 if (c->value > ctrl->maximum) 1168 c->value = ctrl->maximum; 1169 break; 1170 default: 1171 /* nothing */; 1172 }; 1173 switch (c->id) { 1174 case V4L2_CID_BRIGHTNESS: 1175 dev->ctl_bright = c->value; 1176 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright); 1177 break; 1178 case V4L2_CID_HUE: 1179 dev->ctl_hue = c->value; 1180 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue); 1181 break; 1182 case V4L2_CID_CONTRAST: 1183 dev->ctl_contrast = c->value; 1184 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, 1185 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast); 1186 break; 1187 case V4L2_CID_SATURATION: 1188 dev->ctl_saturation = c->value; 1189 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, 1190 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); 1191 break; 1192 case V4L2_CID_AUDIO_MUTE: 1193 dev->ctl_mute = c->value; 1194 saa7134_tvaudio_setmute(dev); 1195 break; 1196 case V4L2_CID_AUDIO_VOLUME: 1197 dev->ctl_volume = c->value; 1198 saa7134_tvaudio_setvolume(dev,dev->ctl_volume); 1199 break; 1200 case V4L2_CID_PRIVATE_INVERT: 1201 dev->ctl_invert = c->value; 1202 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, 1203 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast); 1204 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, 1205 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); 1206 break; 1207 case V4L2_CID_HFLIP: 1208 dev->ctl_mirror = c->value; 1209 restart_overlay = 1; 1210 break; 1211 case V4L2_CID_PRIVATE_Y_EVEN: 1212 dev->ctl_y_even = c->value; 1213 restart_overlay = 1; 1214 break; 1215 case V4L2_CID_PRIVATE_Y_ODD: 1216 dev->ctl_y_odd = c->value; 1217 restart_overlay = 1; 1218 break; 1219 case V4L2_CID_PRIVATE_AUTOMUTE: 1220 dev->ctl_automute = c->value; 1221 if (dev->tda9887_conf) { 1222 if (dev->ctl_automute) 1223 dev->tda9887_conf |= TDA9887_AUTOMUTE; 1224 else 1225 dev->tda9887_conf &= ~TDA9887_AUTOMUTE; 1226 saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG, 1227 &dev->tda9887_conf); 1228 } 1229 break; 1230 default: 1231 return -EINVAL; 1232 } 1233 if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) { 1234 spin_lock_irqsave(&dev->slock,flags); 1235 stop_preview(dev,fh); 1236 start_preview(dev,fh); 1237 spin_unlock_irqrestore(&dev->slock,flags); 1238 } 1239 return 0; 1240} 1241 1242/* ------------------------------------------------------------------ */ 1243 1244static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh) 1245{ 1246 struct videobuf_queue* q = NULL; 1247 1248 switch (fh->type) { 1249 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1250 q = &fh->cap; 1251 break; 1252 case V4L2_BUF_TYPE_VBI_CAPTURE: 1253 q = &fh->vbi; 1254 break; 1255 default: 1256 BUG(); 1257 } 1258 return q; 1259} 1260 1261static int saa7134_resource(struct saa7134_fh *fh) 1262{ 1263 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1264 return RESOURCE_VIDEO; 1265 1266 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) 1267 return RESOURCE_VBI; 1268 1269 BUG(); 1270 return 0; 1271} 1272 1273static int video_open(struct inode *inode, struct file *file) 1274{ 1275 int minor = iminor(inode); 1276 struct saa7134_dev *h,*dev = NULL; 1277 struct saa7134_fh *fh; 1278 struct list_head *list; 1279 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1280 int radio = 0; 1281 list_for_each(list,&saa7134_devlist) { 1282 h = list_entry(list, struct saa7134_dev, devlist); 1283 if (h->video_dev && (h->video_dev->minor == minor)) 1284 dev = h; 1285 if (h->radio_dev && (h->radio_dev->minor == minor)) { 1286 radio = 1; 1287 dev = h; 1288 } 1289 if (h->vbi_dev && (h->vbi_dev->minor == minor)) { 1290 type = V4L2_BUF_TYPE_VBI_CAPTURE; 1291 dev = h; 1292 } 1293 } 1294 if (NULL == dev) 1295 return -ENODEV; 1296 1297 dprintk("open minor=%d radio=%d type=%s\n",minor,radio, 1298 v4l2_type_names[type]); 1299 1300 /* allocate + initialize per filehandle data */ 1301 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 1302 if (NULL == fh) 1303 return -ENOMEM; 1304 file->private_data = fh; 1305 fh->dev = dev; 1306 fh->radio = radio; 1307 fh->type = type; 1308 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); 1309 fh->width = 720; 1310 fh->height = 576; 1311 v4l2_prio_open(&dev->prio,&fh->prio); 1312 1313 videobuf_queue_init(&fh->cap, &video_qops, 1314 dev->pci, &dev->slock, 1315 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1316 V4L2_FIELD_INTERLACED, 1317 sizeof(struct saa7134_buf), 1318 fh); 1319 videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops, 1320 dev->pci, &dev->slock, 1321 V4L2_BUF_TYPE_VBI_CAPTURE, 1322 V4L2_FIELD_SEQ_TB, 1323 sizeof(struct saa7134_buf), 1324 fh); 1325 saa7134_pgtable_alloc(dev->pci,&fh->pt_cap); 1326 saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi); 1327 1328 if (fh->radio) { 1329 /* switch to radio mode */ 1330 saa7134_tvaudio_setinput(dev,&card(dev).radio); 1331 saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL); 1332 } else { 1333 /* switch to video/vbi mode */ 1334 video_mux(dev,dev->ctl_input); 1335 } 1336 return 0; 1337} 1338 1339static ssize_t 1340video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1341{ 1342 struct saa7134_fh *fh = file->private_data; 1343 1344 switch (fh->type) { 1345 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1346 if (res_locked(fh->dev,RESOURCE_VIDEO)) 1347 return -EBUSY; 1348 return videobuf_read_one(saa7134_queue(fh), 1349 data, count, ppos, 1350 file->f_flags & O_NONBLOCK); 1351 case V4L2_BUF_TYPE_VBI_CAPTURE: 1352 if (!res_get(fh->dev,fh,RESOURCE_VBI)) 1353 return -EBUSY; 1354 return videobuf_read_stream(saa7134_queue(fh), 1355 data, count, ppos, 1, 1356 file->f_flags & O_NONBLOCK); 1357 break; 1358 default: 1359 BUG(); 1360 return 0; 1361 } 1362} 1363 1364static unsigned int 1365video_poll(struct file *file, struct poll_table_struct *wait) 1366{ 1367 struct saa7134_fh *fh = file->private_data; 1368 struct videobuf_buffer *buf = NULL; 1369 1370 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) 1371 return videobuf_poll_stream(file, &fh->vbi, wait); 1372 1373 if (res_check(fh,RESOURCE_VIDEO)) { 1374 if (!list_empty(&fh->cap.stream)) 1375 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); 1376 } else { 1377 mutex_lock(&fh->cap.lock); 1378 if (UNSET == fh->cap.read_off) { 1379 /* need to capture a new frame */ 1380 if (res_locked(fh->dev,RESOURCE_VIDEO)) { 1381 mutex_unlock(&fh->cap.lock); 1382 return POLLERR; 1383 } 1384 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { 1385 mutex_unlock(&fh->cap.lock); 1386 return POLLERR; 1387 } 1388 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1389 fh->cap.read_off = 0; 1390 } 1391 mutex_unlock(&fh->cap.lock); 1392 buf = fh->cap.read_buf; 1393 } 1394 1395 if (!buf) 1396 return POLLERR; 1397 1398 poll_wait(file, &buf->done, wait); 1399 if (buf->state == STATE_DONE || 1400 buf->state == STATE_ERROR) 1401 return POLLIN|POLLRDNORM; 1402 return 0; 1403} 1404 1405static int video_release(struct inode *inode, struct file *file) 1406{ 1407 struct saa7134_fh *fh = file->private_data; 1408 struct saa7134_dev *dev = fh->dev; 1409 unsigned long flags; 1410 1411 /* turn off overlay */ 1412 if (res_check(fh, RESOURCE_OVERLAY)) { 1413 spin_lock_irqsave(&dev->slock,flags); 1414 stop_preview(dev,fh); 1415 spin_unlock_irqrestore(&dev->slock,flags); 1416 res_free(dev,fh,RESOURCE_OVERLAY); 1417 } 1418 1419 /* stop video capture */ 1420 if (res_check(fh, RESOURCE_VIDEO)) { 1421 videobuf_streamoff(&fh->cap); 1422 res_free(dev,fh,RESOURCE_VIDEO); 1423 } 1424 if (fh->cap.read_buf) { 1425 buffer_release(&fh->cap,fh->cap.read_buf); 1426 kfree(fh->cap.read_buf); 1427 } 1428 1429 /* stop vbi capture */ 1430 if (res_check(fh, RESOURCE_VBI)) { 1431 if (fh->vbi.streaming) 1432 videobuf_streamoff(&fh->vbi); 1433 if (fh->vbi.reading) 1434 videobuf_read_stop(&fh->vbi); 1435 res_free(dev,fh,RESOURCE_VBI); 1436 } 1437 1438 /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/ 1439 saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0); 1440 saa_andorb(SAA7134_OFMT_VIDEO_B, 0x1f, 0); 1441 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); 1442 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); 1443 1444 saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); 1445 1446 /* free stuff */ 1447 videobuf_mmap_free(&fh->cap); 1448 videobuf_mmap_free(&fh->vbi); 1449 saa7134_pgtable_free(dev->pci,&fh->pt_cap); 1450 saa7134_pgtable_free(dev->pci,&fh->pt_vbi); 1451 1452 v4l2_prio_close(&dev->prio,&fh->prio); 1453 file->private_data = NULL; 1454 kfree(fh); 1455 return 0; 1456} 1457 1458static int video_mmap(struct file *file, struct vm_area_struct * vma) 1459{ 1460 struct saa7134_fh *fh = file->private_data; 1461 1462 return videobuf_mmap_mapper(saa7134_queue(fh), vma); 1463} 1464 1465/* ------------------------------------------------------------------ */ 1466 1467static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f) 1468{ 1469 struct saa7134_tvnorm *norm = dev->tvnorm; 1470 1471 f->fmt.vbi.sampling_rate = 6750000 * 4; 1472 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */; 1473 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 1474 f->fmt.vbi.offset = 64 * 4; 1475 f->fmt.vbi.start[0] = norm->vbi_v_start_0; 1476 f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1; 1477 f->fmt.vbi.start[1] = norm->vbi_v_start_1; 1478 f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; 1479 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */ 1480 1481} 1482 1483static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, 1484 struct v4l2_format *f) 1485{ 1486 switch (f->type) { 1487 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1488 memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); 1489 f->fmt.pix.width = fh->width; 1490 f->fmt.pix.height = fh->height; 1491 f->fmt.pix.field = fh->cap.field; 1492 f->fmt.pix.pixelformat = fh->fmt->fourcc; 1493 f->fmt.pix.bytesperline = 1494 (f->fmt.pix.width * fh->fmt->depth) >> 3; 1495 f->fmt.pix.sizeimage = 1496 f->fmt.pix.height * f->fmt.pix.bytesperline; 1497 return 0; 1498 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1499 if (saa7134_no_overlay > 0) { 1500 printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); 1501 return -EINVAL; 1502 } 1503 f->fmt.win = fh->win; 1504 return 0; 1505 case V4L2_BUF_TYPE_VBI_CAPTURE: 1506 saa7134_vbi_fmt(dev,f); 1507 return 0; 1508 default: 1509 return -EINVAL; 1510 } 1511} 1512 1513static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, 1514 struct v4l2_format *f) 1515{ 1516 int err; 1517 1518 switch (f->type) { 1519 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1520 { 1521 struct saa7134_format *fmt; 1522 enum v4l2_field field; 1523 unsigned int maxw, maxh; 1524 1525 fmt = format_by_fourcc(f->fmt.pix.pixelformat); 1526 if (NULL == fmt) 1527 return -EINVAL; 1528 1529 field = f->fmt.pix.field; 1530 maxw = min(dev->crop_current.width*4, dev->crop_bounds.width); 1531 maxh = min(dev->crop_current.height*4, dev->crop_bounds.height); 1532 1533 if (V4L2_FIELD_ANY == field) { 1534 field = (f->fmt.pix.height > maxh/2) 1535 ? V4L2_FIELD_INTERLACED 1536 : V4L2_FIELD_BOTTOM; 1537 } 1538 switch (field) { 1539 case V4L2_FIELD_TOP: 1540 case V4L2_FIELD_BOTTOM: 1541 maxh = maxh / 2; 1542 break; 1543 case V4L2_FIELD_INTERLACED: 1544 break; 1545 default: 1546 return -EINVAL; 1547 } 1548 1549 f->fmt.pix.field = field; 1550 if (f->fmt.pix.width < 48) 1551 f->fmt.pix.width = 48; 1552 if (f->fmt.pix.height < 32) 1553 f->fmt.pix.height = 32; 1554 if (f->fmt.pix.width > maxw) 1555 f->fmt.pix.width = maxw; 1556 if (f->fmt.pix.height > maxh) 1557 f->fmt.pix.height = maxh; 1558 f->fmt.pix.width &= ~0x03; 1559 f->fmt.pix.bytesperline = 1560 (f->fmt.pix.width * fmt->depth) >> 3; 1561 f->fmt.pix.sizeimage = 1562 f->fmt.pix.height * f->fmt.pix.bytesperline; 1563 1564 return 0; 1565 } 1566 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1567 if (saa7134_no_overlay > 0) { 1568 printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); 1569 return -EINVAL; 1570 } 1571 err = verify_preview(dev,&f->fmt.win); 1572 if (0 != err) 1573 return err; 1574 return 0; 1575 case V4L2_BUF_TYPE_VBI_CAPTURE: 1576 saa7134_vbi_fmt(dev,f); 1577 return 0; 1578 default: 1579 return -EINVAL; 1580 } 1581} 1582 1583static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, 1584 struct v4l2_format *f) 1585{ 1586 unsigned long flags; 1587 int err; 1588 1589 switch (f->type) { 1590 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1591 err = saa7134_try_fmt(dev,fh,f); 1592 if (0 != err) 1593 return err; 1594 1595 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); 1596 fh->width = f->fmt.pix.width; 1597 fh->height = f->fmt.pix.height; 1598 fh->cap.field = f->fmt.pix.field; 1599 return 0; 1600 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1601 if (saa7134_no_overlay > 0) { 1602 printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); 1603 return -EINVAL; 1604 } 1605 err = verify_preview(dev,&f->fmt.win); 1606 if (0 != err) 1607 return err; 1608 1609 mutex_lock(&dev->lock); 1610 fh->win = f->fmt.win; 1611 fh->nclips = f->fmt.win.clipcount; 1612 if (fh->nclips > 8) 1613 fh->nclips = 8; 1614 if (copy_from_user(fh->clips,f->fmt.win.clips, 1615 sizeof(struct v4l2_clip)*fh->nclips)) { 1616 mutex_unlock(&dev->lock); 1617 return -EFAULT; 1618 } 1619 1620 if (res_check(fh, RESOURCE_OVERLAY)) { 1621 spin_lock_irqsave(&dev->slock,flags); 1622 stop_preview(dev,fh); 1623 start_preview(dev,fh); 1624 spin_unlock_irqrestore(&dev->slock,flags); 1625 } 1626 mutex_unlock(&dev->lock); 1627 return 0; 1628 case V4L2_BUF_TYPE_VBI_CAPTURE: 1629 saa7134_vbi_fmt(dev,f); 1630 return 0; 1631 default: 1632 return -EINVAL; 1633 } 1634} 1635 1636int saa7134_common_ioctl(struct saa7134_dev *dev, 1637 unsigned int cmd, void *arg) 1638{ 1639 int err; 1640 1641 switch (cmd) { 1642 case VIDIOC_QUERYCTRL: 1643 { 1644 const struct v4l2_queryctrl *ctrl; 1645 struct v4l2_queryctrl *c = arg; 1646 1647 if ((c->id < V4L2_CID_BASE || 1648 c->id >= V4L2_CID_LASTP1) && 1649 (c->id < V4L2_CID_PRIVATE_BASE || 1650 c->id >= V4L2_CID_PRIVATE_LASTP1)) 1651 return -EINVAL; 1652 ctrl = ctrl_by_id(c->id); 1653 *c = (NULL != ctrl) ? *ctrl : no_ctrl; 1654 return 0; 1655 } 1656 case VIDIOC_G_CTRL: 1657 return get_control(dev,arg); 1658 case VIDIOC_S_CTRL: 1659 { 1660 mutex_lock(&dev->lock); 1661 err = set_control(dev,NULL,arg); 1662 mutex_unlock(&dev->lock); 1663 return err; 1664 } 1665 /* --- input switching --------------------------------------- */ 1666 case VIDIOC_ENUMINPUT: 1667 { 1668 struct v4l2_input *i = arg; 1669 unsigned int n; 1670 1671 n = i->index; 1672 if (n >= SAA7134_INPUT_MAX) 1673 return -EINVAL; 1674 if (NULL == card_in(dev,i->index).name) 1675 return -EINVAL; 1676 memset(i,0,sizeof(*i)); 1677 i->index = n; 1678 i->type = V4L2_INPUT_TYPE_CAMERA; 1679 strcpy(i->name,card_in(dev,n).name); 1680 if (card_in(dev,n).tv) 1681 i->type = V4L2_INPUT_TYPE_TUNER; 1682 i->audioset = 1; 1683 if (n == dev->ctl_input) { 1684 int v1 = saa_readb(SAA7134_STATUS_VIDEO1); 1685 int v2 = saa_readb(SAA7134_STATUS_VIDEO2); 1686 1687 if (0 != (v1 & 0x40)) 1688 i->status |= V4L2_IN_ST_NO_H_LOCK; 1689 if (0 != (v2 & 0x40)) 1690 i->status |= V4L2_IN_ST_NO_SYNC; 1691 if (0 != (v2 & 0x0e)) 1692 i->status |= V4L2_IN_ST_MACROVISION; 1693 } 1694 for (n = 0; n < TVNORMS; n++) 1695 i->std |= tvnorms[n].id; 1696 return 0; 1697 } 1698 case VIDIOC_G_INPUT: 1699 { 1700 int *i = arg; 1701 *i = dev->ctl_input; 1702 return 0; 1703 } 1704 case VIDIOC_S_INPUT: 1705 { 1706 int *i = arg; 1707 1708 if (*i < 0 || *i >= SAA7134_INPUT_MAX) 1709 return -EINVAL; 1710 if (NULL == card_in(dev,*i).name) 1711 return -EINVAL; 1712 mutex_lock(&dev->lock); 1713 video_mux(dev,*i); 1714 mutex_unlock(&dev->lock); 1715 return 0; 1716 } 1717 1718 } 1719 return 0; 1720} 1721EXPORT_SYMBOL(saa7134_common_ioctl); 1722 1723/* 1724 * This function is _not_ called directly, but from 1725 * video_generic_ioctl (and maybe others). userspace 1726 * copying is done already, arg is a kernel pointer. 1727 */ 1728static int video_do_ioctl(struct inode *inode, struct file *file, 1729 unsigned int cmd, void *arg) 1730{ 1731 struct saa7134_fh *fh = file->private_data; 1732 struct saa7134_dev *dev = fh->dev; 1733 unsigned long flags; 1734 int err; 1735 1736 if (video_debug > 1) 1737 v4l_print_ioctl(dev->name,cmd); 1738 1739 switch (cmd) { 1740 case VIDIOC_S_CTRL: 1741 case VIDIOC_S_STD: 1742 case VIDIOC_S_INPUT: 1743 case VIDIOC_S_TUNER: 1744 case VIDIOC_S_FREQUENCY: 1745 err = v4l2_prio_check(&dev->prio,&fh->prio); 1746 if (0 != err) 1747 return err; 1748 } 1749 1750 switch (cmd) { 1751 case VIDIOC_QUERYCAP: 1752 { 1753 struct v4l2_capability *cap = arg; 1754 unsigned int tuner_type = dev->tuner_type; 1755 1756 memset(cap,0,sizeof(*cap)); 1757 strcpy(cap->driver, "saa7134"); 1758 strlcpy(cap->card, saa7134_boards[dev->board].name, 1759 sizeof(cap->card)); 1760 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1761 cap->version = SAA7134_VERSION_CODE; 1762 cap->capabilities = 1763 V4L2_CAP_VIDEO_CAPTURE | 1764 V4L2_CAP_VBI_CAPTURE | 1765 V4L2_CAP_READWRITE | 1766 V4L2_CAP_STREAMING | 1767 V4L2_CAP_TUNER; 1768 if (saa7134_no_overlay <= 0) { 1769 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; 1770 } 1771 1772 if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) 1773 cap->capabilities &= ~V4L2_CAP_TUNER; 1774 1775 return 0; 1776 } 1777 1778 /* --- tv standards ------------------------------------------ */ 1779 case VIDIOC_ENUMSTD: 1780 { 1781 struct v4l2_standard *e = arg; 1782 unsigned int i; 1783 1784 i = e->index; 1785 if (i >= TVNORMS) 1786 return -EINVAL; 1787 err = v4l2_video_std_construct(e, tvnorms[e->index].id, 1788 tvnorms[e->index].name); 1789 e->index = i; 1790 if (err < 0) 1791 return err; 1792 return 0; 1793 } 1794 case VIDIOC_G_STD: 1795 { 1796 v4l2_std_id *id = arg; 1797 1798 *id = dev->tvnorm->id; 1799 return 0; 1800 } 1801 case VIDIOC_S_STD: 1802 { 1803 v4l2_std_id *id = arg; 1804 unsigned int i; 1805 v4l2_std_id fixup; 1806 1807 for (i = 0; i < TVNORMS; i++) 1808 if (*id == tvnorms[i].id) 1809 break; 1810 if (i == TVNORMS) 1811 for (i = 0; i < TVNORMS; i++) 1812 if (*id & tvnorms[i].id) 1813 break; 1814 if (i == TVNORMS) 1815 return -EINVAL; 1816 if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { 1817 if (secam[0] == 'L' || secam[0] == 'l') { 1818 if (secam[1] == 'C' || secam[1] == 'c') 1819 fixup = V4L2_STD_SECAM_LC; 1820 else 1821 fixup = V4L2_STD_SECAM_L; 1822 } else { 1823 if (secam[0] == 'D' || secam[0] == 'd') 1824 fixup = V4L2_STD_SECAM_DK; 1825 else 1826 fixup = V4L2_STD_SECAM; 1827 } 1828 for (i = 0; i < TVNORMS; i++) 1829 if (fixup == tvnorms[i].id) 1830 break; 1831 } 1832 mutex_lock(&dev->lock); 1833 if (res_check(fh, RESOURCE_OVERLAY)) { 1834 spin_lock_irqsave(&dev->slock,flags); 1835 stop_preview(dev,fh); 1836 set_tvnorm(dev,&tvnorms[i]); 1837 start_preview(dev,fh); 1838 spin_unlock_irqrestore(&dev->slock,flags); 1839 } else 1840 set_tvnorm(dev,&tvnorms[i]); 1841 saa7134_tvaudio_do_scan(dev); 1842 mutex_unlock(&dev->lock); 1843 return 0; 1844 } 1845 1846 case VIDIOC_CROPCAP: 1847 { 1848 struct v4l2_cropcap *cap = arg; 1849 1850 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1851 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 1852 return -EINVAL; 1853 cap->bounds = dev->crop_bounds; 1854 cap->defrect = dev->crop_defrect; 1855 cap->pixelaspect.numerator = 1; 1856 cap->pixelaspect.denominator = 1; 1857 if (dev->tvnorm->id & V4L2_STD_525_60) { 1858 cap->pixelaspect.numerator = 11; 1859 cap->pixelaspect.denominator = 10; 1860 } 1861 if (dev->tvnorm->id & V4L2_STD_625_50) { 1862 cap->pixelaspect.numerator = 54; 1863 cap->pixelaspect.denominator = 59; 1864 } 1865 return 0; 1866 } 1867 1868 case VIDIOC_G_CROP: 1869 { 1870 struct v4l2_crop * crop = arg; 1871 1872 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1873 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 1874 return -EINVAL; 1875 crop->c = dev->crop_current; 1876 return 0; 1877 } 1878 case VIDIOC_S_CROP: 1879 { 1880 struct v4l2_crop *crop = arg; 1881 struct v4l2_rect *b = &dev->crop_bounds; 1882 1883 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1884 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 1885 return -EINVAL; 1886 if (crop->c.height < 0) 1887 return -EINVAL; 1888 if (crop->c.width < 0) 1889 return -EINVAL; 1890 1891 if (res_locked(fh->dev,RESOURCE_OVERLAY)) 1892 return -EBUSY; 1893 if (res_locked(fh->dev,RESOURCE_VIDEO)) 1894 return -EBUSY; 1895 1896 if (crop->c.top < b->top) 1897 crop->c.top = b->top; 1898 if (crop->c.top > b->top + b->height) 1899 crop->c.top = b->top + b->height; 1900 if (crop->c.height > b->top - crop->c.top + b->height) 1901 crop->c.height = b->top - crop->c.top + b->height; 1902 1903 if (crop->c.left < b->left) 1904 crop->c.left = b->left; 1905 if (crop->c.left > b->left + b->width) 1906 crop->c.left = b->left + b->width; 1907 if (crop->c.width > b->left - crop->c.left + b->width) 1908 crop->c.width = b->left - crop->c.left + b->width; 1909 1910 dev->crop_current = crop->c; 1911 return 0; 1912 } 1913 1914 /* --- tuner ioctls ------------------------------------------ */ 1915 case VIDIOC_G_TUNER: 1916 { 1917 struct v4l2_tuner *t = arg; 1918 int n; 1919 1920 if (0 != t->index) 1921 return -EINVAL; 1922 memset(t,0,sizeof(*t)); 1923 for (n = 0; n < SAA7134_INPUT_MAX; n++) 1924 if (card_in(dev,n).tv) 1925 break; 1926 if (NULL != card_in(dev,n).name) { 1927 strcpy(t->name, "Television"); 1928 t->type = V4L2_TUNER_ANALOG_TV; 1929 t->capability = V4L2_TUNER_CAP_NORM | 1930 V4L2_TUNER_CAP_STEREO | 1931 V4L2_TUNER_CAP_LANG1 | 1932 V4L2_TUNER_CAP_LANG2; 1933 t->rangehigh = 0xffffffffUL; 1934 t->rxsubchans = saa7134_tvaudio_getstereo(dev); 1935 t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans); 1936 } 1937 if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03)) 1938 t->signal = 0xffff; 1939 return 0; 1940 } 1941 case VIDIOC_S_TUNER: 1942 { 1943 struct v4l2_tuner *t = arg; 1944 int rx,mode; 1945 1946 mode = dev->thread.mode; 1947 if (UNSET == mode) { 1948 rx = saa7134_tvaudio_getstereo(dev); 1949 mode = saa7134_tvaudio_rx2mode(t->rxsubchans); 1950 } 1951 if (mode != t->audmode) { 1952 dev->thread.mode = t->audmode; 1953 } 1954 return 0; 1955 } 1956 case VIDIOC_G_FREQUENCY: 1957 { 1958 struct v4l2_frequency *f = arg; 1959 1960 memset(f,0,sizeof(*f)); 1961 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1962 f->frequency = dev->ctl_freq; 1963 return 0; 1964 } 1965 case VIDIOC_S_FREQUENCY: 1966 { 1967 struct v4l2_frequency *f = arg; 1968 1969 if (0 != f->tuner) 1970 return -EINVAL; 1971 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type) 1972 return -EINVAL; 1973 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) 1974 return -EINVAL; 1975 mutex_lock(&dev->lock); 1976 dev->ctl_freq = f->frequency; 1977 1978 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); 1979 1980 saa7134_tvaudio_do_scan(dev); 1981 mutex_unlock(&dev->lock); 1982 return 0; 1983 } 1984 1985 /* --- control ioctls ---------------------------------------- */ 1986 case VIDIOC_ENUMINPUT: 1987 case VIDIOC_G_INPUT: 1988 case VIDIOC_S_INPUT: 1989 case VIDIOC_QUERYCTRL: 1990 case VIDIOC_G_CTRL: 1991 case VIDIOC_S_CTRL: 1992 return saa7134_common_ioctl(dev, cmd, arg); 1993 1994 case VIDIOC_G_AUDIO: 1995 { 1996 struct v4l2_audio *a = arg; 1997 1998 memset(a,0,sizeof(*a)); 1999 strcpy(a->name,"audio"); 2000 return 0; 2001 } 2002 case VIDIOC_S_AUDIO: 2003 return 0; 2004 case VIDIOC_G_PARM: 2005 { 2006 struct v4l2_captureparm *parm = arg; 2007 memset(parm,0,sizeof(*parm)); 2008 return 0; 2009 } 2010 2011 case VIDIOC_G_PRIORITY: 2012 { 2013 enum v4l2_priority *p = arg; 2014 2015 *p = v4l2_prio_max(&dev->prio); 2016 return 0; 2017 } 2018 case VIDIOC_S_PRIORITY: 2019 { 2020 enum v4l2_priority *prio = arg; 2021 2022 return v4l2_prio_change(&dev->prio, &fh->prio, *prio); 2023 } 2024 2025 /* --- preview ioctls ---------------------------------------- */ 2026 case VIDIOC_ENUM_FMT: 2027 { 2028 struct v4l2_fmtdesc *f = arg; 2029 enum v4l2_buf_type type; 2030 unsigned int index; 2031 2032 index = f->index; 2033 type = f->type; 2034 switch (type) { 2035 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2036 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 2037 if (saa7134_no_overlay > 0) { 2038 printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); 2039 return -EINVAL; 2040 } 2041 if (index >= FORMATS) 2042 return -EINVAL; 2043 if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && 2044 formats[index].planar) 2045 return -EINVAL; 2046 memset(f,0,sizeof(*f)); 2047 f->index = index; 2048 f->type = type; 2049 strlcpy(f->description,formats[index].name,sizeof(f->description)); 2050 f->pixelformat = formats[index].fourcc; 2051 break; 2052 case V4L2_BUF_TYPE_VBI_CAPTURE: 2053 if (0 != index) 2054 return -EINVAL; 2055 memset(f,0,sizeof(*f)); 2056 f->index = index; 2057 f->type = type; 2058 f->pixelformat = V4L2_PIX_FMT_GREY; 2059 strcpy(f->description,"vbi data"); 2060 break; 2061 default: 2062 return -EINVAL; 2063 } 2064 return 0; 2065 } 2066 case VIDIOC_G_FBUF: 2067 { 2068 struct v4l2_framebuffer *fb = arg; 2069 2070 *fb = dev->ovbuf; 2071 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; 2072 return 0; 2073 } 2074 case VIDIOC_S_FBUF: 2075 { 2076 struct v4l2_framebuffer *fb = arg; 2077 struct saa7134_format *fmt; 2078 2079 if(!capable(CAP_SYS_ADMIN) && 2080 !capable(CAP_SYS_RAWIO)) 2081 return -EPERM; 2082 2083 /* check args */ 2084 fmt = format_by_fourcc(fb->fmt.pixelformat); 2085 if (NULL == fmt) 2086 return -EINVAL; 2087 2088 /* ok, accept it */ 2089 dev->ovbuf = *fb; 2090 dev->ovfmt = fmt; 2091 if (0 == dev->ovbuf.fmt.bytesperline) 2092 dev->ovbuf.fmt.bytesperline = 2093 dev->ovbuf.fmt.width*fmt->depth/8; 2094 return 0; 2095 } 2096 case VIDIOC_OVERLAY: 2097 { 2098 int *on = arg; 2099 2100 if (*on) { 2101 if (saa7134_no_overlay > 0) { 2102 printk ("no_overlay\n"); 2103 return -EINVAL; 2104 } 2105 2106 if (!res_get(dev,fh,RESOURCE_OVERLAY)) 2107 return -EBUSY; 2108 spin_lock_irqsave(&dev->slock,flags); 2109 start_preview(dev,fh); 2110 spin_unlock_irqrestore(&dev->slock,flags); 2111 } 2112 if (!*on) { 2113 if (!res_check(fh, RESOURCE_OVERLAY)) 2114 return -EINVAL; 2115 spin_lock_irqsave(&dev->slock,flags); 2116 stop_preview(dev,fh); 2117 spin_unlock_irqrestore(&dev->slock,flags); 2118 res_free(dev,fh,RESOURCE_OVERLAY); 2119 } 2120 return 0; 2121 } 2122 2123 /* --- capture ioctls ---------------------------------------- */ 2124 case VIDIOC_G_FMT: 2125 { 2126 struct v4l2_format *f = arg; 2127 return saa7134_g_fmt(dev,fh,f); 2128 } 2129 case VIDIOC_S_FMT: 2130 { 2131 struct v4l2_format *f = arg; 2132 return saa7134_s_fmt(dev,fh,f); 2133 } 2134 case VIDIOC_TRY_FMT: 2135 { 2136 struct v4l2_format *f = arg; 2137 return saa7134_try_fmt(dev,fh,f); 2138 } 2139#ifdef CONFIG_VIDEO_V4L1_COMPAT 2140 case VIDIOCGMBUF: 2141 { 2142 struct video_mbuf *mbuf = arg; 2143 struct videobuf_queue *q; 2144 struct v4l2_requestbuffers req; 2145 unsigned int i; 2146 2147 q = saa7134_queue(fh); 2148 memset(&req,0,sizeof(req)); 2149 req.type = q->type; 2150 req.count = gbuffers; 2151 req.memory = V4L2_MEMORY_MMAP; 2152 err = videobuf_reqbufs(q,&req); 2153 if (err < 0) 2154 return err; 2155 memset(mbuf,0,sizeof(*mbuf)); 2156 mbuf->frames = req.count; 2157 mbuf->size = 0; 2158 for (i = 0; i < mbuf->frames; i++) { 2159 mbuf->offsets[i] = q->bufs[i]->boff; 2160 mbuf->size += q->bufs[i]->bsize; 2161 } 2162 return 0; 2163 } 2164#endif 2165 case VIDIOC_REQBUFS: 2166 return videobuf_reqbufs(saa7134_queue(fh),arg); 2167 2168 case VIDIOC_QUERYBUF: 2169 return videobuf_querybuf(saa7134_queue(fh),arg); 2170 2171 case VIDIOC_QBUF: 2172 return videobuf_qbuf(saa7134_queue(fh),arg); 2173 2174 case VIDIOC_DQBUF: 2175 return videobuf_dqbuf(saa7134_queue(fh),arg, 2176 file->f_flags & O_NONBLOCK); 2177 2178 case VIDIOC_STREAMON: 2179 { 2180 int res = saa7134_resource(fh); 2181 2182 if (!res_get(dev,fh,res)) 2183 return -EBUSY; 2184 return videobuf_streamon(saa7134_queue(fh)); 2185 } 2186 case VIDIOC_STREAMOFF: 2187 { 2188 int res = saa7134_resource(fh); 2189 2190 err = videobuf_streamoff(saa7134_queue(fh)); 2191 if (err < 0) 2192 return err; 2193 res_free(dev,fh,res); 2194 return 0; 2195 } 2196 2197 default: 2198 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 2199 video_do_ioctl); 2200 } 2201 return 0; 2202} 2203 2204static int video_ioctl(struct inode *inode, struct file *file, 2205 unsigned int cmd, unsigned long arg) 2206{ 2207 return video_usercopy(inode, file, cmd, arg, video_do_ioctl); 2208} 2209 2210static int radio_do_ioctl(struct inode *inode, struct file *file, 2211 unsigned int cmd, void *arg) 2212{ 2213 struct saa7134_fh *fh = file->private_data; 2214 struct saa7134_dev *dev = fh->dev; 2215 2216 if (video_debug > 1) 2217 v4l_print_ioctl(dev->name,cmd); 2218 switch (cmd) { 2219 case VIDIOC_QUERYCAP: 2220 { 2221 struct v4l2_capability *cap = arg; 2222 2223 memset(cap,0,sizeof(*cap)); 2224 strcpy(cap->driver, "saa7134"); 2225 strlcpy(cap->card, saa7134_boards[dev->board].name, 2226 sizeof(cap->card)); 2227 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 2228 cap->version = SAA7134_VERSION_CODE; 2229 cap->capabilities = V4L2_CAP_TUNER; 2230 return 0; 2231 } 2232 case VIDIOC_G_TUNER: 2233 { 2234 struct v4l2_tuner *t = arg; 2235 2236 if (0 != t->index) 2237 return -EINVAL; 2238 2239 memset(t,0,sizeof(*t)); 2240 strcpy(t->name, "Radio"); 2241 t->type = V4L2_TUNER_RADIO; 2242 2243 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 2244 if (dev->input->amux == TV) { 2245 t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); 2246 t->rxsubchans = (saa_readb(0x529) & 0x08) ? 2247 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; 2248 } 2249 return 0; 2250 } 2251 case VIDIOC_S_TUNER: 2252 { 2253 struct v4l2_tuner *t = arg; 2254 2255 if (0 != t->index) 2256 return -EINVAL; 2257 2258 saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t); 2259 2260 return 0; 2261 } 2262 case VIDIOC_ENUMINPUT: 2263 { 2264 struct v4l2_input *i = arg; 2265 2266 if (i->index != 0) 2267 return -EINVAL; 2268 strcpy(i->name,"Radio"); 2269 i->type = V4L2_INPUT_TYPE_TUNER; 2270 return 0; 2271 } 2272 case VIDIOC_G_INPUT: 2273 { 2274 int *i = arg; 2275 *i = 0; 2276 return 0; 2277 } 2278 case VIDIOC_G_AUDIO: 2279 { 2280 struct v4l2_audio *a = arg; 2281 2282 memset(a,0,sizeof(*a)); 2283 strcpy(a->name,"Radio"); 2284 return 0; 2285 } 2286 case VIDIOC_G_STD: 2287 { 2288 v4l2_std_id *id = arg; 2289 *id = 0; 2290 return 0; 2291 } 2292 case VIDIOC_S_AUDIO: 2293 case VIDIOC_S_INPUT: 2294 case VIDIOC_S_STD: 2295 return 0; 2296 2297 case VIDIOC_QUERYCTRL: 2298 { 2299 const struct v4l2_queryctrl *ctrl; 2300 struct v4l2_queryctrl *c = arg; 2301 2302 if (c->id < V4L2_CID_BASE || 2303 c->id >= V4L2_CID_LASTP1) 2304 return -EINVAL; 2305 if (c->id == V4L2_CID_AUDIO_MUTE) { 2306 ctrl = ctrl_by_id(c->id); 2307 *c = *ctrl; 2308 } else 2309 *c = no_ctrl; 2310 return 0; 2311 } 2312 2313 case VIDIOC_G_CTRL: 2314 case VIDIOC_S_CTRL: 2315 case VIDIOC_G_FREQUENCY: 2316 case VIDIOC_S_FREQUENCY: 2317 return video_do_ioctl(inode,file,cmd,arg); 2318 2319 default: 2320 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 2321 radio_do_ioctl); 2322 } 2323 return 0; 2324} 2325 2326static int radio_ioctl(struct inode *inode, struct file *file, 2327 unsigned int cmd, unsigned long arg) 2328{ 2329 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl); 2330} 2331 2332static const struct file_operations video_fops = 2333{ 2334 .owner = THIS_MODULE, 2335 .open = video_open, 2336 .release = video_release, 2337 .read = video_read, 2338 .poll = video_poll, 2339 .mmap = video_mmap, 2340 .ioctl = video_ioctl, 2341 .compat_ioctl = v4l_compat_ioctl32, 2342 .llseek = no_llseek, 2343}; 2344 2345static const struct file_operations radio_fops = 2346{ 2347 .owner = THIS_MODULE, 2348 .open = video_open, 2349 .release = video_release, 2350 .ioctl = radio_ioctl, 2351 .compat_ioctl = v4l_compat_ioctl32, 2352 .llseek = no_llseek, 2353}; 2354 2355/* ----------------------------------------------------------- */ 2356/* exported stuff */ 2357 2358struct video_device saa7134_video_template = 2359{ 2360 .name = "saa7134-video", 2361 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| 2362 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 2363 .hardware = 0, 2364 .fops = &video_fops, 2365 .minor = -1, 2366}; 2367 2368struct video_device saa7134_vbi_template = 2369{ 2370 .name = "saa7134-vbi", 2371 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT, 2372 .hardware = 0, 2373 .fops = &video_fops, 2374 .minor = -1, 2375}; 2376 2377struct video_device saa7134_radio_template = 2378{ 2379 .name = "saa7134-radio", 2380 .type = VID_TYPE_TUNER, 2381 .hardware = 0, 2382 .fops = &radio_fops, 2383 .minor = -1, 2384}; 2385 2386int saa7134_video_init1(struct saa7134_dev *dev) 2387{ 2388 /* sanitycheck insmod options */ 2389 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) 2390 gbuffers = 2; 2391 if (gbufsize < 0 || gbufsize > gbufsize_max) 2392 gbufsize = gbufsize_max; 2393 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; 2394 2395 /* put some sensible defaults into the data structures ... */ 2396 dev->ctl_bright = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value; 2397 dev->ctl_contrast = ctrl_by_id(V4L2_CID_CONTRAST)->default_value; 2398 dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value; 2399 dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value; 2400 dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value; 2401 dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value; 2402 dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value; 2403 dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value; 2404 2405 if (dev->tda9887_conf && dev->ctl_automute) 2406 dev->tda9887_conf |= TDA9887_AUTOMUTE; 2407 dev->automute = 0; 2408 2409 INIT_LIST_HEAD(&dev->video_q.queue); 2410 init_timer(&dev->video_q.timeout); 2411 dev->video_q.timeout.function = saa7134_buffer_timeout; 2412 dev->video_q.timeout.data = (unsigned long)(&dev->video_q); 2413 dev->video_q.dev = dev; 2414 2415 if (saa7134_boards[dev->board].video_out) { 2416 /* enable video output */ 2417 int vo = saa7134_boards[dev->board].video_out; 2418 int video_reg; 2419 unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts; 2420 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); 2421 video_reg = video_out[vo][1]; 2422 if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED) 2423 video_reg &= ~VP_T_CODE_P_INVERTED; 2424 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg); 2425 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); 2426 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); 2427 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); 2428 video_reg = video_out[vo][5]; 2429 if (vid_port_opts & SET_CLOCK_NOT_DELAYED) 2430 video_reg &= ~VP_CLK_CTRL2_DELAYED; 2431 if (vid_port_opts & SET_CLOCK_INVERTED) 2432 video_reg |= VP_CLK_CTRL1_INVERTED; 2433 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg); 2434 video_reg = video_out[vo][6]; 2435 if (vid_port_opts & SET_VSYNC_OFF) { 2436 video_reg &= ~VP_VS_TYPE_MASK; 2437 video_reg |= VP_VS_TYPE_OFF; 2438 } 2439 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg); 2440 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); 2441 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); 2442 } 2443 2444 return 0; 2445} 2446 2447int saa7134_video_init2(struct saa7134_dev *dev) 2448{ 2449 /* init video hw */ 2450 set_tvnorm(dev,&tvnorms[0]); 2451 video_mux(dev,0); 2452 saa7134_tvaudio_setmute(dev); 2453 saa7134_tvaudio_setvolume(dev,dev->ctl_volume); 2454 return 0; 2455} 2456 2457void saa7134_irq_video_intl(struct saa7134_dev *dev) 2458{ 2459 static const char *st[] = { 2460 "(no signal)", "NTSC", "PAL", "SECAM" }; 2461 u32 st1,st2; 2462 2463 st1 = saa_readb(SAA7134_STATUS_VIDEO1); 2464 st2 = saa_readb(SAA7134_STATUS_VIDEO2); 2465 dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n", 2466 (st1 & 0x40) ? "not locked" : "locked", 2467 (st2 & 0x40) ? "no" : "yes", 2468 st[st1 & 0x03]); 2469 dev->nosignal = (st1 & 0x40) || (st2 & 0x40); 2470 2471 if (dev->nosignal) { 2472 /* no video signal -> mute audio */ 2473 if (dev->ctl_automute) 2474 dev->automute = 1; 2475 saa7134_tvaudio_setmute(dev); 2476 saa_setb(SAA7134_SYNC_CTRL, 0x20); 2477 } else { 2478 /* wake up tvaudio audio carrier scan thread */ 2479 saa7134_tvaudio_do_scan(dev); 2480 if (!noninterlaced) 2481 saa_clearb(SAA7134_SYNC_CTRL, 0x20); 2482 } 2483 if (dev->mops && dev->mops->signal_change) 2484 dev->mops->signal_change(dev); 2485} 2486 2487void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) 2488{ 2489 enum v4l2_field field; 2490 2491 spin_lock(&dev->slock); 2492 if (dev->video_q.curr) { 2493 dev->video_fieldcount++; 2494 field = dev->video_q.curr->vb.field; 2495 if (V4L2_FIELD_HAS_BOTH(field)) { 2496 /* make sure we have seen both fields */ 2497 if ((status & 0x10) == 0x00) { 2498 dev->video_q.curr->top_seen = 1; 2499 goto done; 2500 } 2501 if (!dev->video_q.curr->top_seen) 2502 goto done; 2503 } else if (field == V4L2_FIELD_TOP) { 2504 if ((status & 0x10) != 0x10) 2505 goto done; 2506 } else if (field == V4L2_FIELD_BOTTOM) { 2507 if ((status & 0x10) != 0x00) 2508 goto done; 2509 } 2510 dev->video_q.curr->vb.field_count = dev->video_fieldcount; 2511 saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE); 2512 } 2513 saa7134_buffer_next(dev,&dev->video_q); 2514 2515 done: 2516 spin_unlock(&dev->slock); 2517} 2518 2519/* ----------------------------------------------------------- */ 2520/* 2521 * Local variables: 2522 * c-basic-offset: 8 2523 * End: 2524 */ 2525