ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / media / video / saa7134 / saa7134-ts.c
1 /*
2  * device driver for philips saa7134 based TV cards
3  * video4linux video interface
4  *
5  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <linux/init.h>
23 #include <linux/list.h>
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <linux/delay.h>
28
29 #include "saa7134-reg.h"
30 #include "saa7134.h"
31
32 #include <media/saa6752hs.h>
33
34 /* ------------------------------------------------------------------ */
35
36 static unsigned int ts_debug  = 0;
37 MODULE_PARM(ts_debug,"i");
38 MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
39
40 static unsigned int tsbufs = 4;
41 MODULE_PARM(tsbufs,"i");
42 MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
43
44 #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
45 #define TS_NR_PACKETS 312
46
47 #define dprintk(fmt, arg...)    if (ts_debug) \
48         printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
49
50 /* ------------------------------------------------------------------ */
51
52 static int buffer_activate(struct saa7134_dev *dev,
53                            struct saa7134_buf *buf,
54                            struct saa7134_buf *next)
55 {
56         u32 control;
57         
58         dprintk("buffer_activate [%p]",buf);
59         buf->vb.state = STATE_ACTIVE;
60         buf->top_seen = 0;
61         
62         /* dma: setup channel 5 (= TS) */
63         control = SAA7134_RS_CONTROL_BURST_16 |
64                 SAA7134_RS_CONTROL_ME |
65                 (buf->pt->dma >> 12);
66
67         if (NULL == next)
68                 next = buf;
69         if (V4L2_FIELD_TOP == buf->vb.field) {
70                 dprintk("- [top]     buf=%p next=%p\n",buf,next);
71                 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
72                 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
73         } else {
74                 dprintk("- [bottom]  buf=%p next=%p\n",buf,next);
75                 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
76                 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
77         }
78         saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
79         saa_writel(SAA7134_RS_CONTROL(5),control);
80
81         /* start DMA */
82         saa7134_set_dmabits(dev);
83         
84         mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
85         return 0;
86 }
87
88 static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
89                           enum v4l2_field field)
90 {
91         struct saa7134_dev *dev = file->private_data;
92         struct saa7134_buf *buf = (struct saa7134_buf *)vb;
93         unsigned int lines, llength, size;
94         int err;
95         
96         dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
97
98         llength = TS_PACKET_SIZE;
99         lines = TS_NR_PACKETS;
100         
101         size = lines * llength;
102         if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
103                 return -EINVAL;
104
105         if (buf->vb.size != size) {
106                 saa7134_dma_free(dev,buf);
107         }
108
109         if (STATE_NEEDS_INIT == buf->vb.state) {
110                 buf->vb.width  = llength;
111                 buf->vb.height = lines;
112                 buf->vb.size   = size;
113                 buf->pt        = &dev->ts.pt_ts;
114
115                 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
116                 if (err)
117                         goto oops;
118                 err = saa7134_pgtable_build(dev->pci,buf->pt,
119                                             buf->vb.dma.sglist,
120                                             buf->vb.dma.sglen,
121                                             saa7134_buffer_startpage(buf));
122                 if (err)
123                         goto oops;
124         }
125         buf->vb.state = STATE_PREPARED;
126         buf->activate = buffer_activate;
127         buf->vb.field = field;
128         return 0;
129
130  oops:
131         saa7134_dma_free(dev,buf);
132         return err;
133 }
134
135 static int
136 buffer_setup(struct file *file, unsigned int *count, unsigned int *size)
137 {
138         *size = TS_PACKET_SIZE * TS_NR_PACKETS;
139         if (0 == *count)
140                 *count = tsbufs;
141         *count = saa7134_buffer_count(*size,*count);
142         return 0;
143 }
144
145 static void buffer_queue(struct file *file, struct videobuf_buffer *vb)
146 {
147         struct saa7134_dev *dev = file->private_data;
148         struct saa7134_buf *buf = (struct saa7134_buf *)vb;
149         
150         saa7134_buffer_queue(dev,&dev->ts_q,buf);
151 }
152
153 static void buffer_release(struct file *file, struct videobuf_buffer *vb)
154 {
155         struct saa7134_dev *dev = file->private_data;
156         struct saa7134_buf *buf = (struct saa7134_buf *)vb;
157         
158         saa7134_dma_free(dev,buf);
159 }
160
161 static struct videobuf_queue_ops ts_qops = {
162         .buf_setup    = buffer_setup,
163         .buf_prepare  = buffer_prepare,
164         .buf_queue    = buffer_queue,
165         .buf_release  = buffer_release,
166 };
167
168
169 /* ------------------------------------------------------------------ */
170
171 static void ts_reset_encoder(struct saa7134_dev* dev) 
172 {
173         saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
174         mdelay(10);
175         saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
176         set_current_state(TASK_INTERRUPTIBLE);
177         schedule_timeout(HZ/10);
178 }
179
180 static int ts_init_encoder(struct saa7134_dev* dev, void* arg) 
181 {
182         ts_reset_encoder(dev);
183         saa7134_i2c_call_clients(dev, MPEG_SETPARAMS, arg);
184         return 0;
185 }
186
187
188 /* ------------------------------------------------------------------ */
189
190 static int ts_open(struct inode *inode, struct file *file)
191 {
192         int minor = iminor(inode);
193         struct saa7134_dev *h,*dev = NULL;
194         struct list_head *list;
195         int err;
196         
197         list_for_each(list,&saa7134_devlist) {
198                 h = list_entry(list, struct saa7134_dev, devlist);
199                 if (h->ts_dev && h->ts_dev->minor == minor)
200                         dev = h;
201         }
202         if (NULL == dev)
203                 return -ENODEV;
204
205         dprintk("open minor=%d\n",minor);
206         down(&dev->ts.ts.lock);
207         err = -EBUSY;
208         if (dev->ts.users)
209                 goto done;
210
211         dev->ts.started = 0;
212         dev->ts.users++;
213         file->private_data = dev;
214         err = 0;
215
216  done:
217         up(&dev->ts.ts.lock);
218         return err;
219 }
220
221 static int ts_release(struct inode *inode, struct file *file)
222 {
223         struct saa7134_dev *dev = file->private_data;
224
225         if (dev->ts.ts.streaming)
226                 videobuf_streamoff(file,&dev->ts.ts);
227         down(&dev->ts.ts.lock);
228         if (dev->ts.ts.reading)
229                 videobuf_read_stop(file,&dev->ts.ts);
230         dev->ts.users--;
231
232         /* stop the encoder */
233         if (dev->ts.started)
234                 ts_reset_encoder(dev);
235   
236         up(&dev->ts.ts.lock);
237         return 0;
238 }
239
240 static ssize_t
241 ts_read(struct file *file, char *data, size_t count, loff_t *ppos)
242 {
243         struct saa7134_dev *dev = file->private_data;
244
245         if (!dev->ts.started) {
246                 ts_init_encoder(dev, NULL);
247                 dev->ts.started = 1;
248         }
249   
250         return videobuf_read_stream(file, &dev->ts.ts, data, count, ppos, 0);
251 }
252
253 static unsigned int
254 ts_poll(struct file *file, struct poll_table_struct *wait)
255 {
256         struct saa7134_dev *dev = file->private_data;
257
258         return videobuf_poll_stream(file, &dev->ts.ts, wait);
259 }
260
261
262 static int
263 ts_mmap(struct file *file, struct vm_area_struct * vma)
264 {
265         struct saa7134_dev *dev = file->private_data;
266
267         return videobuf_mmap_mapper(vma, &dev->ts.ts);
268 }
269
270 /*
271  * This function is _not_ called directly, but from
272  * video_generic_ioctl (and maybe others).  userspace
273  * copying is done already, arg is a kernel pointer.
274  */
275 static int ts_do_ioctl(struct inode *inode, struct file *file,
276                        unsigned int cmd, void *arg)
277 {
278         struct saa7134_dev *dev = file->private_data;
279
280         if (ts_debug > 1)
281                 saa7134_print_ioctl(dev->name,cmd);
282         switch (cmd) {
283         case VIDIOC_QUERYCAP:
284         {
285                 struct v4l2_capability *cap = arg;
286
287                 memset(cap,0,sizeof(*cap));
288                 strcpy(cap->driver, "saa7134");
289                 strlcpy(cap->card, saa7134_boards[dev->board].name,
290                         sizeof(cap->card));
291                 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
292                 cap->version = SAA7134_VERSION_CODE;
293                 cap->capabilities =
294                         V4L2_CAP_VIDEO_CAPTURE |
295                         V4L2_CAP_READWRITE |
296                         V4L2_CAP_STREAMING;
297                 return 0;
298         }
299
300         /* --- input switching --------------------------------------- */
301         case VIDIOC_ENUMINPUT:
302         {
303                 struct v4l2_input *i = arg;
304                 
305                 if (i->index != 0)
306                         return -EINVAL;
307                 i->type = V4L2_INPUT_TYPE_CAMERA;
308                 strcpy(i->name,"CCIR656");
309                 return 0;
310         }
311         case VIDIOC_G_INPUT:
312         {
313                 int *i = arg;
314                 *i = 0;
315                 return 0;
316         }
317         case VIDIOC_S_INPUT:
318         {
319                 int *i = arg;
320                 
321                 if (*i != 0)
322                         return -EINVAL;
323                 return 0;
324         }
325         /* --- capture ioctls ---------------------------------------- */
326         
327         case VIDIOC_ENUM_FMT:
328         {
329                 struct v4l2_fmtdesc *f = arg;
330                 int index;
331
332                 index = f->index;
333                 if (index != 0)
334                         return -EINVAL;
335                 
336                 memset(f,0,sizeof(*f));
337                 f->index = index;
338                 strlcpy(f->description, "MPEG TS", sizeof(f->description));
339                 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
340                 f->pixelformat = V4L2_PIX_FMT_MPEG;
341                 return 0;
342         }
343
344         case VIDIOC_G_FMT:
345         {
346                 struct v4l2_format *f = arg;
347
348                 memset(f,0,sizeof(*f));
349                 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
350                 
351                 /* FIXME: translate subsampling type EMPRESS into
352                  *        width/height: */
353                 f->fmt.pix.width        = 720; /* D1 */
354                 f->fmt.pix.height       = 576;
355                 f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
356                 f->fmt.pix.sizeimage    = TS_PACKET_SIZE*TS_NR_PACKETS;
357                 return 0;
358         }
359         
360         case VIDIOC_S_FMT:
361         {
362                 struct v4l2_format *f = arg;
363
364                 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
365                     return -EINVAL;
366
367                 /* 
368                   FIXME: translate and round width/height into EMPRESS
369                   subsample type:
370                  
371                           type  |   PAL   |  NTSC 
372                         ---------------------------
373                           SIF   | 352x288 | 352x240
374                          1/2 D1 | 352x576 | 352x480
375                          2/3 D1 | 480x576 | 480x480
376                           D1    | 720x576 | 720x480
377                 */
378
379                 f->fmt.pix.width        = 720; /* D1 */
380                 f->fmt.pix.height       = 576;
381                 f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
382                 f->fmt.pix.sizeimage    = TS_PACKET_SIZE*TS_NR_PACKETS;
383                 return 0;
384         }
385
386         case VIDIOC_REQBUFS:
387                 return videobuf_reqbufs(file,&dev->ts.ts,arg);
388
389         case VIDIOC_QUERYBUF:
390                 return videobuf_querybuf(&dev->ts.ts,arg);
391
392         case VIDIOC_QBUF:
393                 return videobuf_qbuf(file,&dev->ts.ts,arg);
394
395         case VIDIOC_DQBUF:
396                 return videobuf_dqbuf(file,&dev->ts.ts,arg);
397
398         case VIDIOC_STREAMON:
399                 return videobuf_streamon(file,&dev->ts.ts);
400
401         case VIDIOC_STREAMOFF:
402                 return videobuf_streamoff(file,&dev->ts.ts);
403
404         case VIDIOC_QUERYCTRL:
405         case VIDIOC_G_CTRL:
406         case VIDIOC_S_CTRL:
407                 return saa7134_common_ioctl(dev, cmd, arg);
408
409         case MPEG_SETPARAMS:
410                 return ts_init_encoder(dev, arg);
411           
412         default:
413                 return -ENOIOCTLCMD;
414         }
415         return 0;
416 }
417
418 static int ts_ioctl(struct inode *inode, struct file *file,
419                      unsigned int cmd, unsigned long arg)
420 {
421         return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
422 }
423
424
425 static struct file_operations ts_fops =
426 {
427         .owner    = THIS_MODULE,
428         .open     = ts_open,
429         .release  = ts_release,
430         .read     = ts_read,
431         .poll     = ts_poll,
432         .mmap     = ts_mmap,
433         .ioctl    = ts_ioctl,
434         .llseek   = no_llseek,
435 };
436
437
438 /* ----------------------------------------------------------- */
439 /* exported stuff                                              */
440
441 struct video_device saa7134_ts_template =
442 {
443         .name          = "saa7134-ts",
444         .type          = 0 /* FIXME */,
445         .type2         = 0 /* FIXME */,
446         .hardware      = 0,
447         .fops          = &ts_fops,
448         .minor         = -1,
449 };
450
451 int saa7134_ts_init1(struct saa7134_dev *dev)
452 {
453         /* sanitycheck insmod options */
454         if (tsbufs < 2)
455                 tsbufs = 2;
456         if (tsbufs > VIDEO_MAX_FRAME)
457                 tsbufs = VIDEO_MAX_FRAME;
458
459         INIT_LIST_HEAD(&dev->ts_q.queue);
460         init_timer(&dev->ts_q.timeout);
461         dev->ts_q.timeout.function = saa7134_buffer_timeout;
462         dev->ts_q.timeout.data     = (unsigned long)(&dev->ts_q);
463         dev->ts_q.dev              = dev;
464         dev->ts_q.need_two         = 1;
465         videobuf_queue_init(&dev->ts.ts, &ts_qops, dev->pci, &dev->slock,
466                             V4L2_BUF_TYPE_VIDEO_CAPTURE,
467                             V4L2_FIELD_ALTERNATE,
468                             sizeof(struct saa7134_buf));
469         saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
470
471         /* init TS hw */
472         saa_writeb(SAA7134_TS_SERIAL1, 0x00);  /* deactivate TS softreset */
473         saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
474         saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
475         saa_writeb(SAA7134_TS_DMA0, ((TS_NR_PACKETS-1)&0xff));
476         saa_writeb(SAA7134_TS_DMA1, (((TS_NR_PACKETS-1)>>8)&0xff));
477         saa_writeb(SAA7134_TS_DMA2, ((((TS_NR_PACKETS-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */         
478  
479         return 0;
480 }
481
482 int saa7134_ts_fini(struct saa7134_dev *dev)
483 {
484         /* nothing */
485         saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
486         return 0;
487 }
488
489
490 void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
491 {
492         enum v4l2_field field;
493
494         spin_lock(&dev->slock);
495         if (dev->ts_q.curr) {
496                 field = dev->ts_q.curr->vb.field;
497                 if (field == V4L2_FIELD_TOP) {
498                         if ((status & 0x100000) != 0x100000)
499                                 goto done;
500                 } else {
501                         if ((status & 0x100000) != 0x000000)
502                                 goto done;
503                 }
504                 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
505         }
506         saa7134_buffer_next(dev,&dev->ts_q);
507
508  done:
509         spin_unlock(&dev->slock);
510 }
511
512 /* ----------------------------------------------------------- */
513 /*
514  * Local variables:
515  * c-basic-offset: 8
516  * End:
517  */