diff options
Diffstat (limited to 'linux/drivers/media/video/saa7134/saa7134-ts.c')
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-ts.c | 331 |
1 files changed, 20 insertions, 311 deletions
diff --git a/linux/drivers/media/video/saa7134/saa7134-ts.c b/linux/drivers/media/video/saa7134/saa7134-ts.c index 01e93a720..3bcb51bf3 100644 --- a/linux/drivers/media/video/saa7134/saa7134-ts.c +++ b/linux/drivers/media/video/saa7134/saa7134-ts.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-ts.c,v 1.10 2004/10/13 10:39:00 kraxel Exp $ + * $Id: saa7134-ts.c,v 1.11 2004/10/19 16:02:05 kraxel Exp $ * * device driver for philips saa7134 based TV cards * video4linux video interface @@ -31,28 +31,12 @@ #include "saa7134-reg.h" #include "saa7134.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,64) -#include "saa6752hs.h" -#else -#include <media/saa6752hs.h> -#endif - /* ------------------------------------------------------------------ */ -#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */ - static unsigned int ts_debug = 0; MODULE_PARM(ts_debug,"i"); MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); -static unsigned int tsbufs = 4; -MODULE_PARM(tsbufs,"i"); -MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); - -static unsigned int ts_nr_packets = 30; -MODULE_PARM(ts_nr_packets,"i"); -MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); - #define dprintk(fmt, arg...) if (ts_debug) \ printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg) @@ -105,7 +89,7 @@ static int buffer_prepare(void *priv, struct videobuf_buffer *vb, dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); llength = TS_PACKET_SIZE; - lines = ts_nr_packets; + lines = dev->ts.nr_packets; size = lines * llength; if (0 != buf->vb.baddr && buf->vb.bsize < size) @@ -144,9 +128,11 @@ static int buffer_prepare(void *priv, struct videobuf_buffer *vb, static int buffer_setup(void *priv, unsigned int *count, unsigned int *size) { - *size = TS_PACKET_SIZE * ts_nr_packets; + struct saa7134_dev *dev = priv; + + *size = TS_PACKET_SIZE * dev->ts.nr_packets; if (0 == *count) - *count = tsbufs; + *count = dev->ts.nr_bufs; *count = saa7134_buffer_count(*size,*count); return 0; } @@ -167,298 +153,24 @@ static void buffer_release(void *priv, struct videobuf_buffer *vb) saa7134_dma_free(dev,buf); } -static struct videobuf_queue_ops ts_qops = { +struct videobuf_queue_ops saa7134_ts_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, .buf_release = buffer_release, }; - - -/* ------------------------------------------------------------------ */ - -static void ts_reset_encoder(struct saa7134_dev* dev) -{ - saa_writeb(SAA7134_SPECIAL_MODE, 0x00); - msleep(10); - saa_writeb(SAA7134_SPECIAL_MODE, 0x01); - msleep(100); -} - -static int ts_init_encoder(struct saa7134_dev* dev, void* arg) -{ - ts_reset_encoder(dev); - saa7134_i2c_call_clients(dev, MPEG_SETPARAMS, arg); - return 0; -} - - -/* ------------------------------------------------------------------ */ - -static int ts_open(struct inode *inode, struct file *file) -{ - int minor = iminor(inode); - struct saa7134_dev *h,*dev = NULL; - struct list_head *list; - int err; - - list_for_each(list,&saa7134_devlist) { - h = list_entry(list, struct saa7134_dev, devlist); - if (h->ts_dev && h->ts_dev->minor == minor) - dev = h; - } - if (NULL == dev) - return -ENODEV; - - dprintk("open minor=%d\n",minor); - down(&dev->ts.ts.lock); - err = -EBUSY; - if (dev->ts.users) - goto done; - - dev->ts.started = 0; - dev->ts.users++; - file->private_data = dev; - err = 0; - - done: - up(&dev->ts.ts.lock); - return err; -} - -static int ts_release(struct inode *inode, struct file *file) -{ - struct saa7134_dev *dev = file->private_data; - - if (dev->ts.ts.streaming) - videobuf_streamoff(file->private_data,&dev->ts.ts); - down(&dev->ts.ts.lock); - if (dev->ts.ts.reading) - videobuf_read_stop(file->private_data,&dev->ts.ts); - dev->ts.users--; - - /* stop the encoder */ - if (dev->ts.started) - ts_reset_encoder(dev); - - up(&dev->ts.ts.lock); - return 0; -} - -static ssize_t -ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct saa7134_dev *dev = file->private_data; - - if (!dev->ts.started) { - ts_init_encoder(dev, NULL); - dev->ts.started = 1; - } - - return videobuf_read_stream(file->private_data, - &dev->ts.ts, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static unsigned int -ts_poll(struct file *file, struct poll_table_struct *wait) -{ - struct saa7134_dev *dev = file->private_data; - - return videobuf_poll_stream(file, file->private_data, - &dev->ts.ts, wait); -} - - -static int -ts_mmap(struct file *file, struct vm_area_struct * vma) -{ - struct saa7134_dev *dev = file->private_data; - - return videobuf_mmap_mapper(vma, &dev->ts.ts); -} - -/* - * This function is _not_ called directly, but from - * video_generic_ioctl (and maybe others). userspace - * copying is done already, arg is a kernel pointer. - */ -static int ts_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct saa7134_dev *dev = file->private_data; - - if (ts_debug > 1) - saa7134_print_ioctl(dev->name,cmd); - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap,0,sizeof(*cap)); - strcpy(cap->driver, "saa7134"); - strlcpy(cap->card, saa7134_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); - cap->version = SAA7134_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - return 0; - } - - /* --- input switching --------------------------------------- */ - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - - if (i->index != 0) - return -EINVAL; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name,"CCIR656"); - return 0; - } - case VIDIOC_G_INPUT: - { - int *i = arg; - *i = 0; - return 0; - } - case VIDIOC_S_INPUT: - { - int *i = arg; - - if (*i != 0) - return -EINVAL; - return 0; - } - /* --- capture ioctls ---------------------------------------- */ - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - int index; - - index = f->index; - if (index != 0) - return -EINVAL; - - memset(f,0,sizeof(*f)); - f->index = index; - strlcpy(f->description, "MPEG TS", sizeof(f->description)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->pixelformat = V4L2_PIX_FMT_MPEG; - return 0; - } - - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - - memset(f,0,sizeof(*f)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - /* FIXME: translate subsampling type EMPRESS into - * width/height: */ - f->fmt.pix.width = 720; /* D1 */ - f->fmt.pix.height = 576; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.sizeimage = TS_PACKET_SIZE*ts_nr_packets; - return 0; - } - - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - /* - FIXME: translate and round width/height into EMPRESS - subsample type: - - type | PAL | NTSC - --------------------------- - SIF | 352x288 | 352x240 - 1/2 D1 | 352x576 | 352x480 - 2/3 D1 | 480x576 | 480x480 - D1 | 720x576 | 720x480 - */ - - f->fmt.pix.width = 720; /* D1 */ - f->fmt.pix.height = 576; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.sizeimage = TS_PACKET_SIZE*ts_nr_packets; - return 0; - } - - case VIDIOC_REQBUFS: - return videobuf_reqbufs(file->private_data,&dev->ts.ts,arg); - - case VIDIOC_QUERYBUF: - return videobuf_querybuf(&dev->ts.ts,arg); - - case VIDIOC_QBUF: - return videobuf_qbuf(file->private_data,&dev->ts.ts,arg); - - case VIDIOC_DQBUF: - return videobuf_dqbuf(file->private_data,&dev->ts.ts,arg, - file->f_flags & O_NONBLOCK); - - case VIDIOC_STREAMON: - return videobuf_streamon(file->private_data,&dev->ts.ts); - - case VIDIOC_STREAMOFF: - return videobuf_streamoff(file->private_data,&dev->ts.ts); - - case VIDIOC_QUERYCTRL: - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - return saa7134_common_ioctl(dev, cmd, arg); - - case MPEG_SETPARAMS: - return ts_init_encoder(dev, arg); - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static int ts_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return video_usercopy(inode, file, cmd, arg, ts_do_ioctl); -} - - -static struct file_operations ts_fops = -{ - .owner = THIS_MODULE, - .open = ts_open, - .release = ts_release, - .read = ts_read, - .poll = ts_poll, - .mmap = ts_mmap, - .ioctl = ts_ioctl, - .llseek = no_llseek, -}; - +EXPORT_SYMBOL_GPL(saa7134_ts_qops); /* ----------------------------------------------------------- */ /* exported stuff */ -struct video_device saa7134_ts_template = -{ - .name = "saa7134-ts", - .type = 0 /* FIXME */, - .type2 = 0 /* FIXME */, - .hardware = 0, - .fops = &ts_fops, - .minor = -1, -}; +static unsigned int tsbufs = 4; +MODULE_PARM(tsbufs,"i"); +MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); + +static unsigned int ts_nr_packets = 30; +MODULE_PARM(ts_nr_packets,"i"); +MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); int saa7134_ts_init1(struct saa7134_dev *dev) { @@ -471,6 +183,8 @@ int saa7134_ts_init1(struct saa7134_dev *dev) 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); @@ -478,26 +192,21 @@ int saa7134_ts_init1(struct saa7134_dev *dev) dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); dev->ts_q.dev = dev; dev->ts_q.need_two = 1; - videobuf_queue_init(&dev->ts.ts, &ts_qops, dev->pci, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_ALTERNATE, - sizeof(struct saa7134_buf)); saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); /* init TS hw */ saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* deactivate TS softreset */ saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1)); - saa_writeb(SAA7134_TS_DMA0, ((ts_nr_packets-1)&0xff)); - saa_writeb(SAA7134_TS_DMA1, (((ts_nr_packets-1)>>8)&0xff)); - saa_writeb(SAA7134_TS_DMA2, ((((ts_nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */ + saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff)); + saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff)); + saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */ return 0; } int saa7134_ts_fini(struct saa7134_dev *dev) { - /* nothing */ saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); return 0; } |