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",
 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_q.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_q,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_q.curr) {
 339                saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
 340        }
 341
 342        videobuf_queue_cancel(&fh->vbi_q);
 343
 344        vv->vbi_streaming = NULL;
 345
 346        del_timer(&vv->vbi_q.timeout);
 347        del_timer(&fh->vbi_read_timeout);
 348
 349        spin_unlock_irqrestore(&dev->slock, flags);
 350}
 351
 352static void vbi_read_timeout(unsigned long data)
 353{
 354        struct file *file = (struct file*)data;
 355        struct saa7146_fh *fh = file->private_data;
 356        struct saa7146_dev *dev = fh->dev;
 357
 358        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 359
 360        vbi_stop(fh, file);
 361}
 362
 363static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
 364{
 365        DEB_VBI("dev:%p\n", dev);
 366
 367        INIT_LIST_HEAD(&vv->vbi_q.queue);
 368
 369        init_timer(&vv->vbi_q.timeout);
 370        vv->vbi_q.timeout.function = saa7146_buffer_timeout;
 371        vv->vbi_q.timeout.data     = (unsigned long)(&vv->vbi_q);
 372        vv->vbi_q.dev              = dev;
 373
 374        init_waitqueue_head(&vv->vbi_wq);
 375}
 376
 377static int vbi_open(struct saa7146_dev *dev, struct file *file)
 378{
 379        struct saa7146_fh *fh = file->private_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        memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
 399
 400        fh->vbi_fmt.sampling_rate       = 27000000;
 401        fh->vbi_fmt.offset              = 248; /* todo */
 402        fh->vbi_fmt.samples_per_line    = vbi_pixel_to_capture;
 403        fh->vbi_fmt.sample_format       = V4L2_PIX_FMT_GREY;
 404
 405        /* fixme: this only works for PAL */
 406        fh->vbi_fmt.start[0] = 5;
 407        fh->vbi_fmt.count[0] = 16;
 408        fh->vbi_fmt.start[1] = 312;
 409        fh->vbi_fmt.count[1] = 16;
 410
 411        videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
 412                            &dev->pci->dev, &dev->slock,
 413                            V4L2_BUF_TYPE_VBI_CAPTURE,
 414                            V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 415                            sizeof(struct saa7146_buf),
 416                            file, &dev->v4l2_lock);
 417
 418        init_timer(&fh->vbi_read_timeout);
 419        fh->vbi_read_timeout.function = vbi_read_timeout;
 420        fh->vbi_read_timeout.data = (unsigned long)file;
 421
 422        /* initialize the brs */
 423        if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
 424                saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
 425        } else {
 426                saa7146_write(dev, BRS_CTRL, 0x00000001);
 427
 428                if (0 != (ret = vbi_workaround(dev))) {
 429                        DEB_VBI("vbi workaround failed!\n");
 430                        /* return ret;*/
 431                }
 432        }
 433
 434        /* upload brs register */
 435        saa7146_write(dev, MC2, (MASK_08|MASK_24));
 436        return 0;
 437}
 438
 439static void vbi_close(struct saa7146_dev *dev, struct file *file)
 440{
 441        struct saa7146_fh *fh = file->private_data;
 442        struct saa7146_vv *vv = dev->vv_data;
 443        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 444
 445        if( fh == vv->vbi_streaming ) {
 446                vbi_stop(fh, file);
 447        }
 448        saa7146_res_free(fh, RESOURCE_DMA3_BRS);
 449}
 450
 451static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
 452{
 453        struct saa7146_vv *vv = dev->vv_data;
 454        spin_lock(&dev->slock);
 455
 456        if (vv->vbi_q.curr) {
 457                DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_q.curr);
 458                /* this must be += 2, one count for each field */
 459                vv->vbi_fieldcount+=2;
 460                vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
 461                saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
 462        } else {
 463                DEB_VBI("dev:%p\n", dev);
 464        }
 465        saa7146_buffer_next(dev,&vv->vbi_q,1);
 466
 467        spin_unlock(&dev->slock);
 468}
 469
 470static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 471{
 472        struct saa7146_fh *fh = file->private_data;
 473        struct saa7146_dev *dev = fh->dev;
 474        struct saa7146_vv *vv = dev->vv_data;
 475        ssize_t ret = 0;
 476
 477        DEB_VBI("dev:%p, fh:%p\n", dev, fh);
 478
 479        if( NULL == vv->vbi_streaming ) {
 480                // fixme: check if dma3 is available
 481                // fixme: activate vbi engine here if necessary. (really?)
 482                vv->vbi_streaming = fh;
 483        }
 484
 485        if( fh != vv->vbi_streaming ) {
 486                DEB_VBI("open %p is already using vbi capture\n",
 487                        vv->vbi_streaming);
 488                return -EBUSY;
 489        }
 490
 491        mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
 492        ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
 493                                   file->f_flags & O_NONBLOCK);
 494/*
 495        printk("BASE_ODD3:      0x%08x\n", saa7146_read(dev, BASE_ODD3));
 496        printk("BASE_EVEN3:     0x%08x\n", saa7146_read(dev, BASE_EVEN3));
 497        printk("PROT_ADDR3:     0x%08x\n", saa7146_read(dev, PROT_ADDR3));
 498        printk("PITCH3:         0x%08x\n", saa7146_read(dev, PITCH3));
 499        printk("BASE_PAGE3:     0x%08x\n", saa7146_read(dev, BASE_PAGE3));
 500        printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
 501        printk("BRS_CTRL:       0x%08x\n", saa7146_read(dev, BRS_CTRL));
 502*/
 503        return ret;
 504}
 505
 506struct saa7146_use_ops saa7146_vbi_uops = {
 507        .init           = vbi_init,
 508        .open           = vbi_open,
 509        .release        = vbi_close,
 510        .irq_done       = vbi_irq_done,
 511        .read           = vbi_read,
 512};
 513