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 #include <linux/delay.h>
0018 
0019 /* ------------------------------------------------------------------ */
0020 
0021 static unsigned int ts_debug;
0022 module_param(ts_debug, int, 0644);
0023 MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
0024 
0025 #define ts_dbg(fmt, arg...) do { \
0026     if (ts_debug) \
0027         printk(KERN_DEBUG pr_fmt("ts: " fmt), ## arg); \
0028     } while (0)
0029 
0030 /* ------------------------------------------------------------------ */
0031 static int buffer_activate(struct saa7134_dev *dev,
0032                struct saa7134_buf *buf,
0033                struct saa7134_buf *next)
0034 {
0035 
0036     ts_dbg("buffer_activate [%p]", buf);
0037     buf->top_seen = 0;
0038 
0039     if (!dev->ts_started)
0040         dev->ts_field = V4L2_FIELD_TOP;
0041 
0042     if (NULL == next)
0043         next = buf;
0044     if (V4L2_FIELD_TOP == dev->ts_field) {
0045         ts_dbg("- [top]     buf=%p next=%p\n", buf, next);
0046         saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
0047         saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
0048         dev->ts_field = V4L2_FIELD_BOTTOM;
0049     } else {
0050         ts_dbg("- [bottom]  buf=%p next=%p\n", buf, next);
0051         saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
0052         saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
0053         dev->ts_field = V4L2_FIELD_TOP;
0054     }
0055 
0056     /* start DMA */
0057     saa7134_set_dmabits(dev);
0058 
0059     mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
0060 
0061     if (!dev->ts_started)
0062         saa7134_ts_start(dev);
0063 
0064     return 0;
0065 }
0066 
0067 int saa7134_ts_buffer_init(struct vb2_buffer *vb2)
0068 {
0069     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
0070     struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
0071     struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
0072 
0073     dmaq->curr = NULL;
0074     buf->activate = buffer_activate;
0075 
0076     return 0;
0077 }
0078 EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init);
0079 
0080 int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2)
0081 {
0082     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
0083     struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
0084     struct saa7134_dev *dev = dmaq->dev;
0085     struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
0086     struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
0087     unsigned int lines, llength, size;
0088 
0089     ts_dbg("buffer_prepare [%p]\n", buf);
0090 
0091     llength = TS_PACKET_SIZE;
0092     lines = dev->ts.nr_packets;
0093 
0094     size = lines * llength;
0095     if (vb2_plane_size(vb2, 0) < size)
0096         return -EINVAL;
0097 
0098     vb2_set_plane_payload(vb2, 0, size);
0099     vbuf->field = dev->field;
0100 
0101     return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
0102                     saa7134_buffer_startpage(buf));
0103 }
0104 EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare);
0105 
0106 int saa7134_ts_queue_setup(struct vb2_queue *q,
0107                unsigned int *nbuffers, unsigned int *nplanes,
0108                unsigned int sizes[], struct device *alloc_devs[])
0109 {
0110     struct saa7134_dmaqueue *dmaq = q->drv_priv;
0111     struct saa7134_dev *dev = dmaq->dev;
0112     int size = TS_PACKET_SIZE * dev->ts.nr_packets;
0113 
0114     if (0 == *nbuffers)
0115         *nbuffers = dev->ts.nr_bufs;
0116     *nbuffers = saa7134_buffer_count(size, *nbuffers);
0117     if (*nbuffers < 3)
0118         *nbuffers = 3;
0119     *nplanes = 1;
0120     sizes[0] = size;
0121     return 0;
0122 }
0123 EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup);
0124 
0125 int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count)
0126 {
0127     struct saa7134_dmaqueue *dmaq = vq->drv_priv;
0128     struct saa7134_dev *dev = dmaq->dev;
0129 
0130     /*
0131      * Planar video capture and TS share the same DMA channel,
0132      * so only one can be active at a time.
0133      */
0134     if (vb2_is_busy(&dev->video_vbq) && dev->fmt->planar) {
0135         struct saa7134_buf *buf, *tmp;
0136 
0137         list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) {
0138             list_del(&buf->entry);
0139             vb2_buffer_done(&buf->vb2.vb2_buf,
0140                     VB2_BUF_STATE_QUEUED);
0141         }
0142         if (dmaq->curr) {
0143             vb2_buffer_done(&dmaq->curr->vb2.vb2_buf,
0144                     VB2_BUF_STATE_QUEUED);
0145             dmaq->curr = NULL;
0146         }
0147         return -EBUSY;
0148     }
0149     dmaq->seq_nr = 0;
0150     return 0;
0151 }
0152 EXPORT_SYMBOL_GPL(saa7134_ts_start_streaming);
0153 
0154 void saa7134_ts_stop_streaming(struct vb2_queue *vq)
0155 {
0156     struct saa7134_dmaqueue *dmaq = vq->drv_priv;
0157     struct saa7134_dev *dev = dmaq->dev;
0158 
0159     saa7134_ts_stop(dev);
0160     saa7134_stop_streaming(dev, dmaq);
0161 }
0162 EXPORT_SYMBOL_GPL(saa7134_ts_stop_streaming);
0163 
0164 struct vb2_ops saa7134_ts_qops = {
0165     .queue_setup    = saa7134_ts_queue_setup,
0166     .buf_init   = saa7134_ts_buffer_init,
0167     .buf_prepare    = saa7134_ts_buffer_prepare,
0168     .buf_queue  = saa7134_vb2_buffer_queue,
0169     .wait_prepare   = vb2_ops_wait_prepare,
0170     .wait_finish    = vb2_ops_wait_finish,
0171     .stop_streaming = saa7134_ts_stop_streaming,
0172 };
0173 EXPORT_SYMBOL_GPL(saa7134_ts_qops);
0174 
0175 /* ----------------------------------------------------------- */
0176 /* exported stuff                                              */
0177 
0178 static unsigned int tsbufs = 8;
0179 module_param(tsbufs, int, 0444);
0180 MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32");
0181 
0182 static unsigned int ts_nr_packets = 64;
0183 module_param(ts_nr_packets, int, 0444);
0184 MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
0185 
0186 int saa7134_ts_init_hw(struct saa7134_dev *dev)
0187 {
0188     /* deactivate TS softreset */
0189     saa_writeb(SAA7134_TS_SERIAL1, 0x00);
0190     /* TSSOP high active, TSVAL high active, TSLOCK ignored */
0191     saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
0192     saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
0193     saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
0194     saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
0195     /* TSNOPIT=0, TSCOLAP=0 */
0196     saa_writeb(SAA7134_TS_DMA2,
0197         ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00));
0198 
0199     return 0;
0200 }
0201 
0202 int saa7134_ts_init1(struct saa7134_dev *dev)
0203 {
0204     /* sanitycheck insmod options */
0205     if (tsbufs < 2)
0206         tsbufs = 2;
0207     if (tsbufs > VIDEO_MAX_FRAME)
0208         tsbufs = VIDEO_MAX_FRAME;
0209     if (ts_nr_packets < 4)
0210         ts_nr_packets = 4;
0211     if (ts_nr_packets > 312)
0212         ts_nr_packets = 312;
0213     dev->ts.nr_bufs    = tsbufs;
0214     dev->ts.nr_packets = ts_nr_packets;
0215 
0216     INIT_LIST_HEAD(&dev->ts_q.queue);
0217     timer_setup(&dev->ts_q.timeout, saa7134_buffer_timeout, 0);
0218     dev->ts_q.dev              = dev;
0219     dev->ts_q.need_two         = 1;
0220     dev->ts_started            = 0;
0221     saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt);
0222 
0223     /* init TS hw */
0224     saa7134_ts_init_hw(dev);
0225 
0226     return 0;
0227 }
0228 
0229 /* Function for stop TS */
0230 int saa7134_ts_stop(struct saa7134_dev *dev)
0231 {
0232     ts_dbg("TS stop\n");
0233 
0234     if (!dev->ts_started)
0235         return 0;
0236 
0237     /* Stop TS stream */
0238     switch (saa7134_boards[dev->board].ts_type) {
0239     case SAA7134_MPEG_TS_PARALLEL:
0240         saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
0241         dev->ts_started = 0;
0242         break;
0243     case SAA7134_MPEG_TS_SERIAL:
0244         saa_writeb(SAA7134_TS_SERIAL0, 0x40);
0245         dev->ts_started = 0;
0246         break;
0247     }
0248     return 0;
0249 }
0250 
0251 /* Function for start TS */
0252 int saa7134_ts_start(struct saa7134_dev *dev)
0253 {
0254     ts_dbg("TS start\n");
0255 
0256     if (WARN_ON(dev->ts_started))
0257         return 0;
0258 
0259     /* dma: setup channel 5 (= TS) */
0260     saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
0261     saa_writeb(SAA7134_TS_DMA1,
0262         ((dev->ts.nr_packets - 1) >> 8) & 0xff);
0263     /* TSNOPIT=0, TSCOLAP=0 */
0264     saa_writeb(SAA7134_TS_DMA2,
0265         (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
0266     saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
0267     saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
0268                       SAA7134_RS_CONTROL_ME |
0269                       (dev->ts_q.pt.dma >> 12));
0270 
0271     /* reset hardware TS buffers */
0272     saa_writeb(SAA7134_TS_SERIAL1, 0x00);
0273     saa_writeb(SAA7134_TS_SERIAL1, 0x03);
0274     saa_writeb(SAA7134_TS_SERIAL1, 0x00);
0275     saa_writeb(SAA7134_TS_SERIAL1, 0x01);
0276 
0277     /* TS clock non-inverted */
0278     saa_writeb(SAA7134_TS_SERIAL1, 0x00);
0279 
0280     /* Start TS stream */
0281     switch (saa7134_boards[dev->board].ts_type) {
0282     case SAA7134_MPEG_TS_PARALLEL:
0283         saa_writeb(SAA7134_TS_SERIAL0, 0x40);
0284         saa_writeb(SAA7134_TS_PARALLEL, 0xec |
0285             (saa7134_boards[dev->board].ts_force_val << 4));
0286         break;
0287     case SAA7134_MPEG_TS_SERIAL:
0288         saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
0289         saa_writeb(SAA7134_TS_PARALLEL, 0x6c |
0290             (saa7134_boards[dev->board].ts_force_val << 4));
0291         saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
0292         saa_writeb(SAA7134_TS_SERIAL1, 0x02);
0293         break;
0294     }
0295 
0296     dev->ts_started = 1;
0297 
0298     return 0;
0299 }
0300 
0301 int saa7134_ts_fini(struct saa7134_dev *dev)
0302 {
0303     saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);
0304     return 0;
0305 }
0306 
0307 void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
0308 {
0309     enum v4l2_field field;
0310 
0311     spin_lock(&dev->slock);
0312     if (dev->ts_q.curr) {
0313         field = dev->ts_field;
0314         if (field != V4L2_FIELD_TOP) {
0315             if ((status & 0x100000) != 0x000000)
0316                 goto done;
0317         } else {
0318             if ((status & 0x100000) != 0x100000)
0319                 goto done;
0320         }
0321         saa7134_buffer_finish(dev, &dev->ts_q, VB2_BUF_STATE_DONE);
0322     }
0323     saa7134_buffer_next(dev,&dev->ts_q);
0324 
0325  done:
0326     spin_unlock(&dev->slock);
0327 }