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