| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * device driver for philips saa7134 based TV cards | 
					
						
							|  |  |  |  * video4linux video interface | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  *  it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  *  the Free Software Foundation; either version 2 of the License, or | 
					
						
							|  |  |  |  *  (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  *  GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  *  along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | #include <linux/list.h>
 | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/delay.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "saa7134-reg.h"
 | 
					
						
							|  |  |  | #include "saa7134.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------------------------------------ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-22 14:41:48 -03:00
										 |  |  | static unsigned int ts_debug; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | module_param(ts_debug, int, 0644); | 
					
						
							|  |  |  | MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define dprintk(fmt, arg...)	if (ts_debug) \
 | 
					
						
							|  |  |  | 	printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------------------------------------ */ | 
					
						
							|  |  |  | static int buffer_activate(struct saa7134_dev *dev, | 
					
						
							|  |  |  | 			   struct saa7134_buf *buf, | 
					
						
							|  |  |  | 			   struct saa7134_buf *next) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dprintk("buffer_activate [%p]",buf); | 
					
						
							|  |  |  | 	buf->top_seen = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	if (!dev->ts_started) | 
					
						
							|  |  |  | 		dev->ts_field = V4L2_FIELD_TOP; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	if (NULL == next) | 
					
						
							|  |  |  | 		next = buf; | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	if (V4L2_FIELD_TOP == dev->ts_field) { | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		dprintk("- [top]     buf=%p next=%p\n",buf,next); | 
					
						
							|  |  |  | 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); | 
					
						
							|  |  |  | 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 		dev->ts_field = V4L2_FIELD_BOTTOM; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		dprintk("- [bottom]  buf=%p next=%p\n",buf,next); | 
					
						
							|  |  |  | 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); | 
					
						
							|  |  |  | 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 		dev->ts_field = V4L2_FIELD_TOP; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* start DMA */ | 
					
						
							|  |  |  | 	saa7134_set_dmabits(dev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-28 06:41:08 -03:00
										 |  |  | 	mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT); | 
					
						
							| 
									
										
										
										
											2008-08-26 14:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 	if (!dev->ts_started) | 
					
						
							|  |  |  | 		saa7134_ts_start(dev); | 
					
						
							| 
									
										
										
										
											2008-08-26 14:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | int saa7134_ts_buffer_init(struct vb2_buffer *vb2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; | 
					
						
							|  |  |  | 	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dmaq->curr = NULL; | 
					
						
							|  |  |  | 	buf->activate = buffer_activate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 	struct saa7134_dev *dev = dmaq->dev; | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | 
					
						
							|  |  |  | 	struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	unsigned int lines, llength, size; | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	dprintk("buffer_prepare [%p]\n", buf); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	llength = TS_PACKET_SIZE; | 
					
						
							|  |  |  | 	lines = dev->ts.nr_packets; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size = lines * llength; | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	if (vb2_plane_size(vb2, 0) < size) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	vb2_set_plane_payload(vb2, 0, size); | 
					
						
							|  |  |  | 	vb2->v4l2_buf.field = dev->field; | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		return -EIO; | 
					
						
							|  |  |  | 	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, | 
					
						
							|  |  |  | 				    saa7134_buffer_startpage(buf)); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | void saa7134_ts_buffer_finish(struct vb2_buffer *vb2) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 	struct saa7134_dev *dev = dmaq->dev; | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | 
					
						
							|  |  |  | 	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_buffer_finish); | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, | 
					
						
							|  |  |  | 			   unsigned int *nbuffers, unsigned int *nplanes, | 
					
						
							|  |  |  | 			   unsigned int sizes[], void *alloc_ctxs[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct saa7134_dmaqueue *dmaq = q->drv_priv; | 
					
						
							|  |  |  | 	struct saa7134_dev *dev = dmaq->dev; | 
					
						
							|  |  |  | 	int size = TS_PACKET_SIZE * dev->ts.nr_packets; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (0 == *nbuffers) | 
					
						
							|  |  |  | 		*nbuffers = dev->ts.nr_bufs; | 
					
						
							|  |  |  | 	*nbuffers = saa7134_buffer_count(size, *nbuffers); | 
					
						
							|  |  |  | 	if (*nbuffers < 3) | 
					
						
							|  |  |  | 		*nbuffers = 3; | 
					
						
							|  |  |  | 	*nplanes = 1; | 
					
						
							|  |  |  | 	sizes[0] = size; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	struct saa7134_dmaqueue *dmaq = vq->drv_priv; | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 	struct saa7134_dev *dev = dmaq->dev; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Planar video capture and TS share the same DMA channel, | 
					
						
							|  |  |  | 	 * so only one can be active at a time. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (vb2_is_busy(&dev->video_vbq) && dev->fmt->planar) { | 
					
						
							|  |  |  | 		struct saa7134_buf *buf, *tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) { | 
					
						
							|  |  |  | 			list_del(&buf->entry); | 
					
						
							|  |  |  | 			vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (dmaq->curr) { | 
					
						
							|  |  |  | 			vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED); | 
					
						
							|  |  |  | 			dmaq->curr = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return -EBUSY; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dmaq->seq_nr = 0; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_start_streaming); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | void saa7134_ts_stop_streaming(struct vb2_queue *vq) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	struct saa7134_dmaqueue *dmaq = vq->drv_priv; | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 	struct saa7134_dev *dev = dmaq->dev; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	saa7134_ts_stop(dev); | 
					
						
							|  |  |  | 	saa7134_stop_streaming(dev, dmaq); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_stop_streaming); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct vb2_ops saa7134_ts_qops = { | 
					
						
							|  |  |  | 	.queue_setup	= saa7134_ts_queue_setup, | 
					
						
							|  |  |  | 	.buf_init	= saa7134_ts_buffer_init, | 
					
						
							|  |  |  | 	.buf_prepare	= saa7134_ts_buffer_prepare, | 
					
						
							|  |  |  | 	.buf_finish	= saa7134_ts_buffer_finish, | 
					
						
							|  |  |  | 	.buf_queue	= saa7134_vb2_buffer_queue, | 
					
						
							|  |  |  | 	.wait_prepare	= vb2_ops_wait_prepare, | 
					
						
							|  |  |  | 	.wait_finish	= vb2_ops_wait_finish, | 
					
						
							|  |  |  | 	.stop_streaming = saa7134_ts_stop_streaming, | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(saa7134_ts_qops); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ----------------------------------------------------------- */ | 
					
						
							|  |  |  | /* exported stuff                                              */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-08 21:36:30 -08:00
										 |  |  | static unsigned int tsbufs = 8; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | module_param(tsbufs, int, 0444); | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-08 21:36:30 -08:00
										 |  |  | static unsigned int ts_nr_packets = 64; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | module_param(ts_nr_packets, int, 0444); | 
					
						
							|  |  |  | MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 20:34:25 -03:00
										 |  |  | int saa7134_ts_init_hw(struct saa7134_dev *dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* deactivate TS softreset */ | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 
					
						
							|  |  |  | 	/* TSSOP high active, TSVAL high active, TSLOCK ignored */ | 
					
						
							| 
									
										
										
										
											2008-08-26 14:16:33 -03:00
										 |  |  | 	saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | 
					
						
							| 
									
										
										
										
											2007-09-27 20:34:25 -03:00
										 |  |  | 	saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1)); | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff)); | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff)); | 
					
						
							|  |  |  | 	/* TSNOPIT=0, TSCOLAP=0 */ | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_DMA2, | 
					
						
							|  |  |  | 		((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | int saa7134_ts_init1(struct saa7134_dev *dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* sanitycheck insmod options */ | 
					
						
							|  |  |  | 	if (tsbufs < 2) | 
					
						
							|  |  |  | 		tsbufs = 2; | 
					
						
							|  |  |  | 	if (tsbufs > VIDEO_MAX_FRAME) | 
					
						
							|  |  |  | 		tsbufs = VIDEO_MAX_FRAME; | 
					
						
							|  |  |  | 	if (ts_nr_packets < 4) | 
					
						
							|  |  |  | 		ts_nr_packets = 4; | 
					
						
							|  |  |  | 	if (ts_nr_packets > 312) | 
					
						
							|  |  |  | 		ts_nr_packets = 312; | 
					
						
							|  |  |  | 	dev->ts.nr_bufs    = tsbufs; | 
					
						
							|  |  |  | 	dev->ts.nr_packets = ts_nr_packets; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&dev->ts_q.queue); | 
					
						
							|  |  |  | 	init_timer(&dev->ts_q.timeout); | 
					
						
							|  |  |  | 	dev->ts_q.timeout.function = saa7134_buffer_timeout; | 
					
						
							|  |  |  | 	dev->ts_q.timeout.data     = (unsigned long)(&dev->ts_q); | 
					
						
							|  |  |  | 	dev->ts_q.dev              = dev; | 
					
						
							|  |  |  | 	dev->ts_q.need_two         = 1; | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 	dev->ts_started            = 0; | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 	saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* init TS hw */ | 
					
						
							| 
									
										
										
										
											2007-09-27 20:34:25 -03:00
										 |  |  | 	saa7134_ts_init_hw(dev); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | /* Function for stop TS */ | 
					
						
							|  |  |  | int saa7134_ts_stop(struct saa7134_dev *dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dprintk("TS stop\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	if (!dev->ts_started) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Stop TS stream */ | 
					
						
							|  |  |  | 	switch (saa7134_boards[dev->board].ts_type) { | 
					
						
							|  |  |  | 	case SAA7134_MPEG_TS_PARALLEL: | 
					
						
							|  |  |  | 		saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | 
					
						
							|  |  |  | 		dev->ts_started = 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SAA7134_MPEG_TS_SERIAL: | 
					
						
							|  |  |  | 		saa_writeb(SAA7134_TS_SERIAL0, 0x40); | 
					
						
							|  |  |  | 		dev->ts_started = 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Function for start TS */ | 
					
						
							|  |  |  | int saa7134_ts_start(struct saa7134_dev *dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dprintk("TS start\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 	if (WARN_ON(dev->ts_started)) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-08 06:38:28 -03:00
										 |  |  | 	/* dma: setup channel 5 (= TS) */ | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_DMA1, | 
					
						
							|  |  |  | 		((dev->ts.nr_packets - 1) >> 8) & 0xff); | 
					
						
							|  |  |  | 	/* TSNOPIT=0, TSCOLAP=0 */ | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_DMA2, | 
					
						
							|  |  |  | 		(((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); | 
					
						
							|  |  |  | 	saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | 
					
						
							|  |  |  | 	saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | 
					
						
							|  |  |  | 					  SAA7134_RS_CONTROL_ME | | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 					  (dev->ts_q.pt.dma >> 12)); | 
					
						
							| 
									
										
										
										
											2010-01-08 06:38:28 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* reset hardware TS buffers */ | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 	saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_SERIAL1, 0x03); | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_SERIAL1, 0x01); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* TS clock non-inverted */ | 
					
						
							|  |  |  | 	saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Start TS stream */ | 
					
						
							|  |  |  | 	switch (saa7134_boards[dev->board].ts_type) { | 
					
						
							|  |  |  | 	case SAA7134_MPEG_TS_PARALLEL: | 
					
						
							|  |  |  | 		saa_writeb(SAA7134_TS_SERIAL0, 0x40); | 
					
						
							| 
									
										
										
										
											2009-11-04 14:19:35 -03:00
										 |  |  | 		saa_writeb(SAA7134_TS_PARALLEL, 0xec | | 
					
						
							|  |  |  | 			(saa7134_boards[dev->board].ts_force_val << 4)); | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SAA7134_MPEG_TS_SERIAL: | 
					
						
							|  |  |  | 		saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | 
					
						
							| 
									
										
										
										
											2009-11-04 14:19:35 -03:00
										 |  |  | 		saa_writeb(SAA7134_TS_PARALLEL, 0x6c | | 
					
						
							|  |  |  | 			(saa7134_boards[dev->board].ts_force_val << 4)); | 
					
						
							| 
									
										
										
										
											2009-05-28 01:58:57 -03:00
										 |  |  | 		saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | 
					
						
							|  |  |  | 		saa_writeb(SAA7134_TS_SERIAL1, 0x02); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dev->ts_started = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | int saa7134_ts_fini(struct saa7134_dev *dev) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-17 06:06:06 -03:00
										 |  |  | 	saa7134_pgtable_free(dev->pci, &dev->ts_q.pt); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	enum v4l2_field field; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock(&dev->slock); | 
					
						
							|  |  |  | 	if (dev->ts_q.curr) { | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 		field = dev->ts_field; | 
					
						
							|  |  |  | 		if (field != V4L2_FIELD_TOP) { | 
					
						
							| 
									
										
										
										
											2005-11-08 21:36:30 -08:00
										 |  |  | 			if ((status & 0x100000) != 0x000000) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 				goto done; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2005-11-08 21:36:30 -08:00
										 |  |  | 			if ((status & 0x100000) != 0x100000) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 				goto done; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-04-17 07:30:53 -03:00
										 |  |  | 		saa7134_buffer_finish(dev, &dev->ts_q, VB2_BUF_STATE_DONE); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	saa7134_buffer_next(dev,&dev->ts_q); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  done: | 
					
						
							|  |  |  | 	spin_unlock(&dev->slock); | 
					
						
							|  |  |  | } |