* [PATCH v4 0/2] add SAMA5D2 PIOBU GPIO driver @ 2018-12-12 11:56 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:56 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu On SAMA5D2 SoC the PIOBU pins do not lose their voltage during Backup/Self-refresh mode. This can be useful, for example, when the voltage must remain positive for a peripheral during Backup/Self-refresh mode (suspend-to ram is the Linux equivalent state). v4: - readd Makefile and Kconfig changes which are missing in v3 v3: - change driver's compatible to atmel,sama5d2-secumod - get syscon using syscon_node_to_regmap(pdev->dev.of_node) - document how to use SECUMOD as a gpio-controller v2: - make driver be a subnode of the syscon node - change Kconfig to depend on MFD_SYSCON and select GPIO_SYSCON - change include header from linux/gpio.h to linux/gpio/driver.h - include linux/bits.h header - change intrusion in comment to tamper - fix kerneldoc of functions - replace GPIOF_DIR_* flags with 0/1 - replace ?: statement with if-else - remove the use of sama5d2_piobu_template_chip - retrieve syscon via syscon_node_to_regmap(pdev->dev.parent->of_node); Note that PIOBU_REG_SIZE is used to determine the register to write to with regmap: reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; Also, no irq capability implemented. Andrei Stefanescu (2): dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller gpio: add driver for SAMA5D2 PIOBU pins .../devicetree/bindings/arm/atmel-sysregs.txt | 12 +- MAINTAINERS | 6 + drivers/gpio/Kconfig | 11 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-sama5d2-piobu.c | 253 +++++++++++++++++++++ 5 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c -- 2.7.4 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 0/2] add SAMA5D2 PIOBU GPIO driver @ 2018-12-12 11:56 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:56 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu On SAMA5D2 SoC the PIOBU pins do not lose their voltage during Backup/Self-refresh mode. This can be useful, for example, when the voltage must remain positive for a peripheral during Backup/Self-refresh mode (suspend-to ram is the Linux equivalent state). v4: - readd Makefile and Kconfig changes which are missing in v3 v3: - change driver's compatible to atmel,sama5d2-secumod - get syscon using syscon_node_to_regmap(pdev->dev.of_node) - document how to use SECUMOD as a gpio-controller v2: - make driver be a subnode of the syscon node - change Kconfig to depend on MFD_SYSCON and select GPIO_SYSCON - change include header from linux/gpio.h to linux/gpio/driver.h - include linux/bits.h header - change intrusion in comment to tamper - fix kerneldoc of functions - replace GPIOF_DIR_* flags with 0/1 - replace ?: statement with if-else - remove the use of sama5d2_piobu_template_chip - retrieve syscon via syscon_node_to_regmap(pdev->dev.parent->of_node); Note that PIOBU_REG_SIZE is used to determine the register to write to with regmap: reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; Also, no irq capability implemented. Andrei Stefanescu (2): dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller gpio: add driver for SAMA5D2 PIOBU pins .../devicetree/bindings/arm/atmel-sysregs.txt | 12 +- MAINTAINERS | 6 + drivers/gpio/Kconfig | 11 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-sama5d2-piobu.c | 253 +++++++++++++++++++++ 5 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c -- 2.7.4 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 0/2] add SAMA5D2 PIOBU GPIO driver @ 2018-12-12 11:56 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:56 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: devicetree, Andrei.Stefanescu, linux-kernel, linux-gpio, Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel On SAMA5D2 SoC the PIOBU pins do not lose their voltage during Backup/Self-refresh mode. This can be useful, for example, when the voltage must remain positive for a peripheral during Backup/Self-refresh mode (suspend-to ram is the Linux equivalent state). v4: - readd Makefile and Kconfig changes which are missing in v3 v3: - change driver's compatible to atmel,sama5d2-secumod - get syscon using syscon_node_to_regmap(pdev->dev.of_node) - document how to use SECUMOD as a gpio-controller v2: - make driver be a subnode of the syscon node - change Kconfig to depend on MFD_SYSCON and select GPIO_SYSCON - change include header from linux/gpio.h to linux/gpio/driver.h - include linux/bits.h header - change intrusion in comment to tamper - fix kerneldoc of functions - replace GPIOF_DIR_* flags with 0/1 - replace ?: statement with if-else - remove the use of sama5d2_piobu_template_chip - retrieve syscon via syscon_node_to_regmap(pdev->dev.parent->of_node); Note that PIOBU_REG_SIZE is used to determine the register to write to with regmap: reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; Also, no irq capability implemented. Andrei Stefanescu (2): dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller gpio: add driver for SAMA5D2 PIOBU pins .../devicetree/bindings/arm/atmel-sysregs.txt | 12 +- MAINTAINERS | 6 + drivers/gpio/Kconfig | 11 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-sama5d2-piobu.c | 253 +++++++++++++++++++++ 5 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller 2018-12-12 11:56 ` Andrei.Stefanescu (?) @ 2018-12-12 11:57 ` Andrei.Stefanescu -1 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:57 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu This patch describes the Security Module's usage as a GPIO controller for its PIOBU pins. These pins have the special property of maintaining their voltage during suspend-to-mem. Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> --- Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt index 4b96608..c89db84 100644 --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt @@ -158,14 +158,24 @@ Security Module (SECUMOD) The Security Module macrocell provides all necessary secure functions to avoid voltage, temperature, frequency and mechanical attacks on the chip. It also -embeds secure memories that can be scrambled +embeds secure memories that can be scrambled. + +The Security Module also offers the PIOBU pins which can be used as GPIO pins. +Note that they maintain their voltage during Backup/Self-refresh. required properties: - compatible: Should be "atmel,<chip>-secumod", "syscon". <chip> can be "sama5d2". - reg: Should contain registers location and length +- gpio-controller: Marks the port as GPIO controller. +- #gpio-cells: There are 2. The pin number is the + first, the second represents additional + parameters such as GPIO_ACTIVE_HIGH/LOW. + secumod@fc040000 { compatible = "atmel,sama5d2-secumod", "syscon"; reg = <0xfc040000 0x100>; + gpio-controller; + #gpio-cells = <2>; }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller @ 2018-12-12 11:57 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:57 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu This patch describes the Security Module's usage as a GPIO controller for its PIOBU pins. These pins have the special property of maintaining their voltage during suspend-to-mem. Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> --- Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt index 4b96608..c89db84 100644 --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt @@ -158,14 +158,24 @@ Security Module (SECUMOD) The Security Module macrocell provides all necessary secure functions to avoid voltage, temperature, frequency and mechanical attacks on the chip. It also -embeds secure memories that can be scrambled +embeds secure memories that can be scrambled. + +The Security Module also offers the PIOBU pins which can be used as GPIO pins. +Note that they maintain their voltage during Backup/Self-refresh. required properties: - compatible: Should be "atmel,<chip>-secumod", "syscon". <chip> can be "sama5d2". - reg: Should contain registers location and length +- gpio-controller: Marks the port as GPIO controller. +- #gpio-cells: There are 2. The pin number is the + first, the second represents additional + parameters such as GPIO_ACTIVE_HIGH/LOW. + secumod@fc040000 { compatible = "atmel,sama5d2-secumod", "syscon"; reg = <0xfc040000 0x100>; + gpio-controller; + #gpio-cells = <2>; }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller @ 2018-12-12 11:57 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:57 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: devicetree, Andrei.Stefanescu, linux-kernel, linux-gpio, Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel This patch describes the Security Module's usage as a GPIO controller for its PIOBU pins. These pins have the special property of maintaining their voltage during suspend-to-mem. Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> --- Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt index 4b96608..c89db84 100644 --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt @@ -158,14 +158,24 @@ Security Module (SECUMOD) The Security Module macrocell provides all necessary secure functions to avoid voltage, temperature, frequency and mechanical attacks on the chip. It also -embeds secure memories that can be scrambled +embeds secure memories that can be scrambled. + +The Security Module also offers the PIOBU pins which can be used as GPIO pins. +Note that they maintain their voltage during Backup/Self-refresh. required properties: - compatible: Should be "atmel,<chip>-secumod", "syscon". <chip> can be "sama5d2". - reg: Should contain registers location and length +- gpio-controller: Marks the port as GPIO controller. +- #gpio-cells: There are 2. The pin number is the + first, the second represents additional + parameters such as GPIO_ACTIVE_HIGH/LOW. + secumod@fc040000 { compatible = "atmel,sama5d2-secumod", "syscon"; reg = <0xfc040000 0x100>; + gpio-controller; + #gpio-cells = <2>; }; -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller 2018-12-12 11:57 ` Andrei.Stefanescu (?) @ 2018-12-17 21:47 ` Rob Herring -1 siblings, 0 replies; 16+ messages in thread From: Rob Herring @ 2018-12-17 21:47 UTC (permalink / raw) Cc: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland, Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu On Wed, 12 Dec 2018 11:57:11 +0000, <Andrei.Stefanescu@microchip.com> wrote: > This patch describes the Security Module's usage as a GPIO > controller for its PIOBU pins. These pins have the special > property of maintaining their voltage during suspend-to-mem. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> > --- > Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller @ 2018-12-17 21:47 ` Rob Herring 0 siblings, 0 replies; 16+ messages in thread From: Rob Herring @ 2018-12-17 21:47 UTC (permalink / raw) To: Andrei.Stefanescu Cc: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland, Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu On Wed, 12 Dec 2018 11:57:11 +0000, <Andrei.Stefanescu@microchip.com> wrote: > This patch describes the Security Module's usage as a GPIO > controller for its PIOBU pins. These pins have the special > property of maintaining their voltage during suspend-to-mem. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> > --- > Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller @ 2018-12-17 21:47 ` Rob Herring 0 siblings, 0 replies; 16+ messages in thread From: Rob Herring @ 2018-12-17 21:47 UTC (permalink / raw) To: Andrei.Stefanescu Cc: mark.rutland, devicetree, Andrei.Stefanescu, gregkh, linus.walleij, linux-kernel, linux-gpio, Ludovic.Desroches, robh+dt, linux-arm-kernel, Cristian.Birsan On Wed, 12 Dec 2018 11:57:11 +0000, <Andrei.Stefanescu@microchip.com> wrote: > This patch describes the Security Module's usage as a GPIO > controller for its PIOBU pins. These pins have the special > property of maintaining their voltage during suspend-to-mem. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> > --- > Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > Reviewed-by: Rob Herring <robh@kernel.org> _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller 2018-12-12 11:57 ` Andrei.Stefanescu @ 2018-12-21 9:55 ` Linus Walleij -1 siblings, 0 replies; 16+ messages in thread From: Linus Walleij @ 2018-12-21 9:55 UTC (permalink / raw) To: Andrei.Stefanescu Cc: Rob Herring, Greg KH, Nicolas Ferre, Mark Rutland, Ludovic Desroches, Cristian.Birsan, Linux ARM, open list:GPIO SUBSYSTEM, linux-kernel@vger.kernel.org, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS On Wed, Dec 12, 2018 at 12:57 PM <Andrei.Stefanescu@microchip.com> wrote: > This patch describes the Security Module's usage as a GPIO > controller for its PIOBU pins. These pins have the special > property of maintaining their voltage during suspend-to-mem. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> Patch applied with Rob's ACK. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller @ 2018-12-21 9:55 ` Linus Walleij 0 siblings, 0 replies; 16+ messages in thread From: Linus Walleij @ 2018-12-21 9:55 UTC (permalink / raw) To: Andrei.Stefanescu Cc: Mark Rutland, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, Greg KH, linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM, Ludovic Desroches, Rob Herring, Linux ARM, Cristian.Birsan On Wed, Dec 12, 2018 at 12:57 PM <Andrei.Stefanescu@microchip.com> wrote: > This patch describes the Security Module's usage as a GPIO > controller for its PIOBU pins. These pins have the special > property of maintaining their voltage during suspend-to-mem. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> Patch applied with Rob's ACK. Yours, Linus Walleij _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins 2018-12-12 11:56 ` Andrei.Stefanescu (?) @ 2018-12-12 11:57 ` Andrei.Stefanescu -1 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:57 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu PIOBU pins do not lose their voltage during Backup/Self-refresh. This patch adds a simple GPIO controller for them and a maintainer for the driver. This driver adds support for using the pins as GPIO offering the possibility to read/set the voltage. Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> --- MAINTAINERS | 6 + drivers/gpio/Kconfig | 11 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-sama5d2-piobu.c | 253 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c diff --git a/MAINTAINERS b/MAINTAINERS index f485597..fadc96d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9760,6 +9760,12 @@ M: Nicolas Ferre <nicolas.ferre@microchip.com> S: Supported F: drivers/power/reset/at91-sama5d2_shdwc.c +MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO +M: Andrei Stefanescu <andrei.stefanescu@microchip.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-gpio@vger.kernel.org +F: drivers/gpio/gpio-sama5d2-piobu.c + MICROCHIP SPI DRIVER M: Nicolas Ferre <nicolas.ferre@microchip.com> S: Supported diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 833a1b5..1c41fac 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -429,6 +429,17 @@ config GPIO_REG A 32-bit single register GPIO fixed in/out implementation. This can be used to represent any register as a set of GPIO signals. +config GPIO_SAMA5D2_PIOBU + tristate "SAMA5D2 PIOBU GPIO support" + depends on MFD_SYSCON + select GPIO_SYSCON + help + Say yes here to use the PIOBU pins as GPIOs. + + PIOBU pins on the SAMA5D2 can be used as GPIOs. + The difference from regular GPIOs is that they + maintain their value during backup/self-refresh. + config GPIO_SIOX tristate "SIOX GPIO support" depends on SIOX diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 671c447..f18d345 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o obj-$(CONFIG_GPIO_REG) += gpio-reg.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o +obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o diff --git a/drivers/gpio/gpio-sama5d2-piobu.c b/drivers/gpio/gpio-sama5d2-piobu.c new file mode 100644 index 0000000..03a0006 --- /dev/null +++ b/drivers/gpio/gpio-sama5d2-piobu.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SAMA5D2 PIOBU GPIO controller + * + * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries + * + * Author: Andrei Stefanescu <andrei.stefanescu@microchip.com> + * + */ +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define PIOBU_NUM 8 +#define PIOBU_REG_SIZE 4 + +/* + * backup mode protection register for tamper detection + * normal mode protection register for tamper detection + * wakeup signal generation + */ +#define PIOBU_BMPR 0x7C +#define PIOBU_NMPR 0x80 +#define PIOBU_WKPR 0x90 + +#define PIOBU_BASE 0x18 /* PIOBU offset from SECUMOD base register address. */ + +#define PIOBU_DET_OFFSET 16 + +/* In the datasheet this bit is called OUTPUT */ +#define PIOBU_DIRECTION BIT(8) +#define PIOBU_OUT BIT(8) +#define PIOBU_IN 0 + +#define PIOBU_SOD BIT(9) +#define PIOBU_PDS BIT(10) + +#define PIOBU_HIGH BIT(9) +#define PIOBU_LOW 0 + +struct sama5d2_piobu { + struct gpio_chip chip; + struct regmap *regmap; +}; + +/** + * sama5d2_piobu_setup_pin() - prepares a pin for set_direction call + * + * Do not consider pin for tamper detection (normal and backup modes) + * Do not consider pin as tamper wakeup interrupt source + */ +static int sama5d2_piobu_setup_pin(struct gpio_chip *chip, unsigned int pin) +{ + int ret; + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + unsigned int mask = BIT(PIOBU_DET_OFFSET + pin); + + ret = regmap_update_bits(piobu->regmap, PIOBU_BMPR, mask, 0); + if (ret) + return ret; + + ret = regmap_update_bits(piobu->regmap, PIOBU_NMPR, mask, 0); + if (ret) + return ret; + + return regmap_update_bits(piobu->regmap, PIOBU_WKPR, mask, 0); +} + +/** + * sama5d2_piobu_write_value() - writes value & mask at the pin's PIOBU register + */ +static int sama5d2_piobu_write_value(struct gpio_chip *chip, unsigned int pin, + unsigned int mask, unsigned int value) +{ + int reg; + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + + reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; + + return regmap_update_bits(piobu->regmap, reg, mask, value); +} + +/** + * sama5d2_piobu_read_value() - read the value with masking from the pin's PIOBU + * register + */ +static int sama5d2_piobu_read_value(struct gpio_chip *chip, unsigned int pin, + unsigned int mask) +{ + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + unsigned int val, reg; + int ret; + + reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; + ret = regmap_read(piobu->regmap, reg, &val); + if (ret < 0) + return ret; + + return val & mask; +} + +/** + * sama5d2_piobu_set_direction() - mark pin as input or output + */ +static int sama5d2_piobu_set_direction(struct gpio_chip *chip, + unsigned int direction, + unsigned int pin) +{ + return sama5d2_piobu_write_value(chip, pin, PIOBU_DIRECTION, direction); +} + +/** + * sama5d2_piobu_get_direction() - gpiochip get_direction + */ +static int sama5d2_piobu_get_direction(struct gpio_chip *chip, + unsigned int pin) +{ + int ret = sama5d2_piobu_read_value(chip, pin, PIOBU_DIRECTION); + + if (ret < 0) + return ret; + + return (ret == PIOBU_IN) ? 1 : 0; +} + +/** + * sama5d2_piobu_direction_input() - gpiochip direction_input + */ +static int sama5d2_piobu_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + return sama5d2_piobu_set_direction(chip, PIOBU_IN, pin); +} + +/** + * sama5d2_piobu_direction_output() - gpiochip direction_output + */ +static int sama5d2_piobu_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + return sama5d2_piobu_set_direction(chip, PIOBU_OUT, pin); +} + +/** + * sama5d2_piobu_get() - gpiochip get + */ +static int sama5d2_piobu_get(struct gpio_chip *chip, unsigned int pin) +{ + /* if pin is input, read value from PDS else read from SOD */ + int ret = sama5d2_piobu_get_direction(chip, pin); + + if (ret == 1) + ret = sama5d2_piobu_read_value(chip, pin, PIOBU_PDS); + else if (!ret) + ret = sama5d2_piobu_read_value(chip, pin, PIOBU_SOD); + + if (ret < 0) + return ret; + + return !!ret; +} + +/** + * sama5d2_piobu_set() - gpiochip set + */ +static void sama5d2_piobu_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + if (!value) + value = PIOBU_LOW; + else + value = PIOBU_HIGH; + + sama5d2_piobu_write_value(chip, pin, PIOBU_SOD, value); +} + +static int sama5d2_piobu_probe(struct platform_device *pdev) +{ + struct sama5d2_piobu *piobu; + int ret, i; + + piobu = devm_kzalloc(&pdev->dev, sizeof(*piobu), GFP_KERNEL); + if (!piobu) + return -ENOMEM; + + platform_set_drvdata(pdev, piobu); + piobu->chip.label = pdev->name; + piobu->chip.parent = &pdev->dev; + piobu->chip.of_node = pdev->dev.of_node; + piobu->chip.owner = THIS_MODULE, + piobu->chip.get_direction = sama5d2_piobu_get_direction, + piobu->chip.direction_input = sama5d2_piobu_direction_input, + piobu->chip.direction_output = sama5d2_piobu_direction_output, + piobu->chip.get = sama5d2_piobu_get, + piobu->chip.set = sama5d2_piobu_set, + piobu->chip.base = -1, + piobu->chip.ngpio = PIOBU_NUM, + piobu->chip.can_sleep = 0, + + piobu->regmap = syscon_node_to_regmap(pdev->dev.of_node); + if (IS_ERR(piobu->regmap)) { + dev_err(&pdev->dev, "Failed to get syscon regmap %ld\n", + PTR_ERR(piobu->regmap)); + return PTR_ERR(piobu->regmap); + } + + ret = devm_gpiochip_add_data(&pdev->dev, &piobu->chip, piobu); + if (ret) { + dev_err(&pdev->dev, "Failed to add gpiochip %d\n", ret); + return ret; + } + + for (i = 0; i < PIOBU_NUM; ++i) { + ret = sama5d2_piobu_setup_pin(&piobu->chip, i); + if (ret) { + dev_err(&pdev->dev, "Failed to setup pin: %d %d\n", + i, ret); + return ret; + } + } + + return 0; +} + +static const struct of_device_id sama5d2_piobu_ids[] = { + { .compatible = "atmel,sama5d2-secumod" }, + {}, +}; +MODULE_DEVICE_TABLE(of, sama5d2_piobu_ids); + +static struct platform_driver sama5d2_piobu_driver = { + .driver = { + .name = "sama5d2-piobu", + .of_match_table = of_match_ptr(sama5d2_piobu_ids) + }, + .probe = sama5d2_piobu_probe, +}; + +module_platform_driver(sama5d2_piobu_driver); + +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SAMA5D2 PIOBU controller driver"); +MODULE_AUTHOR("Andrei Stefanescu <andrei.stefanescu@microchip.com>"); -- 2.7.4 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins @ 2018-12-12 11:57 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:57 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel, linux-gpio, linux-kernel, devicetree, Andrei.Stefanescu PIOBU pins do not lose their voltage during Backup/Self-refresh. This patch adds a simple GPIO controller for them and a maintainer for the driver. This driver adds support for using the pins as GPIO offering the possibility to read/set the voltage. Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> --- MAINTAINERS | 6 + drivers/gpio/Kconfig | 11 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-sama5d2-piobu.c | 253 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c diff --git a/MAINTAINERS b/MAINTAINERS index f485597..fadc96d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9760,6 +9760,12 @@ M: Nicolas Ferre <nicolas.ferre@microchip.com> S: Supported F: drivers/power/reset/at91-sama5d2_shdwc.c +MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO +M: Andrei Stefanescu <andrei.stefanescu@microchip.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-gpio@vger.kernel.org +F: drivers/gpio/gpio-sama5d2-piobu.c + MICROCHIP SPI DRIVER M: Nicolas Ferre <nicolas.ferre@microchip.com> S: Supported diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 833a1b5..1c41fac 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -429,6 +429,17 @@ config GPIO_REG A 32-bit single register GPIO fixed in/out implementation. This can be used to represent any register as a set of GPIO signals. +config GPIO_SAMA5D2_PIOBU + tristate "SAMA5D2 PIOBU GPIO support" + depends on MFD_SYSCON + select GPIO_SYSCON + help + Say yes here to use the PIOBU pins as GPIOs. + + PIOBU pins on the SAMA5D2 can be used as GPIOs. + The difference from regular GPIOs is that they + maintain their value during backup/self-refresh. + config GPIO_SIOX tristate "SIOX GPIO support" depends on SIOX diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 671c447..f18d345 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o obj-$(CONFIG_GPIO_REG) += gpio-reg.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o +obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o diff --git a/drivers/gpio/gpio-sama5d2-piobu.c b/drivers/gpio/gpio-sama5d2-piobu.c new file mode 100644 index 0000000..03a0006 --- /dev/null +++ b/drivers/gpio/gpio-sama5d2-piobu.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SAMA5D2 PIOBU GPIO controller + * + * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries + * + * Author: Andrei Stefanescu <andrei.stefanescu@microchip.com> + * + */ +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define PIOBU_NUM 8 +#define PIOBU_REG_SIZE 4 + +/* + * backup mode protection register for tamper detection + * normal mode protection register for tamper detection + * wakeup signal generation + */ +#define PIOBU_BMPR 0x7C +#define PIOBU_NMPR 0x80 +#define PIOBU_WKPR 0x90 + +#define PIOBU_BASE 0x18 /* PIOBU offset from SECUMOD base register address. */ + +#define PIOBU_DET_OFFSET 16 + +/* In the datasheet this bit is called OUTPUT */ +#define PIOBU_DIRECTION BIT(8) +#define PIOBU_OUT BIT(8) +#define PIOBU_IN 0 + +#define PIOBU_SOD BIT(9) +#define PIOBU_PDS BIT(10) + +#define PIOBU_HIGH BIT(9) +#define PIOBU_LOW 0 + +struct sama5d2_piobu { + struct gpio_chip chip; + struct regmap *regmap; +}; + +/** + * sama5d2_piobu_setup_pin() - prepares a pin for set_direction call + * + * Do not consider pin for tamper detection (normal and backup modes) + * Do not consider pin as tamper wakeup interrupt source + */ +static int sama5d2_piobu_setup_pin(struct gpio_chip *chip, unsigned int pin) +{ + int ret; + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + unsigned int mask = BIT(PIOBU_DET_OFFSET + pin); + + ret = regmap_update_bits(piobu->regmap, PIOBU_BMPR, mask, 0); + if (ret) + return ret; + + ret = regmap_update_bits(piobu->regmap, PIOBU_NMPR, mask, 0); + if (ret) + return ret; + + return regmap_update_bits(piobu->regmap, PIOBU_WKPR, mask, 0); +} + +/** + * sama5d2_piobu_write_value() - writes value & mask at the pin's PIOBU register + */ +static int sama5d2_piobu_write_value(struct gpio_chip *chip, unsigned int pin, + unsigned int mask, unsigned int value) +{ + int reg; + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + + reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; + + return regmap_update_bits(piobu->regmap, reg, mask, value); +} + +/** + * sama5d2_piobu_read_value() - read the value with masking from the pin's PIOBU + * register + */ +static int sama5d2_piobu_read_value(struct gpio_chip *chip, unsigned int pin, + unsigned int mask) +{ + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + unsigned int val, reg; + int ret; + + reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; + ret = regmap_read(piobu->regmap, reg, &val); + if (ret < 0) + return ret; + + return val & mask; +} + +/** + * sama5d2_piobu_set_direction() - mark pin as input or output + */ +static int sama5d2_piobu_set_direction(struct gpio_chip *chip, + unsigned int direction, + unsigned int pin) +{ + return sama5d2_piobu_write_value(chip, pin, PIOBU_DIRECTION, direction); +} + +/** + * sama5d2_piobu_get_direction() - gpiochip get_direction + */ +static int sama5d2_piobu_get_direction(struct gpio_chip *chip, + unsigned int pin) +{ + int ret = sama5d2_piobu_read_value(chip, pin, PIOBU_DIRECTION); + + if (ret < 0) + return ret; + + return (ret == PIOBU_IN) ? 1 : 0; +} + +/** + * sama5d2_piobu_direction_input() - gpiochip direction_input + */ +static int sama5d2_piobu_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + return sama5d2_piobu_set_direction(chip, PIOBU_IN, pin); +} + +/** + * sama5d2_piobu_direction_output() - gpiochip direction_output + */ +static int sama5d2_piobu_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + return sama5d2_piobu_set_direction(chip, PIOBU_OUT, pin); +} + +/** + * sama5d2_piobu_get() - gpiochip get + */ +static int sama5d2_piobu_get(struct gpio_chip *chip, unsigned int pin) +{ + /* if pin is input, read value from PDS else read from SOD */ + int ret = sama5d2_piobu_get_direction(chip, pin); + + if (ret == 1) + ret = sama5d2_piobu_read_value(chip, pin, PIOBU_PDS); + else if (!ret) + ret = sama5d2_piobu_read_value(chip, pin, PIOBU_SOD); + + if (ret < 0) + return ret; + + return !!ret; +} + +/** + * sama5d2_piobu_set() - gpiochip set + */ +static void sama5d2_piobu_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + if (!value) + value = PIOBU_LOW; + else + value = PIOBU_HIGH; + + sama5d2_piobu_write_value(chip, pin, PIOBU_SOD, value); +} + +static int sama5d2_piobu_probe(struct platform_device *pdev) +{ + struct sama5d2_piobu *piobu; + int ret, i; + + piobu = devm_kzalloc(&pdev->dev, sizeof(*piobu), GFP_KERNEL); + if (!piobu) + return -ENOMEM; + + platform_set_drvdata(pdev, piobu); + piobu->chip.label = pdev->name; + piobu->chip.parent = &pdev->dev; + piobu->chip.of_node = pdev->dev.of_node; + piobu->chip.owner = THIS_MODULE, + piobu->chip.get_direction = sama5d2_piobu_get_direction, + piobu->chip.direction_input = sama5d2_piobu_direction_input, + piobu->chip.direction_output = sama5d2_piobu_direction_output, + piobu->chip.get = sama5d2_piobu_get, + piobu->chip.set = sama5d2_piobu_set, + piobu->chip.base = -1, + piobu->chip.ngpio = PIOBU_NUM, + piobu->chip.can_sleep = 0, + + piobu->regmap = syscon_node_to_regmap(pdev->dev.of_node); + if (IS_ERR(piobu->regmap)) { + dev_err(&pdev->dev, "Failed to get syscon regmap %ld\n", + PTR_ERR(piobu->regmap)); + return PTR_ERR(piobu->regmap); + } + + ret = devm_gpiochip_add_data(&pdev->dev, &piobu->chip, piobu); + if (ret) { + dev_err(&pdev->dev, "Failed to add gpiochip %d\n", ret); + return ret; + } + + for (i = 0; i < PIOBU_NUM; ++i) { + ret = sama5d2_piobu_setup_pin(&piobu->chip, i); + if (ret) { + dev_err(&pdev->dev, "Failed to setup pin: %d %d\n", + i, ret); + return ret; + } + } + + return 0; +} + +static const struct of_device_id sama5d2_piobu_ids[] = { + { .compatible = "atmel,sama5d2-secumod" }, + {}, +}; +MODULE_DEVICE_TABLE(of, sama5d2_piobu_ids); + +static struct platform_driver sama5d2_piobu_driver = { + .driver = { + .name = "sama5d2-piobu", + .of_match_table = of_match_ptr(sama5d2_piobu_ids) + }, + .probe = sama5d2_piobu_probe, +}; + +module_platform_driver(sama5d2_piobu_driver); + +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SAMA5D2 PIOBU controller driver"); +MODULE_AUTHOR("Andrei Stefanescu <andrei.stefanescu@microchip.com>"); -- 2.7.4 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins @ 2018-12-12 11:57 ` Andrei.Stefanescu 0 siblings, 0 replies; 16+ messages in thread From: Andrei.Stefanescu @ 2018-12-12 11:57 UTC (permalink / raw) To: linus.walleij, robh+dt, gregkh, Nicolas.Ferre, mark.rutland Cc: devicetree, Andrei.Stefanescu, linux-kernel, linux-gpio, Ludovic.Desroches, Cristian.Birsan, linux-arm-kernel PIOBU pins do not lose their voltage during Backup/Self-refresh. This patch adds a simple GPIO controller for them and a maintainer for the driver. This driver adds support for using the pins as GPIO offering the possibility to read/set the voltage. Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> --- MAINTAINERS | 6 + drivers/gpio/Kconfig | 11 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-sama5d2-piobu.c | 253 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c diff --git a/MAINTAINERS b/MAINTAINERS index f485597..fadc96d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9760,6 +9760,12 @@ M: Nicolas Ferre <nicolas.ferre@microchip.com> S: Supported F: drivers/power/reset/at91-sama5d2_shdwc.c +MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO +M: Andrei Stefanescu <andrei.stefanescu@microchip.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-gpio@vger.kernel.org +F: drivers/gpio/gpio-sama5d2-piobu.c + MICROCHIP SPI DRIVER M: Nicolas Ferre <nicolas.ferre@microchip.com> S: Supported diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 833a1b5..1c41fac 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -429,6 +429,17 @@ config GPIO_REG A 32-bit single register GPIO fixed in/out implementation. This can be used to represent any register as a set of GPIO signals. +config GPIO_SAMA5D2_PIOBU + tristate "SAMA5D2 PIOBU GPIO support" + depends on MFD_SYSCON + select GPIO_SYSCON + help + Say yes here to use the PIOBU pins as GPIOs. + + PIOBU pins on the SAMA5D2 can be used as GPIOs. + The difference from regular GPIOs is that they + maintain their value during backup/self-refresh. + config GPIO_SIOX tristate "SIOX GPIO support" depends on SIOX diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 671c447..f18d345 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o obj-$(CONFIG_GPIO_REG) += gpio-reg.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o +obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o diff --git a/drivers/gpio/gpio-sama5d2-piobu.c b/drivers/gpio/gpio-sama5d2-piobu.c new file mode 100644 index 0000000..03a0006 --- /dev/null +++ b/drivers/gpio/gpio-sama5d2-piobu.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SAMA5D2 PIOBU GPIO controller + * + * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries + * + * Author: Andrei Stefanescu <andrei.stefanescu@microchip.com> + * + */ +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define PIOBU_NUM 8 +#define PIOBU_REG_SIZE 4 + +/* + * backup mode protection register for tamper detection + * normal mode protection register for tamper detection + * wakeup signal generation + */ +#define PIOBU_BMPR 0x7C +#define PIOBU_NMPR 0x80 +#define PIOBU_WKPR 0x90 + +#define PIOBU_BASE 0x18 /* PIOBU offset from SECUMOD base register address. */ + +#define PIOBU_DET_OFFSET 16 + +/* In the datasheet this bit is called OUTPUT */ +#define PIOBU_DIRECTION BIT(8) +#define PIOBU_OUT BIT(8) +#define PIOBU_IN 0 + +#define PIOBU_SOD BIT(9) +#define PIOBU_PDS BIT(10) + +#define PIOBU_HIGH BIT(9) +#define PIOBU_LOW 0 + +struct sama5d2_piobu { + struct gpio_chip chip; + struct regmap *regmap; +}; + +/** + * sama5d2_piobu_setup_pin() - prepares a pin for set_direction call + * + * Do not consider pin for tamper detection (normal and backup modes) + * Do not consider pin as tamper wakeup interrupt source + */ +static int sama5d2_piobu_setup_pin(struct gpio_chip *chip, unsigned int pin) +{ + int ret; + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + unsigned int mask = BIT(PIOBU_DET_OFFSET + pin); + + ret = regmap_update_bits(piobu->regmap, PIOBU_BMPR, mask, 0); + if (ret) + return ret; + + ret = regmap_update_bits(piobu->regmap, PIOBU_NMPR, mask, 0); + if (ret) + return ret; + + return regmap_update_bits(piobu->regmap, PIOBU_WKPR, mask, 0); +} + +/** + * sama5d2_piobu_write_value() - writes value & mask at the pin's PIOBU register + */ +static int sama5d2_piobu_write_value(struct gpio_chip *chip, unsigned int pin, + unsigned int mask, unsigned int value) +{ + int reg; + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + + reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; + + return regmap_update_bits(piobu->regmap, reg, mask, value); +} + +/** + * sama5d2_piobu_read_value() - read the value with masking from the pin's PIOBU + * register + */ +static int sama5d2_piobu_read_value(struct gpio_chip *chip, unsigned int pin, + unsigned int mask) +{ + struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu, + chip); + unsigned int val, reg; + int ret; + + reg = PIOBU_BASE + pin * PIOBU_REG_SIZE; + ret = regmap_read(piobu->regmap, reg, &val); + if (ret < 0) + return ret; + + return val & mask; +} + +/** + * sama5d2_piobu_set_direction() - mark pin as input or output + */ +static int sama5d2_piobu_set_direction(struct gpio_chip *chip, + unsigned int direction, + unsigned int pin) +{ + return sama5d2_piobu_write_value(chip, pin, PIOBU_DIRECTION, direction); +} + +/** + * sama5d2_piobu_get_direction() - gpiochip get_direction + */ +static int sama5d2_piobu_get_direction(struct gpio_chip *chip, + unsigned int pin) +{ + int ret = sama5d2_piobu_read_value(chip, pin, PIOBU_DIRECTION); + + if (ret < 0) + return ret; + + return (ret == PIOBU_IN) ? 1 : 0; +} + +/** + * sama5d2_piobu_direction_input() - gpiochip direction_input + */ +static int sama5d2_piobu_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + return sama5d2_piobu_set_direction(chip, PIOBU_IN, pin); +} + +/** + * sama5d2_piobu_direction_output() - gpiochip direction_output + */ +static int sama5d2_piobu_direction_output(struct gpio_chip *chip, + unsigned int pin, int value) +{ + return sama5d2_piobu_set_direction(chip, PIOBU_OUT, pin); +} + +/** + * sama5d2_piobu_get() - gpiochip get + */ +static int sama5d2_piobu_get(struct gpio_chip *chip, unsigned int pin) +{ + /* if pin is input, read value from PDS else read from SOD */ + int ret = sama5d2_piobu_get_direction(chip, pin); + + if (ret == 1) + ret = sama5d2_piobu_read_value(chip, pin, PIOBU_PDS); + else if (!ret) + ret = sama5d2_piobu_read_value(chip, pin, PIOBU_SOD); + + if (ret < 0) + return ret; + + return !!ret; +} + +/** + * sama5d2_piobu_set() - gpiochip set + */ +static void sama5d2_piobu_set(struct gpio_chip *chip, unsigned int pin, + int value) +{ + if (!value) + value = PIOBU_LOW; + else + value = PIOBU_HIGH; + + sama5d2_piobu_write_value(chip, pin, PIOBU_SOD, value); +} + +static int sama5d2_piobu_probe(struct platform_device *pdev) +{ + struct sama5d2_piobu *piobu; + int ret, i; + + piobu = devm_kzalloc(&pdev->dev, sizeof(*piobu), GFP_KERNEL); + if (!piobu) + return -ENOMEM; + + platform_set_drvdata(pdev, piobu); + piobu->chip.label = pdev->name; + piobu->chip.parent = &pdev->dev; + piobu->chip.of_node = pdev->dev.of_node; + piobu->chip.owner = THIS_MODULE, + piobu->chip.get_direction = sama5d2_piobu_get_direction, + piobu->chip.direction_input = sama5d2_piobu_direction_input, + piobu->chip.direction_output = sama5d2_piobu_direction_output, + piobu->chip.get = sama5d2_piobu_get, + piobu->chip.set = sama5d2_piobu_set, + piobu->chip.base = -1, + piobu->chip.ngpio = PIOBU_NUM, + piobu->chip.can_sleep = 0, + + piobu->regmap = syscon_node_to_regmap(pdev->dev.of_node); + if (IS_ERR(piobu->regmap)) { + dev_err(&pdev->dev, "Failed to get syscon regmap %ld\n", + PTR_ERR(piobu->regmap)); + return PTR_ERR(piobu->regmap); + } + + ret = devm_gpiochip_add_data(&pdev->dev, &piobu->chip, piobu); + if (ret) { + dev_err(&pdev->dev, "Failed to add gpiochip %d\n", ret); + return ret; + } + + for (i = 0; i < PIOBU_NUM; ++i) { + ret = sama5d2_piobu_setup_pin(&piobu->chip, i); + if (ret) { + dev_err(&pdev->dev, "Failed to setup pin: %d %d\n", + i, ret); + return ret; + } + } + + return 0; +} + +static const struct of_device_id sama5d2_piobu_ids[] = { + { .compatible = "atmel,sama5d2-secumod" }, + {}, +}; +MODULE_DEVICE_TABLE(of, sama5d2_piobu_ids); + +static struct platform_driver sama5d2_piobu_driver = { + .driver = { + .name = "sama5d2-piobu", + .of_match_table = of_match_ptr(sama5d2_piobu_ids) + }, + .probe = sama5d2_piobu_probe, +}; + +module_platform_driver(sama5d2_piobu_driver); + +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SAMA5D2 PIOBU controller driver"); +MODULE_AUTHOR("Andrei Stefanescu <andrei.stefanescu@microchip.com>"); -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins 2018-12-12 11:57 ` Andrei.Stefanescu @ 2018-12-21 9:57 ` Linus Walleij -1 siblings, 0 replies; 16+ messages in thread From: Linus Walleij @ 2018-12-21 9:57 UTC (permalink / raw) To: Andrei.Stefanescu Cc: Rob Herring, Greg KH, Nicolas Ferre, Mark Rutland, Ludovic Desroches, Cristian.Birsan, Linux ARM, open list:GPIO SUBSYSTEM, linux-kernel@vger.kernel.org, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS On Wed, Dec 12, 2018 at 12:57 PM <Andrei.Stefanescu@microchip.com> wrote: > PIOBU pins do not lose their voltage during Backup/Self-refresh. > This patch adds a simple GPIO controller for them and a > maintainer for the driver. > > This driver adds support for using the pins as GPIO > offering the possibility to read/set the voltage. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> Patch applied for v4.21, sorry for taking so long to reply! Good work on this driver Andrei, it looks really nice now. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins @ 2018-12-21 9:57 ` Linus Walleij 0 siblings, 0 replies; 16+ messages in thread From: Linus Walleij @ 2018-12-21 9:57 UTC (permalink / raw) To: Andrei.Stefanescu Cc: Mark Rutland, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, Greg KH, linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM, Ludovic Desroches, Rob Herring, Linux ARM, Cristian.Birsan On Wed, Dec 12, 2018 at 12:57 PM <Andrei.Stefanescu@microchip.com> wrote: > PIOBU pins do not lose their voltage during Backup/Self-refresh. > This patch adds a simple GPIO controller for them and a > maintainer for the driver. > > This driver adds support for using the pins as GPIO > offering the possibility to read/set the voltage. > > Signed-off-by: Andrei Stefanescu <andrei.stefanescu@microchip.com> Patch applied for v4.21, sorry for taking so long to reply! Good work on this driver Andrei, it looks really nice now. Yours, Linus Walleij _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2018-12-21 9:57 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-12-12 11:56 [PATCH v4 0/2] add SAMA5D2 PIOBU GPIO driver Andrei.Stefanescu 2018-12-12 11:56 ` Andrei.Stefanescu 2018-12-12 11:56 ` Andrei.Stefanescu 2018-12-12 11:57 ` [PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller Andrei.Stefanescu 2018-12-12 11:57 ` Andrei.Stefanescu 2018-12-12 11:57 ` Andrei.Stefanescu 2018-12-17 21:47 ` Rob Herring 2018-12-17 21:47 ` Rob Herring 2018-12-17 21:47 ` Rob Herring 2018-12-21 9:55 ` Linus Walleij 2018-12-21 9:55 ` Linus Walleij 2018-12-12 11:57 ` [PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins Andrei.Stefanescu 2018-12-12 11:57 ` Andrei.Stefanescu 2018-12-12 11:57 ` Andrei.Stefanescu 2018-12-21 9:57 ` Linus Walleij 2018-12-21 9:57 ` Linus Walleij
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.