Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *
0004  * device driver for philips saa7134 based TV cards
0005  * video4linux video interface
0006  *
0007  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
0008  */
0009 
0010 #include "saa7134.h"
0011 #include "saa7134-reg.h"
0012 
0013 #include <linux/init.h>
0014 #include <linux/list.h>
0015 #include <linux/module.h>
0016 #include <linux/kernel.h>
0017 
0018 /* ------------------------------------------------------------------ */
0019 
0020 static unsigned int vbi_debug;
0021 module_param(vbi_debug, int, 0644);
0022 MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
0023 
0024 static unsigned int vbibufs = 4;
0025 module_param(vbibufs, int, 0444);
0026 MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
0027 
0028 #define vbi_dbg(fmt, arg...) do { \
0029     if (vbi_debug) \
0030         printk(KERN_DEBUG pr_fmt("vbi: " fmt), ## arg); \
0031     } while (0)
0032 
0033 /* ------------------------------------------------------------------ */
0034 
0035 #define VBI_LINE_COUNT     17
0036 #define VBI_LINE_LENGTH  2048
0037 #define VBI_SCALE       0x200
0038 
0039 static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
0040               int task)
0041 {
0042     struct saa7134_tvnorm *norm = dev->tvnorm;
0043 
0044     /* setup video scaler */
0045     saa_writeb(SAA7134_VBI_H_START1(task), norm->h_start     &  0xff);
0046     saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start     >> 8);
0047     saa_writeb(SAA7134_VBI_H_STOP1(task),  norm->h_stop      &  0xff);
0048     saa_writeb(SAA7134_VBI_H_STOP2(task),  norm->h_stop      >> 8);
0049     saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start_0 &  0xff);
0050     saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start_0 >> 8);
0051     saa_writeb(SAA7134_VBI_V_STOP1(task),  norm->vbi_v_stop_0  &  0xff);
0052     saa_writeb(SAA7134_VBI_V_STOP2(task),  norm->vbi_v_stop_0  >> 8);
0053 
0054     saa_writeb(SAA7134_VBI_H_SCALE_INC1(task),        VBI_SCALE & 0xff);
0055     saa_writeb(SAA7134_VBI_H_SCALE_INC2(task),        VBI_SCALE >> 8);
0056     saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task),   0x00);
0057     saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
0058 
0059     saa_writeb(SAA7134_VBI_H_LEN1(task), dev->vbi_hlen & 0xff);
0060     saa_writeb(SAA7134_VBI_H_LEN2(task), dev->vbi_hlen >> 8);
0061     saa_writeb(SAA7134_VBI_V_LEN1(task), dev->vbi_vlen & 0xff);
0062     saa_writeb(SAA7134_VBI_V_LEN2(task), dev->vbi_vlen >> 8);
0063 
0064     saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
0065 }
0066 
0067 /* ------------------------------------------------------------------ */
0068 
0069 static int buffer_activate(struct saa7134_dev *dev,
0070                struct saa7134_buf *buf,
0071                struct saa7134_buf *next)
0072 {
0073     struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_buf.vb2_queue->drv_priv;
0074     unsigned long control, base;
0075 
0076     vbi_dbg("buffer_activate [%p]\n", buf);
0077     buf->top_seen = 0;
0078 
0079     task_init(dev, buf, TASK_A);
0080     task_init(dev, buf, TASK_B);
0081     saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
0082     saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
0083 
0084     /* DMA: setup channel 2+3 (= VBI Task A+B) */
0085     base    = saa7134_buffer_base(buf);
0086     control = SAA7134_RS_CONTROL_BURST_16 |
0087         SAA7134_RS_CONTROL_ME |
0088         (dmaq->pt.dma >> 12);
0089     saa_writel(SAA7134_RS_BA1(2), base);
0090     saa_writel(SAA7134_RS_BA2(2), base + dev->vbi_hlen * dev->vbi_vlen);
0091     saa_writel(SAA7134_RS_PITCH(2), dev->vbi_hlen);
0092     saa_writel(SAA7134_RS_CONTROL(2), control);
0093     saa_writel(SAA7134_RS_BA1(3), base);
0094     saa_writel(SAA7134_RS_BA2(3), base + dev->vbi_hlen * dev->vbi_vlen);
0095     saa_writel(SAA7134_RS_PITCH(3), dev->vbi_hlen);
0096     saa_writel(SAA7134_RS_CONTROL(3), control);
0097 
0098     /* start DMA */
0099     saa7134_set_dmabits(dev);
0100     mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT);
0101 
0102     return 0;
0103 }
0104 
0105 static int buffer_prepare(struct vb2_buffer *vb2)
0106 {
0107     struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
0108     struct saa7134_dev *dev = dmaq->dev;
0109     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
0110     struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
0111     struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
0112     unsigned int size;
0113 
0114     if (dma->sgl->offset) {
0115         pr_err("The buffer is not page-aligned\n");
0116         return -EINVAL;
0117     }
0118     size = dev->vbi_hlen * dev->vbi_vlen * 2;
0119     if (vb2_plane_size(vb2, 0) < size)
0120         return -EINVAL;
0121 
0122     vb2_set_plane_payload(vb2, 0, size);
0123 
0124     return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
0125                     saa7134_buffer_startpage(buf));
0126 }
0127 
0128 static int queue_setup(struct vb2_queue *q,
0129                unsigned int *nbuffers, unsigned int *nplanes,
0130                unsigned int sizes[], struct device *alloc_devs[])
0131 {
0132     struct saa7134_dmaqueue *dmaq = q->drv_priv;
0133     struct saa7134_dev *dev = dmaq->dev;
0134     unsigned int size;
0135 
0136     dev->vbi_vlen = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 + 1;
0137     if (dev->vbi_vlen > VBI_LINE_COUNT)
0138         dev->vbi_vlen = VBI_LINE_COUNT;
0139     dev->vbi_hlen = VBI_LINE_LENGTH;
0140     size = dev->vbi_hlen * dev->vbi_vlen * 2;
0141 
0142     *nbuffers = saa7134_buffer_count(size, *nbuffers);
0143     *nplanes = 1;
0144     sizes[0] = size;
0145     return 0;
0146 }
0147 
0148 static int buffer_init(struct vb2_buffer *vb2)
0149 {
0150     struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
0151     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
0152     struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
0153 
0154     dmaq->curr = NULL;
0155     buf->activate = buffer_activate;
0156     return 0;
0157 }
0158 
0159 const struct vb2_ops saa7134_vbi_qops = {
0160     .queue_setup    = queue_setup,
0161     .buf_init   = buffer_init,
0162     .buf_prepare    = buffer_prepare,
0163     .buf_queue  = saa7134_vb2_buffer_queue,
0164     .wait_prepare   = vb2_ops_wait_prepare,
0165     .wait_finish    = vb2_ops_wait_finish,
0166     .start_streaming = saa7134_vb2_start_streaming,
0167     .stop_streaming = saa7134_vb2_stop_streaming,
0168 };
0169 
0170 /* ------------------------------------------------------------------ */
0171 
0172 int saa7134_vbi_init1(struct saa7134_dev *dev)
0173 {
0174     INIT_LIST_HEAD(&dev->vbi_q.queue);
0175     timer_setup(&dev->vbi_q.timeout, saa7134_buffer_timeout, 0);
0176     dev->vbi_q.dev              = dev;
0177 
0178     if (vbibufs < 2)
0179         vbibufs = 2;
0180     if (vbibufs > VIDEO_MAX_FRAME)
0181         vbibufs = VIDEO_MAX_FRAME;
0182     return 0;
0183 }
0184 
0185 int saa7134_vbi_fini(struct saa7134_dev *dev)
0186 {
0187     /* nothing */
0188     return 0;
0189 }
0190 
0191 void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
0192 {
0193     spin_lock(&dev->slock);
0194     if (dev->vbi_q.curr) {
0195         /* make sure we have seen both fields */
0196         if ((status & 0x10) == 0x00) {
0197             dev->vbi_q.curr->top_seen = 1;
0198             goto done;
0199         }
0200         if (!dev->vbi_q.curr->top_seen)
0201             goto done;
0202 
0203         saa7134_buffer_finish(dev, &dev->vbi_q, VB2_BUF_STATE_DONE);
0204     }
0205     saa7134_buffer_next(dev, &dev->vbi_q);
0206 
0207  done:
0208     spin_unlock(&dev->slock);
0209 }