[PATCH v2 0/3] add support for MCP16502 PMIC

2018-11-27 Thread Andrei.Stefanescu
MCP16502 is a Power Management IC from Microchip.
It has 4 Buck outputs and 2 LDOs. The buck regulators
can be used in two modes: normal(FPWM) and low-power(Auto PFM).

This patch series adds support for the MCP16502 PMIC.

v2:
- use lpm-gpios instead of lpm-gpio in devicetree bindings documentation
- describe the regulators present on the PMIC in the devicetree bindings
  documentation
- add SPDX license inside a C++ comment
- prefix macro
- remove mcp16502_update_regulator and mcp16502_read
- replace ?: with if-else
- change some if-else with switch statements for legibility
- use regmap helpers for regultor settings during runtime
- make mcp16502_get_status read the status from the PMIC STS registers
- use module_i2c_driver
- use the PMIC's Hibernate registers for suspend-to-mem, the PMIC's
  Low-power registers for standby and the PMIC's Active registers for
  normal runtime

Note about mcp16502_suspend:
- mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_HIB) has now been changed to
  mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM) for legibility.

Note that the function call only sets the LPM pin of the PMIC to high.
This puts the PMIC in Low-power operating mode. Hibernate operating mode
is reached when the MPU sets the PWRHLD line to zero (typically when
entering suspend-to-ram).

Andrei Stefanescu (3):
  regulator: dt-bindings: add MCP16502 regulator bindings
  MAINTAINERS: add maintainer for MCP16502 PMIC driver
  regulator: mcp16502: add regulator driver for MCP16502

 .../bindings/regulator/mcp16502-regulator.txt  | 143 ++
 MAINTAINERS|   7 +
 drivers/regulator/Kconfig  |   9 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/mcp16502.c   | 542 +
 5 files changed, 702 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 drivers/regulator/mcp16502.c

-- 
2.7.4



[PATCH v2 1/3] regulator: dt-bindings: add MCP16502 regulator bindings

2018-11-27 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the MCP16502 PMIC.

Signed-off-by: Andrei Stefanescu 
---
 .../bindings/regulator/mcp16502-regulator.txt  | 143 +
 1 file changed, 143 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt 
