]> Pileus Git - ~andy/linux/blobdiff - drivers/media/video/em28xx/em28xx-video.c
V4L/DVB (9758): em28xx: replace some magic by register descriptions where known
[~andy/linux] / drivers / media / video / em28xx / em28xx-video.c
index a1ab2ef45578d491ea9951ef1ddfe933b85294fb..87e9f1d7a95889e58ef095b3f1555588579c1f97 100644 (file)
@@ -73,6 +73,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 static LIST_HEAD(em28xx_devlist);
+static DEFINE_MUTEX(em28xx_devlist_mutex);
 
 static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
 static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
@@ -516,8 +517,8 @@ static int em28xx_config(struct em28xx *dev)
        int retval;
 
        /* Sets I2C speed to 100 KHz */
-       if (!dev->is_em2800) {
-               retval = em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
+       if (!dev->board.is_em2800) {
+               retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
                if (retval < 0) {
                        em28xx_errdev("%s: em28xx_write_regs_req failed! retval [%d]\n",
                                __func__, retval);
@@ -527,9 +528,9 @@ static int em28xx_config(struct em28xx *dev)
 
        /* enable vbi capturing */
 
-/*     em28xx_write_regs_req(dev, 0x00, 0x0e, "\xC0", 1); audio register */
-/*     em28xx_write_regs_req(dev, 0x00, 0x0f, "\x80", 1); clk register */
-       em28xx_write_regs_req(dev, 0x00, 0x11, "\x51", 1);
+/*     em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
+/*     em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
+       em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
        dev->mute = 1;          /* maybe not the right place... */
        dev->volume = 0x1f;
@@ -548,10 +549,11 @@ static int em28xx_config(struct em28xx *dev)
 static void em28xx_config_i2c(struct em28xx *dev)
 {
        struct v4l2_routing route;
+       int zero = 0;
 
        route.input = INPUT(dev->ctl_input)->vmux;
        route.output = 0;
-       em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL);
+       em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
        em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
        em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
 }
@@ -564,10 +566,14 @@ static void video_mux(struct em28xx *dev, int index)
        route.output = 0;
        dev->ctl_input = index;
        dev->ctl_ainput = INPUT(index)->amux;
+       dev->ctl_aoutput = INPUT(index)->aout;
+
+       if (!dev->ctl_aoutput)
+               dev->ctl_aoutput = EM28XX_AOUT_MASTER;
 
        em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
 
-       if (dev->has_msp34xx) {
+       if (dev->board.has_msp34xx) {
                if (dev->i2s_speed) {
                        em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
                                &dev->i2s_speed);
@@ -741,7 +747,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 
        mutex_lock(&dev->lock);
 
-       if (dev->is_em2800) {
+       if (dev->board.is_em2800) {
                /* the em2800 can only scale down to 50% */
                if (height % (maxh / 2))
                        height = maxh;
@@ -926,20 +932,38 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
 {
        struct em28xx_fh   *fh    = priv;
        struct em28xx      *dev   = fh->dev;
-       unsigned int        index = a->index;
-
-       if (a->index > 1)
-               return -EINVAL;
 
-       index = dev->ctl_ainput;
-
-       if (index == 0)
+       switch (a->index) {
+       case EM28XX_AMUX_VIDEO:
                strcpy(a->name, "Television");
-       else
+               break;
+       case EM28XX_AMUX_LINE_IN:
                strcpy(a->name, "Line In");
+               break;
+       case EM28XX_AMUX_VIDEO2:
+               strcpy(a->name, "Television alt");
+               break;
+       case EM28XX_AMUX_PHONE:
+               strcpy(a->name, "Phone");
+               break;
+       case EM28XX_AMUX_MIC:
+               strcpy(a->name, "Mic");
+               break;
+       case EM28XX_AMUX_CD:
+               strcpy(a->name, "CD");
+               break;
+       case EM28XX_AMUX_AUX:
+               strcpy(a->name, "Aux");
+               break;
+       case EM28XX_AMUX_PCM_OUT:
+               strcpy(a->name, "PCM");
+               break;
+       default:
+               return -EINVAL;
+       }
 
+       a->index = dev->ctl_ainput;
        a->capability = V4L2_AUDCAP_STEREO;
-       a->index = index;
 
        return 0;
 }
@@ -949,9 +973,11 @@ 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 != dev->ctl_ainput)
-               return -EINVAL;
+       dev->ctl_ainput = INPUT(a->index)->amux;
+       dev->ctl_aoutput = INPUT(a->index)->aout;
 
+       if (!dev->ctl_aoutput)
+               dev->ctl_aoutput = EM28XX_AOUT_MASTER;
        return 0;
 }
 
@@ -972,7 +998,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 
        qc->id = id;
 
-       if (!dev->has_msp34xx) {
+       if (!dev->board.has_msp34xx) {
                for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
                        if (qc->id && qc->id == em28xx_qctrl[i].id) {
                                memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
@@ -1002,7 +1028,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
                return rc;
        mutex_lock(&dev->lock);
 
-       if (!dev->has_msp34xx)
+       if (!dev->board.has_msp34xx)
                rc = em28xx_get_ctrl(dev, ctrl);
        else
                rc = -EINVAL;
@@ -1030,7 +1056,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
        mutex_lock(&dev->lock);
 
-       if (dev->has_msp34xx)
+       if (dev->board.has_msp34xx)
                em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
        else {
                rc = 1;
@@ -1269,7 +1295,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->udev->dev.bus_id, sizeof(cap->bus_info));
+       strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
 
        cap->version = EM28XX_VERSION_CODE;
 
@@ -1422,7 +1448,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->udev->dev.bus_id, sizeof(cap->bus_info));
+       strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
 
        cap->version = EM28XX_VERSION_CODE;
        cap->capabilities = V4L2_CAP_TUNER;
@@ -1519,7 +1545,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
        struct em28xx_fh *fh;
        enum v4l2_buf_type fh_type = 0;
 
-       lock_kernel();
+       mutex_lock(&em28xx_devlist_mutex);
        list_for_each_entry(h, &em28xx_devlist, devlist) {
                if (h->vdev->minor == minor) {
                        dev  = h;
@@ -1535,10 +1561,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
                        dev   = h;
                }
        }
-       if (NULL == dev) {
-               unlock_kernel();
+       mutex_unlock(&em28xx_devlist_mutex);
+       if (NULL == dev)
                return -ENODEV;
-       }
+
+       mutex_lock(&dev->lock);
 
        em28xx_videodbg("open minor=%d type=%s users=%d\n",
                                minor, v4l2_type_names[fh_type], dev->users);
@@ -1547,10 +1574,9 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
        fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
        if (!fh) {
                em28xx_errdev("em28xx-video.c: Out of memory?!\n");
-               unlock_kernel();
+               mutex_unlock(&dev->lock);
                return -ENOMEM;
        }
-       mutex_lock(&dev->lock);
        fh->dev = dev;
        fh->radio = radio;
        fh->type = fh_type;
@@ -1584,7 +1610,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
                        sizeof(struct em28xx_buffer), fh);
 
        mutex_unlock(&dev->lock);
-       unlock_kernel();
 
        return errCode;
 }
@@ -1599,11 +1624,13 @@ static void em28xx_release_resources(struct em28xx *dev)
 
        /*FIXME: I2C IR should be disconnected */
 
-       em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n",
-                               dev->vdev->num, dev->vbi_dev->num);
        list_del(&dev->devlist);
        if (dev->sbutton_input_dev)
                em28xx_deregister_snapshot_button(dev);
+
+       if (dev->ir)
+               em28xx_ir_fini(dev);
+
        if (dev->radio_dev) {
                if (-1 != dev->radio_dev->minor)
                        video_unregister_device(dev->radio_dev);
@@ -1612,6 +1639,8 @@ static void em28xx_release_resources(struct em28xx *dev)
                dev->radio_dev = NULL;
        }
        if (dev->vbi_dev) {
+               em28xx_info("V4L2 device /dev/vbi%d deregistered\n",
+                           dev->vbi_dev->num);
                if (-1 != dev->vbi_dev->minor)
                        video_unregister_device(dev->vbi_dev);
                else
@@ -1619,6 +1648,8 @@ static void em28xx_release_resources(struct em28xx *dev)
                dev->vbi_dev = NULL;
        }
        if (dev->vdev) {
+               em28xx_info("V4L2 device /dev/video%d deregistered\n",
+                           dev->vdev->num);
                if (-1 != dev->vdev->minor)
                        video_unregister_device(dev->vdev);
                else
@@ -1871,6 +1902,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
 {
        struct em28xx *dev = NULL;
 
+       mutex_lock(&em28xx_devlist_mutex);
        mutex_lock(&em28xx_extension_devlist_lock);
        list_add_tail(&ops->next, &em28xx_extension_devlist);
        list_for_each_entry(dev, &em28xx_devlist, devlist) {
@@ -1879,6 +1911,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
        }
        printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
        mutex_unlock(&em28xx_extension_devlist_lock);
+       mutex_unlock(&em28xx_devlist_mutex);
        return 0;
 }
 EXPORT_SYMBOL(em28xx_register_extension);
@@ -1887,6 +1920,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
 {
        struct em28xx *dev = NULL;
 
+       mutex_lock(&em28xx_devlist_mutex);
        list_for_each_entry(dev, &em28xx_devlist, devlist) {
                if (dev)
                        ops->fini(dev);
@@ -1896,6 +1930,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
        printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
        list_del(&ops->next);
        mutex_unlock(&em28xx_extension_devlist_lock);
+       mutex_unlock(&em28xx_devlist_mutex);
 }
 EXPORT_SYMBOL(em28xx_unregister_extension);
 
@@ -1920,6 +1955,59 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
        return vfd;
 }
 
+static int register_analog_devices(struct em28xx *dev)
+{
+       int ret;
+
+       /* allocate and fill video video_device struct */
+       dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
+       if (!dev->vdev) {
+               em28xx_errdev("cannot allocate video_device.\n");
+               return -ENODEV;
+       }
+
+       /* register v4l2 video video_device */
+       ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
+                                      video_nr[dev->devno]);
+       if (ret) {
+               em28xx_errdev("unable to register video device (error=%i).\n",
+                             ret);
+               return ret;
+       }
+
+       /* Allocate and fill vbi video_device struct */
+       dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
+
+       /* register v4l2 vbi video_device */
+       ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
+                                       vbi_nr[dev->devno]);
+       if (ret < 0) {
+               em28xx_errdev("unable to register vbi device\n");
+               return ret;
+       }
+
+       if (em28xx_boards[dev->model].radio.type == EM28XX_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;
+               }
+               ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
+                                           radio_nr[dev->devno]);
+               if (ret < 0) {
+                       em28xx_errdev("can't register radio device\n");
+                       return ret;
+               }
+               em28xx_info("Registered radio device as /dev/radio%d\n",
+                           dev->radio_dev->num);
+       }
+
+       em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
+                               dev->vdev->num, dev->vbi_dev->num);
+
+       return 0;
+}
+
 
 /*
  * em28xx_init_dev()
@@ -1936,6 +2024,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 
        dev->udev = udev;
        mutex_init(&dev->lock);
+       mutex_init(&dev->ctrl_urb_lock);
        spin_lock_init(&dev->slock);
        init_waitqueue_head(&dev->open);
        init_waitqueue_head(&dev->wait_frame);
@@ -1946,15 +2035,13 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
        dev->em28xx_write_regs_req = em28xx_write_regs_req;
        dev->em28xx_read_reg_req = em28xx_read_reg_req;
-       dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
+       dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
 
        em28xx_pre_card_setup(dev);
 
        errCode = em28xx_config(dev);
        if (errCode) {
                em28xx_errdev("error configuring device\n");
-               em28xx_devused &= ~(1<<dev->devno);
-               kfree(dev);
                return -ENOMEM;
        }
 
@@ -1970,11 +2057,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        em28xx_card_setup(dev);
 
        /* Configure audio */
