]> err.no Git - linux-2.6/blobdiff - drivers/media/video/cx88/cx88-video.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[linux-2.6] / drivers / media / video / cx88 / cx88-video.c
index f94a3b41782afaf9f9a4f6786cd64656bbfb85de..7f1931aed2070a926ac1502a30518cb72c0bb164 100644 (file)
@@ -392,13 +392,41 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
                break;
        }
 
-       if (core->board.mpeg & CX88_MPEG_BLACKBIRD) {
-               /* sets sound input from external adc */
-               if (INPUT(input).extadc)
+       /* if there are audioroutes defined, we have an external
+          ADC to deal with audio */
+
+       if (INPUT(input).audioroute) {
+
+               /* cx2388's C-ADC is connected to the tuner only.
+                  When used with S-Video, that ADC is busy dealing with
+                  chroma, so an external must be used for baseband audio */
+
+               if (INPUT(input).type != CX88_VMUX_TELEVISION &&
+                       INPUT(input).type != CX88_RADIO) {
+                       /* "ADC mode" */
+                       cx_write(AUD_I2SCNTL, 0x1);
                        cx_set(AUD_CTL, EN_I2SIN_ENABLE);
-               else
+               } else {
+                       /* Normal mode */
+                       cx_write(AUD_I2SCNTL, 0x0);
                        cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
+               }
+
+               /* The wm8775 module has the "2" route hardwired into
+                  the initialization. Some boards may use different
+                  routes for different inputs. HVR-1300 surely does */
+               if (core->board.audio_chip &&
+                   core->board.audio_chip == AUDIO_CHIP_WM8775) {
+                       struct v4l2_routing route;
+
+                       route.input = INPUT(input).audioroute;
+                       cx88_call_i2c_clients(core,
+                               VIDIOC_INT_S_AUDIO_ROUTING, &route);
+
+               }
+
        }
+
        return 0;
 }
 EXPORT_SYMBOL(cx88_video_mux);
