diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-08 00:12:21 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-08 00:12:21 +0300 |
commit | 87840a2b7e048018d18d60bdac5c09224de85370 (patch) | |
tree | 87e9f8a2317e39358f5ea189d79ef2158de5faf8 /drivers/i2c/muxes | |
parent | 2ab704a47e0f27df758840a589aec3298dbb98dd (diff) | |
parent | 662786a5429c3a992c6f884a647ee32424822358 (diff) | |
download | linux-87840a2b7e048018d18d60bdac5c09224de85370.tar.xz |
Merge branch 'i2c/for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Here is the 4.9 pull request from I2C including:
- centralized error messages when registering to the core
- improved lockdep annotations to prevent false positives
- DT support for muxes, gates, and arbitrators
- bus speeds can now be obtained from ACPI
- i2c-octeon got refactored and now supports ThunderX SoCs, too
- i2c-tegra and i2c-designware got a bigger bunch of updates
- a couple of standard driver fixes and improvements"
* 'i2c/for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (71 commits)
i2c: axxia: disable clks in case of failure in probe
i2c: octeon: thunderx: Limit register access retries
i2c: uniphier-f: fix misdetection of incomplete STOP condition
gpio: pca953x: variable 'id' was used twice
i2c: i801: Add support for Kaby Lake PCH-H
gpio: pca953x: fix an incorrect lockdep warning
i2c: add a warning to i2c_adapter_depth()
lockdep: make MAX_LOCKDEP_SUBCLASSES unconditionally visible
i2c: export i2c_adapter_depth()
i2c: rk3x: Fix variable 'min_total_ns' unused warning
i2c: rk3x: Fix sparse warning
i2c / ACPI: Do not touch an I2C device if it belongs to another adapter
i2c: octeon: Fix high-level controller status check
i2c: octeon: Avoid sending STOP during recovery
i2c: octeon: Fix set SCL recovery function
i2c: rcar: add support for r8a7796 (R-Car M3-W)
i2c: imx: make bus recovery through pinctrl optional
i2c: meson: add gxbb compatible string
i2c: uniphier-f: set the adapter to master mode when probing
i2c: uniphier-f: avoid WARN_ON() of clk_disable() in failure path
...
Diffstat (limited to 'drivers/i2c/muxes')
-rw-r--r-- | drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 2 | ||||
-rw-r--r-- | drivers/i2c/muxes/i2c-mux-pca9541.c | 11 | ||||
-rw-r--r-- | drivers/i2c/muxes/i2c-mux-pca954x.c | 46 |
3 files changed, 45 insertions, 14 deletions
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..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. @@ -349,7 +356,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; @@ -382,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, diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 3278ebf1cc5c..1091346f2480 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -42,6 +42,7 @@ #include <linux/i2c/pca954x.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/pm.h> #include <linux/slab.h> @@ -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, |