-       errCode = em28xx_audio_analog_set(dev);
+       errCode = em28xx_audio_setup(dev);
        if (errCode < 0) {
-               em28xx_errdev("%s: em28xx_audio_analog_set - errCode [%d]!\n",
+               em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
                        __func__, errCode);
-               return errCode;
        }
 
        /* configure the device */
@@ -2001,58 +2087,14 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                return errCode;
        }
 
-       list_add_tail(&dev->devlist, &em28xx_devlist);
-
-       /* allocate and fill video video_device struct */
-       dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
-       if (NULL == dev->vdev) {
-               em28xx_errdev("cannot allocate video_device.\n");
-               goto fail_unreg;
-       }
-
-       /* register v4l2 video video_device */
-       retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
-                                      video_nr[dev->devno]);
-       if (retval) {
-               em28xx_errdev("unable to register video device (error=%i).\n",
-                             retval);
-               goto fail_unreg;
-       }
-
-       /* Allocate and fill vbi video_device struct */
-       dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
-       /* register v4l2 vbi video_device */
-       if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
-                                       vbi_nr[dev->devno]) < 0) {
-               em28xx_errdev("unable to register vbi device\n");
-               retval = -ENODEV;
-               goto fail_unreg;
-       }
-
-       if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
-               dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
-               if (NULL == dev->radio_dev) {
-                       em28xx_errdev("cannot allocate video_device.\n");
-                       goto fail_unreg;
-               }
-               retval = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
-                                           radio_nr[dev->devno]);
-               if (retval < 0) {
-                       em28xx_errdev("can't register radio device\n");
-                       goto fail_unreg;
-               }
-               em28xx_info("Registered radio device as /dev/radio%d\n",
-                           dev->radio_dev->num);
-       }
-
        /* init video dma queues */
        INIT_LIST_HEAD(&dev->vidq.active);
        INIT_LIST_HEAD(&dev->vidq.queued);
 
 
