[PATCH v2 0/3] add support for MCP16502 PMIC
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
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
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.
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