lkml.org 
[lkml]   [2014]   [Jun]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH v3 1/1] platform/chrome: Probe multiple i2c adapters of the same name
The chromeos_laptop module probes the first i2c adapter with a specific 
name for expected hardware. However, the Acer C720 Chromebook has two i2c
adapters with the same name. This patch probes each i2c adapter with a
specific name until locating the expected hardware.

Thanks to Mika Westerberg for formatting tips and identifying the need for
unique bus addresses within each set of identically-named adapters.

Signed-off-by: Scot Doyle <lkml14@scotdoyle.com>
CC: Benson Leung <bleung@chromium.org>
CC: Mika Westerberg <mika.westerberg@linux.intel.com>
---
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
index 7f3aad0..82ae5e7 100644
--- a/drivers/platform/chrome/chromeos_laptop.c
+++ b/drivers/platform/chrome/chromeos_laptop.c
@@ -29,6 +29,10 @@
#include <linux/module.h>
#include <linux/platform_device.h>

+/*
+ * Note: Bus addresses must be unique within each set of identically-named
+ * adapters on a board, otherwise device probing may fail.
+ */
#define ATMEL_TP_I2C_ADDR 0x4b
#define ATMEL_TP_I2C_BL_ADDR 0x25
#define ATMEL_TS_I2C_ADDR 0x4a
@@ -173,7 +177,7 @@ static struct i2c_client *__add_probed_i2c_device(
/* add the i2c device */
client = i2c_new_probed_device(adapter, info, addrs, NULL);
if (!client)
- pr_err("%s failed to register device %d-%02x\n",
+ pr_debug("%s did not add i2c device %d-%02x\n",
__func__, bus, info->addr);
else
pr_debug("%s added i2c device %d-%02x\n",
@@ -194,13 +198,14 @@ static int __find_i2c_adap(struct device *dev, void *data)
return (strncmp(adapter->name, name, strlen(name)) == 0);
}

-static int find_i2c_adapter_num(enum i2c_adapter_type type)
+static int find_i2c_next_adapter_num(enum i2c_adapter_type type,
+ struct device *start)
{
struct device *dev = NULL;
struct i2c_adapter *adapter;
const char *name = i2c_adapter_names[type];
- /* find the adapter by name */
- dev = bus_find_device(&i2c_bus_type, NULL, (void *)name,
+ /* find the next adapter by name */
+ dev = bus_find_device(&i2c_bus_type, start, (void *)name,
__find_i2c_adap);
if (!dev) {
/* Adapters may appear later. Deferred probing will retry */
@@ -226,10 +231,15 @@ static struct i2c_client *add_probed_i2c_device(
struct i2c_board_info *info,
const unsigned short *addrs)
{
- return __add_probed_i2c_device(name,
- find_i2c_adapter_num(type),
- info,
- addrs);
+ struct i2c_client *client = NULL;
+ struct device *start = NULL;
+ int num = 0;
+
+ while (!client && num > -1) {
+ num = find_i2c_next_adapter_num(type, start);
+ client = __add_probed_i2c_device(name, num, info, addrs);
+ }
+ return client;
}

/*
@@ -242,10 +252,7 @@ static struct i2c_client *add_i2c_device(const char *name,
struct i2c_board_info *info)
{
const unsigned short addr_list[] = { info->addr, I2C_CLIENT_END };
- return __add_probed_i2c_device(name,
- find_i2c_adapter_num(type),
- info,
- addr_list);
+ return add_probed_i2c_device(name, type, info, addr_list);
}

static int setup_cyapa_tp(enum i2c_adapter_type type)

\
 
 \ /
  Last update: 2014-06-11 19:21    [W:0.053 / U:0.088 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site