linux/drivers/media/common/saa7146/saa7146_vbi.c
<<
>>
Prefs
   1#include <media/drv-intf/saa7146_vv.h>
   2
   3static int vbi_pixel_to_capture = 720 * 2;
   4
   5static int vbi_workaround(struct saa7146_dev *dev)
   6{
   7        struct saa7146_vv *vv = dev->vv_data;
   8
   9        u32          *cpu;
  10        dma_addr_t   dma_addr;
  11
  12        int count = 0;
  13        int i;
  14
  15        DECLARE_WAITQUEUE(wait, current);
  16
  17        DEB_VBI("dev:%p\n", dev);
  18
  19        /* once again, a bug in the saa7146: the brs acquisition
  20           is buggy and especially the BXO-counter does not work
  21           as specified. there is this workaround, but please
  22           don't let me explain it. ;-) */
  23
  24        cpu = pci_alloc_consistent(dev->pci, 4096, &dma_addr);
  25        if (NULL == cpu)
  26                return -ENOMEM;
  27
  28        /* setup some basic programming, just for the workaround */
  29        saa7146_write(dev, BASE_EVEN3,  dma_addr);
  30        saa7146_write(dev, BASE_ODD3,   dma_addr+vbi_pixel_to_capture);
  31        saa7146_write(dev, PROT_ADDR3,  dma_addr+4096);
  32        saa7146_write(dev, PITCH3,      vbi_pixel_to_capture);
  33        saa7146_write(dev, BASE_PAGE3,  0x0);
  34        saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
  35        saa7146_write(dev, MC2, MASK_04|MASK_20);
  36
  37        /* load brs-control register */
  38        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
  39        /* BXO = 1h, BRS to outbound */
  40        WRITE_RPS1(0xc000008c);
  41        /* wait for vbi_a or vbi_b*/
  42        if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
  43                DEB_D("...using port b\n");
  44                WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
  45                WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
  46/*
  47                WRITE_RPS1(CMD_PAUSE | MASK_09);
  48*/
  49        } else {
  50                DEB_D("...using port a\n");
  51                WRITE_RPS1(CMD_PAUSE | MASK_10);
  52        }
  53        /* upload brs */
  54        WRITE_RPS1(CMD_UPLOAD | MASK_08);
  55        /* load brs-control register */
  56        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
  57        /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
  58        WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
  59        /* wait for brs_done */
  60        WRITE_RPS1(CMD_PAUSE | MASK_08);
  61        /* upload brs */
  62        WRITE_RPS1(CMD_UPLOAD | MASK_08);
  63        /* load video-dma3 NumLines3 and NumBytes3 */
  64        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
  65        /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
  66        WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
  67        /* load brs-control register */
  68        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
  69        /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
  70        WRITE_RPS1((540 << 7) | (5 << 19));  // 5 == vbi_start
  71        /* wait for brs_done */
  72        WRITE_RPS1(CMD_PAUSE | MASK_08);
  73        /* upload brs and video-dma3*/
  74        WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
  75        /* load mc2 register: enable dma3 */
  76        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
  77        WRITE_RPS1(MASK_20 | MASK_04);
  78        /* generate interrupt */
  79        WRITE_RPS1(CMD_INTERRUPT);
  80        /* stop rps1 */
  81        WRITE_RPS1(CMD_STOP);
  82
  83        /* we have to do the workaround twice to be sure that
  84           everything is ok */
  85        for(i = 0; i < 2; i++) {
  86
  87                /* indicate to the irq handler that we do the workaround */
  88                saa7146_write(dev, MC2, MASK_31|MASK_15);
  89
  90                saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
  91                saa7146_write(dev, MC2, MASK_04|MASK_20);
  92
  93                /* enable rps1 irqs */
  94                SAA7146_IER_ENABLE(dev,MASK_28);
  95
  96                /* prepare to wait to be woken up by the irq-handler */
  97                add_wait_queue(&vv->vbi_wq, &wait);
  98                set_current_state(TASK_INTERRUPTIBLE);
  99
 100                /* start rps1 to enable workaround */
 101                saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
 102                saa7146_write(dev, MC1, (MASK_13 | MASK_29));
 103
 104                schedule();
 105
 106                DEB_VBI("brs bug workaround %d/1\n", i);
 107
 108                remove_wait_queue(&vv->vbi_wq, &wait);
 109                __set_current_state(TASK_RUNNING);
 110
 111                /* disable rps1 irqs */
 112                SAA7146_IER_DISABLE(dev,MASK_28);
 113
 114                /* stop video-dma3 */
 115                saa7146_write(dev, MC1, MASK_20);
 116
 117                if(signal_pending(current)) {
 118
 119                        DEB_VBI("aborted (rps:0x%08x)\n",
 120                                saa7146_read(dev, RPS_ADDR1));
 121
 122                        /* stop rps1 for sure */
 123                        saa7146_write(dev, MC1, MASK_29);
 124
 125                        pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
 126                        return -EINTR;
 127                }
 128        }
 129
 130        pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
 131        return 0;
 132}
 133
 134static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
 135{
 136        struct saa7146_vv *vv = dev->vv_data;
 137
 138        struct saa7146_video_dma vdma3;
 139
 140        int count = 0;
 141        unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
 142        unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
 143
 144/*
 145        vdma3.base_even = 0xc8000000+2560*70;
 146        vdma3.base_odd  = 0xc8000000;
 147        vdma3.prot_addr = 0xc8000000+2560*164;
 148        vdma3.pitch     = 2560;
 149        vdma3.base_page = 0;
 150        vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
 151*/
 152        vdma3.base_even = buf->pt[2].offset;
 153        vdma3.base_odd  = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
 154        vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
 155        vdma3.pitch     = vbi_pixel_to_capture;
 156        vdma3.base_page = buf->pt[2].dma | ME1;
 157        vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
 158
 159        saa7146_write_out_dma(dev, 3, &vdma3);
 160
 161        /* write beginning of rps-program */
 162        count = 0;
 163
 164        /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
 165
 166        /* we don't wait here for the first field anymore. this is different from the video
 167           capture and might cause that the first buffer is only half filled (with only
 168           one field). but since this is some sort of streaming data, this is not that negative.
 169           but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
 170
 171/*
 172        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
 173        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
 174*/
 175        /* set bit 1 */
 176        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
 177        WRITE_RPS1(MASK_28 | MASK_12);
 178
 179        /* turn on video-dma3 */
 180        WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
 181        WRITE_RPS1(MASK_04 | MASK_20);                  /* => mask */
 182        WRITE_RPS1(MASK_04 | MASK_20);                  /* => values */
 183
 184        /* wait for o_fid_a/b / e_fid_a/b toggle */
 185        WRITE_RPS1(CMD_PAUSE | o_wait);
 186        WRITE_RPS1(CMD_PAUSE | e_wait);
 187
 188        /* generate interrupt */
 189        WRITE_RPS1(CMD_INTERRUPT);
 190
 191        /* stop */
 192        WRITE_RPS1(CMD_STOP);
 193
 194        /* enable rps1 irqs */
 195        SAA7146_IER_ENABLE(dev, MASK_28);
 196
 197        /* write the address of the rps-program */
 198        saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
 199
 200        /* turn on rps */
 201        saa7146_write(dev, MC1, (MASK_13 | MASK_29));
 202}
 203
 204static int buffer_activate(struct saa7146_dev *dev,
 205                           struct saa7146_buf *buf,
 206                           struct saa7146_buf *next)
 207{
 208        struct saa7146_vv *vv = dev->vv_data;
 209        buf->vb.state = VIDEOBUF_ACTIVE;
 210
 211        DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
 212        saa7146_set_vbi_capture(dev,buf,next);
 213
 214        mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
 215        return 0;
 216}
 217
 218static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
 219{
 220        struct file *file = q->priv_data;
 221        struct saa7146_fh *fh = file->private_data;
 222        struct saa7146_dev *dev = fh->dev;
 223        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 224
 225        int err = 0;
 226        int lines, llength, size;
 227
 228        lines   = 16 * 2 ; /* 2 fields */
 229        llength = vbi_pixel_to_capture;
 230        size = lines * llength;
 231
 232        DEB_VBI("vb:%p\n", vb);
 233
 234        if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
 235                DEB_VBI("size mismatch\n");
 236                return -EINVAL;
 237        }
 238
 239        if (buf->vb.size != size)
 240                saa7146_dma_free(dev,q,buf);
 241
 242        if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 243                struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 244
 245                buf->vb.width  = llength;
 246                buf->vb.height = lines;
 247                buf->vb.size   = size;
 248                buf->vb.field  = field; // FIXME: check this
 249
 250                saa7146_pgtable_free(dev->pci, &buf->pt[2]);
 251                saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
 252
 253                err = videobuf_iolock(q,&buf->vb, NULL);
 254                if (err)
 255                        goto oops;
 256                err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
 257                                                 dma->sglist, dma->sglen);
 258                if (0 != err)
 259                        return err;
 260        }
 261        buf->vb.state = VIDEOBUF_PREPARED;
 262        buf->activate = buffer_activate;
 263
 264        return 0;
 265
 266 oops:
 267        DEB_VBI("error out\n");
 268        saa7146_dma_free(dev,q,buf);
 269
 270        return err;
 271}
 272
 273static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 274{
 275        int llength,lines;
 276
 277        lines   = 16 * 2 ; /* 2 fields */
 278        llength = vbi_pixel_to_capture;
 279
 280        *size = lines * llength;
 281        *count = 2;
 282
 283        DEB_VBI("count:%d, size:%d\n", *count, *size);
 284
 285        return 0;
 286}
 287
 288static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
 289{
 290        struct file *file = q->priv_data;
 291        struct saa7146_fh *fh = file->private_data;
 292        struct saa7146_dev *dev = fh->dev;
 293        struct saa7146_vv *vv = dev->vv_data;
 294        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 295
 296        DEB_VBI("vb:%p\n", vb);
 297        saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
 298}
 299
 300static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 301{
 302        struct file *file = q->priv_data;
 303        struct saa7146_fh *fh   = file->private_data;
 304        struct saa7146_dev *dev = fh->dev;
 305        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 306
 307        DEB_VBI("vb:%p\n", vb);
 308        saa7146_dma_free(dev,q,buf);
 309}
 310
 311static struct videobuf_queue_ops vbi_qops = {
 312        .buf_setup    = buffer_setup,
 313        .buf_prepare  = buffer_prepare,
 314        .buf_queue    = buffer_queue,
 315        .buf_release  = buffer_release,
 316};
 317
 318/* ------------------------------------------------------------------ */
 319
 320static void vbi_stop(struct saa7146_fh *fh, struct file *file)
 321{
 322        struct saa7146_dev *dev = fh->dev;
 323        struct saa7146_vv *vv = dev->vv_data;
 324        unsigned long flags;
 325        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 326
 327        spin_lock_irqsave(&dev->slock,flags);
 328
 329        /* disable rps1  */
 330        saa7146_write(dev, MC1, MASK_29);
 331
 332        /* disable rps1 irqs */
 333        SAA7146_IER_DISABLE(dev, MASK_28);
 334
 335        /* shut down dma 3 transfers */
 336        saa7146_write(dev, MC1, MASK_20);
 337
 338        if (vv->vbi_dmaq.curr)
 339                saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
 340
 341        videobuf_queue_cancel(&fh->vbi_q);
 342
 343        vv->vbi_streaming = NULL;
 344
 345        del_timer(&vv->vbi_dmaq.timeout);
 346        del_timer(&vv->vbi_read_timeout);
 347
 348        spin_unlock_irqrestore(&dev->slock, flags);
 349}
 350
 351static void vbi_read_timeout(unsigned long data)
 352{
 353        struct file *file = (struct file*)data;
 354        struct saa7146_fh *fh = file->private_data;
 355        struct saa7146_dev *dev = fh->dev;
 356
 357        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 358
 359        vbi_stop(fh, file);
 360}
 361
 362static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
 363{
 364        DEB_VBI("dev:%p\n", dev);
 365
 366        INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
 367
 368        init_timer(&vv->vbi_dmaq.timeout);
 369        vv->vbi_dmaq.timeout.function = saa7146_buffer_timeout;
 370        vv->vbi_dmaq.timeout.data     = (unsigned long)(&vv->vbi_dmaq);
 371        vv->vbi_dmaq.dev              = dev;
 372
 373        init_waitqueue_head(&vv->vbi_wq);
 374}
 375
 376static int vbi_open(struct saa7146_dev *dev, struct file *file)
 377{
 378        struct saa7146_fh *fh = file->private_data;
 379        struct saa7146_vv *vv = fh->dev->vv_data;
 380
 381        u32 arbtr_ctrl  = saa7146_read(dev, PCI_BT_V1);
 382        int ret = 0;
 383
 384        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 385
 386        ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
 387        if (0 == ret) {
 388                DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n");
 389                return -EBUSY;
 390        }
 391
 392        /* adjust arbitrition control for video dma 3 */
 393        arbtr_ctrl &= ~0x1f0000;
 394        arbtr_ctrl |=  0x1d0000;
 395        saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
 396        saa7146_write(dev, MC2, (MASK_04|MASK_20));
 397
 398        videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
 399                            &dev->pci->dev, &dev->slock,
 400                            V4L2_BUF_TYPE_VBI_CAPTURE,
 401                            V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 402                            sizeof(struct saa7146_buf),
 403                            file, &dev->v4l2_lock);
 404
 405        vv->vbi_read_timeout.function = vbi_read_timeout;
 406        vv->vbi_read_timeout.data = (unsigned long)file;
 407
 408        /* initialize the brs */
 409        if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
 410                saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
 411        } else {
 412                saa7146_write(dev, BRS_CTRL, 0x00000001);
 413
 414                if (0 != (ret = vbi_workaround(dev))) {
 415                        DEB_VBI("vbi workaround failed!\n");
 416                        /* return ret;*/
 417                }
 418        }
 419
 420        /* upload brs register */
 421        saa7146_write(dev, MC2, (MASK_08|MASK_24));
 422        return 0;
 423}
 424
 425static void vbi_close(struct saa7146_dev *dev, struct file *file)
 426{
 427        struct saa7146_fh *fh = file->private_data;
 428        struct saa7146_vv *vv = dev->vv_data;
 429        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 430
 431        if( fh == vv->vbi_streaming ) {
 432                vbi_stop(fh, file);
 433        }
 434        saa7146_res_free(fh, RESOURCE_DMA3_BRS);
 435}
 436
 437static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
 438{
 439        struct saa7146_vv *vv = dev->vv_data;
 440        spin_lock(&dev->slock);
 441
 442        if (vv->vbi_dmaq.curr) {
 443                DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
 444                /* this must be += 2, one count for each field */
 445                vv->vbi_fieldcount+=2;
 446                vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
 447                saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
 448        } else {
 449                DEB_VBI("dev:%p\n", dev);
 450        }
 451        saa7146_buffer_next(dev, &vv->vbi_dmaq, 1);
 452
 453        spin_unlock(&dev->slock);
 454}
 455
 456static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 457{
 458        struct saa7146_fh *fh = file->private_data;
 459        struct saa7146_dev *dev = fh->dev;
 460        struct saa7146_vv *vv = dev->vv_data;
 461        ssize_t ret = 0;
 462
 463        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 464
 465        if( NULL == vv->vbi_streaming ) {
 466                // fixme: check if dma3 is available
 467                // fixme: activate vbi engine here if necessary. (really?)
 468                vv->vbi_streaming = fh;
 469        }
 470
 471        if( fh != vv->vbi_streaming ) {
 472                DEB_VBI("open %p is already using vbi capture\n",
 473                        vv->vbi_streaming);
 474                return -EBUSY;
 475        }
 476
 477        mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
 478        ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
 479                                   file->f_flags & O_NONBLOCK);
 480/*
 481        printk("BASE_ODD3:      0x%08x\n", saa7146_read(dev, BASE_ODD3));
 482        printk("BASE_EVEN3:     0x%08x\n", saa7146_read(dev, BASE_EVEN3));
 483        printk("PROT_ADDR3:     0x%08x\n", saa7146_read(dev, PROT_ADDR3));
 484        printk("PITCH3:         0x%08x\n", saa7146_read(dev, PITCH3));
 485        printk("BASE_PAGE3:     0x%08x\n", saa7146_read(dev, BASE_PAGE3));
 486        printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
 487        printk("BRS_CTRL:       0x%08x\n", saa7146_read(dev, BRS_CTRL));
 488*/
 489        return ret;
 490}
 491
 492struct saa7146_use_ops saa7146_vbi_uops = {
 493        .init           = vbi_init,
 494        .open           = vbi_open,
 495        .release        = vbi_close,
 496        .irq_done       = vbi_irq_done,
 497        .read           = vbi_read,
 498};
 499