@@ -466,17 +494,14 @@ static int restart_video_queue(struct cx8800_dev    *dev,
 {
        struct cx88_core *core = dev->core;
        struct cx88_buffer *buf, *prev;
-       struct list_head *item;
 
        if (!list_empty(&q->active)) {
                buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
                dprintk(2,"restart_queue [%p/%d]: restart dma\n",
                        buf, buf->vb.i);
                start_video_dma(dev, q, buf);
-               list_for_each(item,&q->active) {
-                       buf = list_entry(item, struct cx88_buffer, vb.queue);
-                       buf->count    = q->count++;
-               }
+               list_for_each_entry(buf, &q->active, vb.queue)
+                       buf->count = q->count++;
                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
                return 0;
        }
@@ -489,7 +514,7 @@ static int restart_video_queue(struct cx8800_dev    *dev,
                if (NULL == prev) {
                        list_move_tail(&buf->vb.queue, &q->active);
                        start_video_dma(dev, q, buf);
-                       buf->vb.state = STATE_ACTIVE;
+                       buf->vb.state = VIDEOBUF_ACTIVE;
                        buf->count    = q->count++;
                        mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
                        dprintk(2,"[%p/%d] restart_queue - first active\n",
@@ -499,7 +524,7 @@ static int restart_video_queue(struct cx8800_dev    *dev,
                           prev->vb.height == buf->vb.height &&
                           prev->fmt       == buf->fmt) {
                        list_move_tail(&buf->vb.queue, &q->active);
-                       buf->vb.state = STATE_ACTIVE;
+                       buf->vb.state = VIDEOBUF_ACTIVE;
                        buf->count    = q->count++;
                        prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
                        dprintk(2,"[%p/%d] restart_queue - move to active\n",
@@ -534,6 +559,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
        struct cx8800_dev  *dev = fh->dev;
        struct cx88_core *core = dev->core;
        struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        int rc, init_buffer = 0;
 
        BUG_ON(NULL == fh->fmt);
@@ -555,7 +581,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                init_buffer = 1;
        }
 
-       if (STATE_NEEDS_INIT == buf->vb.state) {
+       if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
                init_buffer = 1;
                if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
                        goto fail;
@@ -566,30 +592,30 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                switch (buf->vb.field) {
                case V4L2_FIELD_TOP:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist, 0, UNSET,
+                                        dma->sglist, 0, UNSET,
                                         buf->bpl, 0, buf->vb.height);
                        break;
                case V4L2_FIELD_BOTTOM:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist, UNSET, 0,
+                                        dma->sglist, UNSET, 0,
                                         buf->bpl, 0, buf->vb.height);
                        break;
                case V4L2_FIELD_INTERLACED:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist, 0, buf->bpl,
+                                        dma->sglist, 0, buf->bpl,
                                         buf->bpl, buf->bpl,
                                         buf->vb.height >> 1);
                        break;
                case V4L2_FIELD_SEQ_TB:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         0, buf->bpl * (buf->vb.height >> 1),
                                         buf->bpl, 0,
                                         buf->vb.height >> 1);
                        break;
                case V4L2_FIELD_SEQ_BT:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         buf->bpl * (buf->vb.height >> 1), 0,
                                         buf->bpl, 0,
                                         buf->vb.height >> 1);
@@ -603,7 +629,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                fh->width, fh->height, fh->fmt->depth, fh->fmt->name,
                (unsigned long)buf->risc.dma);
 
-       buf->vb.state = STATE_PREPARED;
+       buf->vb.state = VIDEOBUF_PREPARED;
        return 0;
 
  fail:
@@ -627,14 +653,14 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 
        if (!list_empty(&q->queued)) {
                list_add_tail(&buf->vb.queue,&q->queued);
-               buf->vb.state = STATE_QUEUED;
+               buf->vb.state = VIDEOBUF_QUEUED;
                dprintk(2,"[%p/%d] buffer_queue - append to queued\n",
                        buf, buf->vb.i);
 
        } else if (list_empty(&q->active)) {
                list_add_tail(&buf->vb.queue,&q->active);
                start_video_dma(dev, q, buf);
-               buf->vb.state = STATE_ACTIVE;
+               buf->vb.state = VIDEOBUF_ACTIVE;
                buf->count    = q->count++;
                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
                dprintk(2,"[%p/%d] buffer_queue - first active\n",
@@ -646,7 +672,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
                    prev->vb.height == buf->vb.height &&
                    prev->fmt       == buf->fmt) {
                        list_add_tail(&buf->vb.queue,&q->active);
-                       buf->vb.state = STATE_ACTIVE;
+                       buf->vb.state = VIDEOBUF_ACTIVE;
                        buf->count    = q->count++;
                        prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
                        dprintk(2,"[%p/%d] buffer_queue - append to active\n",
@@ -654,7 +680,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 
                } else {
                        list_add_tail(&buf->vb.queue,&q->queued);
-                       buf->vb.state = STATE_QUEUED;
+                       buf->vb.state = VIDEOBUF_QUEUED;
                        dprintk(2,"[%p/%d] buffer_queue - first queued\n",
                                buf, buf->vb.i);
                }
@@ -712,12 +738,10 @@ static int video_open(struct inode *inode, struct file *file)
        struct cx8800_dev *h,*dev = NULL;
        struct cx88_core *core;
        struct cx8800_fh *fh;
-       struct list_head *list;
        enum v4l2_buf_type type = 0;
        int radio = 0;
 
-       list_for_each(list,&cx8800_devlist) {
-               h = list_entry(list, struct cx8800_dev, devlist);
+       list_for_each_entry(h, &cx8800_devlist, devlist) {
                if (h->video_dev->minor == minor) {
                        dev  = h;
                        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -752,13 +776,13 @@ static int video_open(struct inode *inode, struct file *file)
        fh->height   = 240;
        fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
 
-       videobuf_queue_init(&fh->vidq, &cx8800_video_qops,
+       videobuf_queue_pci_init(&fh->vidq, &cx8800_video_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct cx88_buffer),
                            fh);
-       videobuf_queue_init(&fh->vbiq, &cx8800_vbi_qops,
+       videobuf_queue_pci_init(&fh->vbiq, &cx8800_vbi_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
@@ -826,8 +850,8 @@ video_poll(struct file *file, struct poll_table_struct *wait)
                        return POLLERR;
        }
        poll_wait(file, &buf->vb.done, wait);
-       if (buf->vb.state == STATE_DONE ||
-           buf->vb.state == STATE_ERROR)
+       if (buf->vb.state == VIDEOBUF_DONE ||
+           buf->vb.state == VIDEOBUF_ERROR)
                return POLLIN|POLLRDNORM;
        return 0;
 }
@@ -855,10 +879,7 @@ static int video_release(struct inode *inode, struct file *file)
 
        /* stop vbi capture */
        if (res_check(fh, RESOURCE_VBI)) {
-               if (fh->vbiq.streaming)
-                       videobuf_streamoff(&fh->vbiq);
-               if (fh->vbiq.reading)
-                       videobuf_read_stop(&fh->vbiq);
+               videobuf_stop(&fh->vbiq);
                res_free(dev,fh,RESOURCE_VBI);
        }
 
@@ -1104,28 +1125,9 @@ static int vidioc_enum_fmt_cap (struct file *file, void  *priv,
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
 {
-       struct cx8800_fh           *fh   = priv;
-       struct videobuf_queue      *q;
-       struct v4l2_requestbuffers req;
-       unsigned int i;
-       int err;
+       struct cx8800_fh           *fh  = priv;
 
-       q = get_queue(fh);
-       memset(&req,0,sizeof(req));
-       req.type   = q->type;
-       req.count  = 8;
-       req.memory = V4L2_MEMORY_MMAP;
-       err = videobuf_reqbufs(q,&req);
-       if (err < 0)
-               return err;
-
-       mbuf->frames = req.count;
-       mbuf->size   = 0;
-       for (i = 0; i < mbuf->frames; i++) {
-               mbuf->offsets[i]  = q->bufs[i]->boff;
-               mbuf->size       += q->bufs[i]->bsize;
-       }
-       return 0;
+       return videobuf_cgmbuf (get_queue(fh), mbuf, 8);
 }
 #endif
 
@@ -1522,7 +1524,7 @@ static void cx8800_vid_timeout(unsigned long data)
        while (!list_empty(&q->active)) {
                buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
                list_del(&buf->vb.queue);
-               buf->vb.state = STATE_ERROR;
+               buf->vb.state = VIDEOBUF_ERROR;
                wake_up(&buf->vb.done);
                printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name,
                       buf, buf->vb.i, (unsigned long)buf->risc.dma);
@@ -1698,7 +1700,6 @@ static struct video_device cx8800_radio_template =
 {
        .name                 = "cx8800-radio",
        .type                 = VID_TYPE_TUNER,
-       .hardware             = 0,
        .fops                 = &radio_fops,
        .minor                = -1,
        .vidioc_querycap      = radio_querycap,
@@ -1954,6 +1955,8 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
        }
        spin_unlock(&dev->slock);
 
+       if (core->ir)
+               cx88_ir_stop(core, core->ir);
        /* FIXME -- shutdown device */
        cx88_shutdown(core);
 
@@ -1993,6 +1996,10 @@ static int cx8800_resume(struct pci_dev *pci_dev)
 
        /* FIXME: re-initialize hardware */
        cx88_reset(core);
+       if (core->ir)
+               cx88_ir_start(core, core->ir);
+
+       cx_set(MO_PCI_INTMSK, core->pci_irqmask);
 
        /* restart video+vbi capture */
        spin_lock(&dev->slock);