Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
saa7134-ts.c
Go to the documentation of this file.
1 /*
2  *
3  * device driver for philips saa7134 based TV cards
4  * video4linux video interface
5  *
6  * (c) 2001,02 Gerd Knorr <[email protected]> [SuSE Labs]
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #include <linux/init.h>
24 #include <linux/list.h>
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/delay.h>
28 
29 #include "saa7134-reg.h"
30 #include "saa7134.h"
31 
32 /* ------------------------------------------------------------------ */
33 
34 static unsigned int ts_debug;
35 module_param(ts_debug, int, 0644);
36 MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
37 
38 #define dprintk(fmt, arg...) if (ts_debug) \
39  printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
40 
41 /* ------------------------------------------------------------------ */
42 
43 static int buffer_activate(struct saa7134_dev *dev,
44  struct saa7134_buf *buf,
45  struct saa7134_buf *next)
46 {
47 
48  dprintk("buffer_activate [%p]",buf);
49  buf->vb.state = VIDEOBUF_ACTIVE;
50  buf->top_seen = 0;
51 
52  if (NULL == next)
53  next = buf;
54  if (V4L2_FIELD_TOP == buf->vb.field) {
55  dprintk("- [top] buf=%p next=%p\n",buf,next);
58  } else {
59  dprintk("- [bottom] buf=%p next=%p\n",buf,next);
62  }
63 
64  /* start DMA */
66 
67  mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
68 
69  if (!dev->ts_started)
70  saa7134_ts_start(dev);
71 
72  return 0;
73 }
74 
75 static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
76  enum v4l2_field field)
77 {
78  struct saa7134_dev *dev = q->priv_data;
79  struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
80  unsigned int lines, llength, size;
81  int err;
82 
83  dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
84 
85  llength = TS_PACKET_SIZE;
86  lines = dev->ts.nr_packets;
87 
88  size = lines * llength;
89  if (0 != buf->vb.baddr && buf->vb.bsize < size)
90  return -EINVAL;
91 
92  if (buf->vb.size != size) {
93  saa7134_dma_free(q,buf);
94  }
95 
96  if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
97 
98  struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
99 
100  dprintk("buffer_prepare: needs_init\n");
101 
102  buf->vb.width = llength;
103  buf->vb.height = lines;
104  buf->vb.size = size;
105  buf->pt = &dev->ts.pt_ts;
106 
107  err = videobuf_iolock(q,&buf->vb,NULL);
108  if (err)
109  goto oops;
110  err = saa7134_pgtable_build(dev->pci,buf->pt,
111  dma->sglist,
112  dma->sglen,
114  if (err)
115  goto oops;
116  }
117 
118  buf->vb.state = VIDEOBUF_PREPARED;
119  buf->activate = buffer_activate;
120  buf->vb.field = field;
121  return 0;
122 
123  oops:
124  saa7134_dma_free(q,buf);
125  return err;
126 }
127 
128 static int
129 buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
130 {
131  struct saa7134_dev *dev = q->priv_data;
132 
133  *size = TS_PACKET_SIZE * dev->ts.nr_packets;
134  if (0 == *count)
135  *count = dev->ts.nr_bufs;
136  *count = saa7134_buffer_count(*size,*count);
137 
138  return 0;
139 }
140 
141 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
142 {
143  struct saa7134_dev *dev = q->priv_data;
144  struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
145 
146  saa7134_buffer_queue(dev,&dev->ts_q,buf);
147 }
148 
149 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
150 {
151  struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
152  struct saa7134_dev *dev = q->priv_data;
153 
154  if (dev->ts_started)
155  saa7134_ts_stop(dev);
156 
157  saa7134_dma_free(q,buf);
158 }
159 
161  .buf_setup = buffer_setup,
162  .buf_prepare = buffer_prepare,
163  .buf_queue = buffer_queue,
164  .buf_release = buffer_release,
165 };
166 EXPORT_SYMBOL_GPL(saa7134_ts_qops);
167 
168 /* ----------------------------------------------------------- */
169 /* exported stuff */
170 
171 static unsigned int tsbufs = 8;
172 module_param(tsbufs, int, 0444);
173 MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32");
174 
175 static unsigned int ts_nr_packets = 64;
176 module_param(ts_nr_packets, int, 0444);
177 MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
178 
180 {
181  /* deactivate TS softreset */
183  /* TSSOP high active, TSVAL high active, TSLOCK ignored */
186  saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
187  saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
188  /* TSNOPIT=0, TSCOLAP=0 */
190  ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00));
191 
192  return 0;
193 }
194 
196 {
197  /* sanitycheck insmod options */
198  if (tsbufs < 2)
199  tsbufs = 2;
200  if (tsbufs > VIDEO_MAX_FRAME)
201  tsbufs = VIDEO_MAX_FRAME;
202  if (ts_nr_packets < 4)
203  ts_nr_packets = 4;
204  if (ts_nr_packets > 312)
205  ts_nr_packets = 312;
206  dev->ts.nr_bufs = tsbufs;
207  dev->ts.nr_packets = ts_nr_packets;
208 
209  INIT_LIST_HEAD(&dev->ts_q.queue);
210  init_timer(&dev->ts_q.timeout);
211  dev->ts_q.timeout.function = saa7134_buffer_timeout;
212  dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
213  dev->ts_q.dev = dev;
214  dev->ts_q.need_two = 1;
215  dev->ts_started = 0;
216  saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
217 
218  /* init TS hw */
219  saa7134_ts_init_hw(dev);
220 
221  return 0;
222 }
223 
224 /* Function for stop TS */
225 int saa7134_ts_stop(struct saa7134_dev *dev)
226 {
227  dprintk("TS stop\n");
228 
229  BUG_ON(!dev->ts_started);
230 
231  /* Stop TS stream */
232  switch (saa7134_boards[dev->board].ts_type) {
235  dev->ts_started = 0;
236  break;
239  dev->ts_started = 0;
240  break;
241  }
242  return 0;
243 }
244 
245 /* Function for start TS */
247 {
248  dprintk("TS start\n");
249 
250  BUG_ON(dev->ts_started);
251 
252  /* dma: setup channel 5 (= TS) */
253  saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
255  ((dev->ts.nr_packets - 1) >> 8) & 0xff);
256  /* TSNOPIT=0, TSCOLAP=0 */
258  (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
262  (dev->ts.pt_ts.dma >> 12));
263 
264  /* reset hardware TS buffers */
269 
270  /* TS clock non-inverted */
272 
273  /* Start TS stream */
274  switch (saa7134_boards[dev->board].ts_type) {
278  (saa7134_boards[dev->board].ts_force_val << 4));
279  break;
283  (saa7134_boards[dev->board].ts_force_val << 4));
286  break;
287  }
288 
289  dev->ts_started = 1;
290 
291  return 0;
292 }
293 
294 int saa7134_ts_fini(struct saa7134_dev *dev)
295 {
296  saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
297  return 0;
298 }
299 
300 void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
301 {
302  enum v4l2_field field;
303 
304  spin_lock(&dev->slock);
305  if (dev->ts_q.curr) {
306  field = dev->ts_q.curr->vb.field;
307  if (field == V4L2_FIELD_TOP) {
308  if ((status & 0x100000) != 0x000000)
309  goto done;
310  } else {
311  if ((status & 0x100000) != 0x100000)
312  goto done;
313  }
315  }
316  saa7134_buffer_next(dev,&dev->ts_q);
317 
318  done:
319  spin_unlock(&dev->slock);
320 }
321 
322 /* ----------------------------------------------------------- */
323 /*
324  * Local variables:
325  * c-basic-offset: 8
326  * End:
327  */