1 /* 2 * 3 * device driver for philips saa7134 based TV cards 4 * video4linux video interface 5 * 6 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [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); 56 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); 57 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); 58 } else { 59 dprintk("- [bottom] buf=%p next=%p\n",buf,next); 60 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); 61 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); 62 } 63 64 /* start DMA */ 65 saa7134_set_dmabits(dev); 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_dmaqueue *dmaq = q->priv_data; 79 struct saa7134_dev *dev = dmaq->dev; 80 struct saa7134_buf *buf = container_of(vb, struct saa7134_buf, vb); 81 unsigned int lines, llength, size; 82 int err; 83 84 dprintk("buffer_prepare [%p,%s]\n", buf, v4l2_field_names[field]); 85 86 llength = TS_PACKET_SIZE; 87 lines = dev->ts.nr_packets; 88 89 size = lines * llength; 90 if (0 != buf->vb.baddr && buf->vb.bsize < size) 91 return -EINVAL; 92 93 if (buf->vb.size != size) { 94 saa7134_dma_free(q,buf); 95 } 96 97 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 98 99 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 100 101 dprintk("buffer_prepare: needs_init\n"); 102 103 buf->vb.width = llength; 104 buf->vb.height = lines; 105 buf->vb.size = size; 106 107 err = videobuf_iolock(q,&buf->vb,NULL); 108 if (err) 109 goto oops; 110 err = saa7134_pgtable_build(dev->pci, &dmaq->pt, 111 dma->sglist, 112 dma->sglen, 113 saa7134_buffer_startpage(buf)); 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_dmaqueue *dmaq = q->priv_data; 132 struct saa7134_dev *dev = dmaq->dev; 133 134 *size = TS_PACKET_SIZE * dev->ts.nr_packets; 135 if (0 == *count) 136 *count = dev->ts.nr_bufs; 137 *count = saa7134_buffer_count(*size,*count); 138 139 return 0; 140 } 141 142 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 143 { 144 struct saa7134_dmaqueue *dmaq = q->priv_data; 145 struct saa7134_dev *dev = dmaq->dev; 146 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 147 148 saa7134_buffer_queue(dev,&dev->ts_q,buf); 149 } 150 151 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 152 { 153 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 154 struct saa7134_dmaqueue *dmaq = q->priv_data; 155 struct saa7134_dev *dev = dmaq->dev; 156 157 if (dev->ts_started) 158 saa7134_ts_stop(dev); 159 160 saa7134_dma_free(q,buf); 161 } 162 163 struct videobuf_queue_ops saa7134_ts_qops = { 164 .buf_setup = buffer_setup, 165 .buf_prepare = buffer_prepare, 166 .buf_queue = buffer_queue, 167 .buf_release = buffer_release, 168 }; 169 EXPORT_SYMBOL_GPL(saa7134_ts_qops); 170 171 /* ----------------------------------------------------------- */ 172 /* exported stuff */ 173 174 static unsigned int tsbufs = 8; 175 module_param(tsbufs, int, 0444); 176 MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32"); 177 178 static unsigned int ts_nr_packets = 64; 179 module_param(ts_nr_packets, int, 0444); 180 MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); 181 182 int saa7134_ts_init_hw(struct saa7134_dev *dev) 183 { 184 /* deactivate TS softreset */ 185 saa_writeb(SAA7134_TS_SERIAL1, 0x00); 186 /* TSSOP high active, TSVAL high active, TSLOCK ignored */ 187 saa_writeb(SAA7134_TS_PARALLEL, 0x6c); 188 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1)); 189 saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff)); 190 saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff)); 191 /* TSNOPIT=0, TSCOLAP=0 */ 192 saa_writeb(SAA7134_TS_DMA2, 193 ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); 194 195 return 0; 196 } 197 198 int saa7134_ts_init1(struct saa7134_dev *dev) 199 { 200 /* sanitycheck insmod options */ 201 if (tsbufs < 2) 202 tsbufs = 2; 203 if (tsbufs > VIDEO_MAX_FRAME) 204 tsbufs = VIDEO_MAX_FRAME; 205 if (ts_nr_packets < 4) 206 ts_nr_packets = 4; 207 if (ts_nr_packets > 312) 208 ts_nr_packets = 312; 209 dev->ts.nr_bufs = tsbufs; 210 dev->ts.nr_packets = ts_nr_packets; 211 212 INIT_LIST_HEAD(&dev->ts_q.queue); 213 init_timer(&dev->ts_q.timeout); 214 dev->ts_q.timeout.function = saa7134_buffer_timeout; 215 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); 216 dev->ts_q.dev = dev; 217 dev->ts_q.need_two = 1; 218 dev->ts_started = 0; 219 saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt); 220 221 /* init TS hw */ 222 saa7134_ts_init_hw(dev); 223 224 return 0; 225 } 226 227 /* Function for stop TS */ 228 int saa7134_ts_stop(struct saa7134_dev *dev) 229 { 230 dprintk("TS stop\n"); 231 232 BUG_ON(!dev->ts_started); 233 234 /* Stop TS stream */ 235 switch (saa7134_boards[dev->board].ts_type) { 236 case SAA7134_MPEG_TS_PARALLEL: 237 saa_writeb(SAA7134_TS_PARALLEL, 0x6c); 238 dev->ts_started = 0; 239 break; 240 case SAA7134_MPEG_TS_SERIAL: 241 saa_writeb(SAA7134_TS_SERIAL0, 0x40); 242 dev->ts_started = 0; 243 break; 244 } 245 return 0; 246 } 247 248 /* Function for start TS */ 249 int saa7134_ts_start(struct saa7134_dev *dev) 250 { 251 dprintk("TS start\n"); 252 253 BUG_ON(dev->ts_started); 254 255 /* dma: setup channel 5 (= TS) */ 256 saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); 257 saa_writeb(SAA7134_TS_DMA1, 258 ((dev->ts.nr_packets - 1) >> 8) & 0xff); 259 /* TSNOPIT=0, TSCOLAP=0 */ 260 saa_writeb(SAA7134_TS_DMA2, 261 (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); 262 saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); 263 saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | 264 SAA7134_RS_CONTROL_ME | 265 (dev->ts_q.pt.dma >> 12)); 266 267 /* reset hardware TS buffers */ 268 saa_writeb(SAA7134_TS_SERIAL1, 0x00); 269 saa_writeb(SAA7134_TS_SERIAL1, 0x03); 270 saa_writeb(SAA7134_TS_SERIAL1, 0x00); 271 saa_writeb(SAA7134_TS_SERIAL1, 0x01); 272 273 /* TS clock non-inverted */ 274 saa_writeb(SAA7134_TS_SERIAL1, 0x00); 275 276 /* Start TS stream */ 277 switch (saa7134_boards[dev->board].ts_type) { 278 case SAA7134_MPEG_TS_PARALLEL: 279 saa_writeb(SAA7134_TS_SERIAL0, 0x40); 280 saa_writeb(SAA7134_TS_PARALLEL, 0xec | 281 (saa7134_boards[dev->board].ts_force_val << 4)); 282 break; 283 case SAA7134_MPEG_TS_SERIAL: 284 saa_writeb(SAA7134_TS_SERIAL0, 0xd8); 285 saa_writeb(SAA7134_TS_PARALLEL, 0x6c | 286 (saa7134_boards[dev->board].ts_force_val << 4)); 287 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); 288 saa_writeb(SAA7134_TS_SERIAL1, 0x02); 289 break; 290 } 291 292 dev->ts_started = 1; 293 294 return 0; 295 } 296 297 int saa7134_ts_fini(struct saa7134_dev *dev) 298 { 299 saa7134_pgtable_free(dev->pci, &dev->ts_q.pt); 300 return 0; 301 } 302 303 void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) 304 { 305 enum v4l2_field field; 306 307 spin_lock(&dev->slock); 308 if (dev->ts_q.curr) { 309 field = dev->ts_q.curr->vb.field; 310 if (field == V4L2_FIELD_TOP) { 311 if ((status & 0x100000) != 0x000000) 312 goto done; 313 } else { 314 if ((status & 0x100000) != 0x100000) 315 goto done; 316 } 317 saa7134_buffer_finish(dev, &dev->ts_q, VIDEOBUF_DONE); 318 } 319 saa7134_buffer_next(dev,&dev->ts_q); 320 321 done: 322 spin_unlock(&dev->slock); 323 } 324