linux/drivers/media/common/saa7146_vbi.c
<<
>>
Prefs
   1#include <media/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                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                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",saa7146_read(dev,RPS_ADDR1)));
 120
 121                        /* stop rps1 for sure */
 122                        saa7146_write(dev, MC1, MASK_29);
 123
 124                        pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
 125                        return -EINTR;
 126                }
 127        }
 128
 129        pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
 130        return 0;
 131}
 132
 133static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
 134{
 135        struct saa7146_vv *vv = dev->vv_data;
 136
 137        struct saa7146_video_dma vdma3;
 138
 139        int count = 0;
 140        unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
 141        unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
 142
 143/*
 144        vdma3.base_even = 0xc8000000+2560*70;
 145        vdma3.base_odd  = 0xc8000000;
 146        vdma3.prot_addr = 0xc8000000+2560*164;
 147        vdma3.pitch     = 2560;
 148        vdma3.base_page = 0;
 149        vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
 150*/
 151        vdma3.base_even = buf->pt[2].offset;
 152        vdma3.base_odd  = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
 153        vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
 154        vdma3.pitch     = vbi_pixel_to_capture;
 155        vdma3.base_page = buf->pt[2].dma | ME1;
 156        vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
 157
 158        saa7146_write_out_dma(dev, 3, &vdma3);
 159
 160        /* write beginning of rps-program */
 161        count = 0;
 162
 163        /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
 164
 165        /* we don't wait here for the first field anymore. this is different from the video
 166           capture and might cause that the first buffer is only half filled (with only
 167           one field). but since this is some sort of streaming data, this is not that negative.
 168           but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
 169
 170/*
 171        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
 172        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
 173*/
 174        /* set bit 1 */
 175        WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
 176        WRITE_RPS1(MASK_28 | MASK_12);
 177
 178        /* turn on video-dma3 */
 179        WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
 180        WRITE_RPS1(MASK_04 | MASK_20);                  /* => mask */
 181        WRITE_RPS1(MASK_04 | MASK_20);                  /* => values */
 182
 183        /* wait for o_fid_a/b / e_fid_a/b toggle */
 184        WRITE_RPS1(CMD_PAUSE | o_wait);
 185        WRITE_RPS1(CMD_PAUSE | e_wait);
 186
 187        /* generate interrupt */
 188        WRITE_RPS1(CMD_INTERRUPT);
 189
 190        /* stop */
 191        WRITE_RPS1(CMD_STOP);
 192
 193        /* enable rps1 irqs */
 194        SAA7146_IER_ENABLE(dev, MASK_28);
 195
 196        /* write the address of the rps-program */
 197        saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
 198
 199        /* turn on rps */
 200        saa7146_write(dev, MC1, (MASK_13 | MASK_29));
 201}
 202
 203static int buffer_activate(struct saa7146_dev *dev,
 204                           struct saa7146_buf *buf,
 205                           struct saa7146_buf *next)
 206{
 207        struct saa7146_vv *vv = dev->vv_data;
 208        buf->vb.state = VIDEOBUF_ACTIVE;
 209
 210        DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
 211        saa7146_set_vbi_capture(dev,buf,next);
 212
 213        mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
 214        return 0;
 215}
 216
 217static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
 218{
 219        struct file *file = q->priv_data;
 220        struct saa7146_fh *fh = file->private_data;
 221        struct saa7146_dev *dev = fh->dev;
 222        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 223
 224        int err = 0;
 225        int lines, llength, size;
 226
 227        lines   = 16 * 2 ; /* 2 fields */
 228        llength = vbi_pixel_to_capture;
 229        size = lines * llength;
 230
 231        DEB_VBI(("vb:%p\n",vb));
 232
 233        if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
 234                DEB_VBI(("size mismatch.\n"));
 235                return -EINVAL;
 236        }
 237
 238        if (buf->vb.size != size)
 239                saa7146_dma_free(dev,q,buf);
 240
 241        if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 242                struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 243
 244                buf->vb.width  = llength;
 245                buf->vb.height = lines;
 246                buf->vb.size   = size;
 247                buf->vb.field  = field; // FIXME: check this
 248
 249                saa7146_pgtable_free(dev->pci, &buf->pt[2]);
 250                saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
 251
 252                err = videobuf_iolock(q,&buf->vb, NULL);
 253                if (err)
 254                        goto oops;
 255                err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
 256                                                 dma->sglist, dma->sglen);
 257                if (0 != err)
 258                        return err;
 259        }
 260        buf->vb.state = VIDEOBUF_PREPARED;
 261        buf->activate = buffer_activate;
 262
 263        return 0;
 264
 265 oops:
 266        DEB_VBI(("error out.\n"));
 267        saa7146_dma_free(dev,q,buf);
 268
 269        return err;
 270}
 271
 272static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 273{
 274        int llength,lines;
 275
 276        lines   = 16 * 2 ; /* 2 fields */
 277        llength = vbi_pixel_to_capture;
 278
 279        *size = lines * llength;
 280        *count = 2;
 281
 282        DEB_VBI(("count:%d, size:%d\n",*count,*size));
 283
 284        return 0;
 285}
 286
 287static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
 288{
 289        struct file *file = q->priv_data;
 290        struct saa7146_fh *fh = file->private_data;
 291        struct saa7146_dev *dev = fh->dev;
 292        struct saa7146_vv *vv = dev->vv_data;
 293        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 294
 295        DEB_VBI(("vb:%p\n",vb));
 296        saa7146_buffer_queue(dev,&vv->vbi_q,buf);
 297}
 298
 299static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 300{
 301        struct file *file = q->priv_data;
 302        struct saa7146_fh *fh   = file->private_data;
 303        struct saa7146_dev *dev = fh->dev;
 304        struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 305
 306        DEB_VBI(("vb:%p\n",vb));
 307        saa7146_dma_free(dev,q,buf);
 308}
 309
 310static struct videobuf_queue_ops vbi_qops = {
 311        .buf_setup    = buffer_setup,
 312        .buf_prepare  = buffer_prepare,
 313        .buf_queue    = buffer_queue,
 314        .buf_release  = buffer_release,
 315};
 316
 317/* ------------------------------------------------------------------ */
 318
 319static void vbi_stop(struct saa7146_fh *fh, struct file *file)
 320{
 321        struct saa7146_dev *dev = fh->dev;
 322        struct saa7146_vv *vv = dev->vv_data;
 323        unsigned long flags;
 324        DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
 325
 326        spin_lock_irqsave(&dev->slock,flags);
 327
 328        /* disable rps1  */
 329        saa7146_write(dev, MC1, MASK_29);
 330
 331        /* disable rps1 irqs */
 332        SAA7146_IER_DISABLE(dev, MASK_28);
 333
 334        /* shut down dma 3 transfers */
 335        saa7146_write(dev, MC1, MASK_20);
 336
 337        if (vv->vbi_q.curr) {
 338                saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
 339        }
 340
 341        videobuf_queue_cancel(&fh->vbi_q);
 342
 343        vv->vbi_streaming = NULL;
 344
 345        del_timer(&vv->vbi_q.timeout);
 346        del_timer(&fh->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_q.queue);
 367
 368        init_timer(&vv->vbi_q.timeout);
 369        vv->vbi_q.timeout.function = saa7146_buffer_timeout;
 370        vv->vbi_q.timeout.data     = (unsigned long)(&vv->vbi_q);
 371        vv->vbi_q.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
 380        u32 arbtr_ctrl  = saa7146_read(dev, PCI_BT_V1);
 381        int ret = 0;
 382
 383        DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
 384
 385        ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
 386        if (0 == ret) {
 387                DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n"));
 388                return -EBUSY;
 389        }
 390
 391        /* adjust arbitrition control for video dma 3 */
 392        arbtr_ctrl &= ~0x1f0000;
 393        arbtr_ctrl |=  0x1d0000;
 394        saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
 395        saa7146_write(dev, MC2, (MASK_04|MASK_20));
 396
 397        memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
 398
 399        fh->vbi_fmt.sampling_rate       = 27000000;
 400        fh->vbi_fmt.offset              = 248; /* todo */
 401        fh->vbi_fmt.samples_per_line    = vbi_pixel_to_capture;
 402        fh->vbi_fmt.sample_format       = V4L2_PIX_FMT_GREY;
 403
 404        /* fixme: this only works for PAL */
 405        fh->vbi_fmt.start[0] = 5;
 406        fh->vbi_fmt.count[0] = 16;
 407        fh->vbi_fmt.start[1] = 312;
 408        fh->vbi_fmt.count[1] = 16;
 409
 410        videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
 411                            &dev->pci->dev, &dev->slock,
 412                            V4L2_BUF_TYPE_VBI_CAPTURE,
 413                            V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 414                            sizeof(struct saa7146_buf),
 415                            file, &dev->v4l2_lock);
 416
 417        init_timer(&fh->vbi_read_timeout);
 418        fh->vbi_read_timeout.function = vbi_read_timeout;
 419        fh->vbi_read_timeout.data = (unsigned long)file;
 420
 421        /* initialize the brs */
 422        if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
 423                saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
 424        } else {
 425                saa7146_write(dev, BRS_CTRL, 0x00000001);
 426
 427                if (0 != (ret = vbi_workaround(dev))) {
 428                        DEB_VBI(("vbi workaround failed!\n"));
 429                        /* return ret;*/
 430                }
 431        }
 432
 433        /* upload brs register */
 434        saa7146_write(dev, MC2, (MASK_08|MASK_24));
 435        return 0;
 436}
 437
 438static void vbi_close(struct saa7146_dev *dev, struct file *file)
 439{
 440        struct saa7146_fh *fh = file->private_data;
 441        struct saa7146_vv *vv = dev->vv_data;
 442        DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
 443
 444        if( fh == vv->vbi_streaming ) {
 445                vbi_stop(fh, file);
 446        }
 447        saa7146_res_free(fh, RESOURCE_DMA3_BRS);
 448}
 449
 450static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
 451{
 452        struct saa7146_vv *vv = dev->vv_data;
 453        spin_lock(&dev->slock);
 454
 455        if (vv->vbi_q.curr) {
 456                DEB_VBI(("dev:%p, curr:%p\n",dev,vv->vbi_q.curr));
 457                /* this must be += 2, one count for each field */
 458                vv->vbi_fieldcount+=2;
 459                vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
 460                saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
 461        } else {
 462                DEB_VBI(("dev:%p\n",dev));
 463        }
 464        saa7146_buffer_next(dev,&vv->vbi_q,1);
 465
 466        spin_unlock(&dev->slock);
 467}
 468
 469static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 470{
 471        struct saa7146_fh *fh = file->private_data;
 472        struct saa7146_dev *dev = fh->dev;
 473        struct saa7146_vv *vv = dev->vv_data;
 474        ssize_t ret = 0;
 475
 476        DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
 477
 478        if( NULL == vv->vbi_streaming ) {
 479                // fixme: check if dma3 is available
 480                // fixme: activate vbi engine here if necessary. (really?)
 481                vv->vbi_streaming = fh;
 482        }
 483
 484        if( fh != vv->vbi_streaming ) {
 485                DEB_VBI(("open %p is already using vbi capture.",vv->vbi_streaming));
 486                return -EBUSY;
 487        }
 488
 489        mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
 490        ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
 491                                   file->f_flags & O_NONBLOCK);
 492/*
 493        printk("BASE_ODD3:      0x%08x\n", saa7146_read(dev, BASE_ODD3));
 494        printk("BASE_EVEN3:     0x%08x\n", saa7146_read(dev, BASE_EVEN3));
 495        printk("PROT_ADDR3:     0x%08x\n", saa7146_read(dev, PROT_ADDR3));
 496        printk("PITCH3:         0x%08x\n", saa7146_read(dev, PITCH3));
 497        printk("BASE_PAGE3:     0x%08x\n", saa7146_read(dev, BASE_PAGE3));
 498        printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
 499        printk("BRS_CTRL:       0x%08x\n", saa7146_read(dev, BRS_CTRL));
 500*/
 501        return ret;
 502}
 503
 504struct saa7146_use_ops saa7146_vbi_uops = {
 505        .init           = vbi_init,
 506        .open           = vbi_open,
 507        .release        = vbi_close,
 508        .irq_done       = vbi_irq_done,
 509        .read           = vbi_read,
 510};
 511