From 40839590f868d77ab8f84ac6e1b1297f553e3dea Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Thu, 11 Aug 2016 16:49:54 +0200 Subject: i2c: mux: inform the i2c mux core about how it is used The i2c mux core can then take appropriate action depending on if it is used for an actual i2c mux, for a gate or for an arbitrator (the last is the case for these drivers). This adds support for the new clearer and more compact devicetree bindings that was added recently. Reviewed-by: Wolfram Sang Signed-off-by: Peter Rosin --- drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 2 +- drivers/i2c/muxes/i2c-mux-pca9541.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/i2c/muxes') diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c index a90bbc4037dd..86fc2d4c081b 100644 --- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c +++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c @@ -130,7 +130,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev) return -EINVAL; } - muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), 0, + muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), I2C_MUX_ARBITRATOR, i2c_arbitrator_select, i2c_arbitrator_deselect); if (!muxc) return -ENOMEM; diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index 3cb8af635db5..f052c3067791 100644 --- a/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c @@ -349,7 +349,8 @@ static int pca9541_probe(struct i2c_client *client, force = 0; if (pdata) force = pdata->modes[0].adap_id; - muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 0, + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, pca9541_select_chan, pca9541_release_chan); if (!muxc) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From a1cbf338abaf4d340b7aee1d8255e20462d11e70 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sat, 9 Jul 2016 20:30:58 +0200 Subject: i2c: pca9541: add device tree binding No longer rely on the implicit matching with the i2c device name, use an explicit compatible string instead. Reviewed-by: Wolfram Sang Signed-off-by: Peter Rosin --- drivers/i2c/muxes/i2c-mux-pca9541.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/i2c/muxes') diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index f052c3067791..4ea7e691afc7 100644 --- a/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c @@ -85,6 +85,13 @@ static const struct i2c_device_id pca9541_id[] = { MODULE_DEVICE_TABLE(i2c, pca9541_id); +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,pca9541" }, + {} +}; +#endif + /* * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() * as they will try to lock the adapter a second time. @@ -383,6 +390,7 @@ static int pca9541_remove(struct i2c_client *client) static struct i2c_driver pca9541_driver = { .driver = { .name = "pca9541", + .of_match_table = of_match_ptr(pca9541_of_match), }, .probe = pca9541_probe, .remove = pca9541_remove, -- cgit v1.2.3-59-g8ed1b From 8a191a7ad4ca9022bb838387b20d3de6acc88b72 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sat, 9 Jul 2016 21:21:15 +0200 Subject: i2c: pca954x: add device tree binding No longer rely on the implicit matching with the i2c device name, use an explicit compatible string instead. Keep a direct pointer to the chip description instead of an index into the chip description array. Reviewed-by: Wolfram Sang Signed-off-by: Peter Rosin --- drivers/i2c/muxes/i2c-mux-pca954x.c | 46 +++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'drivers/i2c/muxes') diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 528e755c468f..6dfd31ba29a0 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -58,14 +59,6 @@ enum pca_type { pca_9548, }; -struct pca954x { - enum pca_type type; - - u8 last_chan; /* last register value */ - u8 deselect; - struct i2c_client *client; -}; - struct chip_desc { u8 nchans; u8 enable; /* used for muxes only */ @@ -75,6 +68,14 @@ struct chip_desc { } muxtype; }; +struct pca954x { + const struct chip_desc *chip; + + u8 last_chan; /* last register value */ + u8 deselect; + struct i2c_client *client; +}; + /* Provide specs for the PCA954x types we know about */ static const struct chip_desc chips[] = { [pca_9540] = { @@ -119,6 +120,20 @@ static const struct i2c_device_id pca954x_id[] = { }; MODULE_DEVICE_TABLE(i2c, pca954x_id); +#ifdef CONFIG_OF +static const struct of_device_id pca954x_of_match[] = { + { .compatible = "nxp,pca9540", .data = &chips[pca_9540] }, + { .compatible = "nxp,pca9542", .data = &chips[pca_9542] }, + { .compatible = "nxp,pca9543", .data = &chips[pca_9543] }, + { .compatible = "nxp,pca9544", .data = &chips[pca_9544] }, + { .compatible = "nxp,pca9545", .data = &chips[pca_9545] }, + { .compatible = "nxp,pca9546", .data = &chips[pca_9546] }, + { .compatible = "nxp,pca9547", .data = &chips[pca_9547] }, + { .compatible = "nxp,pca9548", .data = &chips[pca_9548] }, + {} +}; +#endif + /* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() for this as they will try to lock adapter a second time */ static int pca954x_reg_write(struct i2c_adapter *adap, @@ -151,7 +166,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) { struct pca954x *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; - const struct chip_desc *chip = &chips[data->type]; + const struct chip_desc *chip = data->chip; u8 regval; int ret = 0; @@ -197,6 +212,7 @@ static int pca954x_probe(struct i2c_client *client, int num, force, class; struct i2c_mux_core *muxc; struct pca954x *data; + const struct of_device_id *match; int ret; if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) @@ -226,14 +242,19 @@ static int pca954x_probe(struct i2c_client *client, return -ENODEV; } - data->type = id->driver_data; + match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev); + if (match) + data->chip = of_device_get_match_data(&client->dev); + else + data->chip = &chips[id->driver_data]; + data->last_chan = 0; /* force the first selection */ idle_disconnect_dt = of_node && of_property_read_bool(of_node, "i2c-mux-idle-disconnect"); /* Now create an adapter for each channel */ - for (num = 0; num < chips[data->type].nchans; num++) { + for (num = 0; num < data->chip->nchans; num++) { bool idle_disconnect_pd = false; force = 0; /* dynamic adap number */ @@ -263,7 +284,7 @@ static int pca954x_probe(struct i2c_client *client, dev_info(&client->dev, "registered %d multiplexed busses for I2C %s %s\n", - num, chips[data->type].muxtype == pca954x_ismux + num, data->chip->muxtype == pca954x_ismux ? "mux" : "switch", client->name); return 0; @@ -299,6 +320,7 @@ static struct i2c_driver pca954x_driver = { .driver = { .name = "pca954x", .pm = &pca954x_pm, + .of_match_table = of_match_ptr(pca954x_of_match), }, .probe = pca954x_probe, .remove = pca954x_remove, -- cgit v1.2.3-59-g8ed1b