-       if (dev->has_msp34xx) {
+       if (dev->board.has_msp34xx) {
                /* Send a reset to other chips via gpio */
-               errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
+               errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
                if (errCode < 0) {
                        em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(1) failed! errCode [%d]\n",
                                __func__, errCode);
@@ -2060,7 +2102,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                }
                msleep(3);
 
-               errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
+               errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
                if (errCode < 0) {
                        em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(2) failed! errCode [%d]\n",
                                __func__, errCode);
@@ -2071,8 +2113,14 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 
        video_mux(dev, 0);
 
-       em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
-                               dev->vdev->num, dev->vbi_dev->num);
+       mutex_lock(&em28xx_devlist_mutex);
+       list_add_tail(&dev->devlist, &em28xx_devlist);
+       retval = register_analog_devices(dev);
+       if (retval < 0) {
+               em28xx_release_resources(dev);
+               mutex_unlock(&em28xx_devlist_mutex);
+               goto fail_reg_devices;
+       }
 
        mutex_lock(&em28xx_extension_devlist_lock);
        if (!list_empty(&em28xx_extension_devlist)) {
@@ -2082,13 +2130,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                }
        }
        mutex_unlock(&em28xx_extension_devlist_lock);
+       mutex_unlock(&em28xx_devlist_mutex);
 
        return 0;
 
-fail_unreg:
-       em28xx_release_resources(dev);
+fail_reg_devices:
        mutex_unlock(&dev->lock);
-       kfree(dev);
        return retval;
 }
 
@@ -2100,10 +2147,10 @@ static void request_module_async(struct work_struct *work)
 
        if (dev->has_audio_class)
                request_module("snd-usb-audio");
-       else
+       else if (dev->has_alsa_audio)
                request_module("em28xx-alsa");
 
-       if (dev->has_dvb)
+       if (dev->board.has_dvb)
                request_module("em28xx-dvb");
 }
 
@@ -2128,7 +2175,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        struct usb_interface *uif;
        struct em28xx *dev = NULL;
        int retval = -ENODEV;
-       int i, nr, ifnum;
+       int i, nr, ifnum, isoc_pipe;
 
        udev = usb_get_dev(interface_to_usbdev(interface));
        ifnum = interface->altsetting[0].desc.bInterfaceNumber;
@@ -2149,27 +2196,49 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
+       endpoint = &interface->cur_altsetting->endpoint[0].desc;
+
+       /* check if the device has the iso in endpoint at the correct place */
+       if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+           USB_ENDPOINT_XFER_ISOC &&
+           (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940))
+       {
+               /* It's a newer em2874/em2875 device */
+               isoc_pipe = 0;
+       } else {
+               int check_interface = 1;
+               isoc_pipe = 1;
+               endpoint = &interface->cur_altsetting->endpoint[1].desc;
+               if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+                   USB_ENDPOINT_XFER_ISOC)
+                       check_interface = 0;
+
+               if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
+                       check_interface = 0;
+
+               if (!check_interface) {
+                       em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
+                               "interface %i, class %i found.\n",
+                               udev->descriptor.idVendor,
+                               udev->descriptor.idProduct,
+                               ifnum,
+                               interface->altsetting[0].desc.bInterfaceClass);
+
+                       em28xx_err(DRIVER_NAME " This is an anciliary "
+                               "interface not used by the driver\n");
+
+                       em28xx_devused &= ~(1<<nr);
+                       return -ENODEV;
+               }
+
+       }
+
        em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
                        udev->descriptor.idVendor,
                        udev->descriptor.idProduct,
                        ifnum,
                        interface->altsetting[0].desc.bInterfaceClass);
 
