[media] em28xx: Mark Kworld 305 as validated
[sfrench/cifs-2.6.git] / drivers / media / video / em28xx / em28xx-cards.c
index 4e37375decf54dbdea4e3c9617fcf52b9201912f..c892a1e4ad85e05f71792c912467fd5ca592464f 100644 (file)
@@ -289,7 +289,7 @@ static struct em28xx_reg_seq leadership_reset[] = {
        {       -1,             -1,     -1,     -1},
 };
 
-/* 2013:024f PCTV Systems nanoStick T2 290e
+/* 2013:024f PCTV nanoStick T2 290e
  * GPIO_6 - demod reset
  * GPIO_7 - LED
  */
@@ -1259,7 +1259,7 @@ struct em28xx_board em28xx_boards[] = {
                } },
        },
 
-       [EM2874_LEADERSHIP_ISDBT] = {
+       [EM2874_BOARD_LEADERSHIP_ISDBT] = {
                .i2c_speed      = EM2874_I2C_SECONDARY_BUS_SELECT |
                                  EM28XX_I2C_CLK_WAIT_ENABLE |
                                  EM28XX_I2C_FREQ_100_KHZ,
@@ -1319,7 +1319,6 @@ struct em28xx_board em28xx_boards[] = {
        },
        [EM2880_BOARD_KWORLD_DVB_305U] = {
                .name         = "KWorld DVB-T 305U",
-               .valid        = EM28XX_BOARD_NOT_VALIDATED,
                .tuner_type   = TUNER_XC2028,
                .tuner_gpio   = default_tuner_gpio,
                .decoder      = EM28XX_TVP5150,
@@ -1770,16 +1769,16 @@ struct em28xx_board em28xx_boards[] = {
                .dvb_gpio   = kworld_a340_digital,
                .tuner_gpio = default_tuner_gpio,
        },
-       /* 2013:024f PCTV Systems nanoStick T2 290e.
+       /* 2013:024f PCTV nanoStick T2 290e.
         * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */
        [EM28174_BOARD_PCTV_290E] = {
+               .name          = "PCTV nanoStick T2 290e",
                .i2c_speed      = EM2874_I2C_SECONDARY_BUS_SELECT |
                        EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
-               .xclk          = EM28XX_XCLK_FREQUENCY_12MHZ,
-               .name          = "PCTV Systems nanoStick T2 290e",
                .tuner_type    = TUNER_ABSENT,
                .tuner_gpio    = pctv_290e,
                .has_dvb       = 1,
+               .ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
        },
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
@@ -1937,7 +1936,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
        {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
        {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
        {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
-       {0x6b800080, EM2874_LEADERSHIP_ISDBT, TUNER_ABSENT},
+       {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT},
 };
 
 /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
@@ -2660,10 +2659,9 @@ void em28xx_card_setup(struct em28xx *dev)
                        .addr = 0xba >> 1,
                        .platform_data = &pdata,
                };
-               struct v4l2_subdev *sd;
 
                pdata.xtal = dev->sensor_xtal;
-               sd = v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
+               v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
                                &mt9v011_info, NULL);
        }
 
@@ -2847,6 +2845,16 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                }
        }
 
+       if (dev->is_audio_only) {
+               errCode = em28xx_audio_setup(dev);
+               if (errCode)
+                       return -ENODEV;
+               em28xx_add_into_devlist(dev);
+               em28xx_init_extension(dev);
+
+               return 0;
+       }
+
        /* Prepopulate cached GPO register content */
        retval = em28xx_read_reg(dev, dev->reg_gpo_num);
        if (retval >= 0)
@@ -2947,6 +2955,9 @@ fail_reg_devices:
        return retval;
 }
 
+/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
+#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
+
 /*
  * em28xx_usb_probe()
  * checks for supported devices
@@ -2956,15 +2967,15 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 {
        const struct usb_endpoint_descriptor *endpoint;
        struct usb_device *udev;
-       struct usb_interface *uif;
        struct em28xx *dev = NULL;
        int retval;
-       int i, nr, ifnum, isoc_pipe;
+       bool is_audio_only = false, has_audio = false;
+       int i, nr, isoc_pipe;
+       const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
        char *speed;
        char descr[255] = "";
 
        udev = usb_get_dev(interface_to_usbdev(interface));
-       ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 
        /* Check to see next free device and mark as used */
        nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
@@ -2984,6 +2995,19 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                goto err;
        }
 
+       /* Get endpoints */
+       for (i = 0; i < interface->num_altsetting; i++) {
+               int ep;
+
+               for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
+                       struct usb_host_endpoint        *e;
+                       e = &interface->altsetting[i].endpoint[ep];
+
+                       if (e->desc.bEndpointAddress == 0x83)
+                               has_audio = true;
+               }
+       }
+
        endpoint = &interface->cur_altsetting->endpoint[0].desc;
 
        /* check if the device has the iso in endpoint at the correct place */
@@ -3003,19 +3027,22 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                        check_interface = 0;
 
                if (!check_interface) {
-                       em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
-                               "interface %i, class %i found.\n",
-                               le16_to_cpu(udev->descriptor.idVendor),
-                               le16_to_cpu(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);
-                       retval = -ENODEV;
-                       goto err;
+                       if (has_audio) {
+                               is_audio_only = true;
+                       } else {
+                               em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
+                                       "interface %i, class %i found.\n",
+                                       le16_to_cpu(udev->descriptor.idVendor),
+                                       le16_to_cpu(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);
+                               retval = -ENODEV;
+                               goto err;
+                       }
                }
        }
 
@@ -3045,8 +3072,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        if (*descr)
                strlcat(descr, " ", sizeof(descr));
 
-       printk(DRIVER_NAME ": New device %s@ %s Mbps "
-               "(%04x:%04x, interface %d, class %d)\n",
+       printk(KERN_INFO DRIVER_NAME
+               ": New device %s@ %s Mbps (%04x:%04x, interface %d, class %d)\n",
                descr,
                speed,
                le16_to_cpu(udev->descriptor.idVendor),
@@ -3054,6 +3081,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                ifnum,
                interface->altsetting->desc.bInterfaceNumber);
 
+       if (has_audio)
+               printk(KERN_INFO DRIVER_NAME
+                      ": Audio Vendor Class interface %i found\n",
+                      ifnum);
+
        /*
         * Make sure we have 480 Mbps of bandwidth, otherwise things like
         * video stream wouldn't likely work, since 12 Mbps is generally
@@ -3089,10 +3121,13 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        dev->devno = nr;
        dev->model = id->driver_info;
        dev->alt   = -1;
+       dev->is_audio_only = is_audio_only;
+       dev->has_alsa_audio = has_audio;
+       dev->audio_ifnum = ifnum;
 
        /* Checks if audio is provided by some interface */
        for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
-               uif = udev->config->interface[i];
+               struct usb_interface *uif = udev->config->interface[i];
                if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
                        dev->has_audio_class = 1;
                        break;
@@ -3100,9 +3135,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        }
 
        /* compute alternate max packet sizes */
-       uif = udev->actconfig->interface[0];
-
-       dev->num_alt = uif->num_altsetting;
+       dev->num_alt = interface->num_altsetting;
        dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
 
        if (dev->alt_max_pkt_size == NULL) {
@@ -3114,14 +3147,21 @@ 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[isoc_pipe].desc.wMaxPacketSize);
-               dev->alt_max_pkt_size[i] =
-                   (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+               u16 tmp = le16_to_cpu(interface->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
+               unsigned int size = tmp & 0x7ff;
+
+               if (udev->speed == USB_SPEED_HIGH)
+                       size = size * hb_mult(tmp);
+
+               dev->alt_max_pkt_size[i] = size;
        }
 
        if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
                dev->model = card[nr];
 
+       /* save our data pointer in this interface device */
+       usb_set_intfdata(interface, dev);
+
        /* allocate device struct */
        mutex_init(&dev->lock);
        mutex_lock(&dev->lock);
@@ -3133,9 +3173,6 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                goto err;
        }
 
-       /* save our data pointer in this interface device */
-       usb_set_intfdata(interface, dev);
-
        request_modules(dev);
 
        /* Should be the last thing to do, to avoid newer udev's to
@@ -3164,6 +3201,13 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
        if (!dev)
                return;
 
+       if (dev->is_audio_only) {
+               mutex_lock(&dev->lock);
+               em28xx_close_extension(dev);
+               mutex_unlock(&dev->lock);
+               return;
+       }
+
        em28xx_info("disconnecting %s\n", dev->vdev->name);
 
        flush_request_modules(dev);