Commit 28c5a41e authored by Phil Reid's avatar Phil Reid Committed by Linus Walleij

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: default avatarPhil Reid <preid@electromag.com.au>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent df2e9055
...@@ -10,6 +10,7 @@ Required properties: ...@@ -10,6 +10,7 @@ Required properties:
- "microchip,mcp23s08" for 8 GPIO SPI version - "microchip,mcp23s08" for 8 GPIO SPI version
- "microchip,mcp23s17" for 16 GPIO SPI version - "microchip,mcp23s17" for 16 GPIO SPI version
- "microchip,mcp23s18" for 16 GPIO SPI version
- "microchip,mcp23008" for 8 GPIO I2C version or - "microchip,mcp23008" for 8 GPIO I2C version or
- "microchip,mcp23017" for 16 GPIO I2C version of the chip - "microchip,mcp23017" for 16 GPIO I2C version of the chip
NOTE: Do not use the old mcp prefix any more. It is deprecated and will be NOTE: Do not use the old mcp prefix any more. It is deprecated and will be
...@@ -43,9 +44,6 @@ Optional properties: ...@@ -43,9 +44,6 @@ Optional properties:
- first cell is the pin number - first cell is the pin number
- second cell is used to specify flags. - second cell is used to specify flags.
- interrupt-controller: Marks the device node as a interrupt controller. - interrupt-controller: Marks the device node as a interrupt controller.
NOTE: The interrupt functionality is only supported for i2c versions of the
chips. The spi chips can also do the interrupts, but this is not supported by
the linux driver yet.
Optional device specific properties: Optional device specific properties:
- microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices - microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#define MCP_TYPE_S17 1 #define MCP_TYPE_S17 1
#define MCP_TYPE_008 2 #define MCP_TYPE_008 2
#define MCP_TYPE_017 3 #define MCP_TYPE_017 3
#define MCP_TYPE_S18 4
/* Registers are all 8 bits wide. /* Registers are all 8 bits wide.
* *
...@@ -617,6 +618,12 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, ...@@ -617,6 +618,12 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
mcp->chip.ngpio = 16; mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s17"; mcp->chip.label = "mcp23s17";
break; break;
case MCP_TYPE_S18:
mcp->ops = &mcp23s17_ops;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s18";
break;
#endif /* CONFIG_SPI_MASTER */ #endif /* CONFIG_SPI_MASTER */
#if IS_ENABLED(CONFIG_I2C) #if IS_ENABLED(CONFIG_I2C)
...@@ -657,8 +664,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, ...@@ -657,8 +664,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
of_property_read_bool(mcp->chip.parent->of_node, of_property_read_bool(mcp->chip.parent->of_node,
"microchip,irq-active-high"); "microchip,irq-active-high");
if (type == MCP_TYPE_017) mirror = pdata->mirror;
mirror = pdata->mirror;
} }
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
...@@ -735,6 +741,10 @@ static const struct of_device_id mcp23s08_spi_of_match[] = { ...@@ -735,6 +741,10 @@ static const struct of_device_id mcp23s08_spi_of_match[] = {
.compatible = "microchip,mcp23s17", .compatible = "microchip,mcp23s17",
.data = (void *) MCP_TYPE_S17, .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. */ /* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{ {
.compatible = "mcp,mcp23s08", .compatible = "mcp,mcp23s08",
...@@ -971,8 +981,8 @@ static int mcp23s08_probe(struct spi_device *spi) ...@@ -971,8 +981,8 @@ static int mcp23s08_probe(struct spi_device *spi)
goto fail; goto fail;
if (pdata->base != -1) if (pdata->base != -1)
pdata->base += (type == MCP_TYPE_S17) ? 16 : 8; pdata->base += data->mcp[addr]->chip.ngpio;
ngpio += (type == MCP_TYPE_S17) ? 16 : 8; ngpio += data->mcp[addr]->chip.ngpio;
} }
data->ngpio = ngpio; data->ngpio = ngpio;
...@@ -1014,6 +1024,7 @@ static int mcp23s08_remove(struct spi_device *spi) ...@@ -1014,6 +1024,7 @@ static int mcp23s08_remove(struct spi_device *spi)
static const struct spi_device_id mcp23s08_ids[] = { static const struct spi_device_id mcp23s08_ids[] = {
{ "mcp23s08", MCP_TYPE_S08 }, { "mcp23s08", MCP_TYPE_S08 },
{ "mcp23s17", MCP_TYPE_S17 }, { "mcp23s17", MCP_TYPE_S17 },
{ "mcp23s18", MCP_TYPE_S18 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(spi, mcp23s08_ids); MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment