|
@@ -73,7 +73,7 @@
|
|
|
#define SELECT_DELAY_LONG 1000
|
|
|
|
|
|
struct pca9541 {
|
|
|
- struct i2c_adapter *mux_adap;
|
|
|
+ struct i2c_client *client;
|
|
|
unsigned long select_timeout;
|
|
|
unsigned long arb_timeout;
|
|
|
};
|
|
@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = {
|
|
|
*/
|
|
|
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;
|
|
|
|
|
|
reg = pca9541_reg_read(client, PCA9541_CONTROL);
|
|
@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client)
|
|
|
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;
|
|
|
unsigned long timeout = jiffies + ARB2_TIMEOUT;
|
|
|
/* give up after this time */
|
|
@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
|
|
|
return -ETIMEDOUT;
|
|
|
}
|
|
|
|
|
|
-static int pca9541_release_chan(struct i2c_adapter *adap,
|
|
|
- void *client, u32 chan)
|
|
|
+static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
|
|
|
{
|
|
|
+ struct pca9541 *data = i2c_mux_priv(muxc);
|
|
|
+ struct i2c_client *client = data->client;
|
|
|
+
|
|
|
pca9541_release_bus(client);
|
|
|
return 0;
|
|
|
}
|
|
@@ -324,20 +328,13 @@ static int pca9541_probe(struct i2c_client *client,
|
|
|
{
|
|
|
struct i2c_adapter *adap = client->adapter;
|
|
|
struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
|
|
|
+ struct i2c_mux_core *muxc;
|
|
|
struct pca9541 *data;
|
|
|
int force;
|
|
|
- int ret = -ENODEV;
|
|
|
+ int ret;
|
|
|
|
|
|
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
|
|
|
- goto err;
|
|
|
-
|
|
|
- data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
|
|
|
- if (!data) {
|
|
|
- ret = -ENOMEM;
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- i2c_set_clientdata(client, data);
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
/*
|
|
|
* I2C accesses are unprotected here.
|
|
@@ -352,34 +349,33 @@ static int pca9541_probe(struct i2c_client *client,
|
|
|
force = 0;
|
|
|
if (pdata)
|
|
|
force = pdata->modes[0].adap_id;
|
|
|
- data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
|
|
|
- force, 0, 0,
|
|
|
- pca9541_select_chan,
|
|
|
- pca9541_release_chan);
|
|
|
+ muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 0,
|
|
|
+ pca9541_select_chan, pca9541_release_chan);
|
|
|
+ if (!muxc)
|
|
|
+ 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");
|
|
|
- goto exit_free;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
dev_info(&client->dev, "registered master selector for I2C %s\n",
|
|
|
client->name);
|
|
|
|
|
|
return 0;
|
|
|
-
|
|
|
-exit_free:
|
|
|
- kfree(data);
|
|
|
-err:
|
|
|
- return ret;
|
|
|
}
|
|
|
|
|
|
static int pca9541_remove(struct i2c_client *client)
|
|
|
{
|
|
|
- struct pca9541 *data = i2c_get_clientdata(client);
|
|
|
-
|
|
|
- i2c_del_mux_adapter(data->mux_adap);
|
|
|
+ struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
|
|
|
|
|
- kfree(data);
|
|
|
+ i2c_mux_del_adapters(muxc);
|
|
|
return 0;
|
|
|
}
|
|
|
|