V4L/DVB (12172): em28xx: Add autodetection code for Silvercrest 1.3 mpix
authorMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 3 Jul 2009 18:36:18 +0000 (15:36 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 5 Jul 2009 22:21:47 +0000 (19:21 -0300)
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-i2c.c

index 01fbb7d2e569043f429abbb3ff40be10809bd147..8366c521921dc223b1c85e93b1f165aea8467ce7 100644 (file)
@@ -58,6 +58,8 @@ static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
 module_param_array(card,  int, NULL, 0444);
 MODULE_PARM_DESC(card,     "card type");
 
+#define MT9V011_VERSION                 0x8243
+
 /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
 static unsigned long em28xx_devused;
 
@@ -1702,6 +1704,46 @@ static inline void em28xx_set_model(struct em28xx *dev)
                                       EM28XX_I2C_FREQ_100_KHZ;
 }
 
+/* HINT method: webcam I2C chips
+ *
+ * This method work for webcams with Micron sensors
+ */
+static int em28xx_hint_sensor(struct em28xx *dev)
+{
+       int rc;
+       char *sensor_name;
+       unsigned char cmd;
+       __be16 version_be;
+       u16 version;
+
+       if (dev->model != EM2820_BOARD_UNKNOWN)
+               return 0;
+
+       dev->i2c_client.addr = 0xba >> 1;
+       cmd = 0;
+       i2c_master_send(&dev->i2c_client, &cmd, 1);
+       rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2);
+       if (rc != 2)
+               return -EINVAL;
+
+       version = be16_to_cpu(version_be);
+
+       switch (version) {
+       case MT9V011_VERSION:
+               dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
+               sensor_name = "mt9v011";
+               break;
+       default:
+               printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version));
+               return -EINVAL;
+       }
+
+       em28xx_errdev("Sensor is %s, assuming that webcam is %s\n",
+                     sensor_name, em28xx_boards[dev->model].name);
+
+       return 0;
+}
+
 /* Since em28xx_pre_card_setup() requires a proper dev->model,
  * this won't work for boards with generic PCI IDs
  */
@@ -2368,6 +2410,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                return errCode;
        }
 
+       em28xx_hint_sensor(dev);
+
        /* Do board specific init and eeprom reading */
        em28xx_card_setup(dev);
 
index 2c86fcf089f59b45de048179e4be46fe76c989d4..27e33a287dfc8a53da271359aef3c08ac5283517 100644 (file)
@@ -483,7 +483,7 @@ static char *i2c_devs[128] = {
        [0xa0 >> 1] = "eeprom",
        [0xb0 >> 1] = "tda9874",
        [0xb8 >> 1] = "tvp5150a",
-       [0xba >> 1] = "tvp5150a",
+       [0xba >> 1] = "webcam sensor or tvp5150a",
        [0xc0 >> 1] = "tuner (analog)",
        [0xc2 >> 1] = "tuner (analog)",
        [0xc4 >> 1] = "tuner (analog)",