Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / drivers / media / video / em28xx / em28xx-video.c
index 5352753..575472f 100644 (file)
@@ -186,7 +186,8 @@ static void em28xx_copy_video(struct em28xx *dev,
                em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
                               ((char *)startwrite + lencopy) -
                               ((char *)outp + buf->vb.size));
-               lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
+               remain = (char *)outp + buf->vb.size - (char *)startwrite;
+               lencopy = remain;
        }
        if (lencopy <= 0)
                return;
@@ -202,7 +203,8 @@ static void em28xx_copy_video(struct em28xx *dev,
                else
                        lencopy = bytesperline;
 
-               if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+               if ((char *)startwrite + lencopy > (char *)outp +
+                   buf->vb.size) {
                        em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
                                       ((char *)startwrite + lencopy) -
                                       ((char *)outp + buf->vb.size));
@@ -347,7 +349,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
                }
                if (p[0] == 0x22 && p[1] == 0x5a) {
                        em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
-                                      len, (p[2] & 1)? "odd" : "even");
+                                      len, (p[2] & 1) ? "odd" : "even");
 
                        if (!(p[2] & 1)) {
                                if (buf != NULL)
@@ -476,7 +478,9 @@ fail:
 static void
 buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 {
-       struct em28xx_buffer    *buf     = container_of(vb, struct em28xx_buffer, vb);
+       struct em28xx_buffer    *buf     = container_of(vb,
+                                                       struct em28xx_buffer,
+                                                       vb);
        struct em28xx_fh        *fh      = vq->priv_data;
        struct em28xx           *dev     = fh->dev;
        struct em28xx_dmaqueue  *vidq    = &dev->vidq;
@@ -489,7 +493,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 static void buffer_release(struct videobuf_queue *vq,
                                struct videobuf_buffer *vb)
 {
-       struct em28xx_buffer   *buf  = container_of(vb, struct em28xx_buffer, vb);
+       struct em28xx_buffer   *buf  = container_of(vb,
+                                                   struct em28xx_buffer,
+                                                   vb);
        struct em28xx_fh       *fh   = vq->priv_data;
        struct em28xx          *dev  = (struct em28xx *)fh->dev;
 
@@ -534,6 +540,13 @@ static void video_mux(struct em28xx *dev, int index)
                        &route);
        }
 
+       if (dev->board.adecoder != EM28XX_NOADECODER) {
+               route.input = dev->ctl_ainput;
+               route.output = dev->ctl_aoutput;
+               em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
+                       &route);
+       }
+
        em28xx_audio_analog_set(dev);
 }
 
@@ -557,7 +570,7 @@ static int res_get(struct em28xx_fh *fh)
 
 static int res_check(struct em28xx_fh *fh)
 {
-       return (fh->stream_on);
+       return fh->stream_on;
 }
 
 static void res_free(struct em28xx_fh *fh)
@@ -791,7 +804,7 @@ out:
        return rc;
 }
 
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
        struct em28xx_fh   *fh  = priv;
        struct em28xx      *dev = fh->dev;
@@ -886,10 +899,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
        if (0 == INPUT(i)->type)
                return -EINVAL;
 
-       mutex_lock(&dev->lock);
-
-       video_mux(dev, i);
+       dev->ctl_input = i;
 
+       mutex_lock(&dev->lock);
+       video_mux(dev, dev->ctl_input);
        mutex_unlock(&dev->lock);
        return 0;
 }
@@ -939,6 +952,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
        struct em28xx_fh   *fh  = priv;
        struct em28xx      *dev = fh->dev;
 
+
+       if (a->index >= MAX_EM28XX_INPUT)
+               return -EINVAL;
+       if (0 == INPUT(a->index)->type)
+               return -EINVAL;
+
        mutex_lock(&dev->lock);
 
        dev->ctl_ainput = INPUT(a->index)->amux;
@@ -1002,8 +1021,13 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
 
        if (dev->board.has_msp34xx)
                em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
-       else
+       else {
                rc = em28xx_get_ctrl(dev, ctrl);
+               if (rc < 0) {
+                       em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+                       rc = 0;
+               }
+       }
 
        mutex_unlock(&dev->lock);
        return rc;