b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
new file mode 100644
index 000..b8f843f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
@@ -0,0 +1,143 @@
+MCP16502 PMIC
+
+Required properties:
+- compatible: "microchip,mcp16502"
+- reg: I2C slave address
+- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
+suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+- regulators: A node that houses a sub-node for each regulator within
+  the device. Each sub-node is identified using the node's
+  name. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+
+Regualtors of MCP16502 PMIC:
+1) VDD_IO  - Buck (1.2 - 3.7 V)
+2) VDD_DDR - Buck (0.6 - 1.85 V)
+3) VDD_CORE- Buck (0.6 - 1.85 V)
+4) VDD_OTHER   - BUCK (0.6 - 1.85 V)
+5) LDO1- LDO  (1.2 - 3.7 V)
+6) LDO2- LDO  (1.2 - 3.7 V)
+
+Regulator modes:
+2 - FPWM: higher precision, higher consumption
+4 - AutoPFM: lower precision, lower consumption
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+mcp16502@5b {
+   compatible = "microchip,mcp16502";
+   reg = <0x5b>;
+   status = "okay";
+   lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   VDD_IO {
+   regulator-name = "VDD_IO";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_DDR {
+   regulator-name = "VDD_DDR";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_CORE {
+   regulator-name = "VDD_CORE";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_OTHER {
+   regulator-name = "VDD_OTHER";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   LDO1 {
+   regulator-name = "LDO1";
+   regulator-min-microvolt = <120>;
+

[PATCH v2 2/3] MAINTAINERS: add maintainer for MCP16502 PMIC driver

2018-11-27 Thread Andrei.Stefanescu
This patch adds a maintainer for the MCP16502 PMIC
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b755a89..6a74a65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9730,6 +9730,13 @@ M:   Ludovic Desroches 

 S: Maintained
 F: drivers/mmc/host/atmel-mci.c
 
+MICROCHIP MCP16502 PMIC DRIVER
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F: drivers/regulator/mcp16502.c
+
 MICROCHIP MCP3911 ADC DRIVER
 M: Marcus Folkesson 
 M: Kent Gustavsson 
-- 
2.7.4



[PATCH v2 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-11-27 Thread Andrei.Stefanescu
This patch adds a regulator driver for the MCP16502 PMIC.
This drivers supports basic operations through the
regulator interface such as:
- setting/reading voltage
- setting/reading operating mode
- reading current status
- transitioning to/from suspend-to-ram and standby
  power states

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/mcp16502.c | 542 +++
 3 files changed, 552 insertions(+)
 create mode 100644 drivers/regulator/mcp16502.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 926cee0..719d9d6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -567,6 +567,15 @@ config REGULATOR_MC13892
  Say y here to support the regulators found on the Freescale MC13892
  PMIC.
 
+config REGULATOR_MCP16502
+   tristate "Microchip MCP16502 PMIC"
+   depends on I2C && OF
+   help
+ Say y here to support the MCP16502 PMIC. This driver supports
+ basic operations (get/set voltage, get/set operating mode)
+ through the regulator interface. In addition it enables
+ suspend-to-ram/standby transition.
+
 config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 72488ef..b12e1c9 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
new file mode 100644
index 000..b623fb0
--- /dev/null
+++ b/drivers/regulator/mcp16502.c
@@ -0,0 +1,542 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * MCP16502 PMIC driver
+ *
+ * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Andrei Stefanescu 
+ *
+ * Inspired from tps65086-regulator.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VDD_LOW_SEL 0x0D
+#define VDD_HIGH_SEL 0x3F
+
+#define MCP16502_FLT BIT(7)
+#define MCP16502_ENS BIT(0)
+
+/*
+ *
+ * The PMIC has four sets of registers corresponding to four power modes:
+ * Performance, Active, Low-power, Hibernate.
+ *
+ * Registers:
+ * Each regulator has a register for each power mode. To access a register
+ * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
+ *
+ * Operating modes:
+ * In order for the PMIC to transition to operating modes it has to be
+ * controlled via GPIO lines called LPM and HPM.
+ *
+ * The registers are fully configurable such that you can put all regulators in
+ * a low-power state while the PMIC is in Active mode. They are supposed to be
+ * configured at startup and then simply transition to/from a global low-power
+ * state by setting the GPIO lpm pin high/low.
+ *
+ * This driver keeps the PMIC in Active mode, Low-power state is set for the
+ * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
+ *
+ * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
+ * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
+ * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
+ */
+
+/*
+ * This function is useful for iterating over all regulators and accessing 
their
+ * registers in a generic way or accessing a regulator device by its id.
+ */
+#define MCP16502_BASE(i) (((i) + 1) << 4)
+#define MCP16502_STAT_BASE(i) ((i) + 5)
+
+#define MCP16502_OFFSET_MODE_A 0
+#define MCP16502_OFFSET_MODE_LPM 1
+#define MCP16502_OFFSET_MODE_HIB 2
+
+#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
+#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
+#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
+
+#define MCP16502_MODE_AUTO_PFM 0
+#define MCP16502_MODE_FPWM BIT(6)
+
+#define MCP16502_VSEL 0x3F
+#define MCP16502_EN BIT(7)
+#define MCP16502_MODE BIT(6)
+
+#define MCP16502_MIN_REG 0x0
+#define MCP16502_MAX_REG 0x65
+
+static unsigned int mcp16502_of_map_mode(unsigned int mode)
+{
+   if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
+   return mode;
+
+   return REGULATOR_MODE_INVALID;
+}
+
+#define MCP16502_REGULATOR(_name, _id, _ranges, _ops)  \
+   [_id] = {   \
+   .name   = _name,\
+   .regulators_node= of_match_ptr("regulators"),   \
+   .id

[PATCH v2 1/2] dt-bindings: gpio: add SAMA5D2 PIOBU support

2018-11-20 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the SAMA5D2 PIOBU GPIO.

Signed-off-by: Andrei Stefanescu 
---
 .../bindings/gpio/gpio-sama5d2-piobu.txt   | 31 ++
 1 file changed, 31 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt 
b/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
new file mode 100644
index 000..2e260e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
@@ -0,0 +1,31 @@
+GPIO controller for SAMA5D2 PIOBU pins.
+
+These pins have the property of not losing their voltage
+during Backup/Self-refresh mode.
+
+These bindings should be set to a node in the dtsi file.
+
+Required properties:
+- compatible:  "syscon", "microchip,sama5d2-piobu"
+- #gpio-cells: There are 2. The pin number is the
+   first, the second represents additional
+   parameters such as GPIO_ACTIVE_HIGH/LOW.
+- gpio-controller: Marks the port as GPIO controller.
+
+Note that the driver uses syscon and should be the child of
+the syscon node.
+
+Example:
+
+   secumod@fc04 {
+   compatible = "atmel,sama5d2-secumod", "syscon", "simple-mfd";
+   status = "okay";
+   reg = <0xfc04 0x100>;
+
+   pioBU: piobu {
+   status = "okay";
+   compatible = "microchip,sama5d2-piobu";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
-- 
2.7.4



[PATCH v2 0/2] add SAMA5D2 PIOBU GPIO driver

2018-11-20 Thread 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).

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: gpio: add SAMA5D2 PIOBU support
  gpio: add driver for SAMA5D2 PIOBU pins

 .../bindings/gpio/gpio-sama5d2-piobu.txt   |  31 +++
 MAINTAINERS|   7 +
 drivers/gpio/Kconfig   |  11 +
 drivers/gpio/Makefile  |   1 +
 drivers/gpio/gpio-sama5d2-piobu.c  | 253 +
 5 files changed, 303 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
 create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c

-- 
2.7.4



[PATCH v2 2/2] gpio: add driver for SAMA5D2 PIOBU pins

2018-11-20 Thread 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 
---
 MAINTAINERS   |   7 ++
 drivers/gpio/Kconfig  |  11 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-sama5d2-piobu.c | 253 ++
 4 files changed, 272 insertions(+)
 create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f485597..88369f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9760,6 +9760,13 @@ M:   Nicolas Ferre 
 S: Supported
 F: drivers/power/reset/at91-sama5d2_shdwc.c
 
+MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+L: linux-g...@vger.kernel.org
+F: drivers/gpio/gpio-sama5d2-piobu.c
+F: Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
+
 MICROCHIP SPI DRIVER
 M: Nicolas Ferre 
 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 000..db0cb5d
--- /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 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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 * PI

Re: [PATCH 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-11-21 Thread Andrei.Stefanescu
Hello Mark,

Thank you for your review. While working on the next version I realized that
the implementation should change a bit. The mcp16502 PMIC has separate 
registers
for each of its operating modes (Performance, Active, Low-power, Hibernate).
So, it is possible to setup the values for Low-power (Linux standby) and
Hibernate (Linux suspend-to-ram) and these values would not be affected by
changes made during runtime (which are made to the ACTIVE registers).

This means that the calls to suspend_set_* are not necessary to be made each
time the board suspends. My idea is to add three functions to the 
regulator_ops
(setup_suspend_standby/mem/max) which would be called after the regulator is
registered and which would set the values found inside the devicetree
in the regulator-state-standby/mem/disk subnodes.

However, I am not sure whether this is in fact a good idea or which is 
the best
approach.

Other possible suggestions for this setup_suspend* functions:
- Break each function into smaller pieces(set_voltage, set_mode, 
enable/disable)
- Add support for regmap helpers, which would mean adding reg and mask 
members
   to regulator_desc. However, I am not sure which naming scheme you prefer
   (enable_suspend_mem_reg for example seems not to be a great idea). 
Perhaps use
   arrays (e.g. enable_suspend[] and index it via PM_SUSPEND_*)?


Best regards,
Andrei

On 13.11.2018 19:45, Mark Brown wrote:
> On Tue, Nov 13, 2018 at 11:29:41AM +, andrei.stefane...@microchip.com 
> wrote:
>
>> index 000..29c72d3
>> --- /dev/null
>> +++ b/drivers/regulator/mcp16502.c
>> @@ -0,0 +1,524 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * MCP16502 PMIC driver
> Please make the entire comment a C++ comment so it looks more
> intentional.
>
>> +/*
>> + * This macro is useful for iterating over all regulators and accessing 
>> their
>> + * registers in a generic way or accessing a regulator device by its id.
>> + */
>> +#define BASE(i) (((i) + 1) << 4)
> This macro name is likely to run into collisions at some point, a prefix
> would be better.
>
>> +static int mcp16502_update_regulator(struct regulator_dev *rdev,
>> + bool hibernate,
>> + unsigned int mask, unsigned int val)
>> +{
>> +struct mcp16502 *mcp = rdev_get_drvdata(rdev);
>> +unsigned int reg = BASE(rdev_get_id(rdev));
>> +
>> +reg += (hibernate) ? OFFSET_MODE_HIB : OFFSET_MODE_A;
> Please write this as a normal if statement to improve legibility.
>
>> +static int mcp16502_read(struct regulator_dev *rdev, bool hibernate,
>> + unsigned int mask)
>> +{
>> +struct mcp16502 *mcp = rdev_get_drvdata(rdev);
>> +unsigned int reg = BASE(rdev_get_id(rdev));
>> +int ret, val;
>> +
>> +reg += (hibernate) ? OFFSET_MODE_HIB : OFFSET_MODE_A;
>> +
>> +ret = regmap_read(mcp->rmap, reg, &val);
>> +if (ret)
>> +return ret;
>> +
>> +return val & mask;
>> +}
> I'm not convinced that these custom read/write functions are adding much
> compared to just using the standard regmap helpers for things - they're
> adding a bunch of code instead of data.  If you need extra helpers for
> suspend mode just add those, I'm sure they'd be useful for other
> drivers.
>
>> +static unsigned int mcp16502_get_mode(struct regulator_dev *rdev)
>> +{
>> +int val;
>> +
>> +val = mcp16502_read(rdev, false, MCP16502_MODE_MASK);
>> +if (val < 0)
>> +return val;
>> +
>> +if (val == MCP16502_MODE_FPWM)
>> +return REGULATOR_MODE_NORMAL;
>> +else if (val == MCP16502_MODE_AUTO_PFM)
>> +return REGULATOR_MODE_IDLE;
>> +
>> +return REGULATOR_MODE_INVALID;
>> +}
> Please just write a switch statement to improve legibility.
>
>> +/*
>> + * mcp16502_is_enabled - regulator_ops is_enabled
>> + */
>> +static int mcp16502_is_enabled(struct regulator_dev *rdev)
>> +{
>> +int val;
>> +
>> +val = mcp16502_read(rdev, false, MCP16502_EN_MASK);
>> +if (val < 0)
>> +return val;
>> +
>> +return !!val;
>> +}
> This can use regulator_is_enabled_regmap().
>
>> +if (mode != REGULATOR_MODE_NORMAL && mode != REGULATOR_MODE_IDLE)
>> +return -EINVAL;
>> +
>> +val = (mode == REGULATOR_MODE_NORMAL) ? MCP16502_MODE_FPWM :
>> +MCP16502_MODE_AUTO_PFM;
>> +
>> +return mcp16502_update_regulator(rdev, hibernate, MCP16502_MODE_MASK,
>> + val);
> Again a switch statement would be clearer.
>
>> +static int mcp16502_get_status(struct regulator_dev *rdev)
>> +{
>> +int mode = mcp16502_get_mode(rdev);
>> +
>> +if (!mcp16502_is_enabled(rdev))
>> +return REGULATOR_STATUS_OFF;
>> +else if (mode == REGULATOR_MODE_NORMAL)
>> +return REGULATOR_STATUS_NORMAL;
>> +else if (mode == REGULATOR_MODE_IDLE)
>> +return REGULATOR_STATUS_IDLE;
>> +
>> +return REGULATOR_STATUS

Re: [PATCH] i2c: at91: switched to resume/suspend callbacks.

2018-11-15 Thread Andrei.Stefanescu
Hello Wolfram,

Could you please tell me if there are any changes that I should make
to the patch?

Thank you,
Andrei Stefanescu

On 07.11.2018 10:39, Ludovic Desroches wrote:
> On Mon, Oct 22, 2018 at 12:17:47PM +0200, Andrei Stefanescu - M50506 wrote:
>> In the previous version of the driver resume/suspend_noirq callbacks
>> were used. Because of this, when resuming from suspend-to-ram,
>> an I2C (belonging to a FLEXCOM) would resume before FLEXCOM.
>> The first read on the I2C bus would then result in a timeout.
>>
>> This patch switches to resume/suspend callbacks which are
>> called after FLEXCOM resumes. FLEXCOM, SPI and USART drivers use
>> resume/suspend callbacks.
>>
>> Signed-off-by: Andrei Stefanescu 
> I can't figure out why we use the _noirq variant. When patches for PM
> stuff were sent, suspend/resume callbacks were used but in the latest
> version it moved to the _noirq variant without explanation.
>
> Excepting if someone has an argument to keep the _noirq variant,
> Acked-by: Ludovic Desroches 
>
> Thanks
>
> Regards
>
> Ludovic
>
>> ---
>>   drivers/i2c/busses/i2c-at91.c | 8 
>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
>> index bfd1fdf..81f7b94 100644
>> --- a/drivers/i2c/busses/i2c-at91.c
>> +++ b/drivers/i2c/busses/i2c-at91.c
>> @@ -1174,7 +1174,7 @@ static int at91_twi_runtime_resume(struct device *dev)
>>  return clk_prepare_enable(twi_dev->clk);
>>   }
>>   
>> -static int at91_twi_suspend_noirq(struct device *dev)
>> +static int at91_twi_suspend(struct device *dev)
>>   {
>>  if (!pm_runtime_status_suspended(dev))
>>  at91_twi_runtime_suspend(dev);
>> @@ -1182,7 +1182,7 @@ static int at91_twi_suspend_noirq(struct device *dev)
>>  return 0;
>>   }
>>   
>> -static int at91_twi_resume_noirq(struct device *dev)
>> +static int at91_twi_resume(struct device *dev)
>>   {
>>  struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
>>  int ret;
>> @@ -1202,8 +1202,8 @@ static int at91_twi_resume_noirq(struct device *dev)
>>   }
>>   
>>   static const struct dev_pm_ops at91_twi_pm = {
>> -.suspend_noirq  = at91_twi_suspend_noirq,
>> -.resume_noirq   = at91_twi_resume_noirq,
>> +.suspend= at91_twi_suspend,
>> +.resume = at91_twi_resume,
>>  .runtime_suspend= at91_twi_runtime_suspend,
>>  .runtime_resume = at91_twi_runtime_resume,
>>   };
>> -- 
>> 2.7.4
>>


[PATCH 2/3] MAINTAINERS: add maintainer for MCP16502 PMIC driver

2018-11-13 Thread Andrei.Stefanescu
This patch adds a maintainer for the MCP16502 PMIC
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f485597..edfad02 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9723,6 +9723,13 @@ M:   Ludovic Desroches 

 S: Maintained
 F: drivers/mmc/host/atmel-mci.c
 
+MICROCHIP MCP16502 PMIC DRIVER
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F: drivers/regulator/mcp16502.c
+
 MICROCHIP MCP3911 ADC DRIVER
 M: Marcus Folkesson 
 M: Kent Gustavsson 
-- 
2.7.4



[PATCH 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-11-13 Thread Andrei.Stefanescu
This patch adds a regulator driver for the MCP16502 PMIC.
This drivers supports basic operations through the
regulator interface such as:
- setting/reading voltage
- setting/reading operating mode
- reading current status
- transitioning to/from suspend-to-ram and standby
  power states

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/mcp16502.c | 524 +++
 3 files changed, 534 insertions(+)
 create mode 100644 drivers/regulator/mcp16502.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 926cee0..719d9d6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -567,6 +567,15 @@ config REGULATOR_MC13892
  Say y here to support the regulators found on the Freescale MC13892
  PMIC.
 
+config REGULATOR_MCP16502
+   tristate "Microchip MCP16502 PMIC"
+   depends on I2C && OF
+   help
+ Say y here to support the MCP16502 PMIC. This driver supports
+ basic operations (get/set voltage, get/set operating mode)
+ through the regulator interface. In addition it enables
+ suspend-to-ram/standby transition.
+
 config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 72488ef..b12e1c9 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
new file mode 100644
index 000..29c72d3
--- /dev/null
+++ b/drivers/regulator/mcp16502.c
@@ -0,0 +1,524 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MCP16502 PMIC driver
+ *
+ * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Andrei Stefanescu 
+ *
+ * Inspired from tps65086-regulator.c
+ */
+
+#include  
+#include  
+#include  
+#include  
+#include  
+#include  
+#include  
+#include  
+
+#define VDD_LOW_SEL 0x0D
+#define VDD_HIGH_SEL 0x3F
+
+#define MCP16502_VOL_SEL_MASK 0x3F
+#define MCP16502_EN_MASK BIT(7)
+#define MCP16502_MODE_MASK BIT(6)
+
+/*
+ *
+ * The PMIC has four sets of registers corresponding to four power modes:
+ * Performance, Active, Low-power, Hibernate.
+ *
+ * Registers:
+ * Each regulator has a register for each power mode. To access a register
+ * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
+ *
+ * Operating modes:
+ * In order for the PMIC to transition to operating modes it has to be
+ * controlled via GPIO lines called LPM and HPM.
+ *
+ * The registers are fully configurable such that you can put all regulators in
+ * a low-power state while the PMIC is in Active mode. They are supposed to be
+ * configured at startup and then simply transition to/from a global low-power
+ * state by setting the GPIO lpm pin high/low.
+ *
+ * This driver keeps the PMIC in Active mode, Low-power state is set for the
+ * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
+ *
+ * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
+ * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
+ * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
+ */
+
+/*
+ * This macro is useful for iterating over all regulators and accessing their
+ * registers in a generic way or accessing a regulator device by its id.
+ */
+#define BASE(i) (((i) + 1) << 4)
+
+#define OFFSET_MODE_A 0
+#define OFFSET_MODE_HIB 2
+
+#define MCP16502_MODE_ACTIVE REGULATOR_MODE_NORMAL
+#define MCP16502_MODE_HIB REGULATOR_MODE_STANDBY
+
+#define MCP16502_MODE_AUTO_PFM 0
+#define MCP16502_MODE_FPWM BIT(6)
+
+#define MIN_REG 0x0
+#define MAX_REG 0x65
+
+static unsigned int mcp16502_of_map_mode(unsigned int mode)
+{
+   if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
+   return mode;
+
+   return REGULATOR_MODE_INVALID;
+}
+
+#define MCP16502_REGULATOR(_name, _id, _ranges, _ops)  \
+   [_id] = {   \
+   .name   = _name,\
+   .regulators_node= of_match_ptr("regulators"),   \
+   .id = _id,  \
+   .ops= &(_ops),  \
+   .type   = REGULATOR_VOLTAGE,\
+   .owner   

[PATCH 0/3] add support for MCP16502 PMIC

2018-11-13 Thread Andrei.Stefanescu
MCP16502 is a Power Management IC from Microchip.
It has 4 Buck outputs and 2 LDOs. The buck regulators
can be used in two modes: normal(FPWM) and low-power(Auto PFM).

This patch series adds support for the MCP16502 PMIC.

Andrei Stefanescu (3):
  regulator: dt-bindings: add MCP16502 regulator bindings
  MAINTAINERS: add maintainer for MCP16502 PMIC driver
  regulator: mcp16502: add regulator driver for MCP16502

 .../bindings/regulator/mcp16502-regulator.txt  | 107 +
 MAINTAINERS|   7 +
 drivers/regulator/Kconfig  |   9 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/mcp16502.c   | 524 +
 5 files changed, 648 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 drivers/regulator/mcp16502.c

-- 
2.7.4



[PATCH 1/3] regulator: dt-bindings: add MCP16502 regulator bindings

2018-11-13 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the MCP16502 PMIC.

Signed-off-by: Andrei Stefanescu 
---
 .../bindings/regulator/mcp16502-regulator.txt  | 107 +
 1 file changed, 107 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt 
b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
new file mode 100644
index 000..bb3d787
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
@@ -0,0 +1,107 @@
+MCP16502 PMIC
+
+Required properties:
+- compatible: "microchip,mcp16502"
+- reg: I2C slave address
+- lpm-gpio: GPIO for LPM pin. Note that this GPIO *must* remain high during
+suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+- regulators: A node that houses a sub-node for each regulator within
+  the device. Each sub-node is identified using the node's
+  name. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+
+Regulator modes:
+2 - FPWM: higher precision, higher consumption
+4 - AutoPFM: lower precision, lower consumption
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+mcp16502@5b {
+   compatible = "microchip,mcp16502";
+   reg = <0x5b>;
+   status = "okay";
+   lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   VDD_IO {
+   regulator-name = "VDD_IO";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_DDR {
+   regulator-name = "VDD_DDR";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-mem {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_CORE {
+   regulator-name = "VDD_CORE";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_OTHER {
+   regulator-name = "VDD_OTHER";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   LDO1 {
+   regulator-name = "LDO1";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-always-on;
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   };
+   };
+
+   LDO2 {
+   regulator-name = "LDO2";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-always-on;
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   };
+   };
+
+   };
+};
-- 
2.7.4



[PATCH 1/2] regulator: dt-bindings: add regulator-state-standby bindings

2018-11-13 Thread Andrei.Stefanescu
For state-mem and state-disk regulators can have
various parameters applied such as enabled/disabled,
current mode, voltage etc.

This patch adds documentation on how to set these parameters
in the device tree for the standby state.

Signed-off-by: Andrei Stefanescu 
---
 Documentation/devicetree/bindings/regulator/regulator.txt | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt 
b/Documentation/devicetree/bindings/regulator/regulator.txt
index 0c3a243..0a3f087 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -33,13 +33,16 @@ Optional properties:
   decreases of any level. This is useful for regulators with exponential
   voltage changes.
 - regulator-soft-start: Enable soft start so that voltage ramps slowly
+- regulator-state-standby sub-root node for Standby mode
+  : equivalent with standby Linux sleep state, which provides energy savings
+  with a relatively quick transition back time.
 - regulator-state-mem sub-root node for Suspend-to-RAM mode
   : suspend to memory, the device goes to sleep, but all data stored in memory,
   only some external interrupt can wake the device.
 - regulator-state-disk sub-root node for Suspend-to-DISK mode
   : suspend to disk, this state operates similarly to Suspend-to-RAM,
   but includes a final step of writing memory contents to disk.
-- regulator-state-[mem/disk] node has following common properties:
+- regulator-state-[mem/disk/standby] node has following common properties:
- regulator-on-in-suspend: regulator should be on in suspend state.
- regulator-off-in-suspend: regulator should be off in suspend state.
- regulator-suspend-min-microvolt: minimum voltage may be set in
-- 
2.7.4



[PATCH 0/2] set regulator constraints for standby state

2018-11-13 Thread Andrei.Stefanescu
This patch series adds support for setting the regulator constraints
when entering standby Linux state.

The new bindings are called regulator-state-standby and have
the same syntax as regulator-state-mem/disk.

Before this patch, if the regulator driver implemented
set_suspend_voltage/mode the rdev_warn message: "No configuration"
(drivers/regulator/core.c:suspend_set_state) would be issued when
resuming from standby.

Andrei Stefanescu (2):
  regulator: dt-bindings: add regulator-state-standby bindings
  regulator: of: add support for parsing regulator-state-standby

 Documentation/devicetree/bindings/regulator/regulator.txt | 5 -
 drivers/regulator/of_regulator.c  | 5 -
 2 files changed, 8 insertions(+), 2 deletions(-)

-- 
2.7.4



[PATCH 2/2] regulator: of: add support for parsing regulator-state-standby

2018-11-13 Thread Andrei.Stefanescu
Set the according constraints for PM_SUSPEND_STANDBY case.
Previously, only suspend to mem/disk were taken into
consideration.

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/of_regulator.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index a732f09..c711a0a 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -20,6 +20,7 @@
 #include "internal.h"
 
 static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
+   [PM_SUSPEND_STANDBY]= "regulator-state-standby",
[PM_SUSPEND_MEM]= "regulator-state-mem",
[PM_SUSPEND_MAX]= "regulator-state-disk",
 };
@@ -185,9 +186,11 @@ static void of_get_regulation_constraints(struct 
device_node *np,
case PM_SUSPEND_MAX:
suspend_state = &constraints->state_disk;
break;
+   case PM_SUSPEND_STANDBY:
+   suspend_state = &constraints->state_standby;
+   break;
case PM_SUSPEND_ON:
case PM_SUSPEND_TO_IDLE:
-   case PM_SUSPEND_STANDBY:
default:
continue;
}
-- 
2.7.4



Re: [PATCH v2 1/2] dt-bindings: gpio: add SAMA5D2 PIOBU support

2018-12-05 Thread Andrei.Stefanescu
Hello Rob,

Thank you for your feedback.

I will add a bit of context regarding the secumod. The 
"atmel,sama5d2-secumod"
compatible string is not used for loading a driver. It is used by atmel 
securam
driver (drivers/misc/sram.c) which has access to secumod's registers via:

     syscon_regmap_lookup_by_compatible("atmel,sama5d2-secumod")

So the secumod exports multiple hardware functions, eg: the securam, the 
PIOBU
pins which can be used as GPIO pins.

My initial patch had the "microchip,sama5d2-piobu" compatible appended 
to the
secumod's compatible e.g.:

secumod@fc04 {
     compatible = "syscon", "microchip,sama5d2-piobu";
...

Taking into consideration Linus Walleij's advice I arrived to the current
version. I thought this was a good idea because it separates the secumod 
node
from the GPIO controller node. Please notice that securam node is already
separated from secumod node (it is a separate node in the device tree).

I have a few questions because I am not sure of the best approach:

1. Is it ok to have the GPIO controller as a child node?
2. I used simple-mfd because it was the only way I could think of in 
order to
    get the driver probed.
3. Should I add a register range? I thought that because the driver uses 
syscon
    it is not necessary to add the register range. Also, the register 
range would
    have been a subset of the secumod's register range.



[PATCH v3 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller

2018-12-06 Thread 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 
---
 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,-secumod", "syscon".
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@fc04 {
compatible = "atmel,sama5d2-secumod", "syscon";
reg = <0xfc04 0x100>;
+   gpio-controller;
+   #gpio-cells = <2>;
};
-- 
2.7.4



[PATCH v3 2/2] gpio: add driver for SAMA5D2 PIOBU pins

2018-12-06 Thread 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 
---
 MAINTAINERS   |   6 +
 drivers/gpio/gpio-sama5d2-piobu.c | 253 ++
 2 files changed, 259 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 
 S: Supported
 F: drivers/power/reset/at91-sama5d2_shdwc.c
 
+MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+L: linux-g...@vger.kernel.org
+F: drivers/gpio/gpio-sama5d2-piobu.c
+
 MICROCHIP SPI DRIVER
 M: Nicolas Ferre 
 S: Supported
diff --git a/drivers/gpio/gpio-sama5d2-piobu.c 
b/drivers/gpio/gpio-sama5d2-piobu.c
new file mode 100644
index 000..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 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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
+ */

[PATCH v3 0/2] add SAMA5D2 PIOBU GPIO driver

2018-12-06 Thread 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).

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/gpio-sama5d2-piobu.c  | 253 +
 3 files changed, 270 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c

-- 
2.7.4



[RESEND PATCH] i2c: at91: switched to resume/suspend callbacks.

2018-12-07 Thread Andrei.Stefanescu
In the previous version of the driver resume/suspend_noirq callbacks
were used. Because of this, when resuming from suspend-to-ram,
an I2C (belonging to a FLEXCOM) would resume before FLEXCOM.
The first read on the I2C bus would then result in a timeout.

This patch switches to resume/suspend callbacks which are 
called after FLEXCOM resumes. FLEXCOM, SPI and USART drivers use
resume/suspend callbacks.

Signed-off-by: Andrei Stefanescu 
---
 drivers/i2c/busses/i2c-at91.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index bfd1fdf..81f7b94 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -1174,7 +1174,7 @@ static int at91_twi_runtime_resume(struct device *dev)
return clk_prepare_enable(twi_dev->clk);
 }
 
-static int at91_twi_suspend_noirq(struct device *dev)
+static int at91_twi_suspend(struct device *dev)
 {
if (!pm_runtime_status_suspended(dev))
at91_twi_runtime_suspend(dev);
@@ -1182,7 +1182,7 @@ static int at91_twi_suspend_noirq(struct device *dev)
return 0;
 }
 
-static int at91_twi_resume_noirq(struct device *dev)
+static int at91_twi_resume(struct device *dev)
 {
struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
int ret;
@@ -1202,8 +1202,8 @@ static int at91_twi_resume_noirq(struct device *dev)
 }
 
 static const struct dev_pm_ops at91_twi_pm = {
-   .suspend_noirq  = at91_twi_suspend_noirq,
-   .resume_noirq   = at91_twi_resume_noirq,
+   .suspend= at91_twi_suspend,
+   .resume = at91_twi_resume,
.runtime_suspend= at91_twi_runtime_suspend,
.runtime_resume = at91_twi_runtime_resume,
 };
-- 
2.7.4



[PATCH v3 0/3] add support for MCP16502 PMIC

2018-12-04 Thread Andrei.Stefanescu
MCP16502 is a Power Management IC from Microchip.
It has 4 Buck outputs and 2 LDOs. The buck regulators
can be used in two modes: normal(FPWM) and low-power(Auto PFM).

This patch series adds support for the MCP16502 PMIC.

v3:
- use CONFIG_SUSPEND and CONFIG_PM to fix compile errors for some configs

v2:
- use lpm-gpios instead of lpm-gpio in devicetree bindings documentation
- describe the regulators present on the PMIC in the devicetree bindings
  documentation
- add SPDX license inside a C++ comment
- prefix macro
- remove mcp16502_update_regulator and mcp16502_read
- replace ?: with if-else
- change some if-else with switch statements for legibility
- use regmap helpers for regultor settings during runtime
- make mcp16502_get_status read the status from the PMIC STS registers
- use module_i2c_driver
- use the PMIC's Hibernate registers for suspend-to-mem, the PMIC's
  Low-power registers for standby and the PMIC's Active registers for
  normal runtime

Note about mcp16502_suspend:
- mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_HIB) has now been changed to
  mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM) for legibility.

Note that the function call only sets the LPM pin of the PMIC to high.
This puts the PMIC in Low-power operating mode. Hibernate operating mode
is reached when the MPU sets the PWRHLD line to zero (typically when
entering suspend-to-ram).

Andrei Stefanescu (3):
  regulator: dt-bindings: add MCP16502 regulator bindings
  MAINTAINERS: add maintainer for MCP16502 PMIC driver
  regulator: mcp16502: add regulator driver for MCP16502

 .../bindings/regulator/mcp16502-regulator.txt  | 143 ++
 MAINTAINERS|   7 +
 drivers/regulator/Kconfig  |   9 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/mcp16502.c   | 555 +
 5 files changed, 715 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 drivers/regulator/mcp16502.c

-- 
2.7.4



[PATCH v3 1/3] regulator: dt-bindings: add MCP16502 regulator bindings

2018-12-04 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the MCP16502 PMIC.

Signed-off-by: Andrei Stefanescu 
---
 .../bindings/regulator/mcp16502-regulator.txt  | 143 +
 1 file changed, 143 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt 
b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
new file mode 100644
index 000..b8f843f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
@@ -0,0 +1,143 @@
+MCP16502 PMIC
+
+Required properties:
+- compatible: "microchip,mcp16502"
+- reg: I2C slave address
+- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
+suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+- regulators: A node that houses a sub-node for each regulator within
+  the device. Each sub-node is identified using the node's
+  name. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+
+Regualtors of MCP16502 PMIC:
+1) VDD_IO  - Buck (1.2 - 3.7 V)
+2) VDD_DDR - Buck (0.6 - 1.85 V)
+3) VDD_CORE- Buck (0.6 - 1.85 V)
+4) VDD_OTHER   - BUCK (0.6 - 1.85 V)
+5) LDO1- LDO  (1.2 - 3.7 V)
+6) LDO2- LDO  (1.2 - 3.7 V)
+
+Regulator modes:
+2 - FPWM: higher precision, higher consumption
+4 - AutoPFM: lower precision, lower consumption
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+mcp16502@5b {
+   compatible = "microchip,mcp16502";
+   reg = <0x5b>;
+   status = "okay";
+   lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   VDD_IO {
+   regulator-name = "VDD_IO";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_DDR {
+   regulator-name = "VDD_DDR";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_CORE {
+   regulator-name = "VDD_CORE";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_OTHER {
+   regulator-name = "VDD_OTHER";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   LDO1 {
+   regulator-name = "LDO1";
+   regulator-min-microvolt = <120>;
+

[PATCH v3 2/3] MAINTAINERS: add maintainer for MCP16502 PMIC driver

2018-12-04 Thread Andrei.Stefanescu
This patch adds a maintainer for the MCP16502 PMIC
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b755a89..6a74a65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9730,6 +9730,13 @@ M:   Ludovic Desroches 

 S: Maintained
 F: drivers/mmc/host/atmel-mci.c
 
+MICROCHIP MCP16502 PMIC DRIVER
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F: drivers/regulator/mcp16502.c
+
 MICROCHIP MCP3911 ADC DRIVER
 M: Marcus Folkesson 
 M: Kent Gustavsson 
-- 
2.7.4



[PATCH v3 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-12-04 Thread Andrei.Stefanescu
This patch adds a regulator driver for the MCP16502 PMIC.
This drivers supports basic operations through the
regulator interface such as:
- setting/reading voltage
- setting/reading operating mode
- reading current status
- transitioning to/from suspend-to-ram and standby
  power states

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/mcp16502.c | 555 +++
 3 files changed, 565 insertions(+)
 create mode 100644 drivers/regulator/mcp16502.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 926cee0..719d9d6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -567,6 +567,15 @@ config REGULATOR_MC13892
  Say y here to support the regulators found on the Freescale MC13892
  PMIC.
 
+config REGULATOR_MCP16502
+   tristate "Microchip MCP16502 PMIC"
+   depends on I2C && OF
+   help
+ Say y here to support the MCP16502 PMIC. This driver supports
+ basic operations (get/set voltage, get/set operating mode)
+ through the regulator interface. In addition it enables
+ suspend-to-ram/standby transition.
+
 config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 72488ef..b12e1c9 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
new file mode 100644
index 000..54db3df
--- /dev/null
+++ b/drivers/regulator/mcp16502.c
@@ -0,0 +1,555 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * MCP16502 PMIC driver
+ *
+ * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Andrei Stefanescu 
+ *
+ * Inspired from tps65086-regulator.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VDD_LOW_SEL 0x0D
+#define VDD_HIGH_SEL 0x3F
+
+#define MCP16502_FLT BIT(7)
+#define MCP16502_ENS BIT(0)
+
+/*
+ *
+ * The PMIC has four sets of registers corresponding to four power modes:
+ * Performance, Active, Low-power, Hibernate.
+ *
+ * Registers:
+ * Each regulator has a register for each power mode. To access a register
+ * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
+ *
+ * Operating modes:
+ * In order for the PMIC to transition to operating modes it has to be
+ * controlled via GPIO lines called LPM and HPM.
+ *
+ * The registers are fully configurable such that you can put all regulators in
+ * a low-power state while the PMIC is in Active mode. They are supposed to be
+ * configured at startup and then simply transition to/from a global low-power
+ * state by setting the GPIO lpm pin high/low.
+ *
+ * This driver keeps the PMIC in Active mode, Low-power state is set for the
+ * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
+ *
+ * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
+ * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
+ * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
+ */
+
+/*
+ * This function is useful for iterating over all regulators and accessing 
their
+ * registers in a generic way or accessing a regulator device by its id.
+ */
+#define MCP16502_BASE(i) (((i) + 1) << 4)
+#define MCP16502_STAT_BASE(i) ((i) + 5)
+
+#define MCP16502_OFFSET_MODE_A 0
+#define MCP16502_OFFSET_MODE_LPM 1
+#define MCP16502_OFFSET_MODE_HIB 2
+
+#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
+#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
+#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
+
+#define MCP16502_MODE_AUTO_PFM 0
+#define MCP16502_MODE_FPWM BIT(6)
+
+#define MCP16502_VSEL 0x3F
+#define MCP16502_EN BIT(7)
+#define MCP16502_MODE BIT(6)
+
+#define MCP16502_MIN_REG 0x0
+#define MCP16502_MAX_REG 0x65
+
+static unsigned int mcp16502_of_map_mode(unsigned int mode)
+{
+   if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
+   return mode;
+
+   return REGULATOR_MODE_INVALID;
+}
+
+#define MCP16502_REGULATOR(_name, _id, _ranges, _ops)  \
+   [_id] = {   \
+   .name   = _name,\
+   .regulators_node= of_match_ptr("regulators"),   \
+   .id

Re: [PATCH v2 1/2] dt-bindings: gpio: add SAMA5D2 PIOBU support

2018-12-04 Thread Andrei.Stefanescu
Hello Rob,

Could you please tell me if there are any improvements
to be made to the patch?

Best regards,
Andrei

On 20.11.2018 10:08, Andrei Stefanescu - M50506 wrote:
> This patch describes the compatible and the device tree
> bindings necessary for the SAMA5D2 PIOBU GPIO.
>
> Signed-off-by: Andrei Stefanescu 
> ---
>   .../bindings/gpio/gpio-sama5d2-piobu.txt   | 31 
> ++
>   1 file changed, 31 insertions(+)
>   create mode 100644 
> Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
>
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt 
> b/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
> new file mode 100644
> index 000..2e260e1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
> @@ -0,0 +1,31 @@
> +GPIO controller for SAMA5D2 PIOBU pins.
> +
> +These pins have the property of not losing their voltage
> +during Backup/Self-refresh mode.
> +
> +These bindings should be set to a node in the dtsi file.
> +
> +Required properties:
> +- compatible:"syscon", "microchip,sama5d2-piobu"
> +- #gpio-cells:   There are 2. The pin number is the
> + first, the second represents additional
> + parameters such as GPIO_ACTIVE_HIGH/LOW.
> +- gpio-controller:   Marks the port as GPIO controller.
> +
> +Note that the driver uses syscon and should be the child of
> +the syscon node.
> +
> +Example:
> +
> + secumod@fc04 {
> + compatible = "atmel,sama5d2-secumod", "syscon", "simple-mfd";
> + status = "okay";
> + reg = <0xfc04 0x100>;
> +
> + pioBU: piobu {
> + status = "okay";
> + compatible = "microchip,sama5d2-piobu";
> + gpio-controller;
> + #gpio-cells = <2>;
> + };
> + };


[PATCH v4 2/3] MAINTAINERS: add maintainer for MCP16502 PMIC driver

2018-12-11 Thread Andrei.Stefanescu
This patch adds a maintainer for the MCP16502 PMIC
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b755a89..6a74a65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9730,6 +9730,13 @@ M:   Ludovic Desroches 

 S: Maintained
 F: drivers/mmc/host/atmel-mci.c
 
+MICROCHIP MCP16502 PMIC DRIVER
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F: drivers/regulator/mcp16502.c
+
 MICROCHIP MCP3911 ADC DRIVER
 M: Marcus Folkesson 
 M: Kent Gustavsson 
-- 
2.7.4



[PATCH v4 1/3] regulator: dt-bindings: add MCP16502 regulator bindings

2018-12-11 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the MCP16502 PMIC.

Signed-off-by: Andrei Stefanescu 
Reviewed-by: Rob Herring 
---
 .../bindings/regulator/mcp16502-regulator.txt  | 143 +
 1 file changed, 143 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt 
b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
new file mode 100644
index 000..b8f843f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
@@ -0,0 +1,143 @@
+MCP16502 PMIC
+
+Required properties:
+- compatible: "microchip,mcp16502"
+- reg: I2C slave address
+- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
+suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+- regulators: A node that houses a sub-node for each regulator within
+  the device. Each sub-node is identified using the node's
+  name. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+
+Regualtors of MCP16502 PMIC:
+1) VDD_IO  - Buck (1.2 - 3.7 V)
+2) VDD_DDR - Buck (0.6 - 1.85 V)
+3) VDD_CORE- Buck (0.6 - 1.85 V)
+4) VDD_OTHER   - BUCK (0.6 - 1.85 V)
+5) LDO1- LDO  (1.2 - 3.7 V)
+6) LDO2- LDO  (1.2 - 3.7 V)
+
+Regulator modes:
+2 - FPWM: higher precision, higher consumption
+4 - AutoPFM: lower precision, lower consumption
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+mcp16502@5b {
+   compatible = "microchip,mcp16502";
+   reg = <0x5b>;
+   status = "okay";
+   lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   VDD_IO {
+   regulator-name = "VDD_IO";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_DDR {
+   regulator-name = "VDD_DDR";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_CORE {
+   regulator-name = "VDD_CORE";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_OTHER {
+   regulator-name = "VDD_OTHER";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   LDO1 {
+   regulator-name = "LDO1";
+   regulator-min-microvolt = <12000

[PATCH v4 0/3] add support for MCP16502 PMIC

2018-12-11 Thread Andrei.Stefanescu
MCP16502 is a Power Management IC from Microchip.
It has 4 Buck outputs and 2 LDOs. The buck regulators
can be used in two modes: normal(FPWM) and low-power(Auto PFM).

This patch series adds support for the MCP16502 PMIC.

v4:
- make entire intial comment a C++ comment

v3:
- use CONFIG_SUSPEND and CONFIG_PM to fix compile errors for some configs

v2:
- use lpm-gpios instead of lpm-gpio in devicetree bindings documentation
- describe the regulators present on the PMIC in the devicetree bindings
  documentation
- add SPDX license inside a C++ comment
- prefix macro
- remove mcp16502_update_regulator and mcp16502_read
- replace ?: with if-else
- change some if-else with switch statements for legibility
- use regmap helpers for regultor settings during runtime
- make mcp16502_get_status read the status from the PMIC STS registers
- use module_i2c_driver
- use the PMIC's Hibernate registers for suspend-to-mem, the PMIC's
  Low-power registers for standby and the PMIC's Active registers for
  normal runtime

Note about mcp16502_suspend:
- mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_HIB) has now been changed to
  mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM) for legibility.

Note that the function call only sets the LPM pin of the PMIC to high.
This puts the PMIC in Low-power operating mode. Hibernate operating mode
is reached when the MPU sets the PWRHLD line to zero (typically when
entering suspend-to-ram).

Andrei Stefanescu (3):
  regulator: dt-bindings: add MCP16502 regulator bindings
  MAINTAINERS: add maintainer for MCP16502 PMIC driver
  regulator: mcp16502: add regulator driver for MCP16502

 .../bindings/regulator/mcp16502-regulator.txt  | 143 ++
 MAINTAINERS|   7 +
 drivers/regulator/Kconfig  |   9 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/mcp16502.c   | 553 +
 5 files changed, 713 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 drivers/regulator/mcp16502.c

-- 
2.7.4



[PATCH v4 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-12-11 Thread Andrei.Stefanescu
This patch adds a regulator driver for the MCP16502 PMIC.
This drivers supports basic operations through the
regulator interface such as:
- setting/reading voltage
- setting/reading operating mode
- reading current status
- transitioning to/from suspend-to-ram and standby
  power states

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/mcp16502.c | 553 +++
 3 files changed, 563 insertions(+)
 create mode 100644 drivers/regulator/mcp16502.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 926cee0..719d9d6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -567,6 +567,15 @@ config REGULATOR_MC13892
  Say y here to support the regulators found on the Freescale MC13892
  PMIC.
 
+config REGULATOR_MCP16502
+   tristate "Microchip MCP16502 PMIC"
+   depends on I2C && OF
+   help
+ Say y here to support the MCP16502 PMIC. This driver supports
+ basic operations (get/set voltage, get/set operating mode)
+ through the regulator interface. In addition it enables
+ suspend-to-ram/standby transition.
+
 config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 72488ef..b12e1c9 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
new file mode 100644
index 000..bde3172
--- /dev/null
+++ b/drivers/regulator/mcp16502.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// MCP16502 PMIC driver
+//
+// Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+//
+// Author: Andrei Stefanescu 
+//
+// Inspired from tps65086-regulator.c
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VDD_LOW_SEL 0x0D
+#define VDD_HIGH_SEL 0x3F
+
+#define MCP16502_FLT BIT(7)
+#define MCP16502_ENS BIT(0)
+
+/*
+ * The PMIC has four sets of registers corresponding to four power modes:
+ * Performance, Active, Low-power, Hibernate.
+ *
+ * Registers:
+ * Each regulator has a register for each power mode. To access a register
+ * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
+ *
+ * Operating modes:
+ * In order for the PMIC to transition to operating modes it has to be
+ * controlled via GPIO lines called LPM and HPM.
+ *
+ * The registers are fully configurable such that you can put all regulators in
+ * a low-power state while the PMIC is in Active mode. They are supposed to be
+ * configured at startup and then simply transition to/from a global low-power
+ * state by setting the GPIO lpm pin high/low.
+ *
+ * This driver keeps the PMIC in Active mode, Low-power state is set for the
+ * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
+ *
+ * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
+ * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
+ * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
+ */
+
+/*
+ * This function is useful for iterating over all regulators and accessing 
their
+ * registers in a generic way or accessing a regulator device by its id.
+ */
+#define MCP16502_BASE(i) (((i) + 1) << 4)
+#define MCP16502_STAT_BASE(i) ((i) + 5)
+
+#define MCP16502_OFFSET_MODE_A 0
+#define MCP16502_OFFSET_MODE_LPM 1
+#define MCP16502_OFFSET_MODE_HIB 2
+
+#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
+#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
+#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
+
+#define MCP16502_MODE_AUTO_PFM 0
+#define MCP16502_MODE_FPWM BIT(6)
+
+#define MCP16502_VSEL 0x3F
+#define MCP16502_EN BIT(7)
+#define MCP16502_MODE BIT(6)
+
+#define MCP16502_MIN_REG 0x0
+#define MCP16502_MAX_REG 0x65
+
+static unsigned int mcp16502_of_map_mode(unsigned int mode)
+{
+   if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
+   return mode;
+
+   return REGULATOR_MODE_INVALID;
+}
+
+#define MCP16502_REGULATOR(_name, _id, _ranges, _ops)  \
+   [_id] = {   \
+   .name   = _name,\
+   .regulators_node= of_match_ptr("regulators"),   \
+   .id 

Re: [RESEND PATCH v3 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-12-12 Thread Andrei.Stefanescu
Hi Mark,

Thank you for the review.

> SPDX headers need to be C++ comments - please make the entire comment
> block a C++ one so it looks more intentional.
I sent a new patch (v4) with the modified comment.
>> +#ifdef CONFIG_SUSPEND
>> +static int mcp16502_suspend(struct device *dev)
>> +{
>> +struct i2c_client *client = to_i2c_client(dev);
>> +struct mcp16502 *mcp = i2c_get_clientdata(client);
>> +
>> +mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM);
>> +
>> +return 0;
>> +}
> This puts the device into low power mode when the suspend function gets
> called but this might not be safe - devices using the regulator may not
> be suspended yet so could still need full regulation.  Normally a GPIO
> triggered transition like this would be being done by hardware as part
> of the process of suspending the SoC.  Is there some reason to do this
> manually?
There is a line from the MPU (SHDN) which goes low only when the MPU
turns off. That line is already connected to the PMIC and it differentiates
between suspend-to-mem and standby. To switch to low-power, the PMIC must
be controlled by the GPIO pin LPM.

The suspend sequence is:
- LPM pin goes high (PMIC enters Low-Power <-> Linux standby)
- SHDN goes low (if target suspend state is mem) and then PMIC enters 
HIBERNATE


Best regards,
Andrei


[PATCH v4 2/2] gpio: add driver for SAMA5D2 PIOBU pins

2018-12-12 Thread 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 
---
 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 
 S: Supported
 F: drivers/power/reset/at91-sama5d2_shdwc.c
 
+MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+L: linux-g...@vger.kernel.org
+F: drivers/gpio/gpio-sama5d2-piobu.c
+
 MICROCHIP SPI DRIVER
 M: Nicolas Ferre 
 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 000..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 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, m

[PATCH v4 0/2] add SAMA5D2 PIOBU GPIO driver

2018-12-12 Thread 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



[PATCH v4 1/2] dt-bindings: arm: atmel: describe SECUMOD usage as a GPIO controller

2018-12-12 Thread 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 
---
 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,-secumod", "syscon".
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@fc04 {
compatible = "atmel,sama5d2-secumod", "syscon";
reg = <0xfc04 0x100>;
+   gpio-controller;
+   #gpio-cells = <2>;
};
-- 
2.7.4



[PATCH v5 2/3] MAINTAINERS: add maintainer for MCP16502 PMIC driver

2018-12-12 Thread Andrei.Stefanescu
This patch adds a maintainer for the MCP16502 PMIC
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b755a89..6a74a65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9730,6 +9730,13 @@ M:   Ludovic Desroches 

 S: Maintained
 F: drivers/mmc/host/atmel-mci.c
 
+MICROCHIP MCP16502 PMIC DRIVER
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F: drivers/regulator/mcp16502.c
+
 MICROCHIP MCP3911 ADC DRIVER
 M: Marcus Folkesson 
 M: Kent Gustavsson 
-- 
2.7.4



[PATCH v5 0/3] add support for MCP16502 PMIC

2018-12-12 Thread Andrei.Stefanescu
MCP16502 is a Power Management IC from Microchip.
It has 4 Buck outputs and 2 LDOs. The buck regulators
can be used in two modes: normal(FPWM) and low-power(Auto PFM).

This patch series adds support for the MCP16502 PMIC.

v5:
- split the driver patch in two patches, this one is the initial implementation
  without the support for suspend/resume
 
v4:
- make entire intial comment a C++ comment

v3:
- use CONFIG_SUSPEND and CONFIG_PM to fix compile errors for some configs

v2:
- use lpm-gpios instead of lpm-gpio in devicetree bindings documentation
- describe the regulators present on the PMIC in the devicetree bindings
  documentation
- add SPDX license inside a C++ comment
- prefix macro
- remove mcp16502_update_regulator and mcp16502_read
- replace ?: with if-else
- change some if-else with switch statements for legibility
- use regmap helpers for regultor settings during runtime
- make mcp16502_get_status read the status from the PMIC STS registers
- use module_i2c_driver
- use the PMIC's Hibernate registers for suspend-to-mem, the PMIC's
  Low-power registers for standby and the PMIC's Active registers for
  normal runtime

Note about mcp16502_suspend:
- mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_HIB) has now been changed to
  mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM) for legibility.

Note that the function call only sets the LPM pin of the PMIC to high.
This puts the PMIC in Low-power operating mode. Hibernate operating mode
is reached when the MPU sets the PWRHLD line to zero (typically when
entering suspend-to-ram).


Andrei Stefanescu (3):
  regulator: dt-bindings: add MCP16502 regulator bindings
  MAINTAINERS: add maintainer for MCP16502 PMIC driver
  regulator: mcp16502: add regulator driver for MCP16502

 .../bindings/regulator/mcp16502-regulator.txt  | 143 ++
 MAINTAINERS|   7 +
 drivers/regulator/Kconfig  |   9 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/mcp16502.c   | 520 +
 5 files changed, 680 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 drivers/regulator/mcp16502.c

-- 
2.7.4



[PATCH v5 1/3] regulator: dt-bindings: add MCP16502 regulator bindings

2018-12-12 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the MCP16502 PMIC.

Signed-off-by: Andrei Stefanescu 
Reviewed-by: Rob Herring 
---
 .../bindings/regulator/mcp16502-regulator.txt  | 143 +
 1 file changed, 143 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt 
b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
new file mode 100644
index 000..b8f843f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
@@ -0,0 +1,143 @@
+MCP16502 PMIC
+
+Required properties:
+- compatible: "microchip,mcp16502"
+- reg: I2C slave address
+- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
+suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+- regulators: A node that houses a sub-node for each regulator within
+  the device. Each sub-node is identified using the node's
+  name. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+
+Regualtors of MCP16502 PMIC:
+1) VDD_IO  - Buck (1.2 - 3.7 V)
+2) VDD_DDR - Buck (0.6 - 1.85 V)
+3) VDD_CORE- Buck (0.6 - 1.85 V)
+4) VDD_OTHER   - BUCK (0.6 - 1.85 V)
+5) LDO1- LDO  (1.2 - 3.7 V)
+6) LDO2- LDO  (1.2 - 3.7 V)
+
+Regulator modes:
+2 - FPWM: higher precision, higher consumption
+4 - AutoPFM: lower precision, lower consumption
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+mcp16502@5b {
+   compatible = "microchip,mcp16502";
+   reg = <0x5b>;
+   status = "okay";
+   lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   VDD_IO {
+   regulator-name = "VDD_IO";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_DDR {
+   regulator-name = "VDD_DDR";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_CORE {
+   regulator-name = "VDD_CORE";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_OTHER {
+   regulator-name = "VDD_OTHER";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   LDO1 {
+   regulator-name = "LDO1";
+   regulator-min-microvolt = <12000

[PATCH v5 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-12-12 Thread Andrei.Stefanescu
This patch adds a regulator driver for the MCP16502 PMIC.
This drivers supports basic operations through the
regulator interface such as:
- setting/reading voltage
- setting/reading operating mode
- reading current status

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/mcp16502.c | 520 +++
 3 files changed, 530 insertions(+)
 create mode 100644 drivers/regulator/mcp16502.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 926cee0..719d9d6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -567,6 +567,15 @@ config REGULATOR_MC13892
  Say y here to support the regulators found on the Freescale MC13892
  PMIC.
 
+config REGULATOR_MCP16502
+   tristate "Microchip MCP16502 PMIC"
+   depends on I2C && OF
+   help
+ Say y here to support the MCP16502 PMIC. This driver supports
+ basic operations (get/set voltage, get/set operating mode)
+ through the regulator interface. In addition it enables
+ suspend-to-ram/standby transition.
+
 config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 72488ef..b12e1c9 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
new file mode 100644
index 000..7cbc96f
--- /dev/null
+++ b/drivers/regulator/mcp16502.c
@@ -0,0 +1,520 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// MCP16502 PMIC driver
+//
+// Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+//
+// Author: Andrei Stefanescu 
+//
+// Inspired from tps65086-regulator.c
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VDD_LOW_SEL 0x0D
+#define VDD_HIGH_SEL 0x3F
+
+#define MCP16502_FLT BIT(7)
+#define MCP16502_ENS BIT(0)
+
+/*
+ * The PMIC has four sets of registers corresponding to four power modes:
+ * Performance, Active, Low-power, Hibernate.
+ *
+ * Registers:
+ * Each regulator has a register for each power mode. To access a register
+ * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
+ *
+ * Operating modes:
+ * In order for the PMIC to transition to operating modes it has to be
+ * controlled via GPIO lines called LPM and HPM.
+ *
+ * The registers are fully configurable such that you can put all regulators in
+ * a low-power state while the PMIC is in Active mode. They are supposed to be
+ * configured at startup and then simply transition to/from a global low-power
+ * state by setting the GPIO lpm pin high/low.
+ *
+ * This driver keeps the PMIC in Active mode, Low-power state is set for the
+ * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
+ *
+ * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
+ * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
+ * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
+ */
+
+/*
+ * This function is useful for iterating over all regulators and accessing 
their
+ * registers in a generic way or accessing a regulator device by its id.
+ */
+#define MCP16502_BASE(i) (((i) + 1) << 4)
+#define MCP16502_STAT_BASE(i) ((i) + 5)
+
+#define MCP16502_OFFSET_MODE_A 0
+#define MCP16502_OFFSET_MODE_LPM 1
+#define MCP16502_OFFSET_MODE_HIB 2
+
+#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
+#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
+#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
+
+#define MCP16502_MODE_AUTO_PFM 0
+#define MCP16502_MODE_FPWM BIT(6)
+
+#define MCP16502_VSEL 0x3F
+#define MCP16502_EN BIT(7)
+#define MCP16502_MODE BIT(6)
+
+#define MCP16502_MIN_REG 0x0
+#define MCP16502_MAX_REG 0x65
+
+static unsigned int mcp16502_of_map_mode(unsigned int mode)
+{
+   if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
+   return mode;
+
+   return REGULATOR_MODE_INVALID;
+}
+
+#define MCP16502_REGULATOR(_name, _id, _ranges, _ops)  \
+   [_id] = {   \
+   .name   = _name,\
+   .regulators_node= of_match_ptr("regulators"),   \
+   .id = _id,  \
+   .ops

[PATCH] regulator: mcp16502: add support for suspend

2018-12-12 Thread Andrei.Stefanescu
This patch adds support for entering/resuming suspend states.
It does this by setting the LPM pin of the PMIC.

When suspending the PMIC will enter the Low-power mode
when the LPM pin will be set to high. If the suspend target state
is suspend-to-mem, the PMIC will transition to Hibernate mode,
otherwise, if it is standby, it will remain in Low-power mode.

This patch depends on
0b60c4deca1d regulator: mcp16502: add regulator driver for MCP16502


Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/mcp16502.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
index 7cbc96f..bde3172 100644
--- a/drivers/regulator/mcp16502.c
+++ b/drivers/regulator/mcp16502.c
@@ -497,6 +497,36 @@ static int mcp16502_probe(struct i2c_client *client,
return 0;
 }
 
+#ifdef CONFIG_SUSPEND
+static int mcp16502_suspend(struct device *dev)
+{
+   struct i2c_client *client = to_i2c_client(dev);
+   struct mcp16502 *mcp = i2c_get_clientdata(client);
+
+   mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM);
+
+   return 0;
+}
+
+static int mcp16502_resume(struct device *dev)
+{
+   struct i2c_client *client = to_i2c_client(dev);
+   struct mcp16502 *mcp = i2c_get_clientdata(client);
+
+   mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
+
+   return 0;
+}
+#else /* !CONFIG_SUSPEND */
+#define mcp16502_suspend NULL
+#define mcp16502_resume NULL
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops mcp16502_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend, mcp16502_resume)
+};
+#endif
 static const struct i2c_device_id mcp16502_i2c_id[] = {
{ "mcp16502", 0 },
{ }
@@ -508,6 +538,9 @@ static struct i2c_driver mcp16502_drv = {
.driver = {
.name   = "mcp16502-regulator",
.of_match_table = of_match_ptr(mcp16502_ids),
+#ifdef CONFIG_PM
+   .pm = &mcp16502_pm_ops,
+#endif
},
.id_table   = mcp16502_i2c_id,
 };
-- 
2.7.4



Re: [RESEND PATCH v3 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-12-13 Thread Andrei.Stefanescu
Hi Mark,

On 12.12.2018 17:55, Mark Brown wrote:
> On Wed, Dec 12, 2018 at 08:01:07AM +, andrei.stefane...@microchip.com 
> wrote:
>
>>> This puts the device into low power mode when the suspend function gets
>>> called but this might not be safe - devices using the regulator may not
>>> be suspended yet so could still need full regulation.  Normally a GPIO
>>> triggered transition like this would be being done by hardware as part
>>> of the process of suspending the SoC.  Is there some reason to do this
>>> manually?
>> There is a line from the MPU (SHDN) which goes low only when the MPU
>> turns off. That line is already connected to the PMIC and it differentiates
>> between suspend-to-mem and standby. To switch to low-power, the PMIC must
>> be controlled by the GPIO pin LPM.
>> The suspend sequence is:
>> - LPM pin goes high (PMIC enters Low-Power <-> Linux standby)
>> - SHDN goes low (if target suspend state is mem) and then PMIC enters
>> HIBERNATE
> This feels like it should be being controlled somewhere else, if it's
> actually causing a change in the PMIC state it seems like it wants to be
> done as late as possible in suspend to minimize the risks.  At the very
> least suspend_late() for the driver seems appropriate.
I tried with both suspend_late/resume_early and suspend_noirq/resume_noirq.
Everything seems to work ok.

Which one do you think is more appropriate? I am guessing that during
suspend_late some devices may still need to be turned on and that it would
be the safest during suspend_noirq.

Note: the GPIO pin used for LPM is a special one (it maintains its 
voltage during
suspend-to-mem). It is part of the SoC and its methods for setting the 
values
do not sleep.

>
> Could you submit a version with this feature at least split out into a
> separate patch please so we can apply the rest of the code while this is
> discussed?
Sent one patch series and another patch with the current suspend/resume
implementation.

Best regards,
Andrei


[PATCH v2] regulator: mcp16502: add support for suspend

2018-12-14 Thread Andrei.Stefanescu
This patch adds support for entering/resuming suspend states.
It does this by setting the LPM pin of the PMIC.

When suspending the PMIC will enter the Low-power mode
when the LPM pin will be set to high. If the suspend target state
is suspend-to-mem, the PMIC will transition to Hibernate mode,
otherwise, if it is standby, it will remain in Low-power mode.

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/mcp16502.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
index 7cbc96f..25d7b43 100644
--- a/drivers/regulator/mcp16502.c
+++ b/drivers/regulator/mcp16502.c
@@ -497,6 +497,37 @@ static int mcp16502_probe(struct i2c_client *client,
return 0;
 }
 
+#ifdef CONFIG_SUSPEND
+static int mcp16502_suspend_noirq(struct device *dev)
+{
+   struct i2c_client *client = to_i2c_client(dev);
+   struct mcp16502 *mcp = i2c_get_clientdata(client);
+
+   mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM);
+
+   return 0;
+}
+
+static int mcp16502_resume_noirq(struct device *dev)
+{
+   struct i2c_client *client = to_i2c_client(dev);
+   struct mcp16502 *mcp = i2c_get_clientdata(client);
+
+   mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
+
+   return 0;
+}
+#else /* !CONFIG_SUSPEND */
+#define mcp16502_suspend NULL
+#define mcp16502_resume NULL
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops mcp16502_pm_ops = {
+   SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
+mcp16502_resume_noirq)
+};
+#endif
 static const struct i2c_device_id mcp16502_i2c_id[] = {
{ "mcp16502", 0 },
{ }
@@ -508,6 +539,9 @@ static struct i2c_driver mcp16502_drv = {
.driver = {
.name   = "mcp16502-regulator",
.of_match_table = of_match_ptr(mcp16502_ids),
+#ifdef CONFIG_PM
+   .pm = &mcp16502_pm_ops,
+#endif
},
.id_table   = mcp16502_i2c_id,
 };
-- 
2.7.4



Re: linux-next: Tree for Dec 17 (regulator/mcp16502.c)

2018-12-18 Thread Andrei.Stefanescu
Hi Randy,

Thank you for the email. The error should be fixed with this patch [1].

Best regards,
Andrei

[1] - 
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-December/621292.html

On 17.12.2018 18:03, Randy Dunlap wrote:
> On 12/17/18 3:09 AM, Stephen Rothwell wrote:
>> Hi all,
>>
>> Changes since 20181214:
>>
> on i386:
> # CONFIG_SUSPEND is not set
> CONFIG_PM=y
>
>CC  drivers/regulator/mcp16502.o
> In file included from ../include/linux/device.h:23:0,
>   from ../include/linux/gpio/driver.h:5,
>   from ../include/asm-generic/gpio.h:13,
>   from ../include/linux/gpio.h:62,
>   from ../drivers/regulator/mcp16502.c:11:
> ../drivers/regulator/mcp16502.c:527:32: error: 'mcp16502_suspend_noirq' 
> undeclared here (not in a function)
>SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
>  ^
> ../include/linux/pm.h:342:19: note: in definition of macro 
> 'SET_NOIRQ_SYSTEM_SLEEP_PM_OPS'
>.suspend_noirq = suspend_fn, \
> ^
> ../drivers/regulator/mcp16502.c:528:10: error: 'mcp16502_resume_noirq' 
> undeclared here (not in a function)
>mcp16502_resume_noirq)
>^
> ../include/linux/pm.h:343:18: note: in definition of macro 
> 'SET_NOIRQ_SYSTEM_SLEEP_PM_OPS'
>.resume_noirq = resume_fn, \
>^
>
>
>


Re: [PATCH] regulator: mcp16502: Fix missing n_voltages setting

2018-12-19 Thread Andrei.Stefanescu
Hi Axel,

Thank you for the patch!

However, there are not MCP16502_VSEL + 1 voltages,
but VDD_HIGH_SEL - VDD_LOW_SEL + 1 (=51).

Best regards,
Andrei

On 19.12.2018 10:58, Axel Lin wrote:
> The n_voltages setting is not set, fix it.
>
> Signed-off-by: Axel Lin 
> ---
>   drivers/regulator/mcp16502.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
> index 25d7b433fafd..ec5b6836a20c 100644
> --- a/drivers/regulator/mcp16502.c
> +++ b/drivers/regulator/mcp16502.c
> @@ -90,6 +90,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode)
>   .ops= &(_ops),  \
>   .type   = REGULATOR_VOLTAGE,\
>   .owner  = THIS_MODULE,  \
> + .n_voltages = MCP16502_VSEL + 1,\
>   .linear_ranges  = _ranges,  \
>   .n_linear_ranges= ARRAY_SIZE(_ranges),  \
>   .of_match   = of_match_ptr(_name),  \


[PATCH] regulator: mcp16502: code cleanup

2018-12-17 Thread Andrei.Stefanescu
This patch does the following:
- align parameter with parenthesis
- fix compile error

If CONFIG_SUSPEND is not set the dummy pm_ops
callbacks are named mcp16502_suspend and mcp16502_resume
instead of mcp16502_suspend_noirq and mcp16502_resume_noirq.

Excerpt from compile log (kbuild test robot):

In file included from include/linux/device.h:23:0,
from include/linux/gpio/driver.h:5,
from include/asm-generic/gpio.h:13,
from include/linux/gpio.h:62,
from drivers/regulator/mcp16502.c:11:

>> drivers/regulator/mcp16502.c:527:32: error: 'mcp16502_suspend_noirq'
undeclared here (not in a function); did you mean 'mcp16502_suspend'?
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,

>> drivers/regulator/mcp16502.c:528:10: error: 'mcp16502_resume_noirq'
undeclared here (not in a function); did you mean 'mcp16502_suspend_noirq'?
mcp16502_resume_noirq)

vim +527 drivers/regulator/mcp16502.c

524
525 #ifdef CONFIG_PM
526 static const struct dev_pm_ops mcp16502_pm_ops = {
> 527   SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
> 528mcp16502_resume_noirq)
529 };
530 #endif
531 static const struct i2c_device_id mcp16502_i2c_id[] = {
532 { "mcp16502", 0 },
533 { }
534 };
535 MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
536

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/mcp16502.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
index 25d7b43..809a664 100644
--- a/drivers/regulator/mcp16502.c
+++ b/drivers/regulator/mcp16502.c
@@ -518,14 +518,14 @@ static int mcp16502_resume_noirq(struct device *dev)
return 0;
 }
 #else /* !CONFIG_SUSPEND */
-#define mcp16502_suspend NULL
-#define mcp16502_resume NULL
+#define mcp16502_suspend_noirq NULL
+#define mcp16502_resume_noirq NULL
 #endif /* !CONFIG_SUSPEND */
 
 #ifdef CONFIG_PM
 static const struct dev_pm_ops mcp16502_pm_ops = {
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
-mcp16502_resume_noirq)
+ mcp16502_resume_noirq)
 };
 #endif
 static const struct i2c_device_id mcp16502_i2c_id[] = {
-- 
2.7.4



[RESEND PATCH v3 3/3] regulator: mcp16502: add regulator driver for MCP16502

2018-12-11 Thread Andrei.Stefanescu
This patch adds a regulator driver for the MCP16502 PMIC.
This drivers supports basic operations through the
regulator interface such as:
- setting/reading voltage
- setting/reading operating mode
- reading current status
- transitioning to/from suspend-to-ram and standby
  power states

Signed-off-by: Andrei Stefanescu 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/mcp16502.c | 555 +++
 3 files changed, 565 insertions(+)
 create mode 100644 drivers/regulator/mcp16502.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 926cee0..719d9d6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -567,6 +567,15 @@ config REGULATOR_MC13892
  Say y here to support the regulators found on the Freescale MC13892
  PMIC.
 
+config REGULATOR_MCP16502
+   tristate "Microchip MCP16502 PMIC"
+   depends on I2C && OF
+   help
+ Say y here to support the MCP16502 PMIC. This driver supports
+ basic operations (get/set voltage, get/set operating mode)
+ through the regulator interface. In addition it enables
+ suspend-to-ram/standby transition.
+
 config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 72488ef..b12e1c9 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
new file mode 100644
index 000..54db3df
--- /dev/null
+++ b/drivers/regulator/mcp16502.c
@@ -0,0 +1,555 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * MCP16502 PMIC driver
+ *
+ * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Andrei Stefanescu 
+ *
+ * Inspired from tps65086-regulator.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VDD_LOW_SEL 0x0D
+#define VDD_HIGH_SEL 0x3F
+
+#define MCP16502_FLT BIT(7)
+#define MCP16502_ENS BIT(0)
+
+/*
+ *
+ * The PMIC has four sets of registers corresponding to four power modes:
+ * Performance, Active, Low-power, Hibernate.
+ *
+ * Registers:
+ * Each regulator has a register for each power mode. To access a register
+ * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
+ *
+ * Operating modes:
+ * In order for the PMIC to transition to operating modes it has to be
+ * controlled via GPIO lines called LPM and HPM.
+ *
+ * The registers are fully configurable such that you can put all regulators in
+ * a low-power state while the PMIC is in Active mode. They are supposed to be
+ * configured at startup and then simply transition to/from a global low-power
+ * state by setting the GPIO lpm pin high/low.
+ *
+ * This driver keeps the PMIC in Active mode, Low-power state is set for the
+ * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
+ *
+ * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
+ * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
+ * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
+ */
+
+/*
+ * This function is useful for iterating over all regulators and accessing 
their
+ * registers in a generic way or accessing a regulator device by its id.
+ */
+#define MCP16502_BASE(i) (((i) + 1) << 4)
+#define MCP16502_STAT_BASE(i) ((i) + 5)
+
+#define MCP16502_OFFSET_MODE_A 0
+#define MCP16502_OFFSET_MODE_LPM 1
+#define MCP16502_OFFSET_MODE_HIB 2
+
+#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
+#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
+#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
+
+#define MCP16502_MODE_AUTO_PFM 0
+#define MCP16502_MODE_FPWM BIT(6)
+
+#define MCP16502_VSEL 0x3F
+#define MCP16502_EN BIT(7)
+#define MCP16502_MODE BIT(6)
+
+#define MCP16502_MIN_REG 0x0
+#define MCP16502_MAX_REG 0x65
+
+static unsigned int mcp16502_of_map_mode(unsigned int mode)
+{
+   if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
+   return mode;
+
+   return REGULATOR_MODE_INVALID;
+}
+
+#define MCP16502_REGULATOR(_name, _id, _ranges, _ops)  \
+   [_id] = {   \
+   .name   = _name,\
+   .regulators_node= of_match_ptr("regulators"),   \
+   .id

[RESEND PATCH v3 2/3] MAINTAINERS: add maintainer for MCP16502 PMIC driver

2018-12-11 Thread Andrei.Stefanescu
This patch adds a maintainer for the MCP16502 PMIC
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b755a89..6a74a65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9730,6 +9730,13 @@ M:   Ludovic Desroches 

 S: Maintained
 F: drivers/mmc/host/atmel-mci.c
 
+MICROCHIP MCP16502 PMIC DRIVER
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F: drivers/regulator/mcp16502.c
+
 MICROCHIP MCP3911 ADC DRIVER
 M: Marcus Folkesson 
 M: Kent Gustavsson 
-- 
2.7.4



[RESEND PATCH v3 1/3] regulator: dt-bindings: add MCP16502 regulator bindings

2018-12-11 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the MCP16502 PMIC.

Signed-off-by: Andrei Stefanescu 
Reviewed-by: Rob Herring 
---
 .../bindings/regulator/mcp16502-regulator.txt  | 143 +
 1 file changed, 143 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt 
b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
new file mode 100644
index 000..b8f843f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
@@ -0,0 +1,143 @@
+MCP16502 PMIC
+
+Required properties:
+- compatible: "microchip,mcp16502"
+- reg: I2C slave address
+- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
+suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+- regulators: A node that houses a sub-node for each regulator within
+  the device. Each sub-node is identified using the node's
+  name. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+
+Regualtors of MCP16502 PMIC:
+1) VDD_IO  - Buck (1.2 - 3.7 V)
+2) VDD_DDR - Buck (0.6 - 1.85 V)
+3) VDD_CORE- Buck (0.6 - 1.85 V)
+4) VDD_OTHER   - BUCK (0.6 - 1.85 V)
+5) LDO1- LDO  (1.2 - 3.7 V)
+6) LDO2- LDO  (1.2 - 3.7 V)
+
+Regulator modes:
+2 - FPWM: higher precision, higher consumption
+4 - AutoPFM: lower precision, lower consumption
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+mcp16502@5b {
+   compatible = "microchip,mcp16502";
+   reg = <0x5b>;
+   status = "okay";
+   lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   VDD_IO {
+   regulator-name = "VDD_IO";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <370>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_DDR {
+   regulator-name = "VDD_DDR";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_CORE {
+   regulator-name = "VDD_CORE";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   VDD_OTHER {
+   regulator-name = "VDD_OTHER";
+   regulator-min-microvolt = <60>;
+   regulator-max-microvolt = <185>;
+   regulator-initial-mode = <2>;
+   regulator-allowed-modes = <2>, <4>;
+   regulator-always-on;
+
+   regulator-state-standby {
+   regulator-on-in-suspend;
+   regulator-mode = <4>;
+   };
+
+   regulator-state-mem {
+   regulator-off-in-suspend;
+   regulator-mode = <4>;
+   };
+   };
+
+   LDO1 {
+   regulator-name = "LDO1";
+   regulator-min-microvolt = <12000

[RESEND PATCH v3 0/3] add support for MCP16502 PMIC

2018-12-11 Thread Andrei.Stefanescu
The resend is because I forgot to add Mark.

MCP16502 is a Power Management IC from Microchip.
It has 4 Buck outputs and 2 LDOs. The buck regulators
can be used in two modes: normal(FPWM) and low-power(Auto PFM).

This patch series adds support for the MCP16502 PMIC.

v3:
- use CONFIG_SUSPEND and CONFIG_PM to fix compile errors for some configs

v2:
- use lpm-gpios instead of lpm-gpio in devicetree bindings documentation
- describe the regulators present on the PMIC in the devicetree bindings
  documentation
- add SPDX license inside a C++ comment
- prefix macro
- remove mcp16502_update_regulator and mcp16502_read
- replace ?: with if-else
- change some if-else with switch statements for legibility
- use regmap helpers for regultor settings during runtime
- make mcp16502_get_status read the status from the PMIC STS registers
- use module_i2c_driver
- use the PMIC's Hibernate registers for suspend-to-mem, the PMIC's
  Low-power registers for standby and the PMIC's Active registers for
  normal runtime

Note about mcp16502_suspend:
- mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_HIB) has now been changed to
  mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM) for legibility.

Note that the function call only sets the LPM pin of the PMIC to high.
This puts the PMIC in Low-power operating mode. Hibernate operating mode
is reached when the MPU sets the PWRHLD line to zero (typically when
entering suspend-to-ram).

Andrei Stefanescu (3):
  regulator: dt-bindings: add MCP16502 regulator bindings
  MAINTAINERS: add maintainer for MCP16502 PMIC driver
  regulator: mcp16502: add regulator driver for MCP16502

 .../bindings/regulator/mcp16502-regulator.txt  | 143 ++
 MAINTAINERS|   7 +
 drivers/regulator/Kconfig  |   9 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/mcp16502.c   | 555 +
 5 files changed, 715 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 drivers/regulator/mcp16502.c

-- 
2.7.4



[PATCH 2/3] MAINTAINERS: add maintainer for sama5d2 PIOBU GPIO driver

2018-11-07 Thread Andrei.Stefanescu
This patch adds a maintainer for the sama5d2 GPIO controller
driver.

Signed-off-by: Andrei Stefanescu 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f485597..88369f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9760,6 +9760,13 @@ M:   Nicolas Ferre 
 S: Supported
 F: drivers/power/reset/at91-sama5d2_shdwc.c
 
+MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO
+M: Andrei Stefanescu 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+L: linux-g...@vger.kernel.org
+F: drivers/gpio/gpio-sama5d2-piobu.c
+F: Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
+
 MICROCHIP SPI DRIVER
 M: Nicolas Ferre 
 S: Supported
-- 
2.7.4



[PATCH 3/3] gpio: add driver for sama5d2 PIOBU pins

2018-11-07 Thread Andrei.Stefanescu
PIOBU pins do not lose their voltage during Backup/Self-refresh.
This patch adds a simple GPIO controller for them.

This driver adds support for using the pins as GPIO
offering the possibility to read/set the voltage.

Signed-off-by: Andrei Stefanescu 
---
 drivers/gpio/Kconfig  |  10 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-sama5d2-piobu.c | 254 ++
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 833a1b5..e562e32 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -429,6 +429,16 @@ 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 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 000..4ded370
--- /dev/null
+++ b/drivers/gpio/gpio-sama5d2-piobu.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SAMA5D2 PIOBU GPIO controller
+ *
+ * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Andrei Stefanescu 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PIOBU_NUM 8
+#define PIOBU_REG_SIZE 4
+
+/*
+ * backup mode protection register for intrusion detection
+ * normal mode protection register for intrusion 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 sama5d2_piobu_set_direction 
call
+ *
+ * Do not consider pin for intrusion detection (normal and backup modes)
+ * Do not consider pin as intrusion 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, ret;
+   struct sama5d2_piobu *piobu = container_of(chip, struct sama5d2_piobu,
+  chip);
+
+   reg = PIOBU_BASE + pin * PIOBU_REG_SIZE;
+   ret = regmap_update_bits(piobu->regmap, reg, mask, value);
+   return ret;
+}
+
+/*
+ * 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);
+ 

[PATCH 1/3] dt-bindings: gpio: add sama5d2 PIOBU support

2018-11-07 Thread Andrei.Stefanescu
This patch describes the compatible and the device tree
bindings necessary for the sama5d2 PIOBU GPIO
controller driver.

Signed-off-by: Andrei Stefanescu 
---
 .../bindings/gpio/gpio-sama5d2-piobu.txt   | 23 ++
 1 file changed, 23 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt 
b/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
new file mode 100644
index 000..791ac51
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
@@ -0,0 +1,23 @@
+GPIO controller for SAMA5D2 PIOBU pins.
+
+This pins have the property of not losing their voltage
+during Backup/Self-refresh mode.
+
+These bindings should be set to a node in the dtsi file.
+
+Required properties:
+- compatible:  "syscon", "microchip,sama5d2-piobu"
+- #gpio-cells: There are 2. The pin number is the
+   first, the second represents additional
+   parameters such as GPIO_ACTIVE_HIGH/LOW.
+- gpio-controller: Marks the port as GPIO controller.
+
+Example:
+
+   secumod@fc04 {
+   compatible = "syscon", "microchip,sama5d2-piobu";
+   reg = <0xfc04 0x100>;
+
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
-- 
2.7.4



[PATCH 0/3] add sama5d2 PIOBU GPIO driver

2018-11-07 Thread 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).

This patch series:
- documents the driver's necessary device tree bindings
- adds a MAINTAINER for the driver,
- provides a basic GPIO controller driver for them

Andrei Stefanescu (3):
  dt-bindings: gpio: add sama5d2 PIOBU support
  MAINTAINERS: add maintainer for sama5d2 PIOBU GPIO driver
  gpio: added driver for sama5d2 PIOBU pins

 .../bindings/gpio/gpio-sama5d2-piobu.txt   |  23 ++
 MAINTAINERS|   7 +
 drivers/gpio/Kconfig   |  10 +
 drivers/gpio/Makefile  |   1 +
 drivers/gpio/gpio-sama5d2-piobu.c  | 254 +
 5 files changed, 295 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/gpio/gpio-sama5d2-piobu.txt
 create mode 100644 drivers/gpio/gpio-sama5d2-piobu.c

-- 
2.7.4



[PATCH] i2c: at91: switched to resume/suspend callbacks.

2018-10-22 Thread Andrei.Stefanescu
In the previous version of the driver resume/suspend_noirq callbacks
were used. Because of this, when resuming from suspend-to-ram,
an I2C (belonging to a FLEXCOM) would resume before FLEXCOM.
The first read on the I2C bus would then result in a timeout.

This patch switches to resume/suspend callbacks which are 
called after FLEXCOM resumes. FLEXCOM, SPI and USART drivers use
resume/suspend callbacks.

Signed-off-by: Andrei Stefanescu 
---
 drivers/i2c/busses/i2c-at91.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index bfd1fdf..81f7b94 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -1174,7 +1174,7 @@ static int at91_twi_runtime_resume(struct device *dev)
return clk_prepare_enable(twi_dev->clk);
 }
 
-static int at91_twi_suspend_noirq(struct device *dev)
+static int at91_twi_suspend(struct device *dev)
 {
if (!pm_runtime_status_suspended(dev))
at91_twi_runtime_suspend(dev);
@@ -1182,7 +1182,7 @@ static int at91_twi_suspend_noirq(struct device *dev)
return 0;
 }
 
-static int at91_twi_resume_noirq(struct device *dev)
+static int at91_twi_resume(struct device *dev)
 {
struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
int ret;
@@ -1202,8 +1202,8 @@ static int at91_twi_resume_noirq(struct device *dev)
 }
 
 static const struct dev_pm_ops at91_twi_pm = {
-   .suspend_noirq  = at91_twi_suspend_noirq,
-   .resume_noirq   = at91_twi_resume_noirq,
+   .suspend= at91_twi_suspend,
+   .resume = at91_twi_resume,
.runtime_suspend= at91_twi_runtime_suspend,
.runtime_resume = at91_twi_runtime_resume,
 };
-- 
2.7.4