aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorPeter Rosin <peda@axentia.se>2016-04-20 02:40:02 -0400
committerWolfram Sang <wsa@the-dreams.de>2016-04-22 08:56:39 -0400
commitab88b97c69ce375ef10c551133d6d19ffd55d763 (patch)
tree3a25ecaa40959a517b6e7bf31233e787da569c96 /drivers/i2c
parent8aacd90166f6b60df83e0907b1e931e3971a92ab (diff)
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: Peter Rosin <peda@axentia.se> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca9541.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index d0ba424adebc..3cb8af635db5 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -73,7 +73,7 @@
73#define SELECT_DELAY_LONG 1000 73#define SELECT_DELAY_LONG 1000
74 74
75struct pca9541 { 75struct pca9541 {
76 struct i2c_adapter *mux_adap; 76 struct i2c_client *client;
77 unsigned long select_timeout; 77 unsigned long select_timeout;
78 unsigned long arb_timeout; 78 unsigned long arb_timeout;
79}; 79};
@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = {
217 */ 217 */
218static int pca9541_arbitrate(struct i2c_client *client) 218static int pca9541_arbitrate(struct i2c_client *client)
219{ 219{
220 struct pca9541 *data = i2c_get_clientdata(client); 220 struct i2c_mux_core *muxc = i2c_get_clientdata(client);
221 struct pca9541 *data = i2c_mux_priv(muxc);
221 int reg; 222 int reg;
222 223
223 reg = pca9541_reg_read(client, PCA9541_CONTROL); 224 reg = pca9541_reg_read(client, PCA9541_CONTROL);
@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client)
285 return 0; 286 return 0;
286} 287}
287 288
288static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan) 289static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
289{ 290{
290 struct pca9541 *data = i2c_get_clientdata(client); 291 struct pca9541 *data = i2c_mux_priv(muxc);
292 struct i2c_client *client = data->client;
291 int ret; 293 int ret;
292 unsigned long timeout = jiffies + ARB2_TIMEOUT; 294 unsigned long timeout = jiffies + ARB2_TIMEOUT;
293 /* give up after this time */ 295 /* give up after this time */
@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
309 return -ETIMEDOUT; 311 return -ETIMEDOUT;
310} 312}
311 313
312static int pca9541_release_chan(struct i2c_adapter *adap, 314static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
313 void *client, u32 chan)
314{ 315{
316 struct pca9541 *data = i2c_mux_priv(muxc);
317 struct i2c_client *client = data->client;
318
315 pca9541_release_bus(client); 319 pca9541_release_bus(client);
316 return 0; 320 return 0;
317} 321}
@@ -324,20 +328,13 @@ static int pca9541_probe(struct i2c_client *client,
324{ 328{
325 struct i2c_adapter *adap = client->adapter; 329 struct i2c_adapter *adap = client->adapter;
326 struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); 330 struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
331 struct i2c_mux_core *muxc;
327 struct pca9541 *data; 332 struct pca9541 *data;
328 int force; 333 int force;
329 int ret = -ENODEV; 334 int ret;
330 335
331 if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) 336 if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
332 goto err; 337 return -ENODEV;
333
334 data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
335 if (!data) {
336 ret = -ENOMEM;
337 goto err;
338 }
339
340 i2c_set_clientdata(client, data);
341 338
342 /* 339 /*
343 * I2C accesses are unprotected here. 340 * I2C accesses are unprotected here.
@@ -352,34 +349,33 @@ static int pca9541_probe(struct i2c_client *client,
352 force = 0; 349 force = 0;
353 if (pdata) 350 if (pdata)
354 force = pdata->modes[0].adap_id; 351 force = pdata->modes[0].adap_id;
355 data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client, 352 muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 0,
356 force, 0, 0, 353 pca9541_select_chan, pca9541_release_chan);
357 pca9541_select_chan, 354 if (!muxc)
358 pca9541_release_chan); 355 return -ENOMEM;
359 356
360 if (data->mux_adap == NULL) { 357 data = i2c_mux_priv(muxc);
358 data->client = client;
359
360 i2c_set_clientdata(client, muxc);
361
362 ret = i2c_mux_add_adapter(muxc, force, 0, 0);
363 if (ret) {
361 dev_err(&client->dev, "failed to register master selector\n"); 364 dev_err(&client->dev, "failed to register master selector\n");
362 goto exit_free; 365 return ret;
363 } 366 }
364 367
365 dev_info(&client->dev, "registered master selector for I2C %s\n", 368 dev_info(&client->dev, "registered master selector for I2C %s\n",
366 client->name); 369 client->name);
367 370
368 return 0; 371 return 0;
369
370exit_free:
371 kfree(data);
372err:
373 return ret;
374} 372}
375 373
376static int pca9541_remove(struct i2c_client *client) 374static int pca9541_remove(struct i2c_client *client)
377{ 375{
378 struct pca9541 *data = i2c_get_clientdata(client); 376 struct i2c_mux_core *muxc = i2c_get_clientdata(client);
379
380 i2c_del_mux_adapter(data->mux_adap);
381 377
382 kfree(data); 378 i2c_mux_del_adapters(muxc);
383 return 0; 379 return 0;
384} 380}
385 381