summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpio-mcp23s08.c
diff options
context:
space:
mode:
authorPhil Reid <preid@electromag.com.au>2016-03-01 09:25:41 +0300
committerLinus Walleij <linus.walleij@linaro.org>2016-03-09 05:50:37 +0300
commit28c5a41e4aa44f162297d596030900b90aa1cf08 (patch)
treeb17ea91d50725d924ed7f6f9db4bff1b81ef3fbd /drivers/gpio/gpio-mcp23s08.c
parentdf2e90551b7db4b5a4da5eaa78742f47f2799aa2 (diff)
downloadlinux-28c5a41e4aa44f162297d596030900b90aa1cf08.tar.xz
gpio: mcp23s08: Add support for mcp23s18
This patch adds support for the mcp23s18 which is very similar to the mcp23s17. A couple of control bits are not the same. Notable IOCON_HAEN (s17 only) & IOCON_INTCC. Which can be ignored. Patch changes the following: - Add mcp23s18 types. - Always set mirror bit if the dts defines mcp23s18. regardless of type. Mirror bit is ignored on 8 bit devices anyway. - In mcp23s08_probe use chip.ngpio instead of logic based on type to determine number of gpio lins to increment by. This is set appropiately by the call to mcp23s08_probe_one. - Add mcp23s18 to device tree documentation. - Remove statement that irqs don't work for spi. They do. Tested with mcp23s18. Signed-off-by: Phil Reid <preid@electromag.com.au> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-mcp23s08.c')
-rw-r--r--drivers/gpio/gpio-mcp23s08.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index f8d4abcff573..971915830d7f 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -31,6 +31,7 @@
#define MCP_TYPE_S17 1
#define MCP_TYPE_008 2
#define MCP_TYPE_017 3
+#define MCP_TYPE_S18 4
/* Registers are all 8 bits wide.
*
@@ -617,6 +618,12 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s17";
break;
+
+ case MCP_TYPE_S18:
+ mcp->ops = &mcp23s17_ops;
+ mcp->chip.ngpio = 16;
+ mcp->chip.label = "mcp23s18";
+ break;
#endif /* CONFIG_SPI_MASTER */
#if IS_ENABLED(CONFIG_I2C)
@@ -657,8 +664,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
of_property_read_bool(mcp->chip.parent->of_node,
"microchip,irq-active-high");
- if (type == MCP_TYPE_017)
- mirror = pdata->mirror;
+ mirror = pdata->mirror;
}
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
@@ -735,6 +741,10 @@ static const struct of_device_id mcp23s08_spi_of_match[] = {
.compatible = "microchip,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
+ {
+ .compatible = "microchip,mcp23s18",
+ .data = (void *) MCP_TYPE_S18,
+ },
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23s08",
@@ -971,8 +981,8 @@ static int mcp23s08_probe(struct spi_device *spi)
goto fail;
if (pdata->base != -1)
- pdata->base += (type == MCP_TYPE_S17) ? 16 : 8;
- ngpio += (type == MCP_TYPE_S17) ? 16 : 8;
+ pdata->base += data->mcp[addr]->chip.ngpio;
+ ngpio += data->mcp[addr]->chip.ngpio;
}
data->ngpio = ngpio;
@@ -1014,6 +1024,7 @@ static int mcp23s08_remove(struct spi_device *spi)
static const struct spi_device_id mcp23s08_ids[] = {
{ "mcp23s08", MCP_TYPE_S08 },
{ "mcp23s17", MCP_TYPE_S17 },
+ { "mcp23s18", MCP_TYPE_S18 },
{ },
};
MODULE_DEVICE_TABLE(spi, mcp23s08_ids);