saa7146_video.c revision 84a1d9c83e3e13991b958c897b6e9d6a5e4ce76d
1#include <media/saa7146_vv.h> 2#include <media/v4l2-chip-ident.h> 3 4static int max_memory = 32; 5 6module_param(max_memory, int, 0644); 7MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)"); 8 9#define IS_CAPTURE_ACTIVE(fh) \ 10 (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh)) 11 12#define IS_OVERLAY_ACTIVE(fh) \ 13 (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh)) 14 15/* format descriptions for capture and preview */ 16static struct saa7146_format formats[] = { 17 { 18 .name = "RGB-8 (3-3-2)", 19 .pixelformat = V4L2_PIX_FMT_RGB332, 20 .trans = RGB08_COMPOSED, 21 .depth = 8, 22 .flags = 0, 23 }, { 24 .name = "RGB-16 (5/B-6/G-5/R)", 25 .pixelformat = V4L2_PIX_FMT_RGB565, 26 .trans = RGB16_COMPOSED, 27 .depth = 16, 28 .flags = 0, 29 }, { 30 .name = "RGB-24 (B-G-R)", 31 .pixelformat = V4L2_PIX_FMT_BGR24, 32 .trans = RGB24_COMPOSED, 33 .depth = 24, 34 .flags = 0, 35 }, { 36 .name = "RGB-32 (B-G-R)", 37 .pixelformat = V4L2_PIX_FMT_BGR32, 38 .trans = RGB32_COMPOSED, 39 .depth = 32, 40 .flags = 0, 41 }, { 42 .name = "RGB-32 (R-G-B)", 43 .pixelformat = V4L2_PIX_FMT_RGB32, 44 .trans = RGB32_COMPOSED, 45 .depth = 32, 46 .flags = 0, 47 .swap = 0x2, 48 }, { 49 .name = "Greyscale-8", 50 .pixelformat = V4L2_PIX_FMT_GREY, 51 .trans = Y8, 52 .depth = 8, 53 .flags = 0, 54 }, { 55 .name = "YUV 4:2:2 planar (Y-Cb-Cr)", 56 .pixelformat = V4L2_PIX_FMT_YUV422P, 57 .trans = YUV422_DECOMPOSED, 58 .depth = 16, 59 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, 60 }, { 61 .name = "YVU 4:2:0 planar (Y-Cb-Cr)", 62 .pixelformat = V4L2_PIX_FMT_YVU420, 63 .trans = YUV420_DECOMPOSED, 64 .depth = 12, 65 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, 66 }, { 67 .name = "YUV 4:2:0 planar (Y-Cb-Cr)", 68 .pixelformat = V4L2_PIX_FMT_YUV420, 69 .trans = YUV420_DECOMPOSED, 70 .depth = 12, 71 .flags = FORMAT_IS_PLANAR, 72 }, { 73 .name = "YUV 4:2:2 (U-Y-V-Y)", 74 .pixelformat = V4L2_PIX_FMT_UYVY, 75 .trans = YUV422_COMPOSED, 76 .depth = 16, 77 .flags = 0, 78 } 79}; 80 81/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps. 82 due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped 83 (like V4L2_PIX_FMT_YUYV) ... 8-( */ 84 85static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); 86 87struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) 88{ 89 int i, j = NUM_FORMATS; 90 91 for (i = 0; i < j; i++) { 92 if (formats[i].pixelformat == fourcc) { 93 return formats+i; 94 } 95 } 96 97 DEB_D(("unknown pixelformat:'%4.4s'\n",(char *)&fourcc)); 98 return NULL; 99} 100 101static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f); 102 103int saa7146_start_preview(struct saa7146_fh *fh) 104{ 105 struct saa7146_dev *dev = fh->dev; 106 struct saa7146_vv *vv = dev->vv_data; 107 struct v4l2_format fmt; 108 int ret = 0, err = 0; 109 110 DEB_EE(("dev:%p, fh:%p\n",dev,fh)); 111 112 /* check if we have overlay informations */ 113 if( NULL == fh->ov.fh ) { 114 DEB_D(("no overlay data available. try S_FMT first.\n")); 115 return -EAGAIN; 116 } 117 118 /* check if streaming capture is running */ 119 if (IS_CAPTURE_ACTIVE(fh) != 0) { 120 DEB_D(("streaming capture is active.\n")); 121 return -EBUSY; 122 } 123 124 /* check if overlay is running */ 125 if (IS_OVERLAY_ACTIVE(fh) != 0) { 126 if (vv->video_fh == fh) { 127 DEB_D(("overlay is already active.\n")); 128 return 0; 129 } 130 DEB_D(("overlay is already active in another open.\n")); 131 return -EBUSY; 132 } 133 134 if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) { 135 DEB_D(("cannot get necessary overlay resources\n")); 136 return -EBUSY; 137 } 138 139 fmt.fmt.win = fh->ov.win; 140 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); 141 if (0 != err) { 142 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 143 return -EBUSY; 144 } 145 fh->ov.win = fmt.fmt.win; 146 vv->ov_data = &fh->ov; 147 148 DEB_D(("%dx%d+%d+%d %s field=%s\n", 149 fh->ov.win.w.width,fh->ov.win.w.height, 150 fh->ov.win.w.left,fh->ov.win.w.top, 151 vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field])); 152 153 if (0 != (ret = saa7146_enable_overlay(fh))) { 154 DEB_D(("enabling overlay failed: %d\n",ret)); 155 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 156 return ret; 157 } 158 159 vv->video_status = STATUS_OVERLAY; 160 vv->video_fh = fh; 161 162 return 0; 163} 164EXPORT_SYMBOL_GPL(saa7146_start_preview); 165 166int saa7146_stop_preview(struct saa7146_fh *fh) 167{ 168 struct saa7146_dev *dev = fh->dev; 169 struct saa7146_vv *vv = dev->vv_data; 170 171 DEB_EE(("dev:%p, fh:%p\n",dev,fh)); 172 173 /* check if streaming capture is running */ 174 if (IS_CAPTURE_ACTIVE(fh) != 0) { 175 DEB_D(("streaming capture is active.\n")); 176 return -EBUSY; 177 } 178 179 /* check if overlay is running at all */ 180 if ((vv->video_status & STATUS_OVERLAY) == 0) { 181 DEB_D(("no active overlay.\n")); 182 return 0; 183 } 184 185 if (vv->video_fh != fh) { 186 DEB_D(("overlay is active, but in another open.\n")); 187 return -EBUSY; 188 } 189 190 vv->video_status = 0; 191 vv->video_fh = NULL; 192 193 saa7146_disable_overlay(fh); 194 195 saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 196 197 return 0; 198} 199EXPORT_SYMBOL_GPL(saa7146_stop_preview); 200 201/********************************************************************************/ 202/* device controls */ 203 204static struct v4l2_queryctrl controls[] = { 205 { 206 .id = V4L2_CID_BRIGHTNESS, 207 .name = "Brightness", 208 .minimum = 0, 209 .maximum = 255, 210 .step = 1, 211 .default_value = 128, 212 .type = V4L2_CTRL_TYPE_INTEGER, 213 .flags = V4L2_CTRL_FLAG_SLIDER, 214 },{ 215 .id = V4L2_CID_CONTRAST, 216 .name = "Contrast", 217 .minimum = 0, 218 .maximum = 127, 219 .step = 1, 220 .default_value = 64, 221 .type = V4L2_CTRL_TYPE_INTEGER, 222 .flags = V4L2_CTRL_FLAG_SLIDER, 223 },{ 224 .id = V4L2_CID_SATURATION, 225 .name = "Saturation", 226 .minimum = 0, 227 .maximum = 127, 228 .step = 1, 229 .default_value = 64, 230 .type = V4L2_CTRL_TYPE_INTEGER, 231 .flags = V4L2_CTRL_FLAG_SLIDER, 232 },{ 233 .id = V4L2_CID_VFLIP, 234 .name = "Vertical Flip", 235 .minimum = 0, 236 .maximum = 1, 237 .type = V4L2_CTRL_TYPE_BOOLEAN, 238 },{ 239 .id = V4L2_CID_HFLIP, 240 .name = "Horizontal Flip", 241 .minimum = 0, 242 .maximum = 1, 243 .type = V4L2_CTRL_TYPE_BOOLEAN, 244 }, 245}; 246static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl); 247 248#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0) 249 250static struct v4l2_queryctrl* ctrl_by_id(int id) 251{ 252 int i; 253 254 for (i = 0; i < NUM_CONTROLS; i++) 255 if (controls[i].id == id) 256 return controls+i; 257 return NULL; 258} 259 260/********************************************************************************/ 261/* common pagetable functions */ 262 263static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) 264{ 265 struct pci_dev *pci = dev->pci; 266 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 267 struct scatterlist *list = dma->sglist; 268 int length = dma->sglen; 269 struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); 270 271 DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length)); 272 273 if( 0 != IS_PLANAR(sfmt->trans)) { 274 struct saa7146_pgtable *pt1 = &buf->pt[0]; 275 struct saa7146_pgtable *pt2 = &buf->pt[1]; 276 struct saa7146_pgtable *pt3 = &buf->pt[2]; 277 __le32 *ptr1, *ptr2, *ptr3; 278 __le32 fill; 279 280 int size = buf->fmt->width*buf->fmt->height; 281 int i,p,m1,m2,m3,o1,o2; 282 283 switch( sfmt->depth ) { 284 case 12: { 285 /* create some offsets inside the page table */ 286 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1; 287 m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1; 288 m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1; 289 o1 = size%PAGE_SIZE; 290 o2 = (size+(size/4))%PAGE_SIZE; 291 DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2)); 292 break; 293 } 294 case 16: { 295 /* create some offsets inside the page table */ 296 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1; 297 m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1; 298 m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1; 299 o1 = size%PAGE_SIZE; 300 o2 = (size+(size/2))%PAGE_SIZE; 301 DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2)); 302 break; 303 } 304 default: { 305 return -1; 306 } 307 } 308 309 ptr1 = pt1->cpu; 310 ptr2 = pt2->cpu; 311 ptr3 = pt3->cpu; 312 313 /* walk all pages, copy all page addresses to ptr1 */ 314 for (i = 0; i < length; i++, list++) { 315 for (p = 0; p * 4096 < list->length; p++, ptr1++) { 316 *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset); 317 } 318 } 319/* 320 ptr1 = pt1->cpu; 321 for(j=0;j<40;j++) { 322 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]); 323 } 324*/ 325 326 /* if we have a user buffer, the first page may not be 327 aligned to a page boundary. */ 328 pt1->offset = dma->sglist->offset; 329 pt2->offset = pt1->offset+o1; 330 pt3->offset = pt1->offset+o2; 331 332 /* create video-dma2 page table */ 333 ptr1 = pt1->cpu; 334 for(i = m1; i <= m2 ; i++, ptr2++) { 335 *ptr2 = ptr1[i]; 336 } 337 fill = *(ptr2-1); 338 for(;i<1024;i++,ptr2++) { 339 *ptr2 = fill; 340 } 341 /* create video-dma3 page table */ 342 ptr1 = pt1->cpu; 343 for(i = m2; i <= m3; i++,ptr3++) { 344 *ptr3 = ptr1[i]; 345 } 346 fill = *(ptr3-1); 347 for(;i<1024;i++,ptr3++) { 348 *ptr3 = fill; 349 } 350 /* finally: finish up video-dma1 page table */ 351 ptr1 = pt1->cpu+m1; 352 fill = pt1->cpu[m1]; 353 for(i=m1;i<1024;i++,ptr1++) { 354 *ptr1 = fill; 355 } 356/* 357 ptr1 = pt1->cpu; 358 ptr2 = pt2->cpu; 359 ptr3 = pt3->cpu; 360 for(j=0;j<40;j++) { 361 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]); 362 } 363 for(j=0;j<40;j++) { 364 printk("ptr2 %d: 0x%08x\n",j,ptr2[j]); 365 } 366 for(j=0;j<40;j++) { 367 printk("ptr3 %d: 0x%08x\n",j,ptr3[j]); 368 } 369*/ 370 } else { 371 struct saa7146_pgtable *pt = &buf->pt[0]; 372 return saa7146_pgtable_build_single(pci, pt, list, length); 373 } 374 375 return 0; 376} 377 378 379/********************************************************************************/ 380/* file operations */ 381 382static int video_begin(struct saa7146_fh *fh) 383{ 384 struct saa7146_dev *dev = fh->dev; 385 struct saa7146_vv *vv = dev->vv_data; 386 struct saa7146_format *fmt = NULL; 387 unsigned int resource; 388 int ret = 0, err = 0; 389 390 DEB_EE(("dev:%p, fh:%p\n",dev,fh)); 391 392 if ((vv->video_status & STATUS_CAPTURE) != 0) { 393 if (vv->video_fh == fh) { 394 DEB_S(("already capturing.\n")); 395 return 0; 396 } 397 DEB_S(("already capturing in another open.\n")); 398 return -EBUSY; 399 } 400 401 if ((vv->video_status & STATUS_OVERLAY) != 0) { 402 DEB_S(("warning: suspending overlay video for streaming capture.\n")); 403 vv->ov_suspend = vv->video_fh; 404 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ 405 if (0 != err) { 406 DEB_D(("suspending video failed. aborting\n")); 407 return err; 408 } 409 } 410 411 fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); 412 /* we need to have a valid format set here */ 413 BUG_ON(NULL == fmt); 414 415 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { 416 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; 417 } else { 418 resource = RESOURCE_DMA1_HPS; 419 } 420 421 ret = saa7146_res_get(fh, resource); 422 if (0 == ret) { 423 DEB_S(("cannot get capture resource %d\n",resource)); 424 if (vv->ov_suspend != NULL) { 425 saa7146_start_preview(vv->ov_suspend); 426 vv->ov_suspend = NULL; 427 } 428 return -EBUSY; 429 } 430 431 /* clear out beginning of streaming bit (rps register 0)*/ 432 saa7146_write(dev, MC2, MASK_27 ); 433 434 /* enable rps0 irqs */ 435 SAA7146_IER_ENABLE(dev, MASK_27); 436 437 vv->video_fh = fh; 438 vv->video_status = STATUS_CAPTURE; 439 440 return 0; 441} 442 443static int video_end(struct saa7146_fh *fh, struct file *file) 444{ 445 struct saa7146_dev *dev = fh->dev; 446 struct saa7146_vv *vv = dev->vv_data; 447 struct saa7146_format *fmt = NULL; 448 unsigned long flags; 449 unsigned int resource; 450 u32 dmas = 0; 451 DEB_EE(("dev:%p, fh:%p\n",dev,fh)); 452 453 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { 454 DEB_S(("not capturing.\n")); 455 return 0; 456 } 457 458 if (vv->video_fh != fh) { 459 DEB_S(("capturing, but in another open.\n")); 460 return -EBUSY; 461 } 462 463 fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); 464 /* we need to have a valid format set here */ 465 BUG_ON(NULL == fmt); 466 467 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { 468 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; 469 dmas = MASK_22 | MASK_21 | MASK_20; 470 } else { 471 resource = RESOURCE_DMA1_HPS; 472 dmas = MASK_22; 473 } 474 spin_lock_irqsave(&dev->slock,flags); 475 476 /* disable rps0 */ 477 saa7146_write(dev, MC1, MASK_28); 478 479 /* disable rps0 irqs */ 480 SAA7146_IER_DISABLE(dev, MASK_27); 481 482 /* shut down all used video dma transfers */ 483 saa7146_write(dev, MC1, dmas); 484 485 spin_unlock_irqrestore(&dev->slock, flags); 486 487 vv->video_fh = NULL; 488 vv->video_status = 0; 489 490 saa7146_res_free(fh, resource); 491 492 if (vv->ov_suspend != NULL) { 493 saa7146_start_preview(vv->ov_suspend); 494 vv->ov_suspend = NULL; 495 } 496 497 return 0; 498} 499 500static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 501{ 502 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 503 504 strcpy((char *)cap->driver, "saa7146 v4l2"); 505 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); 506 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); 507 cap->version = SAA7146_VERSION_CODE; 508 cap->capabilities = 509 V4L2_CAP_VIDEO_CAPTURE | 510 V4L2_CAP_VIDEO_OVERLAY | 511 V4L2_CAP_READWRITE | 512 V4L2_CAP_STREAMING; 513 cap->capabilities |= dev->ext_vv_data->capabilities; 514 return 0; 515} 516 517static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 518{ 519 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 520 struct saa7146_vv *vv = dev->vv_data; 521 522 *fb = vv->ov_fb; 523 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; 524 return 0; 525} 526 527static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 528{ 529 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 530 struct saa7146_vv *vv = dev->vv_data; 531 struct saa7146_format *fmt; 532 533 DEB_EE(("VIDIOC_S_FBUF\n")); 534 535 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) 536 return -EPERM; 537 538 /* check args */ 539 fmt = format_by_fourcc(dev, fb->fmt.pixelformat); 540 if (NULL == fmt) 541 return -EINVAL; 542 543 /* planar formats are not allowed for overlay video, clipping and video dma would clash */ 544 if (fmt->flags & FORMAT_IS_PLANAR) 545 DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n", 546 (char *)&fmt->pixelformat)); 547 548 /* check if overlay is running */ 549 if (IS_OVERLAY_ACTIVE(fh) != 0) { 550 if (vv->video_fh != fh) { 551 DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); 552 return -EBUSY; 553 } 554 } 555 556 mutex_lock(&dev->lock); 557 558 /* ok, accept it */ 559 vv->ov_fb = *fb; 560 vv->ov_fmt = fmt; 561 562 if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) { 563 vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8; 564 DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline)); 565 } 566 567 mutex_unlock(&dev->lock); 568 return 0; 569} 570 571static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) 572{ 573 if (f->index >= NUM_FORMATS) 574 return -EINVAL; 575 strlcpy((char *)f->description, formats[f->index].name, 576 sizeof(f->description)); 577 f->pixelformat = formats[f->index].pixelformat; 578 return 0; 579} 580 581static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 582{ 583 const struct v4l2_queryctrl *ctrl; 584 585 if ((c->id < V4L2_CID_BASE || 586 c->id >= V4L2_CID_LASTP1) && 587 (c->id < V4L2_CID_PRIVATE_BASE || 588 c->id >= V4L2_CID_PRIVATE_LASTP1)) 589 return -EINVAL; 590 591 ctrl = ctrl_by_id(c->id); 592 if (ctrl == NULL) 593 return -EINVAL; 594 595 DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id)); 596 *c = *ctrl; 597 return 0; 598} 599 600static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) 601{ 602 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 603 struct saa7146_vv *vv = dev->vv_data; 604 const struct v4l2_queryctrl *ctrl; 605 u32 value = 0; 606 607 ctrl = ctrl_by_id(c->id); 608 if (NULL == ctrl) 609 return -EINVAL; 610 switch (c->id) { 611 case V4L2_CID_BRIGHTNESS: 612 value = saa7146_read(dev, BCS_CTRL); 613 c->value = 0xff & (value >> 24); 614 DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value)); 615 break; 616 case V4L2_CID_CONTRAST: 617 value = saa7146_read(dev, BCS_CTRL); 618 c->value = 0x7f & (value >> 16); 619 DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value)); 620 break; 621 case V4L2_CID_SATURATION: 622 value = saa7146_read(dev, BCS_CTRL); 623 c->value = 0x7f & (value >> 0); 624 DEB_D(("V4L2_CID_SATURATION: %d\n", c->value)); 625 break; 626 case V4L2_CID_VFLIP: 627 c->value = vv->vflip; 628 DEB_D(("V4L2_CID_VFLIP: %d\n", c->value)); 629 break; 630 case V4L2_CID_HFLIP: 631 c->value = vv->hflip; 632 DEB_D(("V4L2_CID_HFLIP: %d\n", c->value)); 633 break; 634 default: 635 return -EINVAL; 636 } 637 return 0; 638} 639 640static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) 641{ 642 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 643 struct saa7146_vv *vv = dev->vv_data; 644 const struct v4l2_queryctrl *ctrl; 645 646 ctrl = ctrl_by_id(c->id); 647 if (NULL == ctrl) { 648 DEB_D(("unknown control %d\n", c->id)); 649 return -EINVAL; 650 } 651 652 mutex_lock(&dev->lock); 653 654 switch (ctrl->type) { 655 case V4L2_CTRL_TYPE_BOOLEAN: 656 case V4L2_CTRL_TYPE_MENU: 657 case V4L2_CTRL_TYPE_INTEGER: 658 if (c->value < ctrl->minimum) 659 c->value = ctrl->minimum; 660 if (c->value > ctrl->maximum) 661 c->value = ctrl->maximum; 662 break; 663 default: 664 /* nothing */; 665 } 666 667 switch (c->id) { 668 case V4L2_CID_BRIGHTNESS: { 669 u32 value = saa7146_read(dev, BCS_CTRL); 670 value &= 0x00ffffff; 671 value |= (c->value << 24); 672 saa7146_write(dev, BCS_CTRL, value); 673 saa7146_write(dev, MC2, MASK_22 | MASK_06); 674 break; 675 } 676 case V4L2_CID_CONTRAST: { 677 u32 value = saa7146_read(dev, BCS_CTRL); 678 value &= 0xff00ffff; 679 value |= (c->value << 16); 680 saa7146_write(dev, BCS_CTRL, value); 681 saa7146_write(dev, MC2, MASK_22 | MASK_06); 682 break; 683 } 684 case V4L2_CID_SATURATION: { 685 u32 value = saa7146_read(dev, BCS_CTRL); 686 value &= 0xffffff00; 687 value |= (c->value << 0); 688 saa7146_write(dev, BCS_CTRL, value); 689 saa7146_write(dev, MC2, MASK_22 | MASK_06); 690 break; 691 } 692 case V4L2_CID_HFLIP: 693 /* fixme: we can support changing VFLIP and HFLIP here... */ 694 if (IS_CAPTURE_ACTIVE(fh) != 0) { 695 DEB_D(("V4L2_CID_HFLIP while active capture.\n")); 696 mutex_unlock(&dev->lock); 697 return -EBUSY; 698 } 699 vv->hflip = c->value; 700 break; 701 case V4L2_CID_VFLIP: 702 if (IS_CAPTURE_ACTIVE(fh) != 0) { 703 DEB_D(("V4L2_CID_VFLIP while active capture.\n")); 704 mutex_unlock(&dev->lock); 705 return -EBUSY; 706 } 707 vv->vflip = c->value; 708 break; 709 default: 710 mutex_unlock(&dev->lock); 711 return -EINVAL; 712 } 713 mutex_unlock(&dev->lock); 714 715 if (IS_OVERLAY_ACTIVE(fh) != 0) { 716 saa7146_stop_preview(fh); 717 saa7146_start_preview(fh); 718 } 719 return 0; 720} 721 722static int vidioc_g_parm(struct file *file, void *fh, 723 struct v4l2_streamparm *parm) 724{ 725 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 726 struct saa7146_vv *vv = dev->vv_data; 727 728 parm->parm.capture.readbuffers = 1; 729 v4l2_video_std_frame_period(vv->standard->id, 730 &parm->parm.capture.timeperframe); 731 return 0; 732} 733 734static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 735{ 736 f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt; 737 return 0; 738} 739 740static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) 741{ 742 f->fmt.win = ((struct saa7146_fh *)fh)->ov.win; 743 return 0; 744} 745 746static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) 747{ 748 f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt; 749 return 0; 750} 751 752static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 753{ 754 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 755 struct saa7146_vv *vv = dev->vv_data; 756 struct saa7146_format *fmt; 757 enum v4l2_field field; 758 int maxw, maxh; 759 int calc_bpl; 760 761 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); 762 763 fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); 764 if (NULL == fmt) 765 return -EINVAL; 766 767 field = f->fmt.pix.field; 768 maxw = vv->standard->h_max_out; 769 maxh = vv->standard->v_max_out; 770 771 if (V4L2_FIELD_ANY == field) { 772 field = (f->fmt.pix.height > maxh / 2) 773 ? V4L2_FIELD_INTERLACED 774 : V4L2_FIELD_BOTTOM; 775 } 776 switch (field) { 777 case V4L2_FIELD_ALTERNATE: 778 vv->last_field = V4L2_FIELD_TOP; 779 maxh = maxh / 2; 780 break; 781 case V4L2_FIELD_TOP: 782 case V4L2_FIELD_BOTTOM: 783 vv->last_field = V4L2_FIELD_INTERLACED; 784 maxh = maxh / 2; 785 break; 786 case V4L2_FIELD_INTERLACED: 787 vv->last_field = V4L2_FIELD_INTERLACED; 788 break; 789 default: 790 DEB_D(("no known field mode '%d'.\n", field)); 791 return -EINVAL; 792 } 793 794 f->fmt.pix.field = field; 795 if (f->fmt.pix.width > maxw) 796 f->fmt.pix.width = maxw; 797 if (f->fmt.pix.height > maxh) 798 f->fmt.pix.height = maxh; 799 800 calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; 801 802 if (f->fmt.pix.bytesperline < calc_bpl) 803 f->fmt.pix.bytesperline = calc_bpl; 804 805 if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ 806 f->fmt.pix.bytesperline = calc_bpl; 807 808 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 809 DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width, 810 f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage)); 811 812 return 0; 813} 814 815 816static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) 817{ 818 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 819 struct saa7146_vv *vv = dev->vv_data; 820 struct v4l2_window *win = &f->fmt.win; 821 enum v4l2_field field; 822 int maxw, maxh; 823 824 DEB_EE(("dev:%p\n", dev)); 825 826 if (NULL == vv->ov_fb.base) { 827 DEB_D(("no fb base set.\n")); 828 return -EINVAL; 829 } 830 if (NULL == vv->ov_fmt) { 831 DEB_D(("no fb fmt set.\n")); 832 return -EINVAL; 833 } 834 if (win->w.width < 48 || win->w.height < 32) { 835 DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height)); 836 return -EINVAL; 837 } 838 if (win->clipcount > 16) { 839 DEB_D(("clipcount too big.\n")); 840 return -EINVAL; 841 } 842 843 field = win->field; 844 maxw = vv->standard->h_max_out; 845 maxh = vv->standard->v_max_out; 846 847 if (V4L2_FIELD_ANY == field) { 848 field = (win->w.height > maxh / 2) 849 ? V4L2_FIELD_INTERLACED 850 : V4L2_FIELD_TOP; 851 } 852 switch (field) { 853 case V4L2_FIELD_TOP: 854 case V4L2_FIELD_BOTTOM: 855 case V4L2_FIELD_ALTERNATE: 856 maxh = maxh / 2; 857 break; 858 case V4L2_FIELD_INTERLACED: 859 break; 860 default: 861 DEB_D(("no known field mode '%d'.\n", field)); 862 return -EINVAL; 863 } 864 865 win->field = field; 866 if (win->w.width > maxw) 867 win->w.width = maxw; 868 if (win->w.height > maxh) 869 win->w.height = maxh; 870 871 return 0; 872} 873 874static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) 875{ 876 struct saa7146_fh *fh = __fh; 877 struct saa7146_dev *dev = fh->dev; 878 struct saa7146_vv *vv = dev->vv_data; 879 int err; 880 881 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); 882 if (IS_CAPTURE_ACTIVE(fh) != 0) { 883 DEB_EE(("streaming capture is active\n")); 884 return -EBUSY; 885 } 886 err = vidioc_try_fmt_vid_cap(file, fh, f); 887 if (0 != err) 888 return err; 889 fh->video_fmt = f->fmt.pix; 890 DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat)); 891 return 0; 892} 893 894static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f) 895{ 896 struct saa7146_fh *fh = __fh; 897 struct saa7146_dev *dev = fh->dev; 898 struct saa7146_vv *vv = dev->vv_data; 899 int err; 900 901 DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh)); 902 err = vidioc_try_fmt_vid_overlay(file, fh, f); 903 if (0 != err) 904 return err; 905 mutex_lock(&dev->lock); 906 fh->ov.win = f->fmt.win; 907 fh->ov.nclips = f->fmt.win.clipcount; 908 if (fh->ov.nclips > 16) 909 fh->ov.nclips = 16; 910 if (copy_from_user(fh->ov.clips, f->fmt.win.clips, 911 sizeof(struct v4l2_clip) * fh->ov.nclips)) { 912 mutex_unlock(&dev->lock); 913 return -EFAULT; 914 } 915 916 /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ 917 fh->ov.fh = fh; 918 919 mutex_unlock(&dev->lock); 920 921 /* check if our current overlay is active */ 922 if (IS_OVERLAY_ACTIVE(fh) != 0) { 923 saa7146_stop_preview(fh); 924 saa7146_start_preview(fh); 925 } 926 return 0; 927} 928 929static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) 930{ 931 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 932 struct saa7146_vv *vv = dev->vv_data; 933 934 *norm = vv->standard->id; 935 return 0; 936} 937 938 /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) 939 PAL / NTSC / SECAM. if your hardware does not (or does more) 940 -- override this function in your extension */ 941/* 942 case VIDIOC_ENUMSTD: 943 { 944 struct v4l2_standard *e = arg; 945 if (e->index < 0 ) 946 return -EINVAL; 947 if( e->index < dev->ext_vv_data->num_stds ) { 948 DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index)); 949 v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name); 950 return 0; 951 } 952 return -EINVAL; 953 } 954 */ 955 956static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) 957{ 958 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 959 struct saa7146_vv *vv = dev->vv_data; 960 int found = 0; 961 int err, i; 962 963 DEB_EE(("VIDIOC_S_STD\n")); 964 965 if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { 966 DEB_D(("cannot change video standard while streaming capture is active\n")); 967 return -EBUSY; 968 } 969 970 if ((vv->video_status & STATUS_OVERLAY) != 0) { 971 vv->ov_suspend = vv->video_fh; 972 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ 973 if (0 != err) { 974 DEB_D(("suspending video failed. aborting\n")); 975 return err; 976 } 977 } 978 979 mutex_lock(&dev->lock); 980 981 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 982 if (*id & dev->ext_vv_data->stds[i].id) 983 break; 984 if (i != dev->ext_vv_data->num_stds) { 985 vv->standard = &dev->ext_vv_data->stds[i]; 986 if (NULL != dev->ext_vv_data->std_callback) 987 dev->ext_vv_data->std_callback(dev, vv->standard); 988 found = 1; 989 } 990 991 mutex_unlock(&dev->lock); 992 993 if (vv->ov_suspend != NULL) { 994 saa7146_start_preview(vv->ov_suspend); 995 vv->ov_suspend = NULL; 996 } 997 998 if (!found) { 999 DEB_EE(("VIDIOC_S_STD: standard not found.\n")); 1000 return -EINVAL; 1001 } 1002 1003 DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name)); 1004 return 0; 1005} 1006 1007static int vidioc_overlay(struct file *file, void *fh, unsigned int on) 1008{ 1009 int err; 1010 1011 DEB_D(("VIDIOC_OVERLAY on:%d\n", on)); 1012 if (on) 1013 err = saa7146_start_preview(fh); 1014 else 1015 err = saa7146_stop_preview(fh); 1016 return err; 1017} 1018 1019static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b) 1020{ 1021 struct saa7146_fh *fh = __fh; 1022 1023 if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1024 return videobuf_reqbufs(&fh->video_q, b); 1025 if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE) 1026 return videobuf_reqbufs(&fh->vbi_q, b); 1027 return -EINVAL; 1028} 1029 1030static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) 1031{ 1032 struct saa7146_fh *fh = __fh; 1033 1034 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1035 return videobuf_querybuf(&fh->video_q, buf); 1036 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) 1037 return videobuf_querybuf(&fh->vbi_q, buf); 1038 return -EINVAL; 1039} 1040 1041static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) 1042{ 1043 struct saa7146_fh *fh = __fh; 1044 1045 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1046 return videobuf_qbuf(&fh->video_q, buf); 1047 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) 1048 return videobuf_qbuf(&fh->vbi_q, buf); 1049 return -EINVAL; 1050} 1051 1052static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) 1053{ 1054 struct saa7146_fh *fh = __fh; 1055 1056 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1057 return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK); 1058 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) 1059 return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK); 1060 return -EINVAL; 1061} 1062 1063static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) 1064{ 1065 struct saa7146_fh *fh = __fh; 1066 int err; 1067 1068 DEB_D(("VIDIOC_STREAMON, type:%d\n", type)); 1069 1070 err = video_begin(fh); 1071 if (err) 1072 return err; 1073 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1074 return videobuf_streamon(&fh->video_q); 1075 if (type == V4L2_BUF_TYPE_VBI_CAPTURE) 1076 return videobuf_streamon(&fh->vbi_q); 1077 return -EINVAL; 1078} 1079 1080static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) 1081{ 1082 struct saa7146_fh *fh = __fh; 1083 struct saa7146_dev *dev = fh->dev; 1084 struct saa7146_vv *vv = dev->vv_data; 1085 int err; 1086 1087 DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type)); 1088 1089 /* ugly: we need to copy some checks from video_end(), 1090 because videobuf_streamoff() relies on the capture running. 1091 check and fix this */ 1092 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { 1093 DEB_S(("not capturing.\n")); 1094 return 0; 1095 } 1096 1097 if (vv->video_fh != fh) { 1098 DEB_S(("capturing, but in another open.\n")); 1099 return -EBUSY; 1100 } 1101 1102 err = -EINVAL; 1103 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1104 err = videobuf_streamoff(&fh->video_q); 1105 else if (type == V4L2_BUF_TYPE_VBI_CAPTURE) 1106 err = videobuf_streamoff(&fh->vbi_q); 1107 if (0 != err) { 1108 DEB_D(("warning: videobuf_streamoff() failed.\n")); 1109 video_end(fh, file); 1110 } else { 1111 err = video_end(fh, file); 1112 } 1113 return err; 1114} 1115 1116static int vidioc_g_chip_ident(struct file *file, void *__fh, 1117 struct v4l2_dbg_chip_ident *chip) 1118{ 1119 struct saa7146_fh *fh = __fh; 1120 struct saa7146_dev *dev = fh->dev; 1121 1122 chip->ident = V4L2_IDENT_NONE; 1123 chip->revision = 0; 1124 if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { 1125 chip->ident = V4L2_IDENT_SAA7146; 1126 return 0; 1127 } 1128 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, 1129 core, g_chip_ident, chip); 1130} 1131 1132#ifdef CONFIG_VIDEO_V4L1_COMPAT 1133static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf) 1134{ 1135 struct saa7146_fh *fh = __fh; 1136 struct videobuf_queue *q = &fh->video_q; 1137 int err, i; 1138 1139 /* fixme: number of capture buffers and sizes for v4l apps */ 1140 int gbuffers = 2; 1141 int gbufsize = 768 * 576 * 4; 1142 1143 DEB_D(("VIDIOCGMBUF \n")); 1144 1145 q = &fh->video_q; 1146 err = videobuf_mmap_setup(q, gbuffers, gbufsize, 1147 V4L2_MEMORY_MMAP); 1148 if (err < 0) 1149 return err; 1150 1151 gbuffers = err; 1152 memset(mbuf, 0, sizeof(*mbuf)); 1153 mbuf->frames = gbuffers; 1154 mbuf->size = gbuffers * gbufsize; 1155 for (i = 0; i < gbuffers; i++) 1156 mbuf->offsets[i] = i * gbufsize; 1157 return 0; 1158} 1159#endif 1160 1161const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { 1162 .vidioc_querycap = vidioc_querycap, 1163 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1164 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap, 1165 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1166 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1167 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1168 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, 1169 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, 1170 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, 1171 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, 1172 .vidioc_g_chip_ident = vidioc_g_chip_ident, 1173 1174 .vidioc_overlay = vidioc_overlay, 1175 .vidioc_g_fbuf = vidioc_g_fbuf, 1176 .vidioc_s_fbuf = vidioc_s_fbuf, 1177 .vidioc_reqbufs = vidioc_reqbufs, 1178 .vidioc_querybuf = vidioc_querybuf, 1179 .vidioc_qbuf = vidioc_qbuf, 1180 .vidioc_dqbuf = vidioc_dqbuf, 1181 .vidioc_g_std = vidioc_g_std, 1182 .vidioc_s_std = vidioc_s_std, 1183 .vidioc_queryctrl = vidioc_queryctrl, 1184 .vidioc_g_ctrl = vidioc_g_ctrl, 1185 .vidioc_s_ctrl = vidioc_s_ctrl, 1186 .vidioc_streamon = vidioc_streamon, 1187 .vidioc_streamoff = vidioc_streamoff, 1188 .vidioc_g_parm = vidioc_g_parm, 1189#ifdef CONFIG_VIDEO_V4L1_COMPAT 1190 .vidiocgmbuf = vidiocgmbuf, 1191#endif 1192}; 1193 1194/*********************************************************************************/ 1195/* buffer handling functions */ 1196 1197static int buffer_activate (struct saa7146_dev *dev, 1198 struct saa7146_buf *buf, 1199 struct saa7146_buf *next) 1200{ 1201 struct saa7146_vv *vv = dev->vv_data; 1202 1203 buf->vb.state = VIDEOBUF_ACTIVE; 1204 saa7146_set_capture(dev,buf,next); 1205 1206 mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT); 1207 return 0; 1208} 1209 1210static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf) 1211{ 1212 saa7146_pgtable_free(dev->pci, &buf->pt[0]); 1213 saa7146_pgtable_free(dev->pci, &buf->pt[1]); 1214 saa7146_pgtable_free(dev->pci, &buf->pt[2]); 1215} 1216 1217static int buffer_prepare(struct videobuf_queue *q, 1218 struct videobuf_buffer *vb, enum v4l2_field field) 1219{ 1220 struct file *file = q->priv_data; 1221 struct saa7146_fh *fh = file->private_data; 1222 struct saa7146_dev *dev = fh->dev; 1223 struct saa7146_vv *vv = dev->vv_data; 1224 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1225 int size,err = 0; 1226 1227 DEB_CAP(("vbuf:%p\n",vb)); 1228 1229 /* sanity checks */ 1230 if (fh->video_fmt.width < 48 || 1231 fh->video_fmt.height < 32 || 1232 fh->video_fmt.width > vv->standard->h_max_out || 1233 fh->video_fmt.height > vv->standard->v_max_out) { 1234 DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height)); 1235 return -EINVAL; 1236 } 1237 1238 size = fh->video_fmt.sizeimage; 1239 if (0 != buf->vb.baddr && buf->vb.bsize < size) { 1240 DEB_D(("size mismatch.\n")); 1241 return -EINVAL; 1242 } 1243 1244 DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n", 1245 fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field])); 1246 if (buf->vb.width != fh->video_fmt.width || 1247 buf->vb.bytesperline != fh->video_fmt.bytesperline || 1248 buf->vb.height != fh->video_fmt.height || 1249 buf->vb.size != size || 1250 buf->vb.field != field || 1251 buf->vb.field != fh->video_fmt.field || 1252 buf->fmt != &fh->video_fmt) { 1253 saa7146_dma_free(dev,q,buf); 1254 } 1255 1256 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 1257 struct saa7146_format *sfmt; 1258 1259 buf->vb.bytesperline = fh->video_fmt.bytesperline; 1260 buf->vb.width = fh->video_fmt.width; 1261 buf->vb.height = fh->video_fmt.height; 1262 buf->vb.size = size; 1263 buf->vb.field = field; 1264 buf->fmt = &fh->video_fmt; 1265 buf->vb.field = fh->video_fmt.field; 1266 1267 sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); 1268 1269 release_all_pagetables(dev, buf); 1270 if( 0 != IS_PLANAR(sfmt->trans)) { 1271 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1272 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); 1273 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); 1274 } else { 1275 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1276 } 1277 1278 err = videobuf_iolock(q,&buf->vb, &vv->ov_fb); 1279 if (err) 1280 goto oops; 1281 err = saa7146_pgtable_build(dev,buf); 1282 if (err) 1283 goto oops; 1284 } 1285 buf->vb.state = VIDEOBUF_PREPARED; 1286 buf->activate = buffer_activate; 1287 1288 return 0; 1289 1290 oops: 1291 DEB_D(("error out.\n")); 1292 saa7146_dma_free(dev,q,buf); 1293 1294 return err; 1295} 1296 1297static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 1298{ 1299 struct file *file = q->priv_data; 1300 struct saa7146_fh *fh = file->private_data; 1301 1302 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS) 1303 *count = MAX_SAA7146_CAPTURE_BUFFERS; 1304 1305 *size = fh->video_fmt.sizeimage; 1306 1307 /* check if we exceed the "max_memory" parameter */ 1308 if( (*count * *size) > (max_memory*1048576) ) { 1309 *count = (max_memory*1048576) / *size; 1310 } 1311 1312 DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size)); 1313 1314 return 0; 1315} 1316 1317static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 1318{ 1319 struct file *file = q->priv_data; 1320 struct saa7146_fh *fh = file->private_data; 1321 struct saa7146_dev *dev = fh->dev; 1322 struct saa7146_vv *vv = dev->vv_data; 1323 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1324 1325 DEB_CAP(("vbuf:%p\n",vb)); 1326 saa7146_buffer_queue(fh->dev,&vv->video_q,buf); 1327} 1328 1329static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 1330{ 1331 struct file *file = q->priv_data; 1332 struct saa7146_fh *fh = file->private_data; 1333 struct saa7146_dev *dev = fh->dev; 1334 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1335 1336 DEB_CAP(("vbuf:%p\n",vb)); 1337 1338 saa7146_dma_free(dev,q,buf); 1339 1340 release_all_pagetables(dev, buf); 1341} 1342 1343static struct videobuf_queue_ops video_qops = { 1344 .buf_setup = buffer_setup, 1345 .buf_prepare = buffer_prepare, 1346 .buf_queue = buffer_queue, 1347 .buf_release = buffer_release, 1348}; 1349 1350/********************************************************************************/ 1351/* file operations */ 1352 1353static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) 1354{ 1355 INIT_LIST_HEAD(&vv->video_q.queue); 1356 1357 init_timer(&vv->video_q.timeout); 1358 vv->video_q.timeout.function = saa7146_buffer_timeout; 1359 vv->video_q.timeout.data = (unsigned long)(&vv->video_q); 1360 vv->video_q.dev = dev; 1361 1362 /* set some default values */ 1363 vv->standard = &dev->ext_vv_data->stds[0]; 1364 1365 /* FIXME: what's this? */ 1366 vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A; 1367 vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A; 1368} 1369 1370 1371static int video_open(struct saa7146_dev *dev, struct file *file) 1372{ 1373 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data; 1374 struct saa7146_format *sfmt; 1375 1376 fh->video_fmt.width = 384; 1377 fh->video_fmt.height = 288; 1378 fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; 1379 fh->video_fmt.bytesperline = 0; 1380 fh->video_fmt.field = V4L2_FIELD_ANY; 1381 sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); 1382 fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8; 1383 1384 videobuf_queue_sg_init(&fh->video_q, &video_qops, 1385 &dev->pci->dev, &dev->slock, 1386 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1387 V4L2_FIELD_INTERLACED, 1388 sizeof(struct saa7146_buf), 1389 file); 1390 1391 return 0; 1392} 1393 1394 1395static void video_close(struct saa7146_dev *dev, struct file *file) 1396{ 1397 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data; 1398 struct saa7146_vv *vv = dev->vv_data; 1399 struct videobuf_queue *q = &fh->video_q; 1400 int err; 1401 1402 if (IS_CAPTURE_ACTIVE(fh) != 0) { 1403 err = video_end(fh, file); 1404 } else if (IS_OVERLAY_ACTIVE(fh) != 0) { 1405 err = saa7146_stop_preview(fh); 1406 } 1407 1408 videobuf_stop(q); 1409 1410 /* hmm, why is this function declared void? */ 1411 /* return err */ 1412} 1413 1414 1415static void video_irq_done(struct saa7146_dev *dev, unsigned long st) 1416{ 1417 struct saa7146_vv *vv = dev->vv_data; 1418 struct saa7146_dmaqueue *q = &vv->video_q; 1419 1420 spin_lock(&dev->slock); 1421 DEB_CAP(("called.\n")); 1422 1423 /* only finish the buffer if we have one... */ 1424 if( NULL != q->curr ) { 1425 saa7146_buffer_finish(dev,q,VIDEOBUF_DONE); 1426 } 1427 saa7146_buffer_next(dev,q,0); 1428 1429 spin_unlock(&dev->slock); 1430} 1431 1432static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1433{ 1434 struct saa7146_fh *fh = file->private_data; 1435 struct saa7146_dev *dev = fh->dev; 1436 struct saa7146_vv *vv = dev->vv_data; 1437 ssize_t ret = 0; 1438 1439 DEB_EE(("called.\n")); 1440 1441 if ((vv->video_status & STATUS_CAPTURE) != 0) { 1442 /* fixme: should we allow read() captures while streaming capture? */ 1443 if (vv->video_fh == fh) { 1444 DEB_S(("already capturing.\n")); 1445 return -EBUSY; 1446 } 1447 DEB_S(("already capturing in another open.\n")); 1448 return -EBUSY; 1449 } 1450 1451 ret = video_begin(fh); 1452 if( 0 != ret) { 1453 goto out; 1454 } 1455 1456 ret = videobuf_read_one(&fh->video_q , data, count, ppos, 1457 file->f_flags & O_NONBLOCK); 1458 if (ret != 0) { 1459 video_end(fh, file); 1460 } else { 1461 ret = video_end(fh, file); 1462 } 1463out: 1464 /* restart overlay if it was active before */ 1465 if (vv->ov_suspend != NULL) { 1466 saa7146_start_preview(vv->ov_suspend); 1467 vv->ov_suspend = NULL; 1468 } 1469 1470 return ret; 1471} 1472 1473struct saa7146_use_ops saa7146_video_uops = { 1474 .init = video_init, 1475 .open = video_open, 1476 .release = video_close, 1477 .irq_done = video_irq_done, 1478 .read = video_read, 1479}; 1480