root/drivers/media/common/saa7146/saa7146_video.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. saa7146_format_by_fourcc
  2. saa7146_start_preview
  3. saa7146_stop_preview
  4. saa7146_pgtable_build
  5. video_begin
  6. video_end
  7. vidioc_querycap
  8. vidioc_g_fbuf
  9. vidioc_s_fbuf
  10. vidioc_enum_fmt_vid_cap
  11. saa7146_s_ctrl
  12. vidioc_g_parm
  13. vidioc_g_fmt_vid_cap
  14. vidioc_g_fmt_vid_overlay
  15. vidioc_g_fmt_vbi_cap
  16. vidioc_try_fmt_vid_cap
  17. vidioc_try_fmt_vid_overlay
  18. vidioc_s_fmt_vid_cap
  19. vidioc_s_fmt_vid_overlay
  20. vidioc_g_std
  21. vidioc_s_std
  22. vidioc_overlay
  23. vidioc_reqbufs
  24. vidioc_querybuf
  25. vidioc_qbuf
  26. vidioc_dqbuf
  27. vidioc_streamon
  28. vidioc_streamoff
  29. buffer_activate
  30. release_all_pagetables
  31. buffer_prepare
  32. buffer_setup
  33. buffer_queue
  34. buffer_release
  35. video_init
  36. video_open
  37. video_close
  38. video_irq_done
  39. video_read

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

/* [<][>][^][v][top][bottom][index][help] */