diff options
author | Peter Rosin <peda@axentia.se> | 2016-04-20 02:40:02 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2016-04-22 08:56:39 -0400 |
commit | ab88b97c69ce375ef10c551133d6d19ffd55d763 (patch) | |
tree | 3a25ecaa40959a517b6e7bf31233e787da569c96 /drivers/i2c | |
parent | 8aacd90166f6b60df83e0907b1e931e3971a92ab (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.c | 58 |
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 | ||
75 | struct pca9541 { | 75 | struct 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 | */ |
218 | static int pca9541_arbitrate(struct i2c_client *client) | 218 | static 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 | ||
288 | static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan) | 289 | static 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 | ||
312 | static int pca9541_release_chan(struct i2c_adapter *adap, | 314 | static 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 | |||
370 | exit_free: | ||
371 | kfree(data); | ||
372 | err: | ||
373 | return ret; | ||
374 | } | 372 | } |
375 | 373 | ||
376 | static int pca9541_remove(struct i2c_client *client) | 374 | static 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 | ||