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