atmel_mxt_ts: [HACK DV20] detect touchscreen i2c addr runtime
authorHong Liu <hong.liu@intel.com>
Wed, 11 Apr 2012 07:05:37 +0000 (15:05 +0800)
committerbuildbot <buildbot@intel.com>
Fri, 13 Apr 2012 15:45:55 +0000 (08:45 -0700)
BZ: 31105

DV1.5/2.0 hardware comes in two variants with different touch panels.
The touchscreen controller has different i2c address depending on the panel,
WintekA0=0x4c and Hannstouch=0x4d.
Searching for device at mxt1386 address, if not found use the other address.

This hack should be removed once SFI table has one correct touchscreen entry.

Patch ported from OTC branch.

Change-Id: Idfcdcf6f43dff1921a515f78dd548bcc3dd3f6dc
Signed-off-by: Hong Liu <hong.liu@intel.com>
Reviewed-on: http://android.intel.com:8080/43070
Reviewed-by: Wood, Brian J <brian.j.wood@intel.com>
Reviewed-by: Lebouc, Christophe <christophe.lebouc@intel.com>
Tested-by: Lebouc, Christophe <christophe.lebouc@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/platform/intel-mid/board-redridge.c
drivers/input/touchscreen/atmel_mxt_ts.c
include/linux/i2c/atmel_mxt_ts.h

index 438c0c2..e5ae713 100644 (file)
@@ -1292,7 +1292,7 @@ void *wl12xx_platform_data_init(void *info)
 #define TOUCH_IRQ_GPIO   62
 
 /* Atmel mxt toucscreen platform setup*/
-static int atmel_mxt_init_platform_hw(void)
+static int atmel_mxt_init_platform_hw(struct i2c_client *client)
 {
        int rc;
        int reset_gpio, int_gpio;
@@ -1326,6 +1326,26 @@ static int atmel_mxt_init_platform_hw(void)
        gpio_set_value(reset_gpio, 1);
        msleep(100);
 
+       /*
+        * HACK: depending on which touchpanel is used the mxt1386 controller
+        * may be at i2c address 0x4d instead of the default 0x4c stated in SFI
+        * table. Probe for chip by sending a i2c message and wait for ACK.
+        * (writing 0x00 will prepare chip for reading chip family id)
+        */
+
+       rc = i2c_smbus_write_byte_data(client, 0, 0);
+       if (rc < 0) {
+               /* retry */
+               msleep(60);
+               rc = i2c_smbus_write_byte_data(client, 0, 0);
+               if (rc < 0) {
+                       if (client->addr == 0x4c)
+                               client->addr = 0x4d;
+                       else if (client->addr == 0x4d)
+                               client->addr = 0x4c;
+               }
+       }
+
        return 0;
 
 err_reset:
index fb3c9a2..4f6a868 100644 (file)
@@ -1317,7 +1317,7 @@ static int __devinit mxt_probe(struct i2c_client *client,
        data->irq = client->irq;
 
        if (pdata->init_platform_hw) {
-               error = pdata->init_platform_hw();
+               error = pdata->init_platform_hw(client);
                if (error)
                        goto err_free_object;
        }
index d62e391..1dcfa35 100644 (file)
@@ -14,6 +14,7 @@
 #define __LINUX_ATMEL_MXT_TS_H
 
 #include <linux/types.h>
+#include <linux/i2c.h>
 
 /* Orient */
 #define MXT_NORMAL             0x0
@@ -39,7 +40,7 @@ struct mxt_platform_data {
        unsigned int voltage;
        unsigned char orient;
        unsigned long irqflags;
-       int (*init_platform_hw)(void);
+       int (*init_platform_hw)(struct i2c_client *client);
 };
 
 #endif /* __LINUX_ATMEL_MXT_TS_H */