@@ -1154,7 +1178,7 @@ static int em28xx_reg_len(int reg)
 }
 
 static int vidioc_g_chip_ident(struct file *file, void *priv,
-              struct v4l2_chip_ident *chip)
+              struct v4l2_dbg_chip_ident *chip)
 {
        struct em28xx_fh      *fh  = priv;
        struct em28xx         *dev = fh->dev;
@@ -1162,20 +1186,20 @@ static int vidioc_g_chip_ident(struct file *file, void *priv,
        chip->ident = V4L2_IDENT_NONE;
        chip->revision = 0;
 
-       em28xx_i2c_call_clients(dev, VIDIOC_G_CHIP_IDENT, chip);
+       em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
 
        return 0;
 }
 
 
 static int vidioc_g_register(struct file *file, void *priv,
-                            struct v4l2_register *reg)
+                            struct v4l2_dbg_register *reg)
 {
        struct em28xx_fh      *fh  = priv;
        struct em28xx         *dev = fh->dev;
        int ret;
 
-       switch (reg->match_type) {
+       switch (reg->match.type) {
        case V4L2_CHIP_MATCH_AC97:
                mutex_lock(&dev->lock);
                ret = em28xx_read_ac97(dev, reg->reg);
@@ -1184,6 +1208,7 @@ static int vidioc_g_register(struct file *file, void *priv,
                        return ret;
 
                reg->val = ret;
+               reg->size = 1;
                return 0;
        case V4L2_CHIP_MATCH_I2C_DRIVER:
                em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
@@ -1192,12 +1217,13 @@ static int vidioc_g_register(struct file *file, void *priv,
                /* Not supported yet */
                return -EINVAL;
        default:
-               if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+               if (!v4l2_chip_match_host(&reg->match))
                        return -EINVAL;
        }
 
        /* Match host */
-       if (em28xx_reg_len(reg->reg) == 1) {
+       reg->size = em28xx_reg_len(reg->reg);
+       if (reg->size == 1) {
                mutex_lock(&dev->lock);
                ret = em28xx_read_reg(dev, reg->reg);
                mutex_unlock(&dev->lock);
@@ -1207,7 +1233,7 @@ static int vidioc_g_register(struct file *file, void *priv,
 
                reg->val = ret;
        } else {
-               __le64 val = 0;
+               __le16 val = 0;
                mutex_lock(&dev->lock);
                ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
                                                   reg->reg, (char *)&val, 2);
@@ -1215,21 +1241,21 @@ static int vidioc_g_register(struct file *file, void *priv,
                if (ret < 0)
                        return ret;
 
-               reg->val = le64_to_cpu(val);
+               reg->val = le16_to_cpu(val);
        }
 
        return 0;
 }
 
 static int vidioc_s_register(struct file *file, void *priv,
-                            struct v4l2_register *reg)
+                            struct v4l2_dbg_register *reg)
 {
        struct em28xx_fh      *fh  = priv;
        struct em28xx         *dev = fh->dev;
-       __le64 buf;
+       __le16 buf;
        int    rc;
 
-       switch (reg->match_type) {
+       switch (reg->match.type) {
        case V4L2_CHIP_MATCH_AC97:
                mutex_lock(&dev->lock);
                rc = em28xx_write_ac97(dev, reg->reg, reg->val);
@@ -1243,12 +1269,12 @@ static int vidioc_s_register(struct file *file, void *priv,
                /* Not supported yet */
                return -EINVAL;
        default:
-               if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+               if (!v4l2_chip_match_host(&reg->match))
                        return -EINVAL;
        }
 
        /* Match host */
-       buf = cpu_to_le64(reg->val);
+       buf = cpu_to_le16(reg->val);
 
        mutex_lock(&dev->lock);
        rc = em28xx_write_regs(dev, reg->reg, (char *)&buf,
@@ -1337,7 +1363,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
 
        strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
        strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
-       strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+       usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
        cap->version = EM28XX_VERSION_CODE;
 
@@ -1423,7 +1449,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
        if (rc < 0)
                return rc;
 
-       return (videobuf_reqbufs(&fh->vb_vidq, rb));
+       return videobuf_reqbufs(&fh->vb_vidq, rb);
 }
 
 static int vidioc_querybuf(struct file *file, void *priv,
@@ -1437,7 +1463,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
        if (rc < 0)
                return rc;
 
-       return (videobuf_querybuf(&fh->vb_vidq, b));
+       return videobuf_querybuf(&fh->vb_vidq, b);
 }
 
 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1450,7 +1476,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
        if (rc < 0)
                return rc;
 
-       return (videobuf_qbuf(&fh->vb_vidq, b));
+       return videobuf_qbuf(&fh->vb_vidq, b);
 }
 
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1463,8 +1489,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
        if (rc < 0)
                return rc;
 
-       return (videobuf_dqbuf(&fh->vb_vidq, b,
-                               file->f_flags & O_NONBLOCK));
+       return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
 }
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1488,7 +1513,7 @@ static int radio_querycap(struct file *file, void  *priv,
 
        strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
        strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
-       strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+       usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
        cap->version = EM28XX_VERSION_CODE;
        cap->capabilities = V4L2_CAP_TUNER;
@@ -1582,15 +1607,15 @@ static int radio_queryctrl(struct file *file, void *priv,
  * em28xx_v4l2_open()
  * inits the device and starts isoc transfer
  */
-static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
+static int em28xx_v4l2_open(struct file *filp)
 {
-       int minor = iminor(inode);
+       int minor = video_devdata(filp)->minor;
        int errCode = 0, radio;
        struct em28xx *dev;
        enum v4l2_buf_type fh_type;
        struct em28xx_fh *fh;
 
-       dev = em28xx_get_device(inode, &fh_type, &radio);
+       dev = em28xx_get_device(minor, &fh_type, &radio);
 
        if (NULL == dev)
                return -ENODEV;
@@ -1686,7 +1711,7 @@ void em28xx_release_analog_resources(struct em28xx *dev)
  * stops streaming and deallocates all resources allocated by the v4l2
  * calls and ioctls
  */
-static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
+static int em28xx_v4l2_close(struct file *filp)
 {
        struct em28xx_fh *fh  = filp->private_data;
        struct em28xx    *dev = fh->dev;
@@ -1773,7 +1798,7 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
  * em28xx_v4l2_poll()
  * will allocate buffers when called for the first time
  */
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
 {
        struct em28xx_fh *fh = filp->private_data;
        struct em28xx *dev = fh->dev;
@@ -1826,7 +1851,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
        return rc;
 }
 
-static const struct file_operations em28xx_v4l_fops = {
+static const struct v4l2_file_operations em28xx_v4l_fops = {
        .owner         = THIS_MODULE,
        .open          = em28xx_v4l2_open,
        .release       = em28xx_v4l2_close,
@@ -1834,8 +1859,6 @@ static const struct file_operations em28xx_v4l_fops = {
        .poll          = em28xx_v4l2_poll,
        .mmap          = em28xx_v4l2_mmap,
        .ioctl         = video_ioctl2,
-       .llseek        = no_llseek,
-       .compat_ioctl  = v4l_compat_ioctl32,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1890,13 +1913,11 @@ static const struct video_device em28xx_video_template = {
        .current_norm               = V4L2_STD_PAL,
 };
 
-static const struct file_operations radio_fops = {
+static const struct v4l2_file_operations radio_fops = {
        .owner         = THIS_MODULE,
        .open          = em28xx_v4l2_open,
        .release       = em28xx_v4l2_close,
        .ioctl         = video_ioctl2,
-       .compat_ioctl  = v4l_compat_ioctl32,
-       .llseek        = no_llseek,
 };
 
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {
@@ -1930,8 +1951,8 @@ static struct video_device em28xx_radio_template = {
 
 
 static struct video_device *em28xx_vdev_init(struct em28xx *dev,
-                                            const struct video_device *template,
-                                            const char *type_name)
+                                       const struct video_device *template,
+                                       const char *type_name)
 {
        struct video_device *vfd;
 
@@ -1952,6 +1973,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 
 int em28xx_register_analog_devices(struct em28xx *dev)
 {
+      u8 val;
        int ret;
 
        printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
@@ -1959,34 +1981,35 @@ int em28xx_register_analog_devices(struct em28xx *dev)
                (EM28XX_VERSION_CODE >> 16) & 0xff,
                (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
 
+       /* set default norm */
+       dev->norm = em28xx_video_template.current_norm;
+       dev->width = norm_maxw(dev);
+       dev->height = norm_maxh(dev);
+       dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+       dev->hscale = 0;
+       dev->vscale = 0;
+       dev->ctl_input = 0;
+
        /* Analog specific initialization */
        dev->format = &format[0];
-       video_mux(dev, 0);
+       video_mux(dev, dev->ctl_input);
+
+       /* Audio defaults */
+       dev->mute = 1;
+       dev->volume = 0x1f;
 
        /* enable vbi capturing */
 
 /*     em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
-/*     em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
+       val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+       em28xx_write_reg(dev, EM28XX_R0F_XCLK,
+                        (EM28XX_XCLK_AUDIO_UNMUTE | val));
        em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
-       dev->mute = 1;          /* maybe not the right place... */
-       dev->volume = 0x1f;
-
        em28xx_set_outfmt(dev);
        em28xx_colorlevels_set_default(dev);
        em28xx_compression_disable(dev);
 
-       /* set default norm */
-       dev->norm = em28xx_video_template.current_norm;
-       dev->width = norm_maxw(dev);
-       dev->height = norm_maxh(dev);
-       dev->interlaced = EM28XX_INTERLACED_DEFAULT;
-       dev->hscale = 0;
-       dev->vscale = 0;
-
-       /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
-       dev->ctl_input = 2;
-
        /* allocate and fill video video_device struct */
        dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
        if (!dev->vdev) {
@@ -2015,7 +2038,8 @@ int em28xx_register_analog_devices(struct em28xx *dev)
        }
 
        if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
-               dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
+               dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
+                                                 "radio");
                if (!dev->radio_dev) {
                        em28xx_errdev("cannot allocate video_device.\n");
                        return -ENODEV;