aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-04-14 16:50:09 -0400
committerOlof Johansson <olof@lixom.net>2015-04-25 01:07:14 -0400
commit96cba9b00e297303774bec59e192064d20adeb3d (patch)
tree6b72ce956c4fc8c8017cb8cf60812321883e765a /drivers/platform
parent8ce580932f8ee40903017a6f1408ccfff319a6a5 (diff)
platform/chrome: chromeos_laptop - instantiate Atmel at primary address
The new Atmel MXT driver expects i2c client's address contain the primary (main address) of the chip, and calculates the expected bootloader address form the primary address. Unfortunately chrome_laptop does probe the devices and if touchpad (or touchscreen, or both) comes up in bootloader mode the i2c device gets instantiated with the bootloader address which confuses the driver. To work around this issue let's probe the primary address first. If the device is not detected at the primary address we'll probe alternative addresses as "dummy" devices. If any of them are found, destroy the dummy client and instantiate client with proper name at primary address still. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/chrome/chromeos_laptop.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
index b84fdd6b629b..a04019ab9feb 100644
--- a/drivers/platform/chrome/chromeos_laptop.c
+++ b/drivers/platform/chrome/chromeos_laptop.c
@@ -133,12 +133,13 @@ static struct i2c_client *__add_probed_i2c_device(
133 const char *name, 133 const char *name,
134 int bus, 134 int bus,
135 struct i2c_board_info *info, 135 struct i2c_board_info *info,
136 const unsigned short *addrs) 136 const unsigned short *alt_addr_list)
137{ 137{
138 const struct dmi_device *dmi_dev; 138 const struct dmi_device *dmi_dev;
139 const struct dmi_dev_onboard *dev_data; 139 const struct dmi_dev_onboard *dev_data;
140 struct i2c_adapter *adapter; 140 struct i2c_adapter *adapter;
141 struct i2c_client *client; 141 struct i2c_client *client = NULL;
142 const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END };
142 143
143 if (bus < 0) 144 if (bus < 0)
144 return NULL; 145 return NULL;
@@ -169,8 +170,28 @@ static struct i2c_client *__add_probed_i2c_device(
169 return NULL; 170 return NULL;
170 } 171 }
171 172
172 /* add the i2c device */ 173 /*
173 client = i2c_new_probed_device(adapter, info, addrs, NULL); 174 * Add the i2c device. If we can't detect it at the primary
175 * address we scan secondary addresses. In any case the client
176 * structure gets assigned primary address.
177 */
178 client = i2c_new_probed_device(adapter, info, addr_list, NULL);
179 if (!client && alt_addr_list) {
180 struct i2c_board_info dummy_info = {
181 I2C_BOARD_INFO("dummy", info->addr),
182 };
183 struct i2c_client *dummy;
184
185 dummy = i2c_new_probed_device(adapter, &dummy_info,
186 alt_addr_list, NULL);
187 if (dummy) {
188 pr_debug("%s %d-%02x is probed at %02x\n",
189 __func__, bus, info->addr, dummy->addr);
190 i2c_unregister_device(dummy);
191 client = i2c_new_device(adapter, info);
192 }
193 }
194
174 if (!client) 195 if (!client)
175 pr_notice("%s failed to register device %d-%02x\n", 196 pr_notice("%s failed to register device %d-%02x\n",
176 __func__, bus, info->addr); 197 __func__, bus, info->addr);
@@ -254,12 +275,10 @@ static struct i2c_client *add_i2c_device(const char *name,
254 enum i2c_adapter_type type, 275 enum i2c_adapter_type type,
255 struct i2c_board_info *info) 276 struct i2c_board_info *info)
256{ 277{
257 const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END };
258
259 return __add_probed_i2c_device(name, 278 return __add_probed_i2c_device(name,
260 find_i2c_adapter_num(type), 279 find_i2c_adapter_num(type),
261 info, 280 info,
262 addr_list); 281 NULL);
263} 282}
264 283
265static int setup_cyapa_tp(enum i2c_adapter_type type) 284static int setup_cyapa_tp(enum i2c_adapter_type type)
@@ -275,7 +294,6 @@ static int setup_cyapa_tp(enum i2c_adapter_type type)
275static int setup_atmel_224s_tp(enum i2c_adapter_type type) 294static int setup_atmel_224s_tp(enum i2c_adapter_type type)
276{ 295{
277 const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR, 296 const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR,
278 ATMEL_TP_I2C_ADDR,
279 I2C_CLIENT_END }; 297 I2C_CLIENT_END };
280 if (tp) 298 if (tp)
281 return 0; 299 return 0;
@@ -289,7 +307,6 @@ static int setup_atmel_224s_tp(enum i2c_adapter_type type)
289static int setup_atmel_1664s_ts(enum i2c_adapter_type type) 307static int setup_atmel_1664s_ts(enum i2c_adapter_type type)
290{ 308{
291 const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR, 309 const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR,
292 ATMEL_TS_I2C_ADDR,
293 I2C_CLIENT_END }; 310 I2C_CLIENT_END };
294 if (ts) 311 if (ts)
295 return 0; 312 return 0;