Commit ab88b97c authored by Peter Rosin's avatar Peter Rosin Committed by Wolfram Sang

i2c: i2c-mux-pca9541: convert to use an explicit i2c mux core

Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.
Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 8aacd901
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
#define SELECT_DELAY_LONG 1000 #define SELECT_DELAY_LONG 1000
struct pca9541 { struct pca9541 {
struct i2c_adapter *mux_adap; struct i2c_client *client;
unsigned long select_timeout; unsigned long select_timeout;
unsigned long arb_timeout; unsigned long arb_timeout;
}; };
...@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = { ...@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = {
*/ */
static int pca9541_arbitrate(struct i2c_client *client) static int pca9541_arbitrate(struct i2c_client *client)
{ {
struct pca9541 *data = i2c_get_clientdata(client); struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct pca9541 *data = i2c_mux_priv(muxc);
int reg; int reg;
reg = pca9541_reg_read(client, PCA9541_CONTROL); reg = pca9541_reg_read(client, PCA9541_CONTROL);
...@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client) ...@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client)
return 0; return 0;
} }
static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan) static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
{ {
struct pca9541 *data = i2c_get_clientdata(client); struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
int ret; int ret;
unsigned long timeout = jiffies + ARB2_TIMEOUT; unsigned long timeout = jiffies + ARB2_TIMEOUT;
/* give up after this time */ /* give up after this time */
...@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan) ...@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
static int pca9541_release_chan(struct i2c_adapter *adap, static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
void *client, u32 chan)
{ {
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
pca9541_release_bus(client); pca9541_release_bus(client);
return 0; return 0;
} }
...@@ -324,20 +328,13 @@ static int pca9541_probe(struct i2c_client *client, ...@@ -324,20 +328,13 @@ static int pca9541_probe(struct i2c_client *client,
{ {
struct i2c_adapter *adap = client->adapter; struct i2c_adapter *adap = client->adapter;
struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
struct i2c_mux_core *muxc;
struct pca9541 *data; struct pca9541 *data;
int force; int force;
int ret = -ENODEV; int ret;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
goto err; return -ENODEV;
data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto err;
}
i2c_set_clientdata(client, data);
/* /*
* I2C accesses are unprotected here. * I2C accesses are unprotected here.
...@@ -352,34 +349,33 @@ static int pca9541_probe(struct i2c_client *client, ...@@ -352,34 +349,33 @@ static int pca9541_probe(struct i2c_client *client,
force = 0; force = 0;
if (pdata) if (pdata)
force = pdata->modes[0].adap_id; force = pdata->modes[0].adap_id;
data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client, muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 0,
force, 0, 0, pca9541_select_chan, pca9541_release_chan);
pca9541_select_chan, if (!muxc)
pca9541_release_chan); return -ENOMEM;
if (data->mux_adap == NULL) { data = i2c_mux_priv(muxc);
data->client = client;
i2c_set_clientdata(client, muxc);
ret = i2c_mux_add_adapter(muxc, force, 0, 0);
if (ret) {
dev_err(&client->dev, "failed to register master selector\n"); dev_err(&client->dev, "failed to register master selector\n");
goto exit_free; return ret;
} }
dev_info(&client->dev, "registered master selector for I2C %s\n", dev_info(&client->dev, "registered master selector for I2C %s\n",
client->name); client->name);
return 0; return 0;
exit_free:
kfree(data);
err:
return ret;
} }
static int pca9541_remove(struct i2c_client *client) static int pca9541_remove(struct i2c_client *client)
{ {
struct pca9541 *data = i2c_get_clientdata(client); struct i2c_mux_core *muxc = i2c_get_clientdata(client);
i2c_del_mux_adapter(data->mux_adap);
kfree(data); i2c_mux_del_adapters(muxc);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment