summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-mcp23s08.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 21:20:54 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 21:20:54 +0200
commit77624cd2a7783fccf2c518768a6fd7a7aeccd002 (patch)
tree406283e54084299dc83f8c5456375941ed5dd67a /drivers/pinctrl/pinctrl-mcp23s08.c
parentMerge tag 'mmc-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc (diff)
parentpinctrl: uniphier: add UART hardware flow control pin-mux settings (diff)
downloadlinux-77624cd2a7783fccf2c518768a6fd7a7aeccd002.tar.xz
linux-77624cd2a7783fccf2c518768a6fd7a7aeccd002.zip
Merge tag 'pinctrl-v4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control bulk updates from Linus Walleij: "New drivers: - Qualcomm SDM845: this is their new flagship SoC platform which seems to be targeted at premium mobile handsets. - Renesas R-Car M3-N SoC. - Renesas R8A77980 SoC. - NXP (ex Freescale) i.MX 6SLL SoC. - Mediatek MT2712 SoC. - Allwinner H6 SoC. Improvements: - Uniphier adds a few new functions and pins. - Renesas refactorings and additional pin definitions. - Improved pin groups for Axis Artpec6. Cleanup: - Drop the TZ1090 drivers. This platform is no longer maintained and is being deleted. - Drop ST-Ericsson U8540/U9540 support as this was never productified. - Overall minor fixes and janitorial" * tag 'pinctrl-v4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (82 commits) pinctrl: uniphier: add UART hardware flow control pin-mux settings pinctrl: sunxi: add support for the Allwinner H6 main pin controller pinctrl: sunxi: change irq_bank_base to irq_bank_map pinctrl: sunxi: introduce IRQ bank conversion function pinctrl: sunxi: refactor irq related register function to have desc pinctrl: msm8998: Remove owner assignment from platform_driver pinctrl: uniphier: divide I2S and S/PDIF audio out pin-mux group pinctrl: uniphier: add PXs2 Audio in/out pin-mux settings pinctrl/amd: poll InterruptEnable bits in enable_irq pinctrl: ocelot: fix gpio direction pinctrl: mtk: fix check warnings. pintcrl: mtk: support bias-disable of generic and special pins simultaneously pinctrl: add mt2712 pinctrl driver pinctrl: pinctrl-single: Fix pcs_request_gpio() when bits_per_mux != 0 pinctrl: imx: Add pinctrl driver support for imx6sll dt-bindings: imx: update pinctrl doc for imx6sll pinctrl: intel: Implement intel_gpio_get_direction callback pinctrl: stm32: add 'depends on HAS_IOMEM' to fix unmet dependency pinctrl: mediatek: mtk-common: use true and false for boolean values pinctrl: sunxi: always look for apb block ...
Diffstat (limited to 'drivers/pinctrl/pinctrl-mcp23s08.c')
-rw-r--r--drivers/pinctrl/pinctrl-mcp23s08.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c
index 644c5beb05cb..022307dd4b54 100644
--- a/drivers/pinctrl/pinctrl-mcp23s08.c
+++ b/drivers/pinctrl/pinctrl-mcp23s08.c
@@ -771,6 +771,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
{
int status, ret;
bool mirror = false;
+ bool open_drain = false;
+ struct regmap_config *one_regmap_config = NULL;
+ int raw_chip_address = (addr & ~0x40) >> 1;
mutex_init(&mcp->lock);
@@ -791,19 +794,33 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
switch (type) {
#ifdef CONFIG_SPI_MASTER
case MCP_TYPE_S08:
- mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp,
- &mcp23x08_regmap);
- mcp->reg_shift = 0;
- mcp->chip.ngpio = 8;
- mcp->chip.label = "mcp23s08";
- break;
-
case MCP_TYPE_S17:
+ switch (type) {
+ case MCP_TYPE_S08:
+ one_regmap_config =
+ devm_kmemdup(dev, &mcp23x08_regmap,
+ sizeof(struct regmap_config), GFP_KERNEL);
+ mcp->reg_shift = 0;
+ mcp->chip.ngpio = 8;
+ mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL,
+ "mcp23s08.%d", raw_chip_address);
+ break;
+ case MCP_TYPE_S17:
+ one_regmap_config =
+ devm_kmemdup(dev, &mcp23x17_regmap,
+ sizeof(struct regmap_config), GFP_KERNEL);
+ mcp->reg_shift = 1;
+ mcp->chip.ngpio = 16;
+ mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL,
+ "mcp23s17.%d", raw_chip_address);
+ break;
+ }
+ if (!one_regmap_config)
+ return -ENOMEM;
+
+ one_regmap_config->name = devm_kasprintf(dev, GFP_KERNEL, "%d", raw_chip_address);
mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp,
- &mcp23x17_regmap);
- mcp->reg_shift = 1;
- mcp->chip.ngpio = 16;
- mcp->chip.label = "mcp23s17";
+ one_regmap_config);
break;
case MCP_TYPE_S18:
@@ -867,10 +884,11 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
"microchip,irq-active-high");
mirror = device_property_read_bool(dev, "microchip,irq-mirror");
+ open_drain = device_property_read_bool(dev, "drive-open-drain");
}
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
- mcp->irq_active_high) {
+ mcp->irq_active_high || open_drain) {
/* mcp23s17 has IOCON twice, make sure they are in sync */
status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8));
status |= IOCON_HAEN | (IOCON_HAEN << 8);
@@ -882,6 +900,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (mirror)
status |= IOCON_MIRROR | (IOCON_MIRROR << 8);
+ if (open_drain)
+ status |= IOCON_ODR | (IOCON_ODR << 8);
+
if (type == MCP_TYPE_S18 || type == MCP_TYPE_018)
status |= IOCON_INTCC | (IOCON_INTCC << 8);
@@ -900,7 +921,14 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (ret < 0)
goto fail;
- mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
+ if (one_regmap_config) {
+ mcp->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
+ "mcp23xxx-pinctrl.%d", raw_chip_address);
+ if (!mcp->pinctrl_desc.name)
+ return -ENOMEM;
+ } else {
+ mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
+ }
mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops;
mcp->pinctrl_desc.confops = &mcp_pinconf_ops;
mcp->pinctrl_desc.npins = mcp->chip.ngpio;