-       endpoint = &interface->cur_altsetting->endpoint[1].desc;
-
-       /* check if the device has the iso in endpoint at the correct place */
-       if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
-           USB_ENDPOINT_XFER_ISOC) {
-               em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
-               em28xx_devused &= ~(1<<nr);
-               return -ENODEV;
-       }
-       if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
-               em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
-               em28xx_devused &= ~(1<<nr);
-               return -ENODEV;
-       }
-
        if (nr >= EM28XX_MAXBOARDS) {
                printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
                                EM28XX_MAXBOARDS);
@@ -2199,14 +2268,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                }
        }
 
-       printk(KERN_INFO DRIVER_NAME " %s usb audio class\n",
-                  dev->has_audio_class ? "Has" : "Doesn't have");
-
        /* compute alternate max packet sizes */
        uif = udev->actconfig->interface[0];
 
        dev->num_alt = uif->num_altsetting;
-       em28xx_info("Alternate settings: %i\n", dev->num_alt);
+       em28xx_videodbg("Alternate settings: %i\n", dev->num_alt);
 /*     dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */
        dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
 
@@ -2218,11 +2284,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        }
 
        for (i = 0; i < dev->num_alt ; i++) {
-               u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+               u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
                                                        wMaxPacketSize);
                dev->alt_max_pkt_size[i] =
                    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
-               em28xx_info("Alternate setting %i, max size= %i\n", i,
+               em28xx_videodbg("Alternate setting %i, max size= %i\n", i,
                                                dev->alt_max_pkt_size[i]);
        }
 
@@ -2231,10 +2297,12 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 
        /* allocate device struct */
        retval = em28xx_init_dev(&dev, udev, nr);
-       if (retval)
-               return retval;
+       if (retval) {
+               em28xx_devused &= ~(1<<dev->devno);
+               kfree(dev);
 
-       em28xx_info("Found %s\n", em28xx_boards[dev->model].name);
+               return retval;
+       }
 
        /* save our data pointer in this interface device */
        usb_set_intfdata(interface, dev);