aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Reid <preid@electromag.com.au>2018-02-19 04:25:20 -0500
committerLinus Walleij <linus.walleij@linaro.org>2018-02-22 10:08:59 -0500
commitfa2b7fae8426e2cd690278e514abcc09e4f89a8f (patch)
tree2869ac85c88bbd39c84532d0b2a913f37451c5da
parent39aba4714da62946ef9d081ab6e41462517ccb34 (diff)
pinctrl: mcp23s08: add open drain configuration for irq output
The mcp23s08 series device can be configured for wired and interrupts using an external pull-up and open drain output via the IOCON_ODR bit. And "drive-open-drain" property to enable this. Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk> Signed-off-by: Phil Reid <preid@electromag.com.au> Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pinctrl-mcp23s08.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c
index 832775709eff..022307dd4b54 100644
--- a/drivers/pinctrl/pinctrl-mcp23s08.c
+++ b/drivers/pinctrl/pinctrl-mcp23s08.c
@@ -771,6 +771,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
771{ 771{
772 int status, ret; 772 int status, ret;
773 bool mirror = false; 773 bool mirror = false;
774 bool open_drain = false;
774 struct regmap_config *one_regmap_config = NULL; 775 struct regmap_config *one_regmap_config = NULL;
775 int raw_chip_address = (addr & ~0x40) >> 1; 776 int raw_chip_address = (addr & ~0x40) >> 1;
776 777
@@ -883,10 +884,11 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
883 "microchip,irq-active-high"); 884 "microchip,irq-active-high");
884 885
885 mirror = device_property_read_bool(dev, "microchip,irq-mirror"); 886 mirror = device_property_read_bool(dev, "microchip,irq-mirror");
887 open_drain = device_property_read_bool(dev, "drive-open-drain");
886 } 888 }
887 889
888 if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || 890 if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
889 mcp->irq_active_high) { 891 mcp->irq_active_high || open_drain) {
890 /* mcp23s17 has IOCON twice, make sure they are in sync */ 892 /* mcp23s17 has IOCON twice, make sure they are in sync */
891 status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8)); 893 status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8));
892 status |= IOCON_HAEN | (IOCON_HAEN << 8); 894 status |= IOCON_HAEN | (IOCON_HAEN << 8);
@@ -898,6 +900,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
898 if (mirror) 900 if (mirror)
899 status |= IOCON_MIRROR | (IOCON_MIRROR << 8); 901 status |= IOCON_MIRROR | (IOCON_MIRROR << 8);
900 902
903 if (open_drain)
904 status |= IOCON_ODR | (IOCON_ODR << 8);
905
901 if (type == MCP_TYPE_S18 || type == MCP_TYPE_018) 906 if (type == MCP_TYPE_S18 || type == MCP_TYPE_018)
902 status |= IOCON_INTCC | (IOCON_INTCC << 8); 907 status |= IOCON_INTCC | (IOCON_INTCC << 8);
903 908