All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] Add support for TI TPS65219 PMIC.
@ 2022-07-26 10:33 ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Not implemented
- DVS

1-Regulators:
Full implementation and test
Visual check: cat /sys/kernel/debug/regulator/regulator_summary
Full validation requires userspace-consumer and virtual-regulator
LDO1 is not used and output can be probbed on TP84.

2-Reset WARM/COLD
test procedure: launch reboot on the console and check visually

warm vs. cold can be configured on the kernel command-line at boot time.
Default is cold, but adding `reboot=w`
to kernel command allow testing warm reboot.

Alternative:
`# echo warm > /sys/kernel/reboot/mode` 

3-SW Shutdown
test procedure: launch halt on the console and check visually

Note: enters in competition with other source during probe

Board Test Points can be used to check voltage after system shutdown.
baseport is not handling wakeup.
A power OFF/ON cycle is needed to recover.

4-Interrupt Pin (nINT):

Interrupt occurring on PMIC TPS65219 is propagated to SOC
through EXTINTn pin connected to gic500 interrupt controller

Interrupt lines for TPS65219 shows-up on console:
cat /proc/interrupts

Validation:
Create a Residual Voltage interrupt and handling and interrupt source is cleared.
`tps65219 0-0030: Registered residual voltage for LDO1`
`533:          1          0  tps65219_irq  35 Edge      LDO1_RV`

Mapped to power button (use TP90 to GND to emulate a physical button)

5-PB Startup and Shutdown:
New implementation to support both rising and falling edge.

TPS65219 has different interrupts compared to other TPS6521* chips.
TPS65219 defines two interrupts for the powerbutton one for push and one
for release.


Interrupt support: cat proc/interrupts
`557:          0          0  tps65219_irq  47 Edge      tps65219-pwrbutton.1.auto`
`558:          0          0  tps65219_irq  48 Edge      tps65219-pwrbutton.1.auto`

TPS65219 has a multipurpose pin called EN/PB/VSENSE that can be either:
- EN in which case it functions as an enable pin.
- VSENSE which compares the voltages and triggers an automatic on/off request.
- PB in which case it can be configured to trigger an interrupt to the SoC.
ti,power-button reflects the last one of those options
where the board has a button wired to the pin and triggers
an interrupt on pressing it.

6-Changes vs v1:

6.1- Regulators:
- Further to Mark Brown review:
Use standard regmap helpers for set_voltage, enable and disable.
tps65219_set_mode, return -EINVAL in default statement for clarity.
Reshaped irq handler to report events through the notification API:
regulator_notifier_call_chain().
Use standard regulator events (consumer.h).

6.2- Device tree
- Further to Nishanth Menon review:
add tag DONOTMERGE
Board support is pending waiting for TI commitment.
This device tree is needed for driver test purpose but should not go upstream.

6.3- Bindings
- Further to Rob Herring review:
Squash interrupt commit into regulator dt-binding.
Squash pwrbutton commit into regulator dt-binding.
Remove interrupt-controller/cells properties because no consumer for those interrupts.

- Further to Mark Brown review:
Remove constraints on regulator-name.

- Pending for decision from Lee Jones further to Mark Brown review
The entire binding document should probably be in MFD if it's going to
have properties for other functions added to it.

6.4- Misc
- Further to Mark Brown review:
Use C++ (//) formatting for file header block including SPDX License
in mfd, regulator and pwrbutton.

Jerome Neanne (7):
  DONOTMERGE: arm64: dts: ti: Add TI TPS65219 PMIC support for AM642 SK
    board.
  DONOTMERGE: arm64: dts: ti: Add pinmux and irq mapping for TPS65219
    external interrupts
  regulator: dt-bindings: Add TI TPS65219 PMIC bindings
  mfd: drivers: Add TI TPS65219 PMIC support
  mfd: drivers: Add interrupts support to TI TPS65219 PMIC
  regulator: drivers: Add TI TPS65219 PMIC regulators support
  arm64: defconfig: Add tps65219 as modules

Markus Schneider-Pargmann (4):
  DONOTMERGE: arm64: dts: ti: k3-am642-sk: Enable tps65219 power-button
  MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton
  mfd: tps65219: Add power-button support
  Input: Add tps65219 interrupt driven powerbutton

 .../bindings/regulator/ti,tps65219.yaml       | 164 +++++++
 MAINTAINERS                                   |   4 +
 arch/arm64/boot/dts/ti/k3-am642-sk.dts        | 115 +++++
 arch/arm64/configs/defconfig                  |   3 +
 drivers/input/misc/Kconfig                    |  10 +
 drivers/input/misc/Makefile                   |   1 +
 drivers/input/misc/tps65219-pwrbutton.c       | 150 ++++++
 drivers/mfd/Kconfig                           |  15 +
 drivers/mfd/Makefile                          |   1 +
 drivers/mfd/tps65219.c                        | 437 ++++++++++++++++++
 drivers/regulator/Kconfig                     |   9 +
 drivers/regulator/Makefile                    |   1 +
 drivers/regulator/tps65219-regulator.c        | 416 +++++++++++++++++
 include/linux/mfd/tps65219.h                  | 364 +++++++++++++++
 14 files changed, 1690 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
 create mode 100644 drivers/input/misc/tps65219-pwrbutton.c
 create mode 100644 drivers/mfd/tps65219.c
 create mode 100644 drivers/regulator/tps65219-regulator.c
 create mode 100644 include/linux/mfd/tps65219.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 00/11] Add support for TI TPS65219 PMIC.
@ 2022-07-26 10:33 ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Not implemented
- DVS

1-Regulators:
Full implementation and test
Visual check: cat /sys/kernel/debug/regulator/regulator_summary
Full validation requires userspace-consumer and virtual-regulator
LDO1 is not used and output can be probbed on TP84.

2-Reset WARM/COLD
test procedure: launch reboot on the console and check visually

warm vs. cold can be configured on the kernel command-line at boot time.
Default is cold, but adding `reboot=w`
to kernel command allow testing warm reboot.

Alternative:
`# echo warm > /sys/kernel/reboot/mode` 

3-SW Shutdown
test procedure: launch halt on the console and check visually

Note: enters in competition with other source during probe

Board Test Points can be used to check voltage after system shutdown.
baseport is not handling wakeup.
A power OFF/ON cycle is needed to recover.

4-Interrupt Pin (nINT):

Interrupt occurring on PMIC TPS65219 is propagated to SOC
through EXTINTn pin connected to gic500 interrupt controller

Interrupt lines for TPS65219 shows-up on console:
cat /proc/interrupts

Validation:
Create a Residual Voltage interrupt and handling and interrupt source is cleared.
`tps65219 0-0030: Registered residual voltage for LDO1`
`533:          1          0  tps65219_irq  35 Edge      LDO1_RV`

Mapped to power button (use TP90 to GND to emulate a physical button)

5-PB Startup and Shutdown:
New implementation to support both rising and falling edge.

TPS65219 has different interrupts compared to other TPS6521* chips.
TPS65219 defines two interrupts for the powerbutton one for push and one
for release.


Interrupt support: cat proc/interrupts
`557:          0          0  tps65219_irq  47 Edge      tps65219-pwrbutton.1.auto`
`558:          0          0  tps65219_irq  48 Edge      tps65219-pwrbutton.1.auto`

TPS65219 has a multipurpose pin called EN/PB/VSENSE that can be either:
- EN in which case it functions as an enable pin.
- VSENSE which compares the voltages and triggers an automatic on/off request.
- PB in which case it can be configured to trigger an interrupt to the SoC.
ti,power-button reflects the last one of those options
where the board has a button wired to the pin and triggers
an interrupt on pressing it.

6-Changes vs v1:

6.1- Regulators:
- Further to Mark Brown review:
Use standard regmap helpers for set_voltage, enable and disable.
tps65219_set_mode, return -EINVAL in default statement for clarity.
Reshaped irq handler to report events through the notification API:
regulator_notifier_call_chain().
Use standard regulator events (consumer.h).

6.2- Device tree
- Further to Nishanth Menon review:
add tag DONOTMERGE
Board support is pending waiting for TI commitment.
This device tree is needed for driver test purpose but should not go upstream.

6.3- Bindings
- Further to Rob Herring review:
Squash interrupt commit into regulator dt-binding.
Squash pwrbutton commit into regulator dt-binding.
Remove interrupt-controller/cells properties because no consumer for those interrupts.

- Further to Mark Brown review:
Remove constraints on regulator-name.

- Pending for decision from Lee Jones further to Mark Brown review
The entire binding document should probably be in MFD if it's going to
have properties for other functions added to it.

6.4- Misc
- Further to Mark Brown review:
Use C++ (//) formatting for file header block including SPDX License
in mfd, regulator and pwrbutton.

Jerome Neanne (7):
  DONOTMERGE: arm64: dts: ti: Add TI TPS65219 PMIC support for AM642 SK
    board.
  DONOTMERGE: arm64: dts: ti: Add pinmux and irq mapping for TPS65219
    external interrupts
  regulator: dt-bindings: Add TI TPS65219 PMIC bindings
  mfd: drivers: Add TI TPS65219 PMIC support
  mfd: drivers: Add interrupts support to TI TPS65219 PMIC
  regulator: drivers: Add TI TPS65219 PMIC regulators support
  arm64: defconfig: Add tps65219 as modules

Markus Schneider-Pargmann (4):
  DONOTMERGE: arm64: dts: ti: k3-am642-sk: Enable tps65219 power-button
  MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton
  mfd: tps65219: Add power-button support
  Input: Add tps65219 interrupt driven powerbutton

 .../bindings/regulator/ti,tps65219.yaml       | 164 +++++++
 MAINTAINERS                                   |   4 +
 arch/arm64/boot/dts/ti/k3-am642-sk.dts        | 115 +++++
 arch/arm64/configs/defconfig                  |   3 +
 drivers/input/misc/Kconfig                    |  10 +
 drivers/input/misc/Makefile                   |   1 +
 drivers/input/misc/tps65219-pwrbutton.c       | 150 ++++++
 drivers/mfd/Kconfig                           |  15 +
 drivers/mfd/Makefile                          |   1 +
 drivers/mfd/tps65219.c                        | 437 ++++++++++++++++++
 drivers/regulator/Kconfig                     |   9 +
 drivers/regulator/Makefile                    |   1 +
 drivers/regulator/tps65219-regulator.c        | 416 +++++++++++++++++
 include/linux/mfd/tps65219.h                  | 364 +++++++++++++++
 14 files changed, 1690 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
 create mode 100644 drivers/input/misc/tps65219-pwrbutton.c
 create mode 100644 drivers/mfd/tps65219.c
 create mode 100644 drivers/regulator/tps65219-regulator.c
 create mode 100644 include/linux/mfd/tps65219.h

-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 01/11] DONOTMERGE: arm64: dts: ti: Add TI TPS65219 PMIC support for AM642 SK board.
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Add support fot the TI Power Management IC TPS65219
on the AM642 SKEVM board.

Needed for driver testing but official board support pending.
TI commitment is required before board upstream kick-off.

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 104 +++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 59f506cbd275..4daf55b9d61a 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -150,6 +150,20 @@
 		vin-supply = <&com8_ls_en>;
 		gpio = <&main_gpio0 48 GPIO_ACTIVE_HIGH>;
 	};
+
+	vsel_sd_nddr: gpio-regulator {
+		compatible = "regulator-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vsel_sd_nddr_pins_default>;
+		regulator-name = "tps65219-LDO1-SEL-SD";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&ldo1_reg>;
+		gpios = <&main_gpio0 45 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+	};
 };
 
 &main_pmx0 {
@@ -172,6 +186,13 @@
 		>;
 	};
 
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0260, PIN_INPUT_PULLUP, 0) /* (A18) I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT_PULLUP, 0) /* (B18) I2C0_SDA */
+		>;
+	};
+
 	main_i2c1_pins_default: main-i2c1-pins-default {
 		pinctrl-single,pins = <
 			AM64X_IOPAD(0x0268, PIN_INPUT_PULLUP, 0) /* (C18) I2C1_SCL */
@@ -258,6 +279,12 @@
 			AM64X_IOPAD(0x00bc, PIN_INPUT, 7) /* (U8) GPIO0_46 */
 		>;
 	};
+
+	vsel_sd_nddr_pins_default: vsel-sd-nddr-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 7) /* (Y7) PRG1_PRU0_GPO0.GPIO0_45 */
+		>;
+	};
 };
 
 &mcu_uart0 {
@@ -301,6 +328,83 @@
 	status = "disabled";
 };
 
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	tps65219: pmic@30 {
+		compatible = "ti,tps65219";
+		reg = <0x30>;
+		system-power-controller;
+
+		buck1-supply = <&vcc_3v3_sys>;
+		buck2-supply = <&vcc_3v3_sys>;
+		buck3-supply = <&vcc_3v3_sys>;
+		ldo1-supply = <&vcc_3v3_sys>;
+		ldo2-supply = <&buck2_reg>;
+		ldo3-supply = <&vcc_3v3_sys>;
+		ldo4-supply = <&vcc_3v3_sys>;
+
+		regulators {
+			buck1_reg: buck1 {
+				regulator-name = "VDD_CORE";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck2_reg: buck2 {
+				regulator-name = "VCC1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck3_reg: buck3 {
+				regulator-name = "VDD_LPDDR4";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1_reg: ldo1 {
+				regulator-name = "VDDSHV_SD_IO_PMIC";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allow-bypass;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-name = "VDDAR_CORE";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3_reg: ldo3 {
+				regulator-name = "VDDA_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo4_reg: ldo4 {
+				regulator-name = "VDD_PHY_2V5";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+};
 &main_i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c1_pins_default>;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 01/11] DONOTMERGE: arm64: dts: ti: Add TI TPS65219 PMIC support for AM642 SK board.
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Add support fot the TI Power Management IC TPS65219
on the AM642 SKEVM board.

Needed for driver testing but official board support pending.
TI commitment is required before board upstream kick-off.

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 104 +++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 59f506cbd275..4daf55b9d61a 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -150,6 +150,20 @@
 		vin-supply = <&com8_ls_en>;
 		gpio = <&main_gpio0 48 GPIO_ACTIVE_HIGH>;
 	};
+
+	vsel_sd_nddr: gpio-regulator {
+		compatible = "regulator-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vsel_sd_nddr_pins_default>;
+		regulator-name = "tps65219-LDO1-SEL-SD";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&ldo1_reg>;
+		gpios = <&main_gpio0 45 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+	};
 };
 
 &main_pmx0 {
@@ -172,6 +186,13 @@
 		>;
 	};
 
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0260, PIN_INPUT_PULLUP, 0) /* (A18) I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT_PULLUP, 0) /* (B18) I2C0_SDA */
+		>;
+	};
+
 	main_i2c1_pins_default: main-i2c1-pins-default {
 		pinctrl-single,pins = <
 			AM64X_IOPAD(0x0268, PIN_INPUT_PULLUP, 0) /* (C18) I2C1_SCL */
@@ -258,6 +279,12 @@
 			AM64X_IOPAD(0x00bc, PIN_INPUT, 7) /* (U8) GPIO0_46 */
 		>;
 	};
+
+	vsel_sd_nddr_pins_default: vsel-sd-nddr-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 7) /* (Y7) PRG1_PRU0_GPO0.GPIO0_45 */
+		>;
+	};
 };
 
 &mcu_uart0 {
@@ -301,6 +328,83 @@
 	status = "disabled";
 };
 
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	tps65219: pmic@30 {
+		compatible = "ti,tps65219";
+		reg = <0x30>;
+		system-power-controller;
+
+		buck1-supply = <&vcc_3v3_sys>;
+		buck2-supply = <&vcc_3v3_sys>;
+		buck3-supply = <&vcc_3v3_sys>;
+		ldo1-supply = <&vcc_3v3_sys>;
+		ldo2-supply = <&buck2_reg>;
+		ldo3-supply = <&vcc_3v3_sys>;
+		ldo4-supply = <&vcc_3v3_sys>;
+
+		regulators {
+			buck1_reg: buck1 {
+				regulator-name = "VDD_CORE";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck2_reg: buck2 {
+				regulator-name = "VCC1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck3_reg: buck3 {
+				regulator-name = "VDD_LPDDR4";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1_reg: ldo1 {
+				regulator-name = "VDDSHV_SD_IO_PMIC";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allow-bypass;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-name = "VDDAR_CORE";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3_reg: ldo3 {
+				regulator-name = "VDDA_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo4_reg: ldo4 {
+				regulator-name = "VDD_PHY_2V5";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+};
 &main_i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c1_pins_default>;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 02/11] DONOTMERGE: arm64: dts: ti: Add pinmux and irq mapping for TPS65219 external interrupts
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Interrupt occurring on PMIC TPS65219 is propagated to SOC
through EXTINTn pin connected to gic500 interrupt controller

Needed for driver testing but official board support pending.
TI commitment is required before board upstream kick-off.

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 4daf55b9d61a..7a84223406f5 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -285,6 +285,12 @@
 			AM64X_IOPAD(0x00b8, PIN_INPUT, 7) /* (Y7) PRG1_PRU0_GPO0.GPIO0_45 */
 		>;
 	};
+
+	pmic_irq_pins_default: pmic-irq-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0278, PIN_INPUT, 0) /* (C19) EXTINTn */
+		>;
+	};
 };
 
 &mcu_uart0 {
@@ -338,6 +344,12 @@
 		compatible = "ti,tps65219";
 		reg = <0x30>;
 		system-power-controller;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
 
 		buck1-supply = <&vcc_3v3_sys>;
 		buck2-supply = <&vcc_3v3_sys>;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 02/11] DONOTMERGE: arm64: dts: ti: Add pinmux and irq mapping for TPS65219 external interrupts
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Interrupt occurring on PMIC TPS65219 is propagated to SOC
through EXTINTn pin connected to gic500 interrupt controller

Needed for driver testing but official board support pending.
TI commitment is required before board upstream kick-off.

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 4daf55b9d61a..7a84223406f5 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -285,6 +285,12 @@
 			AM64X_IOPAD(0x00b8, PIN_INPUT, 7) /* (Y7) PRG1_PRU0_GPO0.GPIO0_45 */
 		>;
 	};
+
+	pmic_irq_pins_default: pmic-irq-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0278, PIN_INPUT, 0) /* (C19) EXTINTn */
+		>;
+	};
 };
 
 &mcu_uart0 {
@@ -338,6 +344,12 @@
 		compatible = "ti,tps65219";
 		reg = <0x30>;
 		system-power-controller;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
 
 		buck1-supply = <&vcc_3v3_sys>;
 		buck2-supply = <&vcc_3v3_sys>;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 03/11] DONOTMERGE: arm64: dts: ti: k3-am642-sk: Enable tps65219 power-button
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

This board uses the pin as a power-button, enable it.

Needed for driver testing but official board support pending.
TI commitment is required before board upstream kick-off.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 7a84223406f5..d789fb7c2162 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -348,8 +348,7 @@
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&gic500>;
 		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-controller;
-		#interrupt-cells = <1>;
+		power-button;
 
 		buck1-supply = <&vcc_3v3_sys>;
 		buck2-supply = <&vcc_3v3_sys>;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 03/11] DONOTMERGE: arm64: dts: ti: k3-am642-sk: Enable tps65219 power-button
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

This board uses the pin as a power-button, enable it.

Needed for driver testing but official board support pending.
TI commitment is required before board upstream kick-off.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 7a84223406f5..d789fb7c2162 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -348,8 +348,7 @@
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&gic500>;
 		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-controller;
-		#interrupt-cells = <1>;
+		power-button;
 
 		buck1-supply = <&vcc_3v3_sys>;
 		buck2-supply = <&vcc_3v3_sys>;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 04/11] MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

The entry for the pwrbutton driver seems to be missing. Add it to the
list for OMAP2+ SUPPORT.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 64379c699903..67850b321cbb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14704,6 +14704,7 @@ F:	arch/arm/mach-omap2/
 F:	arch/arm/plat-omap/
 F:	drivers/bus/ti-sysc.c
 F:	drivers/i2c/busses/i2c-omap.c
+F:	drivers/input/misc/tps65218-pwrbutton.c
 F:	drivers/irqchip/irq-omap-intc.c
 F:	drivers/mfd/*omap*.c
 F:	drivers/mfd/menelaus.c
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 04/11] MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

The entry for the pwrbutton driver seems to be missing. Add it to the
list for OMAP2+ SUPPORT.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 64379c699903..67850b321cbb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14704,6 +14704,7 @@ F:	arch/arm/mach-omap2/
 F:	arch/arm/plat-omap/
 F:	drivers/bus/ti-sysc.c
 F:	drivers/i2c/busses/i2c-omap.c
+F:	drivers/input/misc/tps65218-pwrbutton.c
 F:	drivers/irqchip/irq-omap-intc.c
 F:	drivers/mfd/*omap*.c
 F:	drivers/mfd/menelaus.c
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 05/11] regulator: dt-bindings: Add TI TPS65219 PMIC bindings
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Add TPS65219 PMIC bindings using json-schema.

Describe required properties and regname-supply.
regname-supply is required when bypass mode is used for a regulator.
Describes regulator topology.
Interrupts support.
Add a power-button property to configure the EN/PB/VSENSE pin as a
powerbutton:

TPS65219 has a multipurpose pin called EN/PB/VSENSE that can be either:
- EN in which case it functions as an enable pin.
- VSENSE which compares the voltages and triggers an automatic
on/off request.
- PB in which case it can be configured to trigger an interrupt
to the SoC.
ti,power-button reflects the last one of those options
where the board has a button wired to the pin and triggers
an interrupt on pressing it.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 .../bindings/regulator/ti,tps65219.yaml       | 164 ++++++++++++++++++
 1 file changed, 164 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/ti,tps65219.yaml

diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
new file mode 100644
index 000000000000..8fca4db6c64c
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps65219.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI tps65219 Power Management Integrated Circuit regulators
+
+maintainers:
+  - Jerome Neanne <jerome.neanne@baylibre.com>
+
+description: |
+  Regulator nodes should be named to buck<number> and ldo<number>.
+
+properties:
+  compatible:
+    enum:
+      - ti,tps65219
+
+  reg:
+    maxItems: 1
+
+  system-power-controller:
+    type: boolean
+    description: Optional property that indicates that this device is
+      controlling system power.
+
+  interrupts:
+    description: Short-circuit, over-current, under-voltage for regulators, PB interrupts.
+    maxItems: 1
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    description: Specifies the PIN numbers and Flags, as defined in
+      include/dt-bindings/interrupt-controller/irq.h
+    const: 1
+
+  power-button:
+    type: boolean
+    description: Optional property that sets the EN/PB/VSENSE pin to be a
+      power-button.
+
+patternProperties:
+  "^buck[1-3]-supply$":
+    description: Input supply phandle of one regulator.
+
+  "^ldo[1-4]-supply$":
+    description: Input supply phandle of one regulator.
+
+  regulators:
+    type: object
+    description: |
+      list of regulators provided by this controller
+
+    patternProperties:
+      "^ldo[1-4]$":
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single LDO regulator.
+
+        unevaluatedProperties: false
+
+      "^buck[1-3]$":
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single BUCK regulator.
+
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        tps65219: pmic@30 {
+            compatible = "ti,tps65219";
+            reg = <0x30>;
+            buck1-supply = <&vcc_3v3_sys>;
+            buck2-supply = <&vcc_3v3_sys>;
+            buck3-supply = <&vcc_3v3_sys>;
+            ldo1-supply = <&vcc_3v3_sys>;
+            ldo2-supply = <&buck2_reg>;
+            ldo3-supply = <&vcc_3v3_sys>;
+            ldo4-supply = <&vcc_3v3_sys>;
+
+            pinctrl-0 = <&pmic_irq_pins_default>;
+
+            interrupt-parent = <&gic500>;
+            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-controller;
+            #interrupt-cells = <1>;
+
+            regulators {
+                buck1_reg: buck1 {
+                    regulator-name = "VDD_CORE";
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                buck2_reg: buck2 {
+                    regulator-name = "VCC1V8";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                buck3_reg: buck3 {
+                    regulator-name = "VDD_LPDDR4";
+                    regulator-min-microvolt = <1100000>;
+                    regulator-max-microvolt = <1100000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo1_reg: ldo1 {
+                    regulator-name = "VDDSHV_SD_IO_PMIC";
+                    regulator-min-microvolt = <33000000>;
+                    regulator-max-microvolt = <33000000>;
+                };
+
+                ldo2_reg: ldo2 {
+                    regulator-name = "VDDAR_CORE";
+                    regulator-min-microvolt = <850000>;
+                    regulator-max-microvolt = <850000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo3_reg: ldo3 {
+                    regulator-name = "VDDA_1V8";
+                    regulator-min-microvolt = <18000000>;
+                    regulator-max-microvolt = <18000000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo4_reg: ldo4 {
+                    regulator-name = "VDD_PHY_2V5";
+                    regulator-min-microvolt = <25000000>;
+                    regulator-max-microvolt = <25000000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+            };
+        };
+    };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 05/11] regulator: dt-bindings: Add TI TPS65219 PMIC bindings
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Add TPS65219 PMIC bindings using json-schema.

Describe required properties and regname-supply.
regname-supply is required when bypass mode is used for a regulator.
Describes regulator topology.
Interrupts support.
Add a power-button property to configure the EN/PB/VSENSE pin as a
powerbutton:

TPS65219 has a multipurpose pin called EN/PB/VSENSE that can be either:
- EN in which case it functions as an enable pin.
- VSENSE which compares the voltages and triggers an automatic
on/off request.
- PB in which case it can be configured to trigger an interrupt
to the SoC.
ti,power-button reflects the last one of those options
where the board has a button wired to the pin and triggers
an interrupt on pressing it.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 .../bindings/regulator/ti,tps65219.yaml       | 164 ++++++++++++++++++
 1 file changed, 164 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/ti,tps65219.yaml

diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
new file mode 100644
index 000000000000..8fca4db6c64c
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps65219.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI tps65219 Power Management Integrated Circuit regulators
+
+maintainers:
+  - Jerome Neanne <jerome.neanne@baylibre.com>
+
+description: |
+  Regulator nodes should be named to buck<number> and ldo<number>.
+
+properties:
+  compatible:
+    enum:
+      - ti,tps65219
+
+  reg:
+    maxItems: 1
+
+  system-power-controller:
+    type: boolean
+    description: Optional property that indicates that this device is
+      controlling system power.
+
+  interrupts:
+    description: Short-circuit, over-current, under-voltage for regulators, PB interrupts.
+    maxItems: 1
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    description: Specifies the PIN numbers and Flags, as defined in
+      include/dt-bindings/interrupt-controller/irq.h
+    const: 1
+
+  power-button:
+    type: boolean
+    description: Optional property that sets the EN/PB/VSENSE pin to be a
+      power-button.
+
+patternProperties:
+  "^buck[1-3]-supply$":
+    description: Input supply phandle of one regulator.
+
+  "^ldo[1-4]-supply$":
+    description: Input supply phandle of one regulator.
+
+  regulators:
+    type: object
+    description: |
+      list of regulators provided by this controller
+
+    patternProperties:
+      "^ldo[1-4]$":
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single LDO regulator.
+
+        unevaluatedProperties: false
+
+      "^buck[1-3]$":
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single BUCK regulator.
+
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        tps65219: pmic@30 {
+            compatible = "ti,tps65219";
+            reg = <0x30>;
+            buck1-supply = <&vcc_3v3_sys>;
+            buck2-supply = <&vcc_3v3_sys>;
+            buck3-supply = <&vcc_3v3_sys>;
+            ldo1-supply = <&vcc_3v3_sys>;
+            ldo2-supply = <&buck2_reg>;
+            ldo3-supply = <&vcc_3v3_sys>;
+            ldo4-supply = <&vcc_3v3_sys>;
+
+            pinctrl-0 = <&pmic_irq_pins_default>;
+
+            interrupt-parent = <&gic500>;
+            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-controller;
+            #interrupt-cells = <1>;
+
+            regulators {
+                buck1_reg: buck1 {
+                    regulator-name = "VDD_CORE";
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                buck2_reg: buck2 {
+                    regulator-name = "VCC1V8";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                buck3_reg: buck3 {
+                    regulator-name = "VDD_LPDDR4";
+                    regulator-min-microvolt = <1100000>;
+                    regulator-max-microvolt = <1100000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo1_reg: ldo1 {
+                    regulator-name = "VDDSHV_SD_IO_PMIC";
+                    regulator-min-microvolt = <33000000>;
+                    regulator-max-microvolt = <33000000>;
+                };
+
+                ldo2_reg: ldo2 {
+                    regulator-name = "VDDAR_CORE";
+                    regulator-min-microvolt = <850000>;
+                    regulator-max-microvolt = <850000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo3_reg: ldo3 {
+                    regulator-name = "VDDA_1V8";
+                    regulator-min-microvolt = <18000000>;
+                    regulator-max-microvolt = <18000000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo4_reg: ldo4 {
+                    regulator-name = "VDD_PHY_2V5";
+                    regulator-min-microvolt = <25000000>;
+                    regulator-max-microvolt = <25000000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+            };
+        };
+    };
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

The TPS65219 is a power management IC PMIC designed
to supply a wide range of SoCs
in both portable and stationary applications.
Any SoC can control TPS65219 over a standard I2C interface.

It contains the following components:
- Regulators.
- Over Temperature warning and Shut down.
- GPIOs
- Multi Function Pins (MFP)

This patch adds support for tps65219 mfd device. At this time only
the functionalities listed below are made available:

- Regulators probe and functionalities
- warm and cold reset support
- SW shutdown support

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS                  |   1 +
 drivers/mfd/Kconfig          |  15 +++
 drivers/mfd/Makefile         |   1 +
 drivers/mfd/tps65219.c       | 214 +++++++++++++++++++++++++++++
 include/linux/mfd/tps65219.h | 251 +++++++++++++++++++++++++++++++++++
 5 files changed, 482 insertions(+)
 create mode 100644 drivers/mfd/tps65219.c
 create mode 100644 include/linux/mfd/tps65219.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 67850b321cbb..1331c43fc6ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14711,6 +14711,7 @@ F:	drivers/mfd/menelaus.c
 F:	drivers/mfd/palmas.c
 F:	drivers/mfd/tps65217.c
 F:	drivers/mfd/tps65218.c
+F:	drivers/mfd/tps65219.c
 F:	drivers/mfd/tps65910.c
 F:	drivers/mfd/twl-core.[ch]
 F:	drivers/mfd/twl4030*.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3b59456f5545..c66e56374a9a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1574,6 +1574,21 @@ config MFD_TPS65218
 	  This driver can also be built as a module.  If so, the module
 	  will be called tps65218.
 
+config MFD_TPS65219
+	tristate "TI TPS65219 Power Management chips"
+	depends on I2C && OF
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	help
+	  If you say yes here you get support for the TPS65219 series of
+	  Power Management chips.
+	  These include voltage regulators, gpio and other features
+	  that are often used in portable devices.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called tps65219.
+
 config MFD_TPS6586X
 	bool "TI TPS6586x Power Management chips"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 858cacf659d6..a8ff3d6ea3ab 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65086)	+= tps65086.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
+obj-$(CONFIG_MFD_TPS65219)	+= tps65219.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
 obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
new file mode 100644
index 000000000000..c3bf975ea6c7
--- /dev/null
+++ b/drivers/mfd/tps65219.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for TPS65219 Integrated power management chipsets
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+//
+// This implementation derived from tps65218 authored by
+// "J Keerthy <j-keerthy@ti.com>"
+//
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65219.h>
+
+static struct i2c_client *tps65219_i2c_client;
+
+/**
+ * tps65219_warm_reset: issue warm reset to SOC.
+ *
+ * @tps: Device to write to.
+ */
+static int tps65219_warm_reset(struct tps65219 *tps)
+{
+	dev_dbg(tps->dev, "warm reset");
+	pr_flush(1000, true);
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK,
+				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK);
+}
+
+/**
+ * tps65219_cold_reset: issue cold reset to SOC.
+ *
+ * @tps: Device to write to.
+ */
+static int tps65219_cold_reset(struct tps65219 *tps)
+{
+	dev_dbg(tps->dev, "cold reset");
+	pr_flush(1000, true);
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK,
+				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
+}
+
+/**
+ * tps65219_soft_shutdown: issue cold reset to SOC.
+ *
+ * @tps: Device to write to.
+ */
+static int tps65219_soft_shutdown(struct tps65219 *tps)
+{
+	dev_dbg(tps->dev, "software shutdown");
+	pr_flush(1000, true);
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+				  TPS65219_MFP_I2C_OFF_REQ_MASK,
+				  TPS65219_MFP_I2C_OFF_REQ_MASK);
+}
+
+/**
+ * pmic_rst_restart: trig tps65219 reset to SOC.
+ *
+ * Trigged via notifier
+ */
+static int pmic_rst_restart(struct notifier_block *this,
+			    unsigned long reboot_mode, void *cmd)
+{
+	struct tps65219 *tps;
+
+	tps = container_of(this, struct tps65219, nb);
+	if (!tps) {
+		pr_err("%s: pointer to tps65219 is invalid\n", __func__);
+		return -ENODEV;
+	}
+	if (reboot_mode == REBOOT_WARM)
+		tps65219_warm_reset(tps);
+	else
+		tps65219_cold_reset(tps);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block pmic_rst_restart_nb = {
+	.notifier_call = pmic_rst_restart,
+	.priority = 200,
+};
+
+/**
+ * pmic_do_poweroff: trig tps65219 regulators power OFF sequence.
+ */
+static void pmic_do_poweroff(void)
+{
+	struct tps65219 *tps;
+
+	tps = dev_get_drvdata(&tps65219_i2c_client->dev);
+	tps65219_soft_shutdown(tps);
+}
+
+static const struct mfd_cell tps65219_cells[] = {
+	{ .name = "tps65219-regulator", },
+};
+
+static const struct regmap_config tps65219_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
+};
+
+static const struct of_device_id of_tps65219_match_table[] = {
+	{ .compatible = "ti,tps65219", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, of_tps65219_match_table);
+
+static int tps65219_probe(struct i2c_client *client,
+			  const struct i2c_device_id *ids)
+{
+	struct tps65219 *tps;
+	int ret;
+	unsigned int chipid;
+	bool sys_pwr;
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tps);
+	tps->dev = &client->dev;
+	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		ret = PTR_ERR(tps->regmap);
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
+	if (ret) {
+		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
+				   ARRAY_SIZE(tps65219_cells), NULL, 0,
+				   NULL);
+	if (ret) {
+		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
+		return ret;
+	}
+
+	tps->nb = pmic_rst_restart_nb;
+	ret = register_restart_handler(&tps->nb);
+	if (ret) {
+		dev_err(tps->dev, "%s: cannot register restart handler, %d\n",
+			__func__, ret);
+		return -ENODEV;
+	}
+
+	sys_pwr = of_property_read_bool(tps->dev->of_node,
+					"system-power-controller");
+
+	if (sys_pwr) {
+		if (pm_power_off)
+			dev_warn(tps->dev, "Setup as system-power-controller but pm_power_off function already registered, overwriting\n");
+		tps65219_i2c_client = client;
+		pm_power_off = &pmic_do_poweroff;
+	}
+	return ret;
+}
+
+static int tps65219_remove(struct i2c_client *client)
+{
+	struct tps65219 *tps = i2c_get_clientdata(client);
+
+	if (tps65219_i2c_client == client) {
+		pm_power_off = NULL;
+		tps65219_i2c_client = NULL;
+	}
+
+	return unregister_restart_handler(&tps->nb);
+}
+
+static const struct i2c_device_id tps65219_id_table[] = {
+	{ "tps65219", TPS65219 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, tps65219_id_table);
+
+static struct i2c_driver tps65219_driver = {
+	.driver		= {
+		.name	= "tps65219",
+		.of_match_table = of_tps65219_match_table,
+	},
+	.probe		= tps65219_probe,
+	.id_table       = tps65219_id_table,
+	.remove		= tps65219_remove,
+};
+
+module_i2c_driver(tps65219_driver);
+
+MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
+MODULE_DESCRIPTION("TPS65219 chip family multi-function driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
new file mode 100644
index 000000000000..e9197ab8bc75
--- /dev/null
+++ b/include/linux/mfd/tps65219.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * linux/mfd/tps65219.h
+ *
+ * Functions to access TPS65219 power management chip.
+ *
+ * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+ */
+
+#ifndef __LINUX_MFD_TPS65219_H
+#define __LINUX_MFD_TPS65219_H
+
+#include <linux/i2c.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+
+#define TPS65219_1V35					1350000
+#define TPS65219_1V8					1800000
+
+/* TPS chip id list */
+#define TPS65219					0xF0
+
+/* I2C ID for TPS65219 part */
+#define TPS65219_I2C_ID					0x24
+
+/* All register addresses */
+#define TPS65219_REG_TI_DEV_ID				0x00
+#define TPS65219_REG_NVM_ID				0x01
+#define TPS65219_REG_ENABLE_CTRL			0x02
+#define TPS65219_REG_BUCKS_CONFIG			0x03
+#define TPS65219_REG_LDO4_VOUT				0x04
+#define TPS65219_REG_LDO3_VOUT				0x05
+#define TPS65219_REG_LDO2_VOUT				0x06
+#define TPS65219_REG_LDO1_VOUT				0x07
+#define TPS65219_REG_BUCK3_VOUT				0x8
+#define TPS65219_REG_BUCK2_VOUT				0x9
+#define TPS65219_REG_BUCK1_VOUT				0xA
+#define TPS65219_REG_LDO4_SEQUENCE_SLOT			0xB
+#define TPS65219_REG_LDO3_SEQUENCE_SLOT			0xC
+#define TPS65219_REG_LDO2_SEQUENCE_SLOT			0xD
+#define TPS65219_REG_LDO1_SEQUENCE_SLOT			0xE
+#define TPS65219_REG_BUCK3_SEQUENCE_SLOT		0xF
+#define TPS65219_REG_BUCK2_SEQUENCE_SLOT		0x10
+#define TPS65219_REG_BUCK1_SEQUENCE_SLOT		0x11
+#define TPS65219_REG_nRST_SEQUENCE_SLOT			0x12
+#define TPS65219_REG_GPIO_SEQUENCE_SLOT			0x13
+#define TPS65219_REG_GPO2_SEQUENCE_SLOT			0x14
+#define TPS65219_REG_GPO1_SEQUENCE_SLOT			0x15
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_1		0x16
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_2		0x17
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_3		0x18
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_4		0x19
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_1		0x1A
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_2		0x1B
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_3		0x1C
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_4		0x1D
+#define TPS65219_REG_GENERAL_CONFIG			0x1E
+#define TPS65219_REG_MFP_1_CONFIG			0x1F
+#define TPS65219_REG_MFP_2_CONFIG			0x20
+#define TPS65219_REG_STBY_1_CONFIG			0x21
+#define TPS65219_REG_STBY_2_CONFIG			0x22
+#define TPS65219_REG_OC_DEGL_CONFIG			0x23
+/* 'sub irq' MASK registers */
+#define TPS65219_REG_INT_MASK_UV			0x24
+#define TPS65219_REG_MASK_CONFIG			0x25
+
+#define TPS65219_REG_I2C_ADDRESS_REG			0x26
+#define TPS65219_REG_USER_GENERAL_NVM_STORAGE		0x27
+#define TPS65219_REG_MANUFACTURING_VER			0x28
+#define TPS65219_REG_MFP_CTRL				0x29
+#define TPS65219_REG_DISCHARGE_CONFIG			0x2A
+/* main irq registers */
+#define TPS65219_REG_INT_SOURCE				0x2B
+/* 'sub irq' registers */
+#define TPS65219_REG_INT_LDO_3_4			0x2C
+#define TPS65219_REG_INT_LDO_1_2			0x2D
+#define TPS65219_REG_INT_BUCK_3				0x2E
+#define TPS65219_REG_INT_BUCK_1_2			0x2F
+#define TPS65219_REG_INT_SYSTEM				0x30
+#define TPS65219_REG_INT_RV				0x31
+#define TPS65219_REG_INT_TIMEOUT_RV_SD			0x32
+#define TPS65219_REG_INT_PB				0x33
+
+#define TPS65219_REG_USER_NVM_CMD			0x34
+#define TPS65219_REG_POWER_UP_STATUS			0x35
+#define TPS65219_REG_SPARE_2				0x36
+#define TPS65219_REG_SPARE_3				0x37
+#define TPS65219_REG_FACTORY_CONFIG_2			0x41
+
+/* Register field definitions */
+#define TPS65219_DEVID_REV_MASK				GENMASK(7, 0)
+#define TPS65219_BUCKS_LDOS_VOUT_VSET_MASK		GENMASK(5, 0)
+#define TPS65219_BUCKS_UV_THR_SEL_MASK			BIT(6)
+#define TPS65219_BUCKS_BW_SEL_MASK			BIT(7)
+#define LDO_BYP_SHIFT					6
+#define TPS65219_LDOS_BYP_CONFIG_MASK			BIT(LDO_BYP_SHIFT)
+#define TPS65219_LDOS_LSW_CONFIG_MASK			BIT(7)
+/* Regulators enable control */
+#define TPS65219_ENABLE_BUCK1_EN_MASK			BIT(0)
+#define TPS65219_ENABLE_BUCK2_EN_MASK			BIT(1)
+#define TPS65219_ENABLE_BUCK3_EN_MASK			BIT(2)
+#define TPS65219_ENABLE_LDO1_EN_MASK			BIT(3)
+#define TPS65219_ENABLE_LDO2_EN_MASK			BIT(4)
+#define TPS65219_ENABLE_LDO3_EN_MASK			BIT(5)
+#define TPS65219_ENABLE_LDO4_EN_MASK			BIT(6)
+/* power ON-OFF sequence slot */
+#define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK	GENMASK(3, 0)
+#define TPS65219_BUCKS_LDOS_SEQUENCE_ON_SLOT_MASK	GENMASK(7, 4)
+/* TODO: Not needed, same mapping as TPS65219_ENABLE_REGNAME_EN, factorize */
+#define TPS65219_STBY1_BUCK1_STBY_EN_MASK		BIT(0)
+#define TPS65219_STBY1_BUCK2_STBY_EN_MASK		BIT(1)
+#define TPS65219_STBY1_BUCK3_STBY_EN_MASK		BIT(2)
+#define TPS65219_STBY1_LDO1_STBY_EN_MASK		BIT(3)
+#define TPS65219_STBY1_LDO2_STBY_EN_MASK		BIT(4)
+#define TPS65219_STBY1_LDO3_STBY_EN_MASK		BIT(5)
+#define TPS65219_STBY1_LDO4_STBY_EN_MASK		BIT(6)
+/* STBY_2 config */
+#define TPS65219_STBY2_GPO1_STBY_EN_MASK		BIT(0)
+#define TPS65219_STBY2_GPO2_STBY_EN_MASK		BIT(1)
+#define TPS65219_STBY2_GPIO_STBY_EN_MASK		BIT(2)
+/* MFP Control */
+#define TPS65219_MFP_I2C_OFF_REQ_MASK			BIT(0)
+#define TPS65219_MFP_STBY_I2C_CTRL_MASK			BIT(1)
+#define TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK		BIT(2)
+#define TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK		BIT(3)
+#define TPS65219_MFP_GPIO_STATUS_MASK			BIT(4)
+/* MFP_1 Config */
+#define TPS65219_MFP_1_VSEL_DDR_SEL_MASK		BIT(0)
+#define TPS65219_MFP_1_VSEL_SD_POL_MASK			BIT(1)
+#define TPS65219_MFP_1_VSEL_RAIL_MASK			BIT(2)
+/* MFP_2 Config */
+#define TPS65219_MFP_2_MODE_STBY_MASK			GENMASK(1, 0)
+#define TPS65219_MFP_2_MODE_RESET_MASK			BIT(2)
+#define TPS65219_MFP_2_EN_PB_VSENSE_DEGL_MASK		BIT(3)
+#define TPS65219_MFP_2_EN_PB_VSENSE_MASK		GENMASK(5, 4)
+#define TPS65219_MFP_2_WARM_COLD_RESET_MASK		BIT(6)
+#define TPS65219_MFP_2_PU_ON_FSD_MASK			BIT(7)
+#define TPS65219_MFP_2_EN				0
+#define TPS65219_MFP_2_PB				BIT(4)
+#define TPS65219_MFP_2_VSENSE				BIT(5)
+/* MASK_UV Config */
+#define TPS65219_REG_MASK_UV_LDO1_UV_MASK		BIT(0)
+#define TPS65219_REG_MASK_UV_LDO2_UV_MASK		BIT(1)
+#define TPS65219_REG_MASK_UV_LDO3_UV_MASK		BIT(2)
+#define TPS65219_REG_MASK_UV_LDO4_UV_MASK		BIT(3)
+#define TPS65219_REG_MASK_UV_BUCK1_UV_MASK		BIT(4)
+#define TPS65219_REG_MASK_UV_BUCK2_UV_MASK		BIT(5)
+#define TPS65219_REG_MASK_UV_BUCK3_UV_MASK		BIT(6)
+#define TPS65219_REG_MASK_UV_RETRY_MASK			BIT(7)
+/* MASK Config */
+// SENSOR_N_WARM_MASK already defined in Thermal
+#define TPS65219_REG_MASK_INT_FOR_RV_MASK		BIT(4)
+#define TPS65219_REG_MASK_EFFECT_MASK			GENMASK(2, 1)
+#define TPS65219_REG_MASK_INT_FOR_PB_MASK		BIT(7)
+/* UnderVoltage - Short to GND - OverCurrent*/
+/* LDO3-4 */
+#define TPS65219_INT_LDO3_SCG_MASK			BIT(0)
+#define TPS65219_INT_LDO3_OC_MASK			BIT(1)
+#define TPS65219_INT_LDO3_UV_MASK			BIT(2)
+#define TPS65219_INT_LDO4_SCG_MASK			BIT(3)
+#define TPS65219_INT_LDO4_OC_MASK			BIT(4)
+#define TPS65219_INT_LDO4_UV_MASK			BIT(5)
+/* LDO1-2 */
+#define TPS65219_INT_LDO1_SCG_MASK			BIT(0)
+#define TPS65219_INT_LDO1_OC_MASK			BIT(1)
+#define TPS65219_INT_LDO1_UV_MASK			BIT(2)
+#define TPS65219_INT_LDO2_SCG_MASK			BIT(3)
+#define TPS65219_INT_LDO2_OC_MASK			BIT(4)
+#define TPS65219_INT_LDO2_UV_MASK			BIT(5)
+/* BUCK3 */
+#define TPS65219_INT_BUCK3_SCG_MASK			BIT(0)
+#define TPS65219_INT_BUCK3_OC_MASK			BIT(1)
+#define TPS65219_INT_BUCK3_NEG_OC_MASK			BIT(2)
+#define TPS65219_INT_BUCK3_UV_MASK			BIT(3)
+/* BUCK1-2 */
+#define TPS65219_INT_BUCK1_SCG_MASK			BIT(0)
+#define TPS65219_INT_BUCK1_OC_MASK			BIT(1)
+#define TPS65219_INT_BUCK1_NEG_OC_MASK			BIT(2)
+#define TPS65219_INT_BUCK1_UV_MASK			BIT(3)
+#define TPS65219_INT_BUCK2_SCG_MASK			BIT(4)
+#define TPS65219_INT_BUCK2_OC_MASK			BIT(5)
+#define TPS65219_INT_BUCK2_NEG_OC_MASK			BIT(6)
+#define TPS65219_INT_BUCK2_UV_MASK			BIT(7)
+/* Thermal Sensor  */
+#define TPS65219_INT_SENSOR_3_WARM_MASK			BIT(0)
+#define TPS65219_INT_SENSOR_2_WARM_MASK			BIT(1)
+#define TPS65219_INT_SENSOR_1_WARM_MASK			BIT(2)
+#define TPS65219_INT_SENSOR_0_WARM_MASK			BIT(3)
+#define TPS65219_INT_SENSOR_3_HOT_MASK			BIT(4)
+#define TPS65219_INT_SENSOR_2_HOT_MASK			BIT(5)
+#define TPS65219_INT_SENSOR_1_HOT_MASK			BIT(6)
+#define TPS65219_INT_SENSOR_0_HOT_MASK			BIT(7)
+/* Residual Voltage */
+#define TPS65219_INT_BUCK1_RV_MASK			BIT(0)
+#define TPS65219_INT_BUCK2_RV_MASK			BIT(1)
+#define TPS65219_INT_BUCK3_RV_MASK			BIT(2)
+#define TPS65219_INT_LDO1_RV_MASK			BIT(3)
+#define TPS65219_INT_LDO2_RV_MASK			BIT(4)
+#define TPS65219_INT_LDO3_RV_MASK			BIT(5)
+#define TPS65219_INT_LDO4_RV_MASK			BIT(6)
+/* Residual Voltage ShutDown */
+#define TPS65219_INT_BUCK1_RV_SD_MASK			BIT(0)
+#define TPS65219_INT_BUCK2_RV_SD_MASK			BIT(1)
+#define TPS65219_INT_BUCK3_RV_SD_MASK			BIT(2)
+#define TPS65219_INT_LDO1_RV_SD_MASK			BIT(3)
+#define TPS65219_INT_LDO2_RV_SD_MASK			BIT(4)
+#define TPS65219_INT_LDO3_RV_SD_MASK			BIT(5)
+#define TPS65219_INT_LDO4_RV_SD_MASK			BIT(6)
+#define TPS65219_INT_TIMEOUT_MASK			BIT(7)
+/* Power Button */
+#define TPS65219_INT_PB_FALLING_EDGE_DET_MASK		BIT(0)
+#define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
+#define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
+
+enum tps65219_regulator_id {
+	/* DCDC's */
+	TPS65219_BUCK_1,
+	TPS65219_BUCK_2,
+	TPS65219_BUCK_3,
+	/* LDOs */
+	TPS65219_LDO_1,
+	TPS65219_LDO_2,
+	TPS65219_LDO_3,
+	TPS65219_LDO_4,
+};
+
+#define TPS65219_MAX_REG_ID		TPS65219_LDO_4
+
+/* Number of step-down converters available */
+#define TPS65219_NUM_DCDC		3
+/* Number of LDO voltage regulators available */
+#define TPS65219_NUM_LDO		4
+/* Number of total regulators available */
+#define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
+
+/**
+ * struct tps65219 - tps65219 sub-driver chip access routines
+ *
+ * Device data may be used to access the TPS65219 chip
+ */
+struct tps65219 {
+	struct device *dev;
+	unsigned int id;
+	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
+	struct regmap *regmap;
+	struct notifier_block nb;
+};
+
+#endif /*  __LINUX_MFD_TPS65219_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

The TPS65219 is a power management IC PMIC designed
to supply a wide range of SoCs
in both portable and stationary applications.
Any SoC can control TPS65219 over a standard I2C interface.

It contains the following components:
- Regulators.
- Over Temperature warning and Shut down.
- GPIOs
- Multi Function Pins (MFP)

This patch adds support for tps65219 mfd device. At this time only
the functionalities listed below are made available:

- Regulators probe and functionalities
- warm and cold reset support
- SW shutdown support

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS                  |   1 +
 drivers/mfd/Kconfig          |  15 +++
 drivers/mfd/Makefile         |   1 +
 drivers/mfd/tps65219.c       | 214 +++++++++++++++++++++++++++++
 include/linux/mfd/tps65219.h | 251 +++++++++++++++++++++++++++++++++++
 5 files changed, 482 insertions(+)
 create mode 100644 drivers/mfd/tps65219.c
 create mode 100644 include/linux/mfd/tps65219.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 67850b321cbb..1331c43fc6ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14711,6 +14711,7 @@ F:	drivers/mfd/menelaus.c
 F:	drivers/mfd/palmas.c
 F:	drivers/mfd/tps65217.c
 F:	drivers/mfd/tps65218.c
+F:	drivers/mfd/tps65219.c
 F:	drivers/mfd/tps65910.c
 F:	drivers/mfd/twl-core.[ch]
 F:	drivers/mfd/twl4030*.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3b59456f5545..c66e56374a9a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1574,6 +1574,21 @@ config MFD_TPS65218
 	  This driver can also be built as a module.  If so, the module
 	  will be called tps65218.
 
+config MFD_TPS65219
+	tristate "TI TPS65219 Power Management chips"
+	depends on I2C && OF
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	help
+	  If you say yes here you get support for the TPS65219 series of
+	  Power Management chips.
+	  These include voltage regulators, gpio and other features
+	  that are often used in portable devices.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called tps65219.
+
 config MFD_TPS6586X
 	bool "TI TPS6586x Power Management chips"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 858cacf659d6..a8ff3d6ea3ab 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65086)	+= tps65086.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
+obj-$(CONFIG_MFD_TPS65219)	+= tps65219.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
 obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
new file mode 100644
index 000000000000..c3bf975ea6c7
--- /dev/null
+++ b/drivers/mfd/tps65219.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for TPS65219 Integrated power management chipsets
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+//
+// This implementation derived from tps65218 authored by
+// "J Keerthy <j-keerthy@ti.com>"
+//
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65219.h>
+
+static struct i2c_client *tps65219_i2c_client;
+
+/**
+ * tps65219_warm_reset: issue warm reset to SOC.
+ *
+ * @tps: Device to write to.
+ */
+static int tps65219_warm_reset(struct tps65219 *tps)
+{
+	dev_dbg(tps->dev, "warm reset");
+	pr_flush(1000, true);
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK,
+				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK);
+}
+
+/**
+ * tps65219_cold_reset: issue cold reset to SOC.
+ *
+ * @tps: Device to write to.
+ */
+static int tps65219_cold_reset(struct tps65219 *tps)
+{
+	dev_dbg(tps->dev, "cold reset");
+	pr_flush(1000, true);
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK,
+				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
+}
+
+/**
+ * tps65219_soft_shutdown: issue cold reset to SOC.
+ *
+ * @tps: Device to write to.
+ */
+static int tps65219_soft_shutdown(struct tps65219 *tps)
+{
+	dev_dbg(tps->dev, "software shutdown");
+	pr_flush(1000, true);
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+				  TPS65219_MFP_I2C_OFF_REQ_MASK,
+				  TPS65219_MFP_I2C_OFF_REQ_MASK);
+}
+
+/**
+ * pmic_rst_restart: trig tps65219 reset to SOC.
+ *
+ * Trigged via notifier
+ */
+static int pmic_rst_restart(struct notifier_block *this,
+			    unsigned long reboot_mode, void *cmd)
+{
+	struct tps65219 *tps;
+
+	tps = container_of(this, struct tps65219, nb);
+	if (!tps) {
+		pr_err("%s: pointer to tps65219 is invalid\n", __func__);
+		return -ENODEV;
+	}
+	if (reboot_mode == REBOOT_WARM)
+		tps65219_warm_reset(tps);
+	else
+		tps65219_cold_reset(tps);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block pmic_rst_restart_nb = {
+	.notifier_call = pmic_rst_restart,
+	.priority = 200,
+};
+
+/**
+ * pmic_do_poweroff: trig tps65219 regulators power OFF sequence.
+ */
+static void pmic_do_poweroff(void)
+{
+	struct tps65219 *tps;
+
+	tps = dev_get_drvdata(&tps65219_i2c_client->dev);
+	tps65219_soft_shutdown(tps);
+}
+
+static const struct mfd_cell tps65219_cells[] = {
+	{ .name = "tps65219-regulator", },
+};
+
+static const struct regmap_config tps65219_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
+};
+
+static const struct of_device_id of_tps65219_match_table[] = {
+	{ .compatible = "ti,tps65219", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, of_tps65219_match_table);
+
+static int tps65219_probe(struct i2c_client *client,
+			  const struct i2c_device_id *ids)
+{
+	struct tps65219 *tps;
+	int ret;
+	unsigned int chipid;
+	bool sys_pwr;
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tps);
+	tps->dev = &client->dev;
+	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		ret = PTR_ERR(tps->regmap);
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
+	if (ret) {
+		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
+				   ARRAY_SIZE(tps65219_cells), NULL, 0,
+				   NULL);
+	if (ret) {
+		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
+		return ret;
+	}
+
+	tps->nb = pmic_rst_restart_nb;
+	ret = register_restart_handler(&tps->nb);
+	if (ret) {
+		dev_err(tps->dev, "%s: cannot register restart handler, %d\n",
+			__func__, ret);
+		return -ENODEV;
+	}
+
+	sys_pwr = of_property_read_bool(tps->dev->of_node,
+					"system-power-controller");
+
+	if (sys_pwr) {
+		if (pm_power_off)
+			dev_warn(tps->dev, "Setup as system-power-controller but pm_power_off function already registered, overwriting\n");
+		tps65219_i2c_client = client;
+		pm_power_off = &pmic_do_poweroff;
+	}
+	return ret;
+}
+
+static int tps65219_remove(struct i2c_client *client)
+{
+	struct tps65219 *tps = i2c_get_clientdata(client);
+
+	if (tps65219_i2c_client == client) {
+		pm_power_off = NULL;
+		tps65219_i2c_client = NULL;
+	}
+
+	return unregister_restart_handler(&tps->nb);
+}
+
+static const struct i2c_device_id tps65219_id_table[] = {
+	{ "tps65219", TPS65219 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, tps65219_id_table);
+
+static struct i2c_driver tps65219_driver = {
+	.driver		= {
+		.name	= "tps65219",
+		.of_match_table = of_tps65219_match_table,
+	},
+	.probe		= tps65219_probe,
+	.id_table       = tps65219_id_table,
+	.remove		= tps65219_remove,
+};
+
+module_i2c_driver(tps65219_driver);
+
+MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
+MODULE_DESCRIPTION("TPS65219 chip family multi-function driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
new file mode 100644
index 000000000000..e9197ab8bc75
--- /dev/null
+++ b/include/linux/mfd/tps65219.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * linux/mfd/tps65219.h
+ *
+ * Functions to access TPS65219 power management chip.
+ *
+ * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+ */
+
+#ifndef __LINUX_MFD_TPS65219_H
+#define __LINUX_MFD_TPS65219_H
+
+#include <linux/i2c.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+
+#define TPS65219_1V35					1350000
+#define TPS65219_1V8					1800000
+
+/* TPS chip id list */
+#define TPS65219					0xF0
+
+/* I2C ID for TPS65219 part */
+#define TPS65219_I2C_ID					0x24
+
+/* All register addresses */
+#define TPS65219_REG_TI_DEV_ID				0x00
+#define TPS65219_REG_NVM_ID				0x01
+#define TPS65219_REG_ENABLE_CTRL			0x02
+#define TPS65219_REG_BUCKS_CONFIG			0x03
+#define TPS65219_REG_LDO4_VOUT				0x04
+#define TPS65219_REG_LDO3_VOUT				0x05
+#define TPS65219_REG_LDO2_VOUT				0x06
+#define TPS65219_REG_LDO1_VOUT				0x07
+#define TPS65219_REG_BUCK3_VOUT				0x8
+#define TPS65219_REG_BUCK2_VOUT				0x9
+#define TPS65219_REG_BUCK1_VOUT				0xA
+#define TPS65219_REG_LDO4_SEQUENCE_SLOT			0xB
+#define TPS65219_REG_LDO3_SEQUENCE_SLOT			0xC
+#define TPS65219_REG_LDO2_SEQUENCE_SLOT			0xD
+#define TPS65219_REG_LDO1_SEQUENCE_SLOT			0xE
+#define TPS65219_REG_BUCK3_SEQUENCE_SLOT		0xF
+#define TPS65219_REG_BUCK2_SEQUENCE_SLOT		0x10
+#define TPS65219_REG_BUCK1_SEQUENCE_SLOT		0x11
+#define TPS65219_REG_nRST_SEQUENCE_SLOT			0x12
+#define TPS65219_REG_GPIO_SEQUENCE_SLOT			0x13
+#define TPS65219_REG_GPO2_SEQUENCE_SLOT			0x14
+#define TPS65219_REG_GPO1_SEQUENCE_SLOT			0x15
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_1		0x16
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_2		0x17
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_3		0x18
+#define TPS65219_REG_POWER_UP_SLOT_DURATION_4		0x19
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_1		0x1A
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_2		0x1B
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_3		0x1C
+#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_4		0x1D
+#define TPS65219_REG_GENERAL_CONFIG			0x1E
+#define TPS65219_REG_MFP_1_CONFIG			0x1F
+#define TPS65219_REG_MFP_2_CONFIG			0x20
+#define TPS65219_REG_STBY_1_CONFIG			0x21
+#define TPS65219_REG_STBY_2_CONFIG			0x22
+#define TPS65219_REG_OC_DEGL_CONFIG			0x23
+/* 'sub irq' MASK registers */
+#define TPS65219_REG_INT_MASK_UV			0x24
+#define TPS65219_REG_MASK_CONFIG			0x25
+
+#define TPS65219_REG_I2C_ADDRESS_REG			0x26
+#define TPS65219_REG_USER_GENERAL_NVM_STORAGE		0x27
+#define TPS65219_REG_MANUFACTURING_VER			0x28
+#define TPS65219_REG_MFP_CTRL				0x29
+#define TPS65219_REG_DISCHARGE_CONFIG			0x2A
+/* main irq registers */
+#define TPS65219_REG_INT_SOURCE				0x2B
+/* 'sub irq' registers */
+#define TPS65219_REG_INT_LDO_3_4			0x2C
+#define TPS65219_REG_INT_LDO_1_2			0x2D
+#define TPS65219_REG_INT_BUCK_3				0x2E
+#define TPS65219_REG_INT_BUCK_1_2			0x2F
+#define TPS65219_REG_INT_SYSTEM				0x30
+#define TPS65219_REG_INT_RV				0x31
+#define TPS65219_REG_INT_TIMEOUT_RV_SD			0x32
+#define TPS65219_REG_INT_PB				0x33
+
+#define TPS65219_REG_USER_NVM_CMD			0x34
+#define TPS65219_REG_POWER_UP_STATUS			0x35
+#define TPS65219_REG_SPARE_2				0x36
+#define TPS65219_REG_SPARE_3				0x37
+#define TPS65219_REG_FACTORY_CONFIG_2			0x41
+
+/* Register field definitions */
+#define TPS65219_DEVID_REV_MASK				GENMASK(7, 0)
+#define TPS65219_BUCKS_LDOS_VOUT_VSET_MASK		GENMASK(5, 0)
+#define TPS65219_BUCKS_UV_THR_SEL_MASK			BIT(6)
+#define TPS65219_BUCKS_BW_SEL_MASK			BIT(7)
+#define LDO_BYP_SHIFT					6
+#define TPS65219_LDOS_BYP_CONFIG_MASK			BIT(LDO_BYP_SHIFT)
+#define TPS65219_LDOS_LSW_CONFIG_MASK			BIT(7)
+/* Regulators enable control */
+#define TPS65219_ENABLE_BUCK1_EN_MASK			BIT(0)
+#define TPS65219_ENABLE_BUCK2_EN_MASK			BIT(1)
+#define TPS65219_ENABLE_BUCK3_EN_MASK			BIT(2)
+#define TPS65219_ENABLE_LDO1_EN_MASK			BIT(3)
+#define TPS65219_ENABLE_LDO2_EN_MASK			BIT(4)
+#define TPS65219_ENABLE_LDO3_EN_MASK			BIT(5)
+#define TPS65219_ENABLE_LDO4_EN_MASK			BIT(6)
+/* power ON-OFF sequence slot */
+#define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK	GENMASK(3, 0)
+#define TPS65219_BUCKS_LDOS_SEQUENCE_ON_SLOT_MASK	GENMASK(7, 4)
+/* TODO: Not needed, same mapping as TPS65219_ENABLE_REGNAME_EN, factorize */
+#define TPS65219_STBY1_BUCK1_STBY_EN_MASK		BIT(0)
+#define TPS65219_STBY1_BUCK2_STBY_EN_MASK		BIT(1)
+#define TPS65219_STBY1_BUCK3_STBY_EN_MASK		BIT(2)
+#define TPS65219_STBY1_LDO1_STBY_EN_MASK		BIT(3)
+#define TPS65219_STBY1_LDO2_STBY_EN_MASK		BIT(4)
+#define TPS65219_STBY1_LDO3_STBY_EN_MASK		BIT(5)
+#define TPS65219_STBY1_LDO4_STBY_EN_MASK		BIT(6)
+/* STBY_2 config */
+#define TPS65219_STBY2_GPO1_STBY_EN_MASK		BIT(0)
+#define TPS65219_STBY2_GPO2_STBY_EN_MASK		BIT(1)
+#define TPS65219_STBY2_GPIO_STBY_EN_MASK		BIT(2)
+/* MFP Control */
+#define TPS65219_MFP_I2C_OFF_REQ_MASK			BIT(0)
+#define TPS65219_MFP_STBY_I2C_CTRL_MASK			BIT(1)
+#define TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK		BIT(2)
+#define TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK		BIT(3)
+#define TPS65219_MFP_GPIO_STATUS_MASK			BIT(4)
+/* MFP_1 Config */
+#define TPS65219_MFP_1_VSEL_DDR_SEL_MASK		BIT(0)
+#define TPS65219_MFP_1_VSEL_SD_POL_MASK			BIT(1)
+#define TPS65219_MFP_1_VSEL_RAIL_MASK			BIT(2)
+/* MFP_2 Config */
+#define TPS65219_MFP_2_MODE_STBY_MASK			GENMASK(1, 0)
+#define TPS65219_MFP_2_MODE_RESET_MASK			BIT(2)
+#define TPS65219_MFP_2_EN_PB_VSENSE_DEGL_MASK		BIT(3)
+#define TPS65219_MFP_2_EN_PB_VSENSE_MASK		GENMASK(5, 4)
+#define TPS65219_MFP_2_WARM_COLD_RESET_MASK		BIT(6)
+#define TPS65219_MFP_2_PU_ON_FSD_MASK			BIT(7)
+#define TPS65219_MFP_2_EN				0
+#define TPS65219_MFP_2_PB				BIT(4)
+#define TPS65219_MFP_2_VSENSE				BIT(5)
+/* MASK_UV Config */
+#define TPS65219_REG_MASK_UV_LDO1_UV_MASK		BIT(0)
+#define TPS65219_REG_MASK_UV_LDO2_UV_MASK		BIT(1)
+#define TPS65219_REG_MASK_UV_LDO3_UV_MASK		BIT(2)
+#define TPS65219_REG_MASK_UV_LDO4_UV_MASK		BIT(3)
+#define TPS65219_REG_MASK_UV_BUCK1_UV_MASK		BIT(4)
+#define TPS65219_REG_MASK_UV_BUCK2_UV_MASK		BIT(5)
+#define TPS65219_REG_MASK_UV_BUCK3_UV_MASK		BIT(6)
+#define TPS65219_REG_MASK_UV_RETRY_MASK			BIT(7)
+/* MASK Config */
+// SENSOR_N_WARM_MASK already defined in Thermal
+#define TPS65219_REG_MASK_INT_FOR_RV_MASK		BIT(4)
+#define TPS65219_REG_MASK_EFFECT_MASK			GENMASK(2, 1)
+#define TPS65219_REG_MASK_INT_FOR_PB_MASK		BIT(7)
+/* UnderVoltage - Short to GND - OverCurrent*/
+/* LDO3-4 */
+#define TPS65219_INT_LDO3_SCG_MASK			BIT(0)
+#define TPS65219_INT_LDO3_OC_MASK			BIT(1)
+#define TPS65219_INT_LDO3_UV_MASK			BIT(2)
+#define TPS65219_INT_LDO4_SCG_MASK			BIT(3)
+#define TPS65219_INT_LDO4_OC_MASK			BIT(4)
+#define TPS65219_INT_LDO4_UV_MASK			BIT(5)
+/* LDO1-2 */
+#define TPS65219_INT_LDO1_SCG_MASK			BIT(0)
+#define TPS65219_INT_LDO1_OC_MASK			BIT(1)
+#define TPS65219_INT_LDO1_UV_MASK			BIT(2)
+#define TPS65219_INT_LDO2_SCG_MASK			BIT(3)
+#define TPS65219_INT_LDO2_OC_MASK			BIT(4)
+#define TPS65219_INT_LDO2_UV_MASK			BIT(5)
+/* BUCK3 */
+#define TPS65219_INT_BUCK3_SCG_MASK			BIT(0)
+#define TPS65219_INT_BUCK3_OC_MASK			BIT(1)
+#define TPS65219_INT_BUCK3_NEG_OC_MASK			BIT(2)
+#define TPS65219_INT_BUCK3_UV_MASK			BIT(3)
+/* BUCK1-2 */
+#define TPS65219_INT_BUCK1_SCG_MASK			BIT(0)
+#define TPS65219_INT_BUCK1_OC_MASK			BIT(1)
+#define TPS65219_INT_BUCK1_NEG_OC_MASK			BIT(2)
+#define TPS65219_INT_BUCK1_UV_MASK			BIT(3)
+#define TPS65219_INT_BUCK2_SCG_MASK			BIT(4)
+#define TPS65219_INT_BUCK2_OC_MASK			BIT(5)
+#define TPS65219_INT_BUCK2_NEG_OC_MASK			BIT(6)
+#define TPS65219_INT_BUCK2_UV_MASK			BIT(7)
+/* Thermal Sensor  */
+#define TPS65219_INT_SENSOR_3_WARM_MASK			BIT(0)
+#define TPS65219_INT_SENSOR_2_WARM_MASK			BIT(1)
+#define TPS65219_INT_SENSOR_1_WARM_MASK			BIT(2)
+#define TPS65219_INT_SENSOR_0_WARM_MASK			BIT(3)
+#define TPS65219_INT_SENSOR_3_HOT_MASK			BIT(4)
+#define TPS65219_INT_SENSOR_2_HOT_MASK			BIT(5)
+#define TPS65219_INT_SENSOR_1_HOT_MASK			BIT(6)
+#define TPS65219_INT_SENSOR_0_HOT_MASK			BIT(7)
+/* Residual Voltage */
+#define TPS65219_INT_BUCK1_RV_MASK			BIT(0)
+#define TPS65219_INT_BUCK2_RV_MASK			BIT(1)
+#define TPS65219_INT_BUCK3_RV_MASK			BIT(2)
+#define TPS65219_INT_LDO1_RV_MASK			BIT(3)
+#define TPS65219_INT_LDO2_RV_MASK			BIT(4)
+#define TPS65219_INT_LDO3_RV_MASK			BIT(5)
+#define TPS65219_INT_LDO4_RV_MASK			BIT(6)
+/* Residual Voltage ShutDown */
+#define TPS65219_INT_BUCK1_RV_SD_MASK			BIT(0)
+#define TPS65219_INT_BUCK2_RV_SD_MASK			BIT(1)
+#define TPS65219_INT_BUCK3_RV_SD_MASK			BIT(2)
+#define TPS65219_INT_LDO1_RV_SD_MASK			BIT(3)
+#define TPS65219_INT_LDO2_RV_SD_MASK			BIT(4)
+#define TPS65219_INT_LDO3_RV_SD_MASK			BIT(5)
+#define TPS65219_INT_LDO4_RV_SD_MASK			BIT(6)
+#define TPS65219_INT_TIMEOUT_MASK			BIT(7)
+/* Power Button */
+#define TPS65219_INT_PB_FALLING_EDGE_DET_MASK		BIT(0)
+#define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
+#define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
+
+enum tps65219_regulator_id {
+	/* DCDC's */
+	TPS65219_BUCK_1,
+	TPS65219_BUCK_2,
+	TPS65219_BUCK_3,
+	/* LDOs */
+	TPS65219_LDO_1,
+	TPS65219_LDO_2,
+	TPS65219_LDO_3,
+	TPS65219_LDO_4,
+};
+
+#define TPS65219_MAX_REG_ID		TPS65219_LDO_4
+
+/* Number of step-down converters available */
+#define TPS65219_NUM_DCDC		3
+/* Number of LDO voltage regulators available */
+#define TPS65219_NUM_LDO		4
+/* Number of total regulators available */
+#define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
+
+/**
+ * struct tps65219 - tps65219 sub-driver chip access routines
+ *
+ * Device data may be used to access the TPS65219 chip
+ */
+struct tps65219 {
+	struct device *dev;
+	unsigned int id;
+	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
+	struct regmap *regmap;
+	struct notifier_block nb;
+};
+
+#endif /*  __LINUX_MFD_TPS65219_H */
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 07/11] mfd: drivers: Add interrupts support to TI TPS65219 PMIC
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Add TPS65219 support for interrupts through regmap_irq_chip

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 drivers/mfd/tps65219.c       | 217 ++++++++++++++++++++++++++++++++++-
 include/linux/mfd/tps65219.h | 113 ++++++++++++++++++
 2 files changed, 328 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
index c3bf975ea6c7..7366f251c21d 100644
--- a/drivers/mfd/tps65219.c
+++ b/drivers/mfd/tps65219.c
@@ -107,8 +107,73 @@ static void pmic_do_poweroff(void)
 	tps65219_soft_shutdown(tps);
 }
 
-static const struct mfd_cell tps65219_cells[] = {
-	{ .name = "tps65219-regulator", },
+static const struct resource tps65219_pwrbutton_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
+};
+
+static const struct resource tps65219_regulator_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_UV, "LDO3_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_SCG, "LDO4_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_OC, "LDO4_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_UV, "LDO4_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV, "LDO2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV, "LDO3_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV, "LDO4_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV_SD, "LDO3_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV_SD, "LDO4_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
+};
+
+#define TPS65219_MAX_CELLS 2
+
+static const struct mfd_cell tps65219_regulator_cell = {
+	.name = "tps65219-regulator",
+	.resources = tps65219_regulator_resources,
+	.num_resources = ARRAY_SIZE(tps65219_regulator_resources),
+};
+
+static const struct mfd_cell tps65219_pwrbutton_cell = {
+	.name = "tps65219-pwrbutton",
+	.resources = tps65219_pwrbutton_resources,
+	.num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
 };
 
 static const struct regmap_config tps65219_regmap_config = {
@@ -117,6 +182,147 @@ static const struct regmap_config tps65219_regmap_config = {
 	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
 };
 
+/*
+ * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
+ * access corect sub-IRQ registers based on bits that are set in main IRQ
+ * register.
+ */
+/* Timeout Residual Voltage Shutdown */
+static unsigned int bit0_offsets[] = {TPS65219_TO_RV_POS};
+static unsigned int bit1_offsets[] = {TPS65219_RV_POS};	/* Residual Voltage */
+static unsigned int bit2_offsets[] = {TPS65219_SYS_POS};	/* System */
+static unsigned int bit3_offsets[] = {TPS65219_BUCK_1_2_POS};	/* Buck 1-2 */
+static unsigned int bit4_offsets[] = {TPS65219_BUCK_3_POS};	/* Buck 3 */
+static unsigned int bit5_offsets[] = {TPS65219_LDO_1_2_POS};	/* LDO 1-2 */
+static unsigned int bit6_offsets[] = {TPS65219_LDO_3_4_POS};	/* LDO 3-4 */
+static unsigned int bit7_offsets[] = {TPS65219_PB_POS};	/* Power Button */
+
+static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
+};
+
+static struct regmap_irq tps65219_irqs[] = {
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO3_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC,
+		       TPS65219_LDO_3_4_POS, TPS65219_INT_LDO3_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_UV, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO3_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_SCG, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO4_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_OC, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO4_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_UV, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO4_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG,
+		       TPS65219_LDO_1_2_POS, TPS65219_INT_LDO1_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO1_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO1_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO2_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO2_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO2_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_NEG_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_NEG_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_NEG_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM,
+		       TPS65219_SYS_POS, TPS65219_INT_SENSOR_3_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_2_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_1_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_0_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_3_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_2_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_1_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_0_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_RV_POS,
+		       TPS65219_INT_BUCK1_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_RV_POS,
+		       TPS65219_INT_BUCK2_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_RV_POS,
+		       TPS65219_INT_BUCK3_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO1_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO2_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO3_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO4_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD,
+		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK1_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD,
+		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK2_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_BUCK3_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_LDO1_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_LDO2_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV_SD,
+		       TPS65219_TO_RV_POS, TPS65219_INT_LDO3_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_LDO4_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_TO_RV_POS,
+		       TPS65219_INT_TIMEOUT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT,
+		       TPS65219_PB_POS, TPS65219_INT_PB_FALLING_EDGE_DET_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_PB_POS,
+		       TPS65219_INT_PB_RISING_EDGE_DET_MASK),
+};
+
+static struct regmap_irq_chip tps65219_irq_chip = {
+	.name = "tps65219_irq",
+	.main_status = TPS65219_REG_INT_SOURCE,
+	.num_main_regs = 1,
+	.num_main_status_bits = 8,
+	.irqs = tps65219_irqs,
+	.num_irqs = ARRAY_SIZE(tps65219_irqs),
+	.status_base = TPS65219_REG_INT_LDO_3_4,
+	.ack_base = TPS65219_REG_INT_LDO_3_4,
+	.clear_ack = 1,
+	.num_regs = 8,
+	.sub_reg_offsets = &tps65219_sub_irq_offsets[0],
+};
+
 static const struct of_device_id of_tps65219_match_table[] = {
 	{ .compatible = "ti,tps65219", },
 	{}
@@ -137,6 +343,7 @@ static int tps65219_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, tps);
 	tps->dev = &client->dev;
+	tps->irq = client->irq;
 	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
 	if (IS_ERR(tps->regmap)) {
 		ret = PTR_ERR(tps->regmap);
@@ -145,6 +352,12 @@ static int tps65219_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, tps->irq,
+				       IRQF_ONESHOT, 0, &tps65219_irq_chip,
+				       &tps->irq_data);
+	if (ret)
+		return ret;
+
 	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
 	if (ret) {
 		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
index e9197ab8bc75..8cecaf9bc682 100644
--- a/include/linux/mfd/tps65219.h
+++ b/include/linux/mfd/tps65219.h
@@ -214,6 +214,104 @@
 #define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
 #define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
 
+/* Masks for main IRQ register bits */
+enum {
+	TPS65219_INT_TIMEOUT_RV_SD,
+#define TPS65219_INT_TIMEOUT_RV_SD_MASK BIT(TPS65219_INT_TIMEOUT_RV_SD)
+	TPS65219_INT_RV,
+#define TPS65219_INT_RV_MASK BIT(TPS65219_INT_RV)
+	TPS65219_INT_SYSTEM,
+#define TPS65219_INT_SYSTEM_MASK BIT(TPS65219_INT_SYSTEM)
+	TPS65219_INT_BUCK_1_2,
+#define TPS65219_INT_BUCK_1_2_MASK BIT(TPS65219_INT_BUCK_1_2)
+	TPS65219_INT_BUCK_3,
+#define TPS65219_INT_BUCK_3_MASK BIT(TPS65219_INT_BUCK_3)
+	TPS65219_INT_LDO_1_2,
+#define TPS65219_INT_LDO_1_2_MASK BIT(TPS65219_INT_LDO_1_2)
+	TPS65219_INT_LDO_3_4,
+#define TPS65219_INT_LDO_3_4_MASK BIT(TPS65219_LDO_3_4)
+	TPS65219_INT_PB,
+#define TPS65219_INT_PB_MASK BIT(TPS65219_INT_PB)
+};
+
+/* Timeout Residual Voltage Shutdown */
+#define TPS65219_TO_RV_POS 6
+/* Residual Voltage */
+#define TPS65219_RV_POS 5
+/* System */
+#define TPS65219_SYS_POS 4
+/* Buck 1-2 */
+#define TPS65219_BUCK_1_2_POS 3
+/* Buck 3 */
+#define TPS65219_BUCK_3_POS 2
+/* LDO 1-2 */
+#define TPS65219_LDO_1_2_POS 1
+/* LDO 3-4 */
+#define TPS65219_LDO_3_4_POS 0
+/* Power Button */
+#define TPS65219_PB_POS 7
+
+/* IRQs */
+enum {
+	/* LDO3-4 register IRQs */
+	TPS65219_INT_LDO3_SCG,
+	TPS65219_INT_LDO3_OC,
+	TPS65219_INT_LDO3_UV,
+	TPS65219_INT_LDO4_SCG,
+	TPS65219_INT_LDO4_OC,
+	TPS65219_INT_LDO4_UV,
+	/* LDO1-2 */
+	TPS65219_INT_LDO1_SCG,
+	TPS65219_INT_LDO1_OC,
+	TPS65219_INT_LDO1_UV,
+	TPS65219_INT_LDO2_SCG,
+	TPS65219_INT_LDO2_OC,
+	TPS65219_INT_LDO2_UV,
+	/* BUCK3 */
+	TPS65219_INT_BUCK3_SCG,
+	TPS65219_INT_BUCK3_OC,
+	TPS65219_INT_BUCK3_NEG_OC,
+	TPS65219_INT_BUCK3_UV,
+	/* BUCK1-2 */
+	TPS65219_INT_BUCK1_SCG,
+	TPS65219_INT_BUCK1_OC,
+	TPS65219_INT_BUCK1_NEG_OC,
+	TPS65219_INT_BUCK1_UV,
+	TPS65219_INT_BUCK2_SCG,
+	TPS65219_INT_BUCK2_OC,
+	TPS65219_INT_BUCK2_NEG_OC,
+	TPS65219_INT_BUCK2_UV,
+	/* Thermal Sensor  */
+	TPS65219_INT_SENSOR_3_WARM,
+	TPS65219_INT_SENSOR_2_WARM,
+	TPS65219_INT_SENSOR_1_WARM,
+	TPS65219_INT_SENSOR_0_WARM,
+	TPS65219_INT_SENSOR_3_HOT,
+	TPS65219_INT_SENSOR_2_HOT,
+	TPS65219_INT_SENSOR_1_HOT,
+	TPS65219_INT_SENSOR_0_HOT,
+	/* Residual Voltage */
+	TPS65219_INT_BUCK1_RV,
+	TPS65219_INT_BUCK2_RV,
+	TPS65219_INT_BUCK3_RV,
+	TPS65219_INT_LDO1_RV,
+	TPS65219_INT_LDO2_RV,
+	TPS65219_INT_LDO3_RV,
+	TPS65219_INT_LDO4_RV,
+	/* Residual Voltage ShutDown */
+	TPS65219_INT_BUCK1_RV_SD,
+	TPS65219_INT_BUCK2_RV_SD,
+	TPS65219_INT_BUCK3_RV_SD,
+	TPS65219_INT_LDO1_RV_SD,
+	TPS65219_INT_LDO2_RV_SD,
+	TPS65219_INT_LDO3_RV_SD,
+	TPS65219_INT_LDO4_RV_SD,
+	TPS65219_INT_TIMEOUT,
+	/* Power Button */
+	TPS65219_INT_PB_FALLING_EDGE_DETECT,
+	TPS65219_INT_PB_RISING_EDGE_DETECT,
+};
+
 enum tps65219_regulator_id {
 	/* DCDC's */
 	TPS65219_BUCK_1,
@@ -235,6 +333,19 @@ enum tps65219_regulator_id {
 /* Number of total regulators available */
 #define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
 
+/* Define the TPS65219 IRQ numbers */
+enum tps65219_irqs {
+	/* INT source registers */
+	TPS65219_TO_RV_SD_SET_IRQ,
+	TPS65219_RV_SET_IRQ,
+	TPS65219_SYS_SET_IRQ,
+	TPS65219_BUCK_1_2_SET_IRQ,
+	TPS65219_BUCK_3_SET_IRQ,
+	TPS65219_LDO_1_2_SET_IRQ,
+	TPS65219_LDO_3_4_SET_IRQ,
+	TPS65219_PB_SET_IRQ,
+};
+
 /**
  * struct tps65219 - tps65219 sub-driver chip access routines
  *
@@ -243,6 +354,8 @@ enum tps65219_regulator_id {
 struct tps65219 {
 	struct device *dev;
 	unsigned int id;
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
 	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
 	struct regmap *regmap;
 	struct notifier_block nb;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 07/11] mfd: drivers: Add interrupts support to TI TPS65219 PMIC
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

Add TPS65219 support for interrupts through regmap_irq_chip

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 drivers/mfd/tps65219.c       | 217 ++++++++++++++++++++++++++++++++++-
 include/linux/mfd/tps65219.h | 113 ++++++++++++++++++
 2 files changed, 328 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
index c3bf975ea6c7..7366f251c21d 100644
--- a/drivers/mfd/tps65219.c
+++ b/drivers/mfd/tps65219.c
@@ -107,8 +107,73 @@ static void pmic_do_poweroff(void)
 	tps65219_soft_shutdown(tps);
 }
 
-static const struct mfd_cell tps65219_cells[] = {
-	{ .name = "tps65219-regulator", },
+static const struct resource tps65219_pwrbutton_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
+};
+
+static const struct resource tps65219_regulator_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_UV, "LDO3_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_SCG, "LDO4_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_OC, "LDO4_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_UV, "LDO4_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV, "LDO2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV, "LDO3_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV, "LDO4_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV_SD, "LDO3_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV_SD, "LDO4_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
+};
+
+#define TPS65219_MAX_CELLS 2
+
+static const struct mfd_cell tps65219_regulator_cell = {
+	.name = "tps65219-regulator",
+	.resources = tps65219_regulator_resources,
+	.num_resources = ARRAY_SIZE(tps65219_regulator_resources),
+};
+
+static const struct mfd_cell tps65219_pwrbutton_cell = {
+	.name = "tps65219-pwrbutton",
+	.resources = tps65219_pwrbutton_resources,
+	.num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
 };
 
 static const struct regmap_config tps65219_regmap_config = {
@@ -117,6 +182,147 @@ static const struct regmap_config tps65219_regmap_config = {
 	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
 };
 
+/*
+ * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
+ * access corect sub-IRQ registers based on bits that are set in main IRQ
+ * register.
+ */
+/* Timeout Residual Voltage Shutdown */
+static unsigned int bit0_offsets[] = {TPS65219_TO_RV_POS};
+static unsigned int bit1_offsets[] = {TPS65219_RV_POS};	/* Residual Voltage */
+static unsigned int bit2_offsets[] = {TPS65219_SYS_POS};	/* System */
+static unsigned int bit3_offsets[] = {TPS65219_BUCK_1_2_POS};	/* Buck 1-2 */
+static unsigned int bit4_offsets[] = {TPS65219_BUCK_3_POS};	/* Buck 3 */
+static unsigned int bit5_offsets[] = {TPS65219_LDO_1_2_POS};	/* LDO 1-2 */
+static unsigned int bit6_offsets[] = {TPS65219_LDO_3_4_POS};	/* LDO 3-4 */
+static unsigned int bit7_offsets[] = {TPS65219_PB_POS};	/* Power Button */
+
+static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
+};
+
+static struct regmap_irq tps65219_irqs[] = {
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO3_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC,
+		       TPS65219_LDO_3_4_POS, TPS65219_INT_LDO3_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_UV, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO3_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_SCG, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO4_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_OC, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO4_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_UV, TPS65219_LDO_3_4_POS,
+		       TPS65219_INT_LDO4_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG,
+		       TPS65219_LDO_1_2_POS, TPS65219_INT_LDO1_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO1_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO1_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO2_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO2_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65219_LDO_1_2_POS,
+		       TPS65219_INT_LDO2_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_NEG_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_BUCK_3_POS,
+		       TPS65219_INT_BUCK3_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_NEG_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK2_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_SCG_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_NEG_OC_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_BUCK_1_2_POS,
+		       TPS65219_INT_BUCK1_UV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM,
+		       TPS65219_SYS_POS, TPS65219_INT_SENSOR_3_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_2_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_1_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_0_WARM_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_3_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_2_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_1_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_SYS_POS,
+		       TPS65219_INT_SENSOR_0_HOT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_RV_POS,
+		       TPS65219_INT_BUCK1_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_RV_POS,
+		       TPS65219_INT_BUCK2_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_RV_POS,
+		       TPS65219_INT_BUCK3_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO1_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO2_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO3_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV, TPS65219_RV_POS,
+		       TPS65219_INT_LDO4_RV_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD,
+		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK1_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD,
+		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK2_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_BUCK3_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_LDO1_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_LDO2_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV_SD,
+		       TPS65219_TO_RV_POS, TPS65219_INT_LDO3_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV_SD, TPS65219_TO_RV_POS,
+		       TPS65219_INT_LDO4_RV_SD_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_TO_RV_POS,
+		       TPS65219_INT_TIMEOUT_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT,
+		       TPS65219_PB_POS, TPS65219_INT_PB_FALLING_EDGE_DET_MASK),
+	REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_PB_POS,
+		       TPS65219_INT_PB_RISING_EDGE_DET_MASK),
+};
+
+static struct regmap_irq_chip tps65219_irq_chip = {
+	.name = "tps65219_irq",
+	.main_status = TPS65219_REG_INT_SOURCE,
+	.num_main_regs = 1,
+	.num_main_status_bits = 8,
+	.irqs = tps65219_irqs,
+	.num_irqs = ARRAY_SIZE(tps65219_irqs),
+	.status_base = TPS65219_REG_INT_LDO_3_4,
+	.ack_base = TPS65219_REG_INT_LDO_3_4,
+	.clear_ack = 1,
+	.num_regs = 8,
+	.sub_reg_offsets = &tps65219_sub_irq_offsets[0],
+};
+
 static const struct of_device_id of_tps65219_match_table[] = {
 	{ .compatible = "ti,tps65219", },
 	{}
@@ -137,6 +343,7 @@ static int tps65219_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, tps);
 	tps->dev = &client->dev;
+	tps->irq = client->irq;
 	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
 	if (IS_ERR(tps->regmap)) {
 		ret = PTR_ERR(tps->regmap);
@@ -145,6 +352,12 @@ static int tps65219_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, tps->irq,
+				       IRQF_ONESHOT, 0, &tps65219_irq_chip,
+				       &tps->irq_data);
+	if (ret)
+		return ret;
+
 	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
 	if (ret) {
 		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
index e9197ab8bc75..8cecaf9bc682 100644
--- a/include/linux/mfd/tps65219.h
+++ b/include/linux/mfd/tps65219.h
@@ -214,6 +214,104 @@
 #define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
 #define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
 
+/* Masks for main IRQ register bits */
+enum {
+	TPS65219_INT_TIMEOUT_RV_SD,
+#define TPS65219_INT_TIMEOUT_RV_SD_MASK BIT(TPS65219_INT_TIMEOUT_RV_SD)
+	TPS65219_INT_RV,
+#define TPS65219_INT_RV_MASK BIT(TPS65219_INT_RV)
+	TPS65219_INT_SYSTEM,
+#define TPS65219_INT_SYSTEM_MASK BIT(TPS65219_INT_SYSTEM)
+	TPS65219_INT_BUCK_1_2,
+#define TPS65219_INT_BUCK_1_2_MASK BIT(TPS65219_INT_BUCK_1_2)
+	TPS65219_INT_BUCK_3,
+#define TPS65219_INT_BUCK_3_MASK BIT(TPS65219_INT_BUCK_3)
+	TPS65219_INT_LDO_1_2,
+#define TPS65219_INT_LDO_1_2_MASK BIT(TPS65219_INT_LDO_1_2)
+	TPS65219_INT_LDO_3_4,
+#define TPS65219_INT_LDO_3_4_MASK BIT(TPS65219_LDO_3_4)
+	TPS65219_INT_PB,
+#define TPS65219_INT_PB_MASK BIT(TPS65219_INT_PB)
+};
+
+/* Timeout Residual Voltage Shutdown */
+#define TPS65219_TO_RV_POS 6
+/* Residual Voltage */
+#define TPS65219_RV_POS 5
+/* System */
+#define TPS65219_SYS_POS 4
+/* Buck 1-2 */
+#define TPS65219_BUCK_1_2_POS 3
+/* Buck 3 */
+#define TPS65219_BUCK_3_POS 2
+/* LDO 1-2 */
+#define TPS65219_LDO_1_2_POS 1
+/* LDO 3-4 */
+#define TPS65219_LDO_3_4_POS 0
+/* Power Button */
+#define TPS65219_PB_POS 7
+
+/* IRQs */
+enum {
+	/* LDO3-4 register IRQs */
+	TPS65219_INT_LDO3_SCG,
+	TPS65219_INT_LDO3_OC,
+	TPS65219_INT_LDO3_UV,
+	TPS65219_INT_LDO4_SCG,
+	TPS65219_INT_LDO4_OC,
+	TPS65219_INT_LDO4_UV,
+	/* LDO1-2 */
+	TPS65219_INT_LDO1_SCG,
+	TPS65219_INT_LDO1_OC,
+	TPS65219_INT_LDO1_UV,
+	TPS65219_INT_LDO2_SCG,
+	TPS65219_INT_LDO2_OC,
+	TPS65219_INT_LDO2_UV,
+	/* BUCK3 */
+	TPS65219_INT_BUCK3_SCG,
+	TPS65219_INT_BUCK3_OC,
+	TPS65219_INT_BUCK3_NEG_OC,
+	TPS65219_INT_BUCK3_UV,
+	/* BUCK1-2 */
+	TPS65219_INT_BUCK1_SCG,
+	TPS65219_INT_BUCK1_OC,
+	TPS65219_INT_BUCK1_NEG_OC,
+	TPS65219_INT_BUCK1_UV,
+	TPS65219_INT_BUCK2_SCG,
+	TPS65219_INT_BUCK2_OC,
+	TPS65219_INT_BUCK2_NEG_OC,
+	TPS65219_INT_BUCK2_UV,
+	/* Thermal Sensor  */
+	TPS65219_INT_SENSOR_3_WARM,
+	TPS65219_INT_SENSOR_2_WARM,
+	TPS65219_INT_SENSOR_1_WARM,
+	TPS65219_INT_SENSOR_0_WARM,
+	TPS65219_INT_SENSOR_3_HOT,
+	TPS65219_INT_SENSOR_2_HOT,
+	TPS65219_INT_SENSOR_1_HOT,
+	TPS65219_INT_SENSOR_0_HOT,
+	/* Residual Voltage */
+	TPS65219_INT_BUCK1_RV,
+	TPS65219_INT_BUCK2_RV,
+	TPS65219_INT_BUCK3_RV,
+	TPS65219_INT_LDO1_RV,
+	TPS65219_INT_LDO2_RV,
+	TPS65219_INT_LDO3_RV,
+	TPS65219_INT_LDO4_RV,
+	/* Residual Voltage ShutDown */
+	TPS65219_INT_BUCK1_RV_SD,
+	TPS65219_INT_BUCK2_RV_SD,
+	TPS65219_INT_BUCK3_RV_SD,
+	TPS65219_INT_LDO1_RV_SD,
+	TPS65219_INT_LDO2_RV_SD,
+	TPS65219_INT_LDO3_RV_SD,
+	TPS65219_INT_LDO4_RV_SD,
+	TPS65219_INT_TIMEOUT,
+	/* Power Button */
+	TPS65219_INT_PB_FALLING_EDGE_DETECT,
+	TPS65219_INT_PB_RISING_EDGE_DETECT,
+};
+
 enum tps65219_regulator_id {
 	/* DCDC's */
 	TPS65219_BUCK_1,
@@ -235,6 +333,19 @@ enum tps65219_regulator_id {
 /* Number of total regulators available */
 #define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
 
+/* Define the TPS65219 IRQ numbers */
+enum tps65219_irqs {
+	/* INT source registers */
+	TPS65219_TO_RV_SD_SET_IRQ,
+	TPS65219_RV_SET_IRQ,
+	TPS65219_SYS_SET_IRQ,
+	TPS65219_BUCK_1_2_SET_IRQ,
+	TPS65219_BUCK_3_SET_IRQ,
+	TPS65219_LDO_1_2_SET_IRQ,
+	TPS65219_LDO_3_4_SET_IRQ,
+	TPS65219_PB_SET_IRQ,
+};
+
 /**
  * struct tps65219 - tps65219 sub-driver chip access routines
  *
@@ -243,6 +354,8 @@ enum tps65219_regulator_id {
 struct tps65219 {
 	struct device *dev;
 	unsigned int id;
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
 	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
 	struct regmap *regmap;
 	struct notifier_block nb;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 08/11] mfd: tps65219: Add power-button support
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

Using a power-button on the EN/PB/VSENSE pin of TPS65219 is optional, so
this driver adds the mfd cell for tps65219-pwrbutton only if needed. Two
interrupts are passed to the driver.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 drivers/mfd/tps65219.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
index 7366f251c21d..e1c30a49bf08 100644
--- a/drivers/mfd/tps65219.c
+++ b/drivers/mfd/tps65219.c
@@ -335,7 +335,10 @@ static int tps65219_probe(struct i2c_client *client,
 	struct tps65219 *tps;
 	int ret;
 	unsigned int chipid;
+	bool pwr_button;
 	bool sys_pwr;
+	struct mfd_cell cells[TPS65219_MAX_CELLS];
+	int nr_cells = 0;
 
 	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
 	if (!tps)
@@ -364,9 +367,16 @@ static int tps65219_probe(struct i2c_client *client,
 		return ret;
 	}
 
-	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
-				   ARRAY_SIZE(tps65219_cells), NULL, 0,
-				   NULL);
+	memcpy(&cells[nr_cells++], &tps65219_regulator_cell,
+	       sizeof(tps65219_regulator_cell));
+	pwr_button = of_property_read_bool(tps->dev->of_node, "power-button");
+	if (pwr_button)
+		memcpy(&cells[nr_cells++], &tps65219_pwrbutton_cell,
+		       sizeof(tps65219_pwrbutton_cell));
+
+	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, cells,
+				   nr_cells, NULL, 0,
+				   regmap_irq_get_domain(tps->irq_data));
 	if (ret) {
 		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
 		return ret;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 08/11] mfd: tps65219: Add power-button support
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

Using a power-button on the EN/PB/VSENSE pin of TPS65219 is optional, so
this driver adds the mfd cell for tps65219-pwrbutton only if needed. Two
interrupts are passed to the driver.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 drivers/mfd/tps65219.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
index 7366f251c21d..e1c30a49bf08 100644
--- a/drivers/mfd/tps65219.c
+++ b/drivers/mfd/tps65219.c
@@ -335,7 +335,10 @@ static int tps65219_probe(struct i2c_client *client,
 	struct tps65219 *tps;
 	int ret;
 	unsigned int chipid;
+	bool pwr_button;
 	bool sys_pwr;
+	struct mfd_cell cells[TPS65219_MAX_CELLS];
+	int nr_cells = 0;
 
 	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
 	if (!tps)
@@ -364,9 +367,16 @@ static int tps65219_probe(struct i2c_client *client,
 		return ret;
 	}
 
-	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
-				   ARRAY_SIZE(tps65219_cells), NULL, 0,
-				   NULL);
+	memcpy(&cells[nr_cells++], &tps65219_regulator_cell,
+	       sizeof(tps65219_regulator_cell));
+	pwr_button = of_property_read_bool(tps->dev->of_node, "power-button");
+	if (pwr_button)
+		memcpy(&cells[nr_cells++], &tps65219_pwrbutton_cell,
+		       sizeof(tps65219_pwrbutton_cell));
+
+	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, cells,
+				   nr_cells, NULL, 0,
+				   regmap_irq_get_domain(tps->irq_data));
 	if (ret) {
 		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
 		return ret;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 09/11] regulator: drivers: Add TI TPS65219 PMIC regulators support
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

The regulators set consists of 3 bucks DCDCs and 4 LDOs. The output
voltages are configurable and are meant to supply power to the
main processor and other components.

Validation:
Visual check: cat /sys/kernel/debug/regulator/regulator_summary
Validation: userspace-consumer and virtual-regulator required
to test further

Enable/Disable:
cat /sys/devices/platform/userspace-consumer-VDDSHV_SD_IO_PMIC/state
echo disabled > /sys/devices/platform/
userspace-consumer-VDDSHV_SD_IO_PMIC/state
echo enabled > /sys/devices/platform/
userspace-consumer-VDDSHV_SD_IO_PMIC/state

Change voltage:
cat /sys/devices/platform/regulator-virtual-ldo1/min_microvolts
echo 1000000 > /sys/devices/platform/regulator-virtual-ldo1/
min_microvolts
echo 3000000 > /sys/devices/platform/regulator-virtual-ldo1/
max_microvolts

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS                            |   1 +
 drivers/regulator/Kconfig              |   9 +
 drivers/regulator/Makefile             |   1 +
 drivers/regulator/tps65219-regulator.c | 416 +++++++++++++++++++++++++
 4 files changed, 427 insertions(+)
 create mode 100644 drivers/regulator/tps65219-regulator.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1331c43fc6ce..c48663a59835 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14721,6 +14721,7 @@ F:	drivers/regulator/palmas-regulator*.c
 F:	drivers/regulator/pbias-regulator.c
 F:	drivers/regulator/tps65217-regulator.c
 F:	drivers/regulator/tps65218-regulator.c
+F:	drivers/regulator/tps65219-regulator.c
 F:	drivers/regulator/tps65910-regulator.c
 F:	drivers/regulator/twl-regulator.c
 F:	drivers/regulator/twl6030-regulator.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index cbe0f96ca342..9b46c3465c46 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1356,6 +1356,15 @@ config REGULATOR_TPS65218
 	  voltage regulators. It supports software based voltage control
 	  for different voltage domains
 
+config REGULATOR_TPS65219
+	tristate "TI TPS65219 Power regulators"
+	depends on MFD_TPS65219 && OF
+	help
+	  This driver supports TPS65219 voltage regulator chips.
+	  TPS65219 series of PMICs have 3 single phase BUCKs & 4 LDOs
+	  voltage regulators. It supports software based voltage control
+	  for different voltage domains.
+
 config REGULATOR_TPS6524X
 	tristate "TI TPS6524X Power regulators"
 	depends on SPI
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 8d3ee8b6d41d..f2e8509a8f89 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65219) += tps65219-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c
new file mode 100644
index 000000000000..7ba2594e437c
--- /dev/null
+++ b/drivers/regulator/tps65219-regulator.c
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// tps65219-regulator.c
+//
+// Regulator driver for TPS65219 PMIC
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+//
+// This implementation derived from tps65218 authored by
+// "J Keerthy <j-keerthy@ti.com>"
+//
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/tps65219.h>
+
+struct tps65219_regulator_irq_type {
+	const char *irq_name;
+	const char *regulator_name;
+	const char *event_name;
+	unsigned long event;
+};
+
+struct tps65219_regulator_irq_type tps65219_regulator_irq_types[] = {
+	{ "LDO3_SCG", "LDO3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO3_OC", "LDO3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO3_UV", "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO4_SCG", "LDO4", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO4_OC", "LDO4", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO4_UV", "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO1_SCG", "LDO1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO1_OC", "LDO1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO1_UV", "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO2_SCG", "LDO2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO2_OC", "LDO2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO2_UV", "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK3_SCG", "BUCK3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "BUCK3_OC", "BUCK3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK3_NEG_OC", "BUCK3", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK3_UV", "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK1_SCG", "BUCK1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "BUCK1_OC", "BUCK1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK1_NEG_OC", "BUCK1", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK1_UV", "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK2_SCG", "BUCK2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "BUCK2_OC", "BUCK2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK2_NEG_OC", "BUCK2", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK2_UV", "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK1_RV", "BUCK1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK2_RV", "BUCK2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK3_RV", "BUCK3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO1_RV", "LDO1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO2_RV", "LDO2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO3_RV", "LDO3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO4_RV", "LDO4", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK1_RV_SD", "BUCK1", "residual voltage on shutdown",
+	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK2_RV_SD", "BUCK2", "residual voltage on shutdown",
+	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK3_RV_SD", "BUCK3", "residual voltage on shutdown",
+	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO1_RV_SD", "LDO1", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO2_RV_SD", "LDO2", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO3_RV_SD", "LDO3", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO4_RV_SD", "LDO4", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN},
+	{ "SENSOR_2_WARM", "SENSOR2", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
+	{ "SENSOR_1_WARM", "SENSOR1", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
+	{ "SENSOR_0_WARM", "SENSOR0", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
+	{ "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP},
+	{ "SENSOR_2_HOT", "SENSOR2", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
+	{ "SENSOR_1_HOT", "SENSOR1", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
+	{ "SENSOR_0_HOT", "SENSOR0", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
+	{ "TIMEOUT", "", "", REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE },
+};
+
+struct tps65219_regulator_irq_data {
+	struct device *dev;
+	struct tps65219_regulator_irq_type *type;
+	struct regulator_dev *rdev;
+};
+
+#define TPS65219_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
+			   _em, _cr, _cm, _lr, _nlr, _delay, _fuv, \
+			   _ct, _ncl, _bpm) \
+	{								\
+		.name			= _name,			\
+		.of_match		= _of,				\
+		.regulators_node	= of_match_ptr("regulators"),	\
+		.supply_name		= _of,				\
+		.id			= _id,				\
+		.ops			= &(_ops),			\
+		.n_voltages		= _n,				\
+		.type			= _type,			\
+		.owner			= THIS_MODULE,			\
+		.vsel_reg		= _vr,				\
+		.vsel_mask		= _vm,				\
+		.csel_reg		= _cr,				\
+		.csel_mask		= _cm,				\
+		.curr_table		= _ct,				\
+		.n_current_limits	= _ncl,				\
+		.enable_reg		= _er,				\
+		.enable_mask		= _em,				\
+		.volt_table		= NULL,				\
+		.linear_ranges		= _lr,				\
+		.n_linear_ranges	= _nlr,				\
+		.ramp_delay		= _delay,			\
+		.fixed_uV		= _fuv,				\
+		.bypass_reg		= _vr,				\
+		.bypass_mask		= _bpm,				\
+		.bypass_val_on		= 1,				\
+	}								\
+
+static const struct linear_range bucks_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x1f, 25000),
+	REGULATOR_LINEAR_RANGE(1400000, 0x20, 0x33, 100000),
+	REGULATOR_LINEAR_RANGE(3400000, 0x34, 0x3f, 0),
+};
+
+static const struct linear_range ldos_1_2_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x37, 50000),
+	REGULATOR_LINEAR_RANGE(3400000, 0x38, 0x3f, 0),
+};
+
+static const struct linear_range ldos_3_4_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xC, 0),
+	REGULATOR_LINEAR_RANGE(1250000, 0xD, 0x35, 50000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x36, 0x3F, 0),
+};
+
+static int tps65219_set_mode(struct regulator_dev *dev, unsigned int mode)
+{
+	struct tps65219 *tps = rdev_get_drvdata(dev);
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		return regmap_set_bits(tps->regmap, TPS65219_REG_STBY_1_CONFIG,
+				       dev->desc->enable_mask);
+
+	case REGULATOR_MODE_STANDBY:
+		return regmap_clear_bits(tps->regmap,
+					 TPS65219_REG_STBY_1_CONFIG,
+					 dev->desc->enable_mask);
+	default:
+		return -EINVAL;
+	}
+}
+
+static unsigned int tps65219_get_mode(struct regulator_dev *dev)
+{
+	struct tps65219 *tps = rdev_get_drvdata(dev);
+	unsigned int rid = rdev_get_id(dev);
+	int ret, value = 0;
+
+	ret = regmap_read(tps->regmap, TPS65219_REG_STBY_1_CONFIG, &value);
+	if (ret) {
+		dev_dbg(tps->dev, "%s failed for regulator %s: %d ",
+			__func__, dev->desc->name, ret);
+		return ret;
+	}
+	value = (value & BIT(rid)) >> rid;
+	if (value)
+		return REGULATOR_MODE_STANDBY;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+/*
+ * generic regulator_set_bypass_regmap does not fully match requirements
+ * TPS65219 Requires explicitly that regulator is disabled before switch
+ */
+static int tps65219_set_bypass(struct regulator_dev *dev, bool enable)
+{
+	struct tps65219 *tps = rdev_get_drvdata(dev);
+	unsigned int rid = rdev_get_id(dev);
+	int ret = 0;
+
+	if (dev->desc->ops->enable) {
+		dev_err(tps->dev,
+			"%s LDO%d enabled, must be shut down to set bypass ",
+			__func__, rid);
+		return -EBUSY;
+	}
+	ret =  regulator_set_bypass_regmap(dev, enable);
+	return ret;
+}
+
+/* Operations permitted on BUCK1/2/3 */
+static const struct regulator_ops tps65219_bucks_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.set_mode		= tps65219_set_mode,
+	.get_mode		= tps65219_get_mode,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+};
+
+/* Operations permitted on LDO1/2 */
+static const struct regulator_ops tps65219_ldos_1_2_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.set_mode		= tps65219_set_mode,
+	.get_mode		= tps65219_get_mode,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.set_bypass		= tps65219_set_bypass,
+	.get_bypass		= regulator_get_bypass_regmap,
+};
+
+/* Operations permitted on LDO3/4 */
+static const struct regulator_ops tps65219_ldos_3_4_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.set_mode		= tps65219_set_mode,
+	.get_mode		= tps65219_get_mode,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_desc regulators[] = {
+	TPS65219_REGULATOR("BUCK1", "buck1", TPS65219_BUCK_1,
+			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   TPS65219_REG_BUCK1_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_BUCK1_EN_MASK, 0, 0, bucks_ranges,
+			   3, 4000, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("BUCK2", "buck2", TPS65219_BUCK_2,
+			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   TPS65219_REG_BUCK2_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_BUCK2_EN_MASK, 0, 0, bucks_ranges,
+			   3, 4000, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("BUCK3", "buck3", TPS65219_BUCK_3,
+			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   TPS65219_REG_BUCK3_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_BUCK3_EN_MASK, 0, 0, bucks_ranges,
+			   3, 0, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("LDO1", "ldo1", TPS65219_LDO_1,
+			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
+			   TPS65219_REG_LDO1_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldos_1_2_ranges,
+			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
+	TPS65219_REGULATOR("LDO2", "ldo2", TPS65219_LDO_2,
+			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
+			   TPS65219_REG_LDO2_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, ldos_1_2_ranges,
+			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
+	TPS65219_REGULATOR("LDO3", "ldo3", TPS65219_LDO_3,
+			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
+			   TPS65219_REG_LDO3_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, ldos_3_4_ranges,
+			   3, 0, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("LDO4", "ldo4", TPS65219_LDO_4,
+			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
+			   TPS65219_REG_LDO4_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO4_EN_MASK, 0, 0, ldos_3_4_ranges,
+			   3, 0, 0, NULL, 0, 0),
+};
+
+static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data)
+{
+	struct tps65219_regulator_irq_data *irq_data = data;
+
+	if (irq_data->type->event_name[0] == '\0') {
+		/* This is the timeout interrupt no specific regulator */
+		dev_err(irq_data->dev,
+			"System was put in shutdown due to timeout during an active or standby transition.\n");
+		return IRQ_HANDLED;
+	}
+
+	regulator_notifier_call_chain(irq_data->rdev,
+				      irq_data->type->event, NULL);
+
+	dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",
+		irq_data->type->event_name, irq_data->type->regulator_name);
+	return IRQ_HANDLED;
+}
+
+static int tps65219_get_rdev_by_name(const char *regulator_name,
+				     struct regulator_dev *rdevtbl[7],
+				     struct regulator_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+		if (strcmp(regulator_name, regulators[i].name) == 0) {
+			dev = rdevtbl[i];
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static int tps65219_regulator_probe(struct platform_device *pdev)
+{
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_dev *rdev;
+	struct regulator_config config = { };
+	int i;
+	int error;
+	int irq;
+	struct tps65219_regulator_irq_data *irq_data;
+	struct tps65219_regulator_irq_type *irq_type;
+	struct regulator_dev *rdevtbl[7];
+
+	config.dev = tps->dev;
+	config.driver_data = tps;
+	config.regmap = tps->regmap;
+
+	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+		dev_dbg(tps->dev, "%s regul i= %d START", __func__, i);
+		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
+					       &config);
+		if (IS_ERR(rdev)) {
+			dev_err(tps->dev, "failed to register %s regulator\n",
+				pdev->name);
+			return PTR_ERR(rdev);
+		}
+		rdevtbl[i] = rdev;
+		dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i);
+	}
+
+	irq_data = devm_kmalloc(tps->dev,
+				ARRAY_SIZE(tps65219_regulator_irq_types) *
+				sizeof(struct tps65219_regulator_irq_data),
+				GFP_KERNEL);
+	if (!irq_data)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(tps65219_regulator_irq_types); ++i) {
+		irq_type = &tps65219_regulator_irq_types[i];
+
+		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+		if (irq < 0) {
+			dev_err(tps->dev, "Failed to get IRQ %s: %d\n",
+				irq_type->irq_name, irq);
+			return -EINVAL;
+		}
+		irq_data[i].dev = tps->dev;
+		irq_data[i].type = irq_type;
+
+		tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, rdev);
+		if (rdev < 0) {
+			dev_err(tps->dev, "Failed to get rdev for %s\n",
+				irq_type->regulator_name);
+			return -EINVAL;
+		}
+		irq_data[i].rdev = rdev;
+
+		error = devm_request_threaded_irq(tps->dev, irq, NULL,
+						  tps65219_regulator_irq_handler,
+						  IRQF_ONESHOT,
+						  irq_type->irq_name,
+						  &irq_data[i]);
+		if (error) {
+			dev_err(tps->dev, "failed to request %s IRQ %d: %d\n",
+				irq_type->irq_name, irq, error);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id tps65219_regulator_id_table[] = {
+	{ "tps65219-regulator", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table);
+
+static struct platform_driver tps65219_regulator_driver = {
+	.driver = {
+		.name = "tps65219-pmic",
+	},
+	.probe = tps65219_regulator_probe,
+	.id_table = tps65219_regulator_id_table,
+};
+
+module_platform_driver(tps65219_regulator_driver);
+
+MODULE_AUTHOR("Jerome Neanne <j-neanne@baylibre.com>");
+MODULE_DESCRIPTION("TPS65219 voltage regulator driver");
+MODULE_ALIAS("platform:tps65219-pmic");
+MODULE_LICENSE("GPL");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 09/11] regulator: drivers: Add TI TPS65219 PMIC regulators support
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

The regulators set consists of 3 bucks DCDCs and 4 LDOs. The output
voltages are configurable and are meant to supply power to the
main processor and other components.

Validation:
Visual check: cat /sys/kernel/debug/regulator/regulator_summary
Validation: userspace-consumer and virtual-regulator required
to test further

Enable/Disable:
cat /sys/devices/platform/userspace-consumer-VDDSHV_SD_IO_PMIC/state
echo disabled > /sys/devices/platform/
userspace-consumer-VDDSHV_SD_IO_PMIC/state
echo enabled > /sys/devices/platform/
userspace-consumer-VDDSHV_SD_IO_PMIC/state

Change voltage:
cat /sys/devices/platform/regulator-virtual-ldo1/min_microvolts
echo 1000000 > /sys/devices/platform/regulator-virtual-ldo1/
min_microvolts
echo 3000000 > /sys/devices/platform/regulator-virtual-ldo1/
max_microvolts

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS                            |   1 +
 drivers/regulator/Kconfig              |   9 +
 drivers/regulator/Makefile             |   1 +
 drivers/regulator/tps65219-regulator.c | 416 +++++++++++++++++++++++++
 4 files changed, 427 insertions(+)
 create mode 100644 drivers/regulator/tps65219-regulator.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1331c43fc6ce..c48663a59835 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14721,6 +14721,7 @@ F:	drivers/regulator/palmas-regulator*.c
 F:	drivers/regulator/pbias-regulator.c
 F:	drivers/regulator/tps65217-regulator.c
 F:	drivers/regulator/tps65218-regulator.c
+F:	drivers/regulator/tps65219-regulator.c
 F:	drivers/regulator/tps65910-regulator.c
 F:	drivers/regulator/twl-regulator.c
 F:	drivers/regulator/twl6030-regulator.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index cbe0f96ca342..9b46c3465c46 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1356,6 +1356,15 @@ config REGULATOR_TPS65218
 	  voltage regulators. It supports software based voltage control
 	  for different voltage domains
 
+config REGULATOR_TPS65219
+	tristate "TI TPS65219 Power regulators"
+	depends on MFD_TPS65219 && OF
+	help
+	  This driver supports TPS65219 voltage regulator chips.
+	  TPS65219 series of PMICs have 3 single phase BUCKs & 4 LDOs
+	  voltage regulators. It supports software based voltage control
+	  for different voltage domains.
+
 config REGULATOR_TPS6524X
 	tristate "TI TPS6524X Power regulators"
 	depends on SPI
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 8d3ee8b6d41d..f2e8509a8f89 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65219) += tps65219-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c
new file mode 100644
index 000000000000..7ba2594e437c
--- /dev/null
+++ b/drivers/regulator/tps65219-regulator.c
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// tps65219-regulator.c
+//
+// Regulator driver for TPS65219 PMIC
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+//
+// This implementation derived from tps65218 authored by
+// "J Keerthy <j-keerthy@ti.com>"
+//
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/tps65219.h>
+
+struct tps65219_regulator_irq_type {
+	const char *irq_name;
+	const char *regulator_name;
+	const char *event_name;
+	unsigned long event;
+};
+
+struct tps65219_regulator_irq_type tps65219_regulator_irq_types[] = {
+	{ "LDO3_SCG", "LDO3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO3_OC", "LDO3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO3_UV", "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO4_SCG", "LDO4", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO4_OC", "LDO4", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO4_UV", "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO1_SCG", "LDO1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO1_OC", "LDO1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO1_UV", "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO2_SCG", "LDO2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "LDO2_OC", "LDO2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "LDO2_UV", "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK3_SCG", "BUCK3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "BUCK3_OC", "BUCK3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK3_NEG_OC", "BUCK3", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK3_UV", "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK1_SCG", "BUCK1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "BUCK1_OC", "BUCK1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK1_NEG_OC", "BUCK1", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK1_UV", "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK2_SCG", "BUCK2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
+	{ "BUCK2_OC", "BUCK2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK2_NEG_OC", "BUCK2", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
+	{ "BUCK2_UV", "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "BUCK1_RV", "BUCK1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK2_RV", "BUCK2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK3_RV", "BUCK3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO1_RV", "LDO1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO2_RV", "LDO2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO3_RV", "LDO3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO4_RV", "LDO4", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK1_RV_SD", "BUCK1", "residual voltage on shutdown",
+	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK2_RV_SD", "BUCK2", "residual voltage on shutdown",
+	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "BUCK3_RV_SD", "BUCK3", "residual voltage on shutdown",
+	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO1_RV_SD", "LDO1", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO2_RV_SD", "LDO2", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO3_RV_SD", "LDO3", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO4_RV_SD", "LDO4", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN},
+	{ "SENSOR_2_WARM", "SENSOR2", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
+	{ "SENSOR_1_WARM", "SENSOR1", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
+	{ "SENSOR_0_WARM", "SENSOR0", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
+	{ "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP},
+	{ "SENSOR_2_HOT", "SENSOR2", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
+	{ "SENSOR_1_HOT", "SENSOR1", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
+	{ "SENSOR_0_HOT", "SENSOR0", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
+	{ "TIMEOUT", "", "", REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE },
+};
+
+struct tps65219_regulator_irq_data {
+	struct device *dev;
+	struct tps65219_regulator_irq_type *type;
+	struct regulator_dev *rdev;
+};
+
+#define TPS65219_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
+			   _em, _cr, _cm, _lr, _nlr, _delay, _fuv, \
+			   _ct, _ncl, _bpm) \
+	{								\
+		.name			= _name,			\
+		.of_match		= _of,				\
+		.regulators_node	= of_match_ptr("regulators"),	\
+		.supply_name		= _of,				\
+		.id			= _id,				\
+		.ops			= &(_ops),			\
+		.n_voltages		= _n,				\
+		.type			= _type,			\
+		.owner			= THIS_MODULE,			\
+		.vsel_reg		= _vr,				\
+		.vsel_mask		= _vm,				\
+		.csel_reg		= _cr,				\
+		.csel_mask		= _cm,				\
+		.curr_table		= _ct,				\
+		.n_current_limits	= _ncl,				\
+		.enable_reg		= _er,				\
+		.enable_mask		= _em,				\
+		.volt_table		= NULL,				\
+		.linear_ranges		= _lr,				\
+		.n_linear_ranges	= _nlr,				\
+		.ramp_delay		= _delay,			\
+		.fixed_uV		= _fuv,				\
+		.bypass_reg		= _vr,				\
+		.bypass_mask		= _bpm,				\
+		.bypass_val_on		= 1,				\
+	}								\
+
+static const struct linear_range bucks_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x1f, 25000),
+	REGULATOR_LINEAR_RANGE(1400000, 0x20, 0x33, 100000),
+	REGULATOR_LINEAR_RANGE(3400000, 0x34, 0x3f, 0),
+};
+
+static const struct linear_range ldos_1_2_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x37, 50000),
+	REGULATOR_LINEAR_RANGE(3400000, 0x38, 0x3f, 0),
+};
+
+static const struct linear_range ldos_3_4_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xC, 0),
+	REGULATOR_LINEAR_RANGE(1250000, 0xD, 0x35, 50000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x36, 0x3F, 0),
+};
+
+static int tps65219_set_mode(struct regulator_dev *dev, unsigned int mode)
+{
+	struct tps65219 *tps = rdev_get_drvdata(dev);
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		return regmap_set_bits(tps->regmap, TPS65219_REG_STBY_1_CONFIG,
+				       dev->desc->enable_mask);
+
+	case REGULATOR_MODE_STANDBY:
+		return regmap_clear_bits(tps->regmap,
+					 TPS65219_REG_STBY_1_CONFIG,
+					 dev->desc->enable_mask);
+	default:
+		return -EINVAL;
+	}
+}
+
+static unsigned int tps65219_get_mode(struct regulator_dev *dev)
+{
+	struct tps65219 *tps = rdev_get_drvdata(dev);
+	unsigned int rid = rdev_get_id(dev);
+	int ret, value = 0;
+
+	ret = regmap_read(tps->regmap, TPS65219_REG_STBY_1_CONFIG, &value);
+	if (ret) {
+		dev_dbg(tps->dev, "%s failed for regulator %s: %d ",
+			__func__, dev->desc->name, ret);
+		return ret;
+	}
+	value = (value & BIT(rid)) >> rid;
+	if (value)
+		return REGULATOR_MODE_STANDBY;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+/*
+ * generic regulator_set_bypass_regmap does not fully match requirements
+ * TPS65219 Requires explicitly that regulator is disabled before switch
+ */
+static int tps65219_set_bypass(struct regulator_dev *dev, bool enable)
+{
+	struct tps65219 *tps = rdev_get_drvdata(dev);
+	unsigned int rid = rdev_get_id(dev);
+	int ret = 0;
+
+	if (dev->desc->ops->enable) {
+		dev_err(tps->dev,
+			"%s LDO%d enabled, must be shut down to set bypass ",
+			__func__, rid);
+		return -EBUSY;
+	}
+	ret =  regulator_set_bypass_regmap(dev, enable);
+	return ret;
+}
+
+/* Operations permitted on BUCK1/2/3 */
+static const struct regulator_ops tps65219_bucks_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.set_mode		= tps65219_set_mode,
+	.get_mode		= tps65219_get_mode,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+};
+
+/* Operations permitted on LDO1/2 */
+static const struct regulator_ops tps65219_ldos_1_2_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.set_mode		= tps65219_set_mode,
+	.get_mode		= tps65219_get_mode,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.set_bypass		= tps65219_set_bypass,
+	.get_bypass		= regulator_get_bypass_regmap,
+};
+
+/* Operations permitted on LDO3/4 */
+static const struct regulator_ops tps65219_ldos_3_4_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.set_mode		= tps65219_set_mode,
+	.get_mode		= tps65219_get_mode,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_desc regulators[] = {
+	TPS65219_REGULATOR("BUCK1", "buck1", TPS65219_BUCK_1,
+			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   TPS65219_REG_BUCK1_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_BUCK1_EN_MASK, 0, 0, bucks_ranges,
+			   3, 4000, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("BUCK2", "buck2", TPS65219_BUCK_2,
+			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   TPS65219_REG_BUCK2_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_BUCK2_EN_MASK, 0, 0, bucks_ranges,
+			   3, 4000, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("BUCK3", "buck3", TPS65219_BUCK_3,
+			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   TPS65219_REG_BUCK3_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_BUCK3_EN_MASK, 0, 0, bucks_ranges,
+			   3, 0, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("LDO1", "ldo1", TPS65219_LDO_1,
+			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
+			   TPS65219_REG_LDO1_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldos_1_2_ranges,
+			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
+	TPS65219_REGULATOR("LDO2", "ldo2", TPS65219_LDO_2,
+			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
+			   TPS65219_REG_LDO2_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, ldos_1_2_ranges,
+			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
+	TPS65219_REGULATOR("LDO3", "ldo3", TPS65219_LDO_3,
+			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
+			   TPS65219_REG_LDO3_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, ldos_3_4_ranges,
+			   3, 0, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("LDO4", "ldo4", TPS65219_LDO_4,
+			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
+			   TPS65219_REG_LDO4_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO4_EN_MASK, 0, 0, ldos_3_4_ranges,
+			   3, 0, 0, NULL, 0, 0),
+};
+
+static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data)
+{
+	struct tps65219_regulator_irq_data *irq_data = data;
+
+	if (irq_data->type->event_name[0] == '\0') {
+		/* This is the timeout interrupt no specific regulator */
+		dev_err(irq_data->dev,
+			"System was put in shutdown due to timeout during an active or standby transition.\n");
+		return IRQ_HANDLED;
+	}
+
+	regulator_notifier_call_chain(irq_data->rdev,
+				      irq_data->type->event, NULL);
+
+	dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",
+		irq_data->type->event_name, irq_data->type->regulator_name);
+	return IRQ_HANDLED;
+}
+
+static int tps65219_get_rdev_by_name(const char *regulator_name,
+				     struct regulator_dev *rdevtbl[7],
+				     struct regulator_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+		if (strcmp(regulator_name, regulators[i].name) == 0) {
+			dev = rdevtbl[i];
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static int tps65219_regulator_probe(struct platform_device *pdev)
+{
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_dev *rdev;
+	struct regulator_config config = { };
+	int i;
+	int error;
+	int irq;
+	struct tps65219_regulator_irq_data *irq_data;
+	struct tps65219_regulator_irq_type *irq_type;
+	struct regulator_dev *rdevtbl[7];
+
+	config.dev = tps->dev;
+	config.driver_data = tps;
+	config.regmap = tps->regmap;
+
+	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+		dev_dbg(tps->dev, "%s regul i= %d START", __func__, i);
+		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
+					       &config);
+		if (IS_ERR(rdev)) {
+			dev_err(tps->dev, "failed to register %s regulator\n",
+				pdev->name);
+			return PTR_ERR(rdev);
+		}
+		rdevtbl[i] = rdev;
+		dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i);
+	}
+
+	irq_data = devm_kmalloc(tps->dev,
+				ARRAY_SIZE(tps65219_regulator_irq_types) *
+				sizeof(struct tps65219_regulator_irq_data),
+				GFP_KERNEL);
+	if (!irq_data)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(tps65219_regulator_irq_types); ++i) {
+		irq_type = &tps65219_regulator_irq_types[i];
+
+		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+		if (irq < 0) {
+			dev_err(tps->dev, "Failed to get IRQ %s: %d\n",
+				irq_type->irq_name, irq);
+			return -EINVAL;
+		}
+		irq_data[i].dev = tps->dev;
+		irq_data[i].type = irq_type;
+
+		tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, rdev);
+		if (rdev < 0) {
+			dev_err(tps->dev, "Failed to get rdev for %s\n",
+				irq_type->regulator_name);
+			return -EINVAL;
+		}
+		irq_data[i].rdev = rdev;
+
+		error = devm_request_threaded_irq(tps->dev, irq, NULL,
+						  tps65219_regulator_irq_handler,
+						  IRQF_ONESHOT,
+						  irq_type->irq_name,
+						  &irq_data[i]);
+		if (error) {
+			dev_err(tps->dev, "failed to request %s IRQ %d: %d\n",
+				irq_type->irq_name, irq, error);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id tps65219_regulator_id_table[] = {
+	{ "tps65219-regulator", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table);
+
+static struct platform_driver tps65219_regulator_driver = {
+	.driver = {
+		.name = "tps65219-pmic",
+	},
+	.probe = tps65219_regulator_probe,
+	.id_table = tps65219_regulator_id_table,
+};
+
+module_platform_driver(tps65219_regulator_driver);
+
+MODULE_AUTHOR("Jerome Neanne <j-neanne@baylibre.com>");
+MODULE_DESCRIPTION("TPS65219 voltage regulator driver");
+MODULE_ALIAS("platform:tps65219-pmic");
+MODULE_LICENSE("GPL");
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 10/11] Input: Add tps65219 interrupt driven powerbutton
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

TPS65219 has different interrupts compared to other TPS6521* chips.
TPS65219 defines two interrupts for the powerbutton one for push and one
for release.

This driver is very simple in that it maps the push interrupt to a key
input and the release interrupt to a key release.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS                             |   1 +
 drivers/input/misc/Kconfig              |  10 ++
 drivers/input/misc/Makefile             |   1 +
 drivers/input/misc/tps65219-pwrbutton.c | 150 ++++++++++++++++++++++++
 4 files changed, 162 insertions(+)
 create mode 100644 drivers/input/misc/tps65219-pwrbutton.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c48663a59835..68959f75d607 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14705,6 +14705,7 @@ F:	arch/arm/plat-omap/
 F:	drivers/bus/ti-sysc.c
 F:	drivers/i2c/busses/i2c-omap.c
 F:	drivers/input/misc/tps65218-pwrbutton.c
+F:	drivers/input/misc/tps65219-pwrbutton.c
 F:	drivers/irqchip/irq-omap-intc.c
 F:	drivers/mfd/*omap*.c
 F:	drivers/mfd/menelaus.c
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a18ab7358d8f..18d4a321e7ff 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -468,6 +468,16 @@ config INPUT_TPS65218_PWRBUTTON
 	  To compile this driver as a module, choose M here. The module will
 	  be called tps65218-pwrbutton.
 
+config INPUT_TPS65219_PWRBUTTON
+	tristate "TPS65219 Power button driver"
+	depends on MFD_TPS65219
+	help
+	  Say Y here if you want to enable power button reporting for
+	  TPS65219 Power Management IC devices.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called tps65219-pwrbutton.
+
 config INPUT_AXP20X_PEK
 	tristate "X-Powers AXP20X power button driver"
 	depends on MFD_AXP20X
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 28dfc444f0a9..fe8f47402d12 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY)	+= soc_button_array.o
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_STPMIC1_ONKEY)  	+= stpmic1_onkey.o
 obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON)	+= tps65218-pwrbutton.o
+obj-$(CONFIG_INPUT_TPS65219_PWRBUTTON)	+= tps65219-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_VIBRA)	+= twl4030-vibra.o
 obj-$(CONFIG_INPUT_TWL6040_VIBRA)	+= twl6040-vibra.o
diff --git a/drivers/input/misc/tps65219-pwrbutton.c b/drivers/input/misc/tps65219-pwrbutton.c
new file mode 100644
index 000000000000..48ced7b63ec3
--- /dev/null
+++ b/drivers/input/misc/tps65219-pwrbutton.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for TPS65219 Push Button
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+//
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps65219.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+struct tps65219_pwrbutton {
+	struct device *dev;
+	struct input_dev *idev;
+	char phys[32];
+};
+
+static irqreturn_t tps65219_pb_push_irq(int irq, void *_pwr)
+{
+	struct tps65219_pwrbutton *pwr = _pwr;
+
+	input_report_key(pwr->idev, KEY_POWER, 1);
+	pm_wakeup_event(pwr->dev, 0);
+	input_sync(pwr->idev);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t tps65219_pb_release_irq(int irq, void *_pwr)
+{
+	struct tps65219_pwrbutton *pwr = _pwr;
+
+	input_report_key(pwr->idev, KEY_POWER, 0);
+	input_sync(pwr->idev);
+
+	return IRQ_HANDLED;
+}
+
+static int tps65219_pb_probe(struct platform_device *pdev)
+{
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct device *dev = &pdev->dev;
+	struct tps65219_pwrbutton *pwr;
+	struct input_dev *idev;
+	int error;
+	int push_irq;
+	int release_irq;
+
+	pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
+	if (!pwr)
+		return -ENOMEM;
+
+	idev = devm_input_allocate_device(dev);
+	if (!idev)
+		return -ENOMEM;
+
+	idev->name = pdev->name;
+	snprintf(pwr->phys, sizeof(pwr->phys), "%s/input0",
+		 pdev->name);
+	idev->phys = pwr->phys;
+	idev->dev.parent = dev;
+	idev->id.bustype = BUS_I2C;
+
+	input_set_capability(idev, EV_KEY, KEY_POWER);
+
+	pwr->dev = dev;
+	pwr->idev = idev;
+	device_init_wakeup(dev, true);
+
+	push_irq = platform_get_irq(pdev, 0);
+	if (push_irq < 0)
+		return -EINVAL;
+
+	release_irq = platform_get_irq(pdev, 1);
+	if (release_irq < 0)
+		return -EINVAL;
+
+	error = devm_request_threaded_irq(dev, push_irq, NULL,
+					  tps65219_pb_push_irq,
+					  IRQF_ONESHOT,
+					  dev->init_name, pwr);
+	if (error) {
+		dev_err(dev, "failed to request push IRQ #%d: %d\n", push_irq,
+			error);
+		return error;
+	}
+
+	error = devm_request_threaded_irq(dev, release_irq, NULL,
+					  tps65219_pb_release_irq,
+					  IRQF_ONESHOT,
+					  dev->init_name, pwr);
+	if (error) {
+		dev_err(dev, "failed to request release IRQ #%d: %d\n",
+			release_irq, error);
+		return error;
+	}
+
+	error = input_register_device(idev);
+	if (error) {
+		dev_err(dev, "Can't register power button: %d\n", error);
+		return error;
+	}
+
+	/* Enable interrupts for the pushbutton */
+	regmap_clear_bits(tps->regmap, TPS65219_REG_MASK_CONFIG,
+			  TPS65219_REG_MASK_INT_FOR_PB_MASK);
+
+	/* Set PB/EN/VSENSE pin to be a pushbutton */
+	regmap_update_bits(tps->regmap, TPS65219_REG_MFP_2_CONFIG,
+			   TPS65219_MFP_2_EN_PB_VSENSE_MASK, TPS65219_MFP_2_PB);
+
+	return 0;
+}
+
+static int tps65219_pb_remove(struct platform_device *pdev)
+{
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+
+	/* Disable interrupt for the pushbutton */
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MASK_CONFIG,
+				  TPS65219_REG_MASK_INT_FOR_PB_MASK,
+				  TPS65219_REG_MASK_INT_FOR_PB_MASK);
+}
+
+static const struct platform_device_id tps65219_pwrbtn_id_table[] = {
+	{ "tps65219-pwrbutton", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, tps65219_pwrbtn_id_table);
+
+static struct platform_driver tps65219_pb_driver = {
+	.probe = tps65219_pb_probe,
+	.remove = tps65219_pb_remove,
+	.driver = {
+		.name = "tps65219_pwrbutton",
+	},
+	.id_table = tps65219_pwrbtn_id_table,
+};
+module_platform_driver(tps65219_pb_driver);
+
+MODULE_DESCRIPTION("TPS65219 Power Button");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 10/11] Input: Add tps65219 interrupt driven powerbutton
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

TPS65219 has different interrupts compared to other TPS6521* chips.
TPS65219 defines two interrupts for the powerbutton one for push and one
for release.

This driver is very simple in that it maps the push interrupt to a key
input and the release interrupt to a key release.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 MAINTAINERS                             |   1 +
 drivers/input/misc/Kconfig              |  10 ++
 drivers/input/misc/Makefile             |   1 +
 drivers/input/misc/tps65219-pwrbutton.c | 150 ++++++++++++++++++++++++
 4 files changed, 162 insertions(+)
 create mode 100644 drivers/input/misc/tps65219-pwrbutton.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c48663a59835..68959f75d607 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14705,6 +14705,7 @@ F:	arch/arm/plat-omap/
 F:	drivers/bus/ti-sysc.c
 F:	drivers/i2c/busses/i2c-omap.c
 F:	drivers/input/misc/tps65218-pwrbutton.c
+F:	drivers/input/misc/tps65219-pwrbutton.c
 F:	drivers/irqchip/irq-omap-intc.c
 F:	drivers/mfd/*omap*.c
 F:	drivers/mfd/menelaus.c
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a18ab7358d8f..18d4a321e7ff 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -468,6 +468,16 @@ config INPUT_TPS65218_PWRBUTTON
 	  To compile this driver as a module, choose M here. The module will
 	  be called tps65218-pwrbutton.
 
+config INPUT_TPS65219_PWRBUTTON
+	tristate "TPS65219 Power button driver"
+	depends on MFD_TPS65219
+	help
+	  Say Y here if you want to enable power button reporting for
+	  TPS65219 Power Management IC devices.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called tps65219-pwrbutton.
+
 config INPUT_AXP20X_PEK
 	tristate "X-Powers AXP20X power button driver"
 	depends on MFD_AXP20X
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 28dfc444f0a9..fe8f47402d12 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY)	+= soc_button_array.o
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_STPMIC1_ONKEY)  	+= stpmic1_onkey.o
 obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON)	+= tps65218-pwrbutton.o
+obj-$(CONFIG_INPUT_TPS65219_PWRBUTTON)	+= tps65219-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_VIBRA)	+= twl4030-vibra.o
 obj-$(CONFIG_INPUT_TWL6040_VIBRA)	+= twl6040-vibra.o
diff --git a/drivers/input/misc/tps65219-pwrbutton.c b/drivers/input/misc/tps65219-pwrbutton.c
new file mode 100644
index 000000000000..48ced7b63ec3
--- /dev/null
+++ b/drivers/input/misc/tps65219-pwrbutton.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for TPS65219 Push Button
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+//
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps65219.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+struct tps65219_pwrbutton {
+	struct device *dev;
+	struct input_dev *idev;
+	char phys[32];
+};
+
+static irqreturn_t tps65219_pb_push_irq(int irq, void *_pwr)
+{
+	struct tps65219_pwrbutton *pwr = _pwr;
+
+	input_report_key(pwr->idev, KEY_POWER, 1);
+	pm_wakeup_event(pwr->dev, 0);
+	input_sync(pwr->idev);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t tps65219_pb_release_irq(int irq, void *_pwr)
+{
+	struct tps65219_pwrbutton *pwr = _pwr;
+
+	input_report_key(pwr->idev, KEY_POWER, 0);
+	input_sync(pwr->idev);
+
+	return IRQ_HANDLED;
+}
+
+static int tps65219_pb_probe(struct platform_device *pdev)
+{
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct device *dev = &pdev->dev;
+	struct tps65219_pwrbutton *pwr;
+	struct input_dev *idev;
+	int error;
+	int push_irq;
+	int release_irq;
+
+	pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
+	if (!pwr)
+		return -ENOMEM;
+
+	idev = devm_input_allocate_device(dev);
+	if (!idev)
+		return -ENOMEM;
+
+	idev->name = pdev->name;
+	snprintf(pwr->phys, sizeof(pwr->phys), "%s/input0",
+		 pdev->name);
+	idev->phys = pwr->phys;
+	idev->dev.parent = dev;
+	idev->id.bustype = BUS_I2C;
+
+	input_set_capability(idev, EV_KEY, KEY_POWER);
+
+	pwr->dev = dev;
+	pwr->idev = idev;
+	device_init_wakeup(dev, true);
+
+	push_irq = platform_get_irq(pdev, 0);
+	if (push_irq < 0)
+		return -EINVAL;
+
+	release_irq = platform_get_irq(pdev, 1);
+	if (release_irq < 0)
+		return -EINVAL;
+
+	error = devm_request_threaded_irq(dev, push_irq, NULL,
+					  tps65219_pb_push_irq,
+					  IRQF_ONESHOT,
+					  dev->init_name, pwr);
+	if (error) {
+		dev_err(dev, "failed to request push IRQ #%d: %d\n", push_irq,
+			error);
+		return error;
+	}
+
+	error = devm_request_threaded_irq(dev, release_irq, NULL,
+					  tps65219_pb_release_irq,
+					  IRQF_ONESHOT,
+					  dev->init_name, pwr);
+	if (error) {
+		dev_err(dev, "failed to request release IRQ #%d: %d\n",
+			release_irq, error);
+		return error;
+	}
+
+	error = input_register_device(idev);
+	if (error) {
+		dev_err(dev, "Can't register power button: %d\n", error);
+		return error;
+	}
+
+	/* Enable interrupts for the pushbutton */
+	regmap_clear_bits(tps->regmap, TPS65219_REG_MASK_CONFIG,
+			  TPS65219_REG_MASK_INT_FOR_PB_MASK);
+
+	/* Set PB/EN/VSENSE pin to be a pushbutton */
+	regmap_update_bits(tps->regmap, TPS65219_REG_MFP_2_CONFIG,
+			   TPS65219_MFP_2_EN_PB_VSENSE_MASK, TPS65219_MFP_2_PB);
+
+	return 0;
+}
+
+static int tps65219_pb_remove(struct platform_device *pdev)
+{
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+
+	/* Disable interrupt for the pushbutton */
+	return regmap_update_bits(tps->regmap, TPS65219_REG_MASK_CONFIG,
+				  TPS65219_REG_MASK_INT_FOR_PB_MASK,
+				  TPS65219_REG_MASK_INT_FOR_PB_MASK);
+}
+
+static const struct platform_device_id tps65219_pwrbtn_id_table[] = {
+	{ "tps65219-pwrbutton", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, tps65219_pwrbtn_id_table);
+
+static struct platform_driver tps65219_pb_driver = {
+	.probe = tps65219_pb_probe,
+	.remove = tps65219_pb_remove,
+	.driver = {
+		.name = "tps65219_pwrbutton",
+	},
+	.id_table = tps65219_pwrbtn_id_table,
+};
+module_platform_driver(tps65219_pb_driver);
+
+MODULE_DESCRIPTION("TPS65219 Power Button");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com");
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 11/11] arm64: defconfig: Add tps65219 as modules
  2022-07-26 10:33 ` Jerome Neanne
@ 2022-07-26 10:33   ` Jerome Neanne
  -1 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

This adds defconfig option to support TPS65219 PMIC, MFD, Regulators
and power-button.

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 7d1105343bc2..988397574e3c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -412,6 +412,7 @@ CONFIG_TOUCHSCREEN_GOODIX=m
 CONFIG_TOUCHSCREEN_EDT_FT5X06=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PM8941_PWRKEY=y
+CONFIG_INPUT_TPS65219_PWRBUTTON=m
 CONFIG_INPUT_PM8XXX_VIBRATOR=m
 CONFIG_INPUT_PWM_BEEPER=m
 CONFIG_INPUT_PWM_VIBRA=m
@@ -641,6 +642,7 @@ CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_RK808=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_SL28CPLD=y
+CONFIG_MFD_TPS65219=m
 CONFIG_MFD_ROHM_BD718XX=y
 CONFIG_MFD_WCD934X=m
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -668,6 +670,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_TPS65132=m
+CONFIG_REGULATOR_TPS65219=m
 CONFIG_REGULATOR_VCTRL=m
 CONFIG_RC_CORE=m
 CONFIG_RC_DECODERS=y
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 11/11] arm64: defconfig: Add tps65219 as modules
@ 2022-07-26 10:33   ` Jerome Neanne
  0 siblings, 0 replies; 36+ messages in thread
From: Jerome Neanne @ 2022-07-26 10:33 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, nm, kristo
  Cc: khilman, narmstrong, msp, j-keerthy, lee.jones, jneanne,
	linux-kernel, devicetree, linux-arm-kernel

This adds defconfig option to support TPS65219 PMIC, MFD, Regulators
and power-button.

Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 7d1105343bc2..988397574e3c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -412,6 +412,7 @@ CONFIG_TOUCHSCREEN_GOODIX=m
 CONFIG_TOUCHSCREEN_EDT_FT5X06=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PM8941_PWRKEY=y
+CONFIG_INPUT_TPS65219_PWRBUTTON=m
 CONFIG_INPUT_PM8XXX_VIBRATOR=m
 CONFIG_INPUT_PWM_BEEPER=m
 CONFIG_INPUT_PWM_VIBRA=m
@@ -641,6 +642,7 @@ CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_RK808=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_SL28CPLD=y
+CONFIG_MFD_TPS65219=m
 CONFIG_MFD_ROHM_BD718XX=y
 CONFIG_MFD_WCD934X=m
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -668,6 +670,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_TPS65132=m
+CONFIG_REGULATOR_TPS65219=m
 CONFIG_REGULATOR_VCTRL=m
 CONFIG_RC_CORE=m
 CONFIG_RC_DECODERS=y
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 05/11] regulator: dt-bindings: Add TI TPS65219 PMIC bindings
  2022-07-26 10:33   ` Jerome Neanne
@ 2022-07-26 12:56     ` Markus Schneider-Pargmann
  -1 siblings, 0 replies; 36+ messages in thread
From: Markus Schneider-Pargmann @ 2022-07-26 12:56 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	j-keerthy, lee.jones, linux-kernel, devicetree, linux-arm-kernel

Hi Jerome,

On Tue, Jul 26, 2022 at 12:33:49PM +0200, Jerome Neanne wrote:
> Add TPS65219 PMIC bindings using json-schema.
> 
> Describe required properties and regname-supply.
> regname-supply is required when bypass mode is used for a regulator.
> Describes regulator topology.
> Interrupts support.
> Add a power-button property to configure the EN/PB/VSENSE pin as a
> powerbutton:
> 
> TPS65219 has a multipurpose pin called EN/PB/VSENSE that can be either:
> - EN in which case it functions as an enable pin.
> - VSENSE which compares the voltages and triggers an automatic
> on/off request.
> - PB in which case it can be configured to trigger an interrupt
> to the SoC.
> ti,power-button reflects the last one of those options
> where the board has a button wired to the pin and triggers
> an interrupt on pressing it.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  .../bindings/regulator/ti,tps65219.yaml       | 164 ++++++++++++++++++
>  1 file changed, 164 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
> 
> diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
> new file mode 100644
> index 000000000000..8fca4db6c64c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml

...

> +
> +  power-button:
> +    type: boolean
> +    description: Optional property that sets the EN/PB/VSENSE pin to be a
> +      power-button.

It seems something went wrong here. This should have been
ti,power-button and have a similar description as the commit message,
right?

Best,
Markus

> +
> +patternProperties:
> +  "^buck[1-3]-supply$":
> +    description: Input supply phandle of one regulator.
> +
> +  "^ldo[1-4]-supply$":
> +    description: Input supply phandle of one regulator.
> +
> +  regulators:
> +    type: object
> +    description: |
> +      list of regulators provided by this controller
> +
> +    patternProperties:
> +      "^ldo[1-4]$":
> +        type: object
> +        $ref: regulator.yaml#
> +        description:
> +          Properties for single LDO regulator.
> +
> +        unevaluatedProperties: false
> +
> +      "^buck[1-3]$":
> +        type: object
> +        $ref: regulator.yaml#
> +        description:
> +          Properties for single BUCK regulator.
> +
> +        unevaluatedProperties: false
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - regulators
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        tps65219: pmic@30 {
> +            compatible = "ti,tps65219";
> +            reg = <0x30>;
> +            buck1-supply = <&vcc_3v3_sys>;
> +            buck2-supply = <&vcc_3v3_sys>;
> +            buck3-supply = <&vcc_3v3_sys>;
> +            ldo1-supply = <&vcc_3v3_sys>;
> +            ldo2-supply = <&buck2_reg>;
> +            ldo3-supply = <&vcc_3v3_sys>;
> +            ldo4-supply = <&vcc_3v3_sys>;
> +
> +            pinctrl-0 = <&pmic_irq_pins_default>;
> +
> +            interrupt-parent = <&gic500>;
> +            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
> +            interrupt-controller;
> +            #interrupt-cells = <1>;
> +
> +            regulators {
> +                buck1_reg: buck1 {
> +                    regulator-name = "VDD_CORE";
> +                    regulator-min-microvolt = <750000>;
> +                    regulator-max-microvolt = <750000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                buck2_reg: buck2 {
> +                    regulator-name = "VCC1V8";
> +                    regulator-min-microvolt = <1800000>;
> +                    regulator-max-microvolt = <1800000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                buck3_reg: buck3 {
> +                    regulator-name = "VDD_LPDDR4";
> +                    regulator-min-microvolt = <1100000>;
> +                    regulator-max-microvolt = <1100000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                ldo1_reg: ldo1 {
> +                    regulator-name = "VDDSHV_SD_IO_PMIC";
> +                    regulator-min-microvolt = <33000000>;
> +                    regulator-max-microvolt = <33000000>;
> +                };
> +
> +                ldo2_reg: ldo2 {
> +                    regulator-name = "VDDAR_CORE";
> +                    regulator-min-microvolt = <850000>;
> +                    regulator-max-microvolt = <850000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                ldo3_reg: ldo3 {
> +                    regulator-name = "VDDA_1V8";
> +                    regulator-min-microvolt = <18000000>;
> +                    regulator-max-microvolt = <18000000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                ldo4_reg: ldo4 {
> +                    regulator-name = "VDD_PHY_2V5";
> +                    regulator-min-microvolt = <25000000>;
> +                    regulator-max-microvolt = <25000000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +            };
> +        };
> +    };
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 05/11] regulator: dt-bindings: Add TI TPS65219 PMIC bindings
@ 2022-07-26 12:56     ` Markus Schneider-Pargmann
  0 siblings, 0 replies; 36+ messages in thread
From: Markus Schneider-Pargmann @ 2022-07-26 12:56 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	j-keerthy, lee.jones, linux-kernel, devicetree, linux-arm-kernel

Hi Jerome,

On Tue, Jul 26, 2022 at 12:33:49PM +0200, Jerome Neanne wrote:
> Add TPS65219 PMIC bindings using json-schema.
> 
> Describe required properties and regname-supply.
> regname-supply is required when bypass mode is used for a regulator.
> Describes regulator topology.
> Interrupts support.
> Add a power-button property to configure the EN/PB/VSENSE pin as a
> powerbutton:
> 
> TPS65219 has a multipurpose pin called EN/PB/VSENSE that can be either:
> - EN in which case it functions as an enable pin.
> - VSENSE which compares the voltages and triggers an automatic
> on/off request.
> - PB in which case it can be configured to trigger an interrupt
> to the SoC.
> ti,power-button reflects the last one of those options
> where the board has a button wired to the pin and triggers
> an interrupt on pressing it.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  .../bindings/regulator/ti,tps65219.yaml       | 164 ++++++++++++++++++
>  1 file changed, 164 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
> 
> diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
> new file mode 100644
> index 000000000000..8fca4db6c64c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml

...

> +
> +  power-button:
> +    type: boolean
> +    description: Optional property that sets the EN/PB/VSENSE pin to be a
> +      power-button.

It seems something went wrong here. This should have been
ti,power-button and have a similar description as the commit message,
right?

Best,
Markus

> +
> +patternProperties:
> +  "^buck[1-3]-supply$":
> +    description: Input supply phandle of one regulator.
> +
> +  "^ldo[1-4]-supply$":
> +    description: Input supply phandle of one regulator.
> +
> +  regulators:
> +    type: object
> +    description: |
> +      list of regulators provided by this controller
> +
> +    patternProperties:
> +      "^ldo[1-4]$":
> +        type: object
> +        $ref: regulator.yaml#
> +        description:
> +          Properties for single LDO regulator.
> +
> +        unevaluatedProperties: false
> +
> +      "^buck[1-3]$":
> +        type: object
> +        $ref: regulator.yaml#
> +        description:
> +          Properties for single BUCK regulator.
> +
> +        unevaluatedProperties: false
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - regulators
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        tps65219: pmic@30 {
> +            compatible = "ti,tps65219";
> +            reg = <0x30>;
> +            buck1-supply = <&vcc_3v3_sys>;
> +            buck2-supply = <&vcc_3v3_sys>;
> +            buck3-supply = <&vcc_3v3_sys>;
> +            ldo1-supply = <&vcc_3v3_sys>;
> +            ldo2-supply = <&buck2_reg>;
> +            ldo3-supply = <&vcc_3v3_sys>;
> +            ldo4-supply = <&vcc_3v3_sys>;
> +
> +            pinctrl-0 = <&pmic_irq_pins_default>;
> +
> +            interrupt-parent = <&gic500>;
> +            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
> +            interrupt-controller;
> +            #interrupt-cells = <1>;
> +
> +            regulators {
> +                buck1_reg: buck1 {
> +                    regulator-name = "VDD_CORE";
> +                    regulator-min-microvolt = <750000>;
> +                    regulator-max-microvolt = <750000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                buck2_reg: buck2 {
> +                    regulator-name = "VCC1V8";
> +                    regulator-min-microvolt = <1800000>;
> +                    regulator-max-microvolt = <1800000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                buck3_reg: buck3 {
> +                    regulator-name = "VDD_LPDDR4";
> +                    regulator-min-microvolt = <1100000>;
> +                    regulator-max-microvolt = <1100000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                ldo1_reg: ldo1 {
> +                    regulator-name = "VDDSHV_SD_IO_PMIC";
> +                    regulator-min-microvolt = <33000000>;
> +                    regulator-max-microvolt = <33000000>;
> +                };
> +
> +                ldo2_reg: ldo2 {
> +                    regulator-name = "VDDAR_CORE";
> +                    regulator-min-microvolt = <850000>;
> +                    regulator-max-microvolt = <850000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                ldo3_reg: ldo3 {
> +                    regulator-name = "VDDA_1V8";
> +                    regulator-min-microvolt = <18000000>;
> +                    regulator-max-microvolt = <18000000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +
> +                ldo4_reg: ldo4 {
> +                    regulator-name = "VDD_PHY_2V5";
> +                    regulator-min-microvolt = <25000000>;
> +                    regulator-max-microvolt = <25000000>;
> +                    regulator-boot-on;
> +                    regulator-always-on;
> +                };
> +            };
> +        };
> +    };
> -- 
> 2.17.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 04/11] MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton
  2022-07-26 10:33   ` Jerome Neanne
@ 2022-07-26 14:30     ` Markus Schneider-Pargmann
  -1 siblings, 0 replies; 36+ messages in thread
From: Markus Schneider-Pargmann @ 2022-07-26 14:30 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	j-keerthy, lee.jones, linux-kernel, devicetree, linux-arm-kernel

Hi,

On Tue, Jul 26, 2022 at 12:33:48PM +0200, Jerome Neanne wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> The entry for the pwrbutton driver seems to be missing. Add it to the
> list for OMAP2+ SUPPORT.

sorry, my mistake, I thought it was missing in this listing. Looking at
the history of the driver all the patches were applied in the INPUT
tree. So we can just drop this patch IMHO.

Best,
Markus

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 64379c699903..67850b321cbb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14704,6 +14704,7 @@ F:	arch/arm/mach-omap2/
>  F:	arch/arm/plat-omap/
>  F:	drivers/bus/ti-sysc.c
>  F:	drivers/i2c/busses/i2c-omap.c
> +F:	drivers/input/misc/tps65218-pwrbutton.c
>  F:	drivers/irqchip/irq-omap-intc.c
>  F:	drivers/mfd/*omap*.c
>  F:	drivers/mfd/menelaus.c
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 04/11] MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton
@ 2022-07-26 14:30     ` Markus Schneider-Pargmann
  0 siblings, 0 replies; 36+ messages in thread
From: Markus Schneider-Pargmann @ 2022-07-26 14:30 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	j-keerthy, lee.jones, linux-kernel, devicetree, linux-arm-kernel

Hi,

On Tue, Jul 26, 2022 at 12:33:48PM +0200, Jerome Neanne wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> The entry for the pwrbutton driver seems to be missing. Add it to the
> list for OMAP2+ SUPPORT.

sorry, my mistake, I thought it was missing in this listing. Looking at
the history of the driver all the patches were applied in the INPUT
tree. So we can just drop this patch IMHO.

Best,
Markus

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 64379c699903..67850b321cbb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14704,6 +14704,7 @@ F:	arch/arm/mach-omap2/
>  F:	arch/arm/plat-omap/
>  F:	drivers/bus/ti-sysc.c
>  F:	drivers/i2c/busses/i2c-omap.c
> +F:	drivers/input/misc/tps65218-pwrbutton.c
>  F:	drivers/irqchip/irq-omap-intc.c
>  F:	drivers/mfd/*omap*.c
>  F:	drivers/mfd/menelaus.c
> -- 
> 2.17.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support
  2022-07-26 10:33   ` Jerome Neanne
@ 2022-08-08 15:49     ` Lee Jones
  -1 siblings, 0 replies; 36+ messages in thread
From: Lee Jones @ 2022-08-08 15:49 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	msp, j-keerthy, linux-kernel, devicetree, linux-arm-kernel,
	Lee Jones

On Tue, 26 Jul 2022, Jerome Neanne wrote:

> The TPS65219 is a power management IC PMIC designed
> to supply a wide range of SoCs
> in both portable and stationary applications.
> Any SoC can control TPS65219 over a standard I2C interface.

Really odd line break choices here.

> It contains the following components:
> - Regulators.
> - Over Temperature warning and Shut down.
> - GPIOs
> - Multi Function Pins (MFP)
> 
> This patch adds support for tps65219 mfd device. At this time only

No such thing as an MFD device, what is it?  PMIC, no?

> the functionalities listed below are made available:
> 
> - Regulators probe and functionalities
> - warm and cold reset support
> - SW shutdown support
> 
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  MAINTAINERS                  |   1 +
>  drivers/mfd/Kconfig          |  15 +++
>  drivers/mfd/Makefile         |   1 +
>  drivers/mfd/tps65219.c       | 214 +++++++++++++++++++++++++++++
>  include/linux/mfd/tps65219.h | 251 +++++++++++++++++++++++++++++++++++
>  5 files changed, 482 insertions(+)
>  create mode 100644 drivers/mfd/tps65219.c
>  create mode 100644 include/linux/mfd/tps65219.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 67850b321cbb..1331c43fc6ce 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14711,6 +14711,7 @@ F:	drivers/mfd/menelaus.c
>  F:	drivers/mfd/palmas.c
>  F:	drivers/mfd/tps65217.c
>  F:	drivers/mfd/tps65218.c
> +F:	drivers/mfd/tps65219.c
>  F:	drivers/mfd/tps65910.c
>  F:	drivers/mfd/twl-core.[ch]
>  F:	drivers/mfd/twl4030*.c
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 3b59456f5545..c66e56374a9a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1574,6 +1574,21 @@ config MFD_TPS65218
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called tps65218.
>  
> +config MFD_TPS65219
> +	tristate "TI TPS65219 Power Management chips"

Abbreviation is PMIC, please reflect that here.

s/chips/ICs/

> +	depends on I2C && OF
> +	select MFD_CORE
> +	select REGMAP_I2C
> +	select REGMAP_IRQ
> +	help
> +	  If you say yes here you get support for the TPS65219 series of
> +	  Power Management chips.

As above.

No need to line break here.

> +	  These include voltage regulators, gpio and other features

GPIO

What "other features"?

> +	  that are often used in portable devices.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called tps65219.
> +
>  config MFD_TPS6586X
>  	bool "TI TPS6586x Power Management chips"
>  	depends on I2C=y
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 858cacf659d6..a8ff3d6ea3ab 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
>  obj-$(CONFIG_MFD_TPS65086)	+= tps65086.o
>  obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
>  obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
> +obj-$(CONFIG_MFD_TPS65219)	+= tps65219.o
>  obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
>  obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
>  obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
> diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
> new file mode 100644
> index 000000000000..c3bf975ea6c7
> --- /dev/null
> +++ b/drivers/mfd/tps65219.c
> @@ -0,0 +1,214 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Driver for TPS65219 Integrated power management chipsets

"Power Management Integrated Chips (PMIC)"

> +//
> +// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> +//
> +// This implementation derived from tps65218 authored by
> +// "J Keerthy <j-keerthy@ti.com>"

Which he probably copied from elsewhere.

Please drop this line.

> +//

Drop this empty comment

Only C++ for the SPDX line please.

'\n' here.

> +#include <linux/kernel.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/init.h>
> +#include <linux/i2c.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/irq.h>
> +#include <linux/interrupt.h>
> +#include <linux/reboot.h>

Alphabetical

> +#include <linux/mfd/core.h>
> +#include <linux/mfd/tps65219.h>
> +
> +static struct i2c_client *tps65219_i2c_client;
> +
> +/**
> + * tps65219_warm_reset: issue warm reset to SOC.
> + *
> + * @tps: Device to write to.
> + */

Why Kerneldoc for static functions.

See: scripts/find-unused-docs.sh

> +static int tps65219_warm_reset(struct tps65219 *tps)
> +{
> +	dev_dbg(tps->dev, "warm reset");

No thank you.

And for all the other useless dev_dbg() prints that in this file which
no one is going to use.

> +	pr_flush(1000, true);

'\n'

> +	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
> +				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK,
> +				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK);
> +}
> +
> +/**
> + * tps65219_cold_reset: issue cold reset to SOC.
> + *
> + * @tps: Device to write to.
> + */
> +static int tps65219_cold_reset(struct tps65219 *tps)
> +{
> +	dev_dbg(tps->dev, "cold reset");
> +	pr_flush(1000, true);
> +	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
> +				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK,
> +				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
> +}
> +
> +/**
> + * tps65219_soft_shutdown: issue cold reset to SOC.
> + *
> + * @tps: Device to write to.
> + */
> +static int tps65219_soft_shutdown(struct tps65219 *tps)
> +{
> +	dev_dbg(tps->dev, "software shutdown");
> +	pr_flush(1000, true);
> +	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
> +				  TPS65219_MFP_I2C_OFF_REQ_MASK,
> +				  TPS65219_MFP_I2C_OFF_REQ_MASK);
> +}
> +
> +/**
> + * pmic_rst_restart: trig tps65219 reset to SOC.
> + *
> + * Trigged via notifier
> + */
> +static int pmic_rst_restart(struct notifier_block *this,
> +			    unsigned long reboot_mode, void *cmd)
> +{
> +	struct tps65219 *tps;
> +
> +	tps = container_of(this, struct tps65219, nb);
> +	if (!tps) {
> +		pr_err("%s: pointer to tps65219 is invalid\n", __func__);
> +		return -ENODEV;
> +	}
> +	if (reboot_mode == REBOOT_WARM)
> +		tps65219_warm_reset(tps);
> +	else
> +		tps65219_cold_reset(tps);
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block pmic_rst_restart_nb = {
> +	.notifier_call = pmic_rst_restart,
> +	.priority = 200,
> +};
> +
> +/**
> + * pmic_do_poweroff: trig tps65219 regulators power OFF sequence.
> + */
> +static void pmic_do_poweroff(void)
> +{
> +	struct tps65219 *tps;
> +
> +	tps = dev_get_drvdata(&tps65219_i2c_client->dev);
> +	tps65219_soft_shutdown(tps);
> +}

Would all of the above be better off in drivers/power?

> +static const struct mfd_cell tps65219_cells[] = {
> +	{ .name = "tps65219-regulator", },
> +};

One device, which isn't even a device, is not an MFD.

Where are the other devices?

They need to be added now, rather than later please.

> +static const struct regmap_config tps65219_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
> +};
> +
> +static const struct of_device_id of_tps65219_match_table[] = {
> +	{ .compatible = "ti,tps65219", },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, of_tps65219_match_table);

This usually goes at the bottom of the file.

> +static int tps65219_probe(struct i2c_client *client,
> +			  const struct i2c_device_id *ids)
> +{
> +	struct tps65219 *tps;
> +	int ret;

Normally placed at the bottom of the list.

> +	unsigned int chipid;
> +	bool sys_pwr;
> +
> +	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
> +	if (!tps)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(client, tps);

'\n'

> +	tps->dev = &client->dev;

'\n'

> +	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
> +	if (IS_ERR(tps->regmap)) {
> +		ret = PTR_ERR(tps->regmap);
> +		dev_err(tps->dev, "Failed to allocate register map: %d\n",
> +			ret);

No line break here please.

> +		return ret;
> +	}
> +
> +	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
> +	if (ret) {
> +		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
> +				   ARRAY_SIZE(tps65219_cells), NULL, 0,
> +				   NULL);

No line break on the 2nd line.

> +	if (ret) {
> +		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);

"Failed to add child devices"

> +		return ret;
> +	}
> +
> +	tps->nb = pmic_rst_restart_nb;
> +	ret = register_restart_handler(&tps->nb);
> +	if (ret) {
> +		dev_err(tps->dev, "%s: cannot register restart handler, %d\n",
> +			__func__, ret);

No __func__

> +		return -ENODEV;

Why not propagate 'ret'?

> +	}
> +
> +	sys_pwr = of_property_read_bool(tps->dev->of_node,
> +					"system-power-controller");

This will probably go onto one line (<100 chars)

> +	if (sys_pwr)

	if (!sys_power_controller)
		return 0;

> +		if (pm_power_off)
> +			dev_warn(tps->dev, "Setup as system-power-controller but pm_power_off function already registered, overwriting\n");

Is that really what you want?

What about the other driver that thinks it's the
system-power-controller? Seems wrong.

In any case, make this line as short / succinct as you can.

> +		tps65219_i2c_client = client;
> +		pm_power_off = &pmic_do_poweroff;
> +	}
> +	return ret;
> +}
> +
> +static int tps65219_remove(struct i2c_client *client)
> +{
> +	struct tps65219 *tps = i2c_get_clientdata(client);
> +
> +	if (tps65219_i2c_client == client) {
> +		pm_power_off = NULL;
> +		tps65219_i2c_client = NULL;
> +	}
> +
> +	return unregister_restart_handler(&tps->nb);
> +}
> +
> +static const struct i2c_device_id tps65219_id_table[] = {
> +	{ "tps65219", TPS65219 },

Do you use this param?

If not drop the whole table and use .probe_new.

> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, tps65219_id_table);
> +
> +static struct i2c_driver tps65219_driver = {
> +	.driver		= {
> +		.name	= "tps65219",
> +		.of_match_table = of_tps65219_match_table,
> +	},
> +	.probe		= tps65219_probe,
> +	.id_table       = tps65219_id_table,
> +	.remove		= tps65219_remove,
> +};
> +

Remove this line.

> +module_i2c_driver(tps65219_driver);
> +
> +MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
> +MODULE_DESCRIPTION("TPS65219 chip family multi-function driver");

Please change this description to something suggested above.

> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
> new file mode 100644
> index 000000000000..e9197ab8bc75
> --- /dev/null
> +++ b/include/linux/mfd/tps65219.h
> @@ -0,0 +1,251 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * linux/mfd/tps65219.h

No filenames please.  They tend to become unsynced.

> + * Functions to access TPS65219 power management chip.

As above.

> + * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> + */
> +
> +#ifndef __LINUX_MFD_TPS65219_H
> +#define __LINUX_MFD_TPS65219_H

LINUX?

> +#include <linux/i2c.h>
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/bitops.h>
> +#include <linux/regmap.h>

Alphabetical.

Some of these should probably be forward declarations, not includes.

> +#define TPS65219_1V35					1350000
> +#define TPS65219_1V8					1800000
> +
> +/* TPS chip id list */
> +#define TPS65219					0xF0
> +
> +/* I2C ID for TPS65219 part */
> +#define TPS65219_I2C_ID					0x24
> +
> +/* All register addresses */
> +#define TPS65219_REG_TI_DEV_ID				0x00
> +#define TPS65219_REG_NVM_ID				0x01
> +#define TPS65219_REG_ENABLE_CTRL			0x02
> +#define TPS65219_REG_BUCKS_CONFIG			0x03
> +#define TPS65219_REG_LDO4_VOUT				0x04
> +#define TPS65219_REG_LDO3_VOUT				0x05
> +#define TPS65219_REG_LDO2_VOUT				0x06
> +#define TPS65219_REG_LDO1_VOUT				0x07
> +#define TPS65219_REG_BUCK3_VOUT				0x8
> +#define TPS65219_REG_BUCK2_VOUT				0x9
> +#define TPS65219_REG_BUCK1_VOUT				0xA
> +#define TPS65219_REG_LDO4_SEQUENCE_SLOT			0xB
> +#define TPS65219_REG_LDO3_SEQUENCE_SLOT			0xC
> +#define TPS65219_REG_LDO2_SEQUENCE_SLOT			0xD
> +#define TPS65219_REG_LDO1_SEQUENCE_SLOT			0xE
> +#define TPS65219_REG_BUCK3_SEQUENCE_SLOT		0xF
> +#define TPS65219_REG_BUCK2_SEQUENCE_SLOT		0x10
> +#define TPS65219_REG_BUCK1_SEQUENCE_SLOT		0x11
> +#define TPS65219_REG_nRST_SEQUENCE_SLOT			0x12
> +#define TPS65219_REG_GPIO_SEQUENCE_SLOT			0x13
> +#define TPS65219_REG_GPO2_SEQUENCE_SLOT			0x14
> +#define TPS65219_REG_GPO1_SEQUENCE_SLOT			0x15
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_1		0x16
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_2		0x17
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_3		0x18
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_4		0x19
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_1		0x1A
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_2		0x1B
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_3		0x1C
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_4		0x1D
> +#define TPS65219_REG_GENERAL_CONFIG			0x1E
> +#define TPS65219_REG_MFP_1_CONFIG			0x1F
> +#define TPS65219_REG_MFP_2_CONFIG			0x20
> +#define TPS65219_REG_STBY_1_CONFIG			0x21
> +#define TPS65219_REG_STBY_2_CONFIG			0x22
> +#define TPS65219_REG_OC_DEGL_CONFIG			0x23
> +/* 'sub irq' MASK registers */
> +#define TPS65219_REG_INT_MASK_UV			0x24
> +#define TPS65219_REG_MASK_CONFIG			0x25
> +
> +#define TPS65219_REG_I2C_ADDRESS_REG			0x26
> +#define TPS65219_REG_USER_GENERAL_NVM_STORAGE		0x27
> +#define TPS65219_REG_MANUFACTURING_VER			0x28
> +#define TPS65219_REG_MFP_CTRL				0x29
> +#define TPS65219_REG_DISCHARGE_CONFIG			0x2A
> +/* main irq registers */
> +#define TPS65219_REG_INT_SOURCE				0x2B
> +/* 'sub irq' registers */
> +#define TPS65219_REG_INT_LDO_3_4			0x2C
> +#define TPS65219_REG_INT_LDO_1_2			0x2D
> +#define TPS65219_REG_INT_BUCK_3				0x2E
> +#define TPS65219_REG_INT_BUCK_1_2			0x2F
> +#define TPS65219_REG_INT_SYSTEM				0x30
> +#define TPS65219_REG_INT_RV				0x31
> +#define TPS65219_REG_INT_TIMEOUT_RV_SD			0x32
> +#define TPS65219_REG_INT_PB				0x33
> +
> +#define TPS65219_REG_USER_NVM_CMD			0x34
> +#define TPS65219_REG_POWER_UP_STATUS			0x35
> +#define TPS65219_REG_SPARE_2				0x36
> +#define TPS65219_REG_SPARE_3				0x37
> +#define TPS65219_REG_FACTORY_CONFIG_2			0x41
> +
> +/* Register field definitions */
> +#define TPS65219_DEVID_REV_MASK				GENMASK(7, 0)
> +#define TPS65219_BUCKS_LDOS_VOUT_VSET_MASK		GENMASK(5, 0)
> +#define TPS65219_BUCKS_UV_THR_SEL_MASK			BIT(6)
> +#define TPS65219_BUCKS_BW_SEL_MASK			BIT(7)
> +#define LDO_BYP_SHIFT					6
> +#define TPS65219_LDOS_BYP_CONFIG_MASK			BIT(LDO_BYP_SHIFT)
> +#define TPS65219_LDOS_LSW_CONFIG_MASK			BIT(7)
> +/* Regulators enable control */
> +#define TPS65219_ENABLE_BUCK1_EN_MASK			BIT(0)
> +#define TPS65219_ENABLE_BUCK2_EN_MASK			BIT(1)
> +#define TPS65219_ENABLE_BUCK3_EN_MASK			BIT(2)
> +#define TPS65219_ENABLE_LDO1_EN_MASK			BIT(3)
> +#define TPS65219_ENABLE_LDO2_EN_MASK			BIT(4)
> +#define TPS65219_ENABLE_LDO3_EN_MASK			BIT(5)
> +#define TPS65219_ENABLE_LDO4_EN_MASK			BIT(6)
> +/* power ON-OFF sequence slot */
> +#define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK	GENMASK(3, 0)
> +#define TPS65219_BUCKS_LDOS_SEQUENCE_ON_SLOT_MASK	GENMASK(7, 4)
> +/* TODO: Not needed, same mapping as TPS65219_ENABLE_REGNAME_EN, factorize */
> +#define TPS65219_STBY1_BUCK1_STBY_EN_MASK		BIT(0)
> +#define TPS65219_STBY1_BUCK2_STBY_EN_MASK		BIT(1)
> +#define TPS65219_STBY1_BUCK3_STBY_EN_MASK		BIT(2)
> +#define TPS65219_STBY1_LDO1_STBY_EN_MASK		BIT(3)
> +#define TPS65219_STBY1_LDO2_STBY_EN_MASK		BIT(4)
> +#define TPS65219_STBY1_LDO3_STBY_EN_MASK		BIT(5)
> +#define TPS65219_STBY1_LDO4_STBY_EN_MASK		BIT(6)
> +/* STBY_2 config */
> +#define TPS65219_STBY2_GPO1_STBY_EN_MASK		BIT(0)
> +#define TPS65219_STBY2_GPO2_STBY_EN_MASK		BIT(1)
> +#define TPS65219_STBY2_GPIO_STBY_EN_MASK		BIT(2)
> +/* MFP Control */
> +#define TPS65219_MFP_I2C_OFF_REQ_MASK			BIT(0)
> +#define TPS65219_MFP_STBY_I2C_CTRL_MASK			BIT(1)
> +#define TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK		BIT(2)
> +#define TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK		BIT(3)
> +#define TPS65219_MFP_GPIO_STATUS_MASK			BIT(4)
> +/* MFP_1 Config */
> +#define TPS65219_MFP_1_VSEL_DDR_SEL_MASK		BIT(0)
> +#define TPS65219_MFP_1_VSEL_SD_POL_MASK			BIT(1)
> +#define TPS65219_MFP_1_VSEL_RAIL_MASK			BIT(2)
> +/* MFP_2 Config */
> +#define TPS65219_MFP_2_MODE_STBY_MASK			GENMASK(1, 0)
> +#define TPS65219_MFP_2_MODE_RESET_MASK			BIT(2)
> +#define TPS65219_MFP_2_EN_PB_VSENSE_DEGL_MASK		BIT(3)
> +#define TPS65219_MFP_2_EN_PB_VSENSE_MASK		GENMASK(5, 4)
> +#define TPS65219_MFP_2_WARM_COLD_RESET_MASK		BIT(6)
> +#define TPS65219_MFP_2_PU_ON_FSD_MASK			BIT(7)
> +#define TPS65219_MFP_2_EN				0
> +#define TPS65219_MFP_2_PB				BIT(4)
> +#define TPS65219_MFP_2_VSENSE				BIT(5)
> +/* MASK_UV Config */
> +#define TPS65219_REG_MASK_UV_LDO1_UV_MASK		BIT(0)
> +#define TPS65219_REG_MASK_UV_LDO2_UV_MASK		BIT(1)
> +#define TPS65219_REG_MASK_UV_LDO3_UV_MASK		BIT(2)
> +#define TPS65219_REG_MASK_UV_LDO4_UV_MASK		BIT(3)
> +#define TPS65219_REG_MASK_UV_BUCK1_UV_MASK		BIT(4)
> +#define TPS65219_REG_MASK_UV_BUCK2_UV_MASK		BIT(5)
> +#define TPS65219_REG_MASK_UV_BUCK3_UV_MASK		BIT(6)
> +#define TPS65219_REG_MASK_UV_RETRY_MASK			BIT(7)
> +/* MASK Config */
> +// SENSOR_N_WARM_MASK already defined in Thermal
> +#define TPS65219_REG_MASK_INT_FOR_RV_MASK		BIT(4)
> +#define TPS65219_REG_MASK_EFFECT_MASK			GENMASK(2, 1)
> +#define TPS65219_REG_MASK_INT_FOR_PB_MASK		BIT(7)
> +/* UnderVoltage - Short to GND - OverCurrent*/
> +/* LDO3-4 */
> +#define TPS65219_INT_LDO3_SCG_MASK			BIT(0)
> +#define TPS65219_INT_LDO3_OC_MASK			BIT(1)
> +#define TPS65219_INT_LDO3_UV_MASK			BIT(2)
> +#define TPS65219_INT_LDO4_SCG_MASK			BIT(3)
> +#define TPS65219_INT_LDO4_OC_MASK			BIT(4)
> +#define TPS65219_INT_LDO4_UV_MASK			BIT(5)
> +/* LDO1-2 */
> +#define TPS65219_INT_LDO1_SCG_MASK			BIT(0)
> +#define TPS65219_INT_LDO1_OC_MASK			BIT(1)
> +#define TPS65219_INT_LDO1_UV_MASK			BIT(2)
> +#define TPS65219_INT_LDO2_SCG_MASK			BIT(3)
> +#define TPS65219_INT_LDO2_OC_MASK			BIT(4)
> +#define TPS65219_INT_LDO2_UV_MASK			BIT(5)
> +/* BUCK3 */
> +#define TPS65219_INT_BUCK3_SCG_MASK			BIT(0)
> +#define TPS65219_INT_BUCK3_OC_MASK			BIT(1)
> +#define TPS65219_INT_BUCK3_NEG_OC_MASK			BIT(2)
> +#define TPS65219_INT_BUCK3_UV_MASK			BIT(3)
> +/* BUCK1-2 */
> +#define TPS65219_INT_BUCK1_SCG_MASK			BIT(0)
> +#define TPS65219_INT_BUCK1_OC_MASK			BIT(1)
> +#define TPS65219_INT_BUCK1_NEG_OC_MASK			BIT(2)
> +#define TPS65219_INT_BUCK1_UV_MASK			BIT(3)
> +#define TPS65219_INT_BUCK2_SCG_MASK			BIT(4)
> +#define TPS65219_INT_BUCK2_OC_MASK			BIT(5)
> +#define TPS65219_INT_BUCK2_NEG_OC_MASK			BIT(6)
> +#define TPS65219_INT_BUCK2_UV_MASK			BIT(7)
> +/* Thermal Sensor  */
> +#define TPS65219_INT_SENSOR_3_WARM_MASK			BIT(0)
> +#define TPS65219_INT_SENSOR_2_WARM_MASK			BIT(1)
> +#define TPS65219_INT_SENSOR_1_WARM_MASK			BIT(2)
> +#define TPS65219_INT_SENSOR_0_WARM_MASK			BIT(3)
> +#define TPS65219_INT_SENSOR_3_HOT_MASK			BIT(4)
> +#define TPS65219_INT_SENSOR_2_HOT_MASK			BIT(5)
> +#define TPS65219_INT_SENSOR_1_HOT_MASK			BIT(6)
> +#define TPS65219_INT_SENSOR_0_HOT_MASK			BIT(7)
> +/* Residual Voltage */
> +#define TPS65219_INT_BUCK1_RV_MASK			BIT(0)
> +#define TPS65219_INT_BUCK2_RV_MASK			BIT(1)
> +#define TPS65219_INT_BUCK3_RV_MASK			BIT(2)
> +#define TPS65219_INT_LDO1_RV_MASK			BIT(3)
> +#define TPS65219_INT_LDO2_RV_MASK			BIT(4)
> +#define TPS65219_INT_LDO3_RV_MASK			BIT(5)
> +#define TPS65219_INT_LDO4_RV_MASK			BIT(6)
> +/* Residual Voltage ShutDown */
> +#define TPS65219_INT_BUCK1_RV_SD_MASK			BIT(0)
> +#define TPS65219_INT_BUCK2_RV_SD_MASK			BIT(1)
> +#define TPS65219_INT_BUCK3_RV_SD_MASK			BIT(2)
> +#define TPS65219_INT_LDO1_RV_SD_MASK			BIT(3)
> +#define TPS65219_INT_LDO2_RV_SD_MASK			BIT(4)
> +#define TPS65219_INT_LDO3_RV_SD_MASK			BIT(5)
> +#define TPS65219_INT_LDO4_RV_SD_MASK			BIT(6)
> +#define TPS65219_INT_TIMEOUT_MASK			BIT(7)
> +/* Power Button */
> +#define TPS65219_INT_PB_FALLING_EDGE_DET_MASK		BIT(0)
> +#define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
> +#define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
> +
> +enum tps65219_regulator_id {
> +	/* DCDC's */
> +	TPS65219_BUCK_1,
> +	TPS65219_BUCK_2,
> +	TPS65219_BUCK_3,
> +	/* LDOs */
> +	TPS65219_LDO_1,
> +	TPS65219_LDO_2,
> +	TPS65219_LDO_3,
> +	TPS65219_LDO_4,
> +};
> +
> +#define TPS65219_MAX_REG_ID		TPS65219_LDO_4
> +
> +/* Number of step-down converters available */
> +#define TPS65219_NUM_DCDC		3
> +/* Number of LDO voltage regulators available */
> +#define TPS65219_NUM_LDO		4
> +/* Number of total regulators available */
> +#define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
> +
> +/**
> + * struct tps65219 - tps65219 sub-driver chip access routines
> + *
> + * Device data may be used to access the TPS65219 chip
> + */

This is not a complete kerneldoc header.

Please compile test with W=1.

> +struct tps65219 {
> +	struct device *dev;
> +	unsigned int id;
> +	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
> +	struct regmap *regmap;
> +	struct notifier_block nb;
> +};
> +
> +#endif /*  __LINUX_MFD_TPS65219_H */

-- 
DEPRECATED: Please use lee@kernel.org

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support
@ 2022-08-08 15:49     ` Lee Jones
  0 siblings, 0 replies; 36+ messages in thread
From: Lee Jones @ 2022-08-08 15:49 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	msp, j-keerthy, linux-kernel, devicetree, linux-arm-kernel,
	Lee Jones

On Tue, 26 Jul 2022, Jerome Neanne wrote:

> The TPS65219 is a power management IC PMIC designed
> to supply a wide range of SoCs
> in both portable and stationary applications.
> Any SoC can control TPS65219 over a standard I2C interface.

Really odd line break choices here.

> It contains the following components:
> - Regulators.
> - Over Temperature warning and Shut down.
> - GPIOs
> - Multi Function Pins (MFP)
> 
> This patch adds support for tps65219 mfd device. At this time only

No such thing as an MFD device, what is it?  PMIC, no?

> the functionalities listed below are made available:
> 
> - Regulators probe and functionalities
> - warm and cold reset support
> - SW shutdown support
> 
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  MAINTAINERS                  |   1 +
>  drivers/mfd/Kconfig          |  15 +++
>  drivers/mfd/Makefile         |   1 +
>  drivers/mfd/tps65219.c       | 214 +++++++++++++++++++++++++++++
>  include/linux/mfd/tps65219.h | 251 +++++++++++++++++++++++++++++++++++
>  5 files changed, 482 insertions(+)
>  create mode 100644 drivers/mfd/tps65219.c
>  create mode 100644 include/linux/mfd/tps65219.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 67850b321cbb..1331c43fc6ce 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14711,6 +14711,7 @@ F:	drivers/mfd/menelaus.c
>  F:	drivers/mfd/palmas.c
>  F:	drivers/mfd/tps65217.c
>  F:	drivers/mfd/tps65218.c
> +F:	drivers/mfd/tps65219.c
>  F:	drivers/mfd/tps65910.c
>  F:	drivers/mfd/twl-core.[ch]
>  F:	drivers/mfd/twl4030*.c
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 3b59456f5545..c66e56374a9a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1574,6 +1574,21 @@ config MFD_TPS65218
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called tps65218.
>  
> +config MFD_TPS65219
> +	tristate "TI TPS65219 Power Management chips"

Abbreviation is PMIC, please reflect that here.

s/chips/ICs/

> +	depends on I2C && OF
> +	select MFD_CORE
> +	select REGMAP_I2C
> +	select REGMAP_IRQ
> +	help
> +	  If you say yes here you get support for the TPS65219 series of
> +	  Power Management chips.

As above.

No need to line break here.

> +	  These include voltage regulators, gpio and other features

GPIO

What "other features"?

> +	  that are often used in portable devices.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called tps65219.
> +
>  config MFD_TPS6586X
>  	bool "TI TPS6586x Power Management chips"
>  	depends on I2C=y
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 858cacf659d6..a8ff3d6ea3ab 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
>  obj-$(CONFIG_MFD_TPS65086)	+= tps65086.o
>  obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
>  obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
> +obj-$(CONFIG_MFD_TPS65219)	+= tps65219.o
>  obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
>  obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
>  obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
> diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
> new file mode 100644
> index 000000000000..c3bf975ea6c7
> --- /dev/null
> +++ b/drivers/mfd/tps65219.c
> @@ -0,0 +1,214 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Driver for TPS65219 Integrated power management chipsets

"Power Management Integrated Chips (PMIC)"

> +//
> +// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> +//
> +// This implementation derived from tps65218 authored by
> +// "J Keerthy <j-keerthy@ti.com>"

Which he probably copied from elsewhere.

Please drop this line.

> +//

Drop this empty comment

Only C++ for the SPDX line please.

'\n' here.

> +#include <linux/kernel.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/init.h>
> +#include <linux/i2c.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/irq.h>
> +#include <linux/interrupt.h>
> +#include <linux/reboot.h>

Alphabetical

> +#include <linux/mfd/core.h>
> +#include <linux/mfd/tps65219.h>
> +
> +static struct i2c_client *tps65219_i2c_client;
> +
> +/**
> + * tps65219_warm_reset: issue warm reset to SOC.
> + *
> + * @tps: Device to write to.
> + */

Why Kerneldoc for static functions.

See: scripts/find-unused-docs.sh

> +static int tps65219_warm_reset(struct tps65219 *tps)
> +{
> +	dev_dbg(tps->dev, "warm reset");

No thank you.

And for all the other useless dev_dbg() prints that in this file which
no one is going to use.

> +	pr_flush(1000, true);

'\n'

> +	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
> +				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK,
> +				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK);
> +}
> +
> +/**
> + * tps65219_cold_reset: issue cold reset to SOC.
> + *
> + * @tps: Device to write to.
> + */
> +static int tps65219_cold_reset(struct tps65219 *tps)
> +{
> +	dev_dbg(tps->dev, "cold reset");
> +	pr_flush(1000, true);
> +	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
> +				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK,
> +				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
> +}
> +
> +/**
> + * tps65219_soft_shutdown: issue cold reset to SOC.
> + *
> + * @tps: Device to write to.
> + */
> +static int tps65219_soft_shutdown(struct tps65219 *tps)
> +{
> +	dev_dbg(tps->dev, "software shutdown");
> +	pr_flush(1000, true);
> +	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
> +				  TPS65219_MFP_I2C_OFF_REQ_MASK,
> +				  TPS65219_MFP_I2C_OFF_REQ_MASK);
> +}
> +
> +/**
> + * pmic_rst_restart: trig tps65219 reset to SOC.
> + *
> + * Trigged via notifier
> + */
> +static int pmic_rst_restart(struct notifier_block *this,
> +			    unsigned long reboot_mode, void *cmd)
> +{
> +	struct tps65219 *tps;
> +
> +	tps = container_of(this, struct tps65219, nb);
> +	if (!tps) {
> +		pr_err("%s: pointer to tps65219 is invalid\n", __func__);
> +		return -ENODEV;
> +	}
> +	if (reboot_mode == REBOOT_WARM)
> +		tps65219_warm_reset(tps);
> +	else
> +		tps65219_cold_reset(tps);
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block pmic_rst_restart_nb = {
> +	.notifier_call = pmic_rst_restart,
> +	.priority = 200,
> +};
> +
> +/**
> + * pmic_do_poweroff: trig tps65219 regulators power OFF sequence.
> + */
> +static void pmic_do_poweroff(void)
> +{
> +	struct tps65219 *tps;
> +
> +	tps = dev_get_drvdata(&tps65219_i2c_client->dev);
> +	tps65219_soft_shutdown(tps);
> +}

Would all of the above be better off in drivers/power?

> +static const struct mfd_cell tps65219_cells[] = {
> +	{ .name = "tps65219-regulator", },
> +};

One device, which isn't even a device, is not an MFD.

Where are the other devices?

They need to be added now, rather than later please.

> +static const struct regmap_config tps65219_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
> +};
> +
> +static const struct of_device_id of_tps65219_match_table[] = {
> +	{ .compatible = "ti,tps65219", },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, of_tps65219_match_table);

This usually goes at the bottom of the file.

> +static int tps65219_probe(struct i2c_client *client,
> +			  const struct i2c_device_id *ids)
> +{
> +	struct tps65219 *tps;
> +	int ret;

Normally placed at the bottom of the list.

> +	unsigned int chipid;
> +	bool sys_pwr;
> +
> +	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
> +	if (!tps)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(client, tps);

'\n'

> +	tps->dev = &client->dev;

'\n'

> +	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
> +	if (IS_ERR(tps->regmap)) {
> +		ret = PTR_ERR(tps->regmap);
> +		dev_err(tps->dev, "Failed to allocate register map: %d\n",
> +			ret);

No line break here please.

> +		return ret;
> +	}
> +
> +	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
> +	if (ret) {
> +		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
> +				   ARRAY_SIZE(tps65219_cells), NULL, 0,
> +				   NULL);

No line break on the 2nd line.

> +	if (ret) {
> +		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);

"Failed to add child devices"

> +		return ret;
> +	}
> +
> +	tps->nb = pmic_rst_restart_nb;
> +	ret = register_restart_handler(&tps->nb);
> +	if (ret) {
> +		dev_err(tps->dev, "%s: cannot register restart handler, %d\n",
> +			__func__, ret);

No __func__

> +		return -ENODEV;

Why not propagate 'ret'?

> +	}
> +
> +	sys_pwr = of_property_read_bool(tps->dev->of_node,
> +					"system-power-controller");

This will probably go onto one line (<100 chars)

> +	if (sys_pwr)

	if (!sys_power_controller)
		return 0;

> +		if (pm_power_off)
> +			dev_warn(tps->dev, "Setup as system-power-controller but pm_power_off function already registered, overwriting\n");

Is that really what you want?

What about the other driver that thinks it's the
system-power-controller? Seems wrong.

In any case, make this line as short / succinct as you can.

> +		tps65219_i2c_client = client;
> +		pm_power_off = &pmic_do_poweroff;
> +	}
> +	return ret;
> +}
> +
> +static int tps65219_remove(struct i2c_client *client)
> +{
> +	struct tps65219 *tps = i2c_get_clientdata(client);
> +
> +	if (tps65219_i2c_client == client) {
> +		pm_power_off = NULL;
> +		tps65219_i2c_client = NULL;
> +	}
> +
> +	return unregister_restart_handler(&tps->nb);
> +}
> +
> +static const struct i2c_device_id tps65219_id_table[] = {
> +	{ "tps65219", TPS65219 },

Do you use this param?

If not drop the whole table and use .probe_new.

> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, tps65219_id_table);
> +
> +static struct i2c_driver tps65219_driver = {
> +	.driver		= {
> +		.name	= "tps65219",
> +		.of_match_table = of_tps65219_match_table,
> +	},
> +	.probe		= tps65219_probe,
> +	.id_table       = tps65219_id_table,
> +	.remove		= tps65219_remove,
> +};
> +

Remove this line.

> +module_i2c_driver(tps65219_driver);
> +
> +MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
> +MODULE_DESCRIPTION("TPS65219 chip family multi-function driver");

Please change this description to something suggested above.

> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
> new file mode 100644
> index 000000000000..e9197ab8bc75
> --- /dev/null
> +++ b/include/linux/mfd/tps65219.h
> @@ -0,0 +1,251 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * linux/mfd/tps65219.h

No filenames please.  They tend to become unsynced.

> + * Functions to access TPS65219 power management chip.

As above.

> + * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> + */
> +
> +#ifndef __LINUX_MFD_TPS65219_H
> +#define __LINUX_MFD_TPS65219_H

LINUX?

> +#include <linux/i2c.h>
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/bitops.h>
> +#include <linux/regmap.h>

Alphabetical.

Some of these should probably be forward declarations, not includes.

> +#define TPS65219_1V35					1350000
> +#define TPS65219_1V8					1800000
> +
> +/* TPS chip id list */
> +#define TPS65219					0xF0
> +
> +/* I2C ID for TPS65219 part */
> +#define TPS65219_I2C_ID					0x24
> +
> +/* All register addresses */
> +#define TPS65219_REG_TI_DEV_ID				0x00
> +#define TPS65219_REG_NVM_ID				0x01
> +#define TPS65219_REG_ENABLE_CTRL			0x02
> +#define TPS65219_REG_BUCKS_CONFIG			0x03
> +#define TPS65219_REG_LDO4_VOUT				0x04
> +#define TPS65219_REG_LDO3_VOUT				0x05
> +#define TPS65219_REG_LDO2_VOUT				0x06
> +#define TPS65219_REG_LDO1_VOUT				0x07
> +#define TPS65219_REG_BUCK3_VOUT				0x8
> +#define TPS65219_REG_BUCK2_VOUT				0x9
> +#define TPS65219_REG_BUCK1_VOUT				0xA
> +#define TPS65219_REG_LDO4_SEQUENCE_SLOT			0xB
> +#define TPS65219_REG_LDO3_SEQUENCE_SLOT			0xC
> +#define TPS65219_REG_LDO2_SEQUENCE_SLOT			0xD
> +#define TPS65219_REG_LDO1_SEQUENCE_SLOT			0xE
> +#define TPS65219_REG_BUCK3_SEQUENCE_SLOT		0xF
> +#define TPS65219_REG_BUCK2_SEQUENCE_SLOT		0x10
> +#define TPS65219_REG_BUCK1_SEQUENCE_SLOT		0x11
> +#define TPS65219_REG_nRST_SEQUENCE_SLOT			0x12
> +#define TPS65219_REG_GPIO_SEQUENCE_SLOT			0x13
> +#define TPS65219_REG_GPO2_SEQUENCE_SLOT			0x14
> +#define TPS65219_REG_GPO1_SEQUENCE_SLOT			0x15
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_1		0x16
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_2		0x17
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_3		0x18
> +#define TPS65219_REG_POWER_UP_SLOT_DURATION_4		0x19
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_1		0x1A
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_2		0x1B
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_3		0x1C
> +#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_4		0x1D
> +#define TPS65219_REG_GENERAL_CONFIG			0x1E
> +#define TPS65219_REG_MFP_1_CONFIG			0x1F
> +#define TPS65219_REG_MFP_2_CONFIG			0x20
> +#define TPS65219_REG_STBY_1_CONFIG			0x21
> +#define TPS65219_REG_STBY_2_CONFIG			0x22
> +#define TPS65219_REG_OC_DEGL_CONFIG			0x23
> +/* 'sub irq' MASK registers */
> +#define TPS65219_REG_INT_MASK_UV			0x24
> +#define TPS65219_REG_MASK_CONFIG			0x25
> +
> +#define TPS65219_REG_I2C_ADDRESS_REG			0x26
> +#define TPS65219_REG_USER_GENERAL_NVM_STORAGE		0x27
> +#define TPS65219_REG_MANUFACTURING_VER			0x28
> +#define TPS65219_REG_MFP_CTRL				0x29
> +#define TPS65219_REG_DISCHARGE_CONFIG			0x2A
> +/* main irq registers */
> +#define TPS65219_REG_INT_SOURCE				0x2B
> +/* 'sub irq' registers */
> +#define TPS65219_REG_INT_LDO_3_4			0x2C
> +#define TPS65219_REG_INT_LDO_1_2			0x2D
> +#define TPS65219_REG_INT_BUCK_3				0x2E
> +#define TPS65219_REG_INT_BUCK_1_2			0x2F
> +#define TPS65219_REG_INT_SYSTEM				0x30
> +#define TPS65219_REG_INT_RV				0x31
> +#define TPS65219_REG_INT_TIMEOUT_RV_SD			0x32
> +#define TPS65219_REG_INT_PB				0x33
> +
> +#define TPS65219_REG_USER_NVM_CMD			0x34
> +#define TPS65219_REG_POWER_UP_STATUS			0x35
> +#define TPS65219_REG_SPARE_2				0x36
> +#define TPS65219_REG_SPARE_3				0x37
> +#define TPS65219_REG_FACTORY_CONFIG_2			0x41
> +
> +/* Register field definitions */
> +#define TPS65219_DEVID_REV_MASK				GENMASK(7, 0)
> +#define TPS65219_BUCKS_LDOS_VOUT_VSET_MASK		GENMASK(5, 0)
> +#define TPS65219_BUCKS_UV_THR_SEL_MASK			BIT(6)
> +#define TPS65219_BUCKS_BW_SEL_MASK			BIT(7)
> +#define LDO_BYP_SHIFT					6
> +#define TPS65219_LDOS_BYP_CONFIG_MASK			BIT(LDO_BYP_SHIFT)
> +#define TPS65219_LDOS_LSW_CONFIG_MASK			BIT(7)
> +/* Regulators enable control */
> +#define TPS65219_ENABLE_BUCK1_EN_MASK			BIT(0)
> +#define TPS65219_ENABLE_BUCK2_EN_MASK			BIT(1)
> +#define TPS65219_ENABLE_BUCK3_EN_MASK			BIT(2)
> +#define TPS65219_ENABLE_LDO1_EN_MASK			BIT(3)
> +#define TPS65219_ENABLE_LDO2_EN_MASK			BIT(4)
> +#define TPS65219_ENABLE_LDO3_EN_MASK			BIT(5)
> +#define TPS65219_ENABLE_LDO4_EN_MASK			BIT(6)
> +/* power ON-OFF sequence slot */
> +#define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK	GENMASK(3, 0)
> +#define TPS65219_BUCKS_LDOS_SEQUENCE_ON_SLOT_MASK	GENMASK(7, 4)
> +/* TODO: Not needed, same mapping as TPS65219_ENABLE_REGNAME_EN, factorize */
> +#define TPS65219_STBY1_BUCK1_STBY_EN_MASK		BIT(0)
> +#define TPS65219_STBY1_BUCK2_STBY_EN_MASK		BIT(1)
> +#define TPS65219_STBY1_BUCK3_STBY_EN_MASK		BIT(2)
> +#define TPS65219_STBY1_LDO1_STBY_EN_MASK		BIT(3)
> +#define TPS65219_STBY1_LDO2_STBY_EN_MASK		BIT(4)
> +#define TPS65219_STBY1_LDO3_STBY_EN_MASK		BIT(5)
> +#define TPS65219_STBY1_LDO4_STBY_EN_MASK		BIT(6)
> +/* STBY_2 config */
> +#define TPS65219_STBY2_GPO1_STBY_EN_MASK		BIT(0)
> +#define TPS65219_STBY2_GPO2_STBY_EN_MASK		BIT(1)
> +#define TPS65219_STBY2_GPIO_STBY_EN_MASK		BIT(2)
> +/* MFP Control */
> +#define TPS65219_MFP_I2C_OFF_REQ_MASK			BIT(0)
> +#define TPS65219_MFP_STBY_I2C_CTRL_MASK			BIT(1)
> +#define TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK		BIT(2)
> +#define TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK		BIT(3)
> +#define TPS65219_MFP_GPIO_STATUS_MASK			BIT(4)
> +/* MFP_1 Config */
> +#define TPS65219_MFP_1_VSEL_DDR_SEL_MASK		BIT(0)
> +#define TPS65219_MFP_1_VSEL_SD_POL_MASK			BIT(1)
> +#define TPS65219_MFP_1_VSEL_RAIL_MASK			BIT(2)
> +/* MFP_2 Config */
> +#define TPS65219_MFP_2_MODE_STBY_MASK			GENMASK(1, 0)
> +#define TPS65219_MFP_2_MODE_RESET_MASK			BIT(2)
> +#define TPS65219_MFP_2_EN_PB_VSENSE_DEGL_MASK		BIT(3)
> +#define TPS65219_MFP_2_EN_PB_VSENSE_MASK		GENMASK(5, 4)
> +#define TPS65219_MFP_2_WARM_COLD_RESET_MASK		BIT(6)
> +#define TPS65219_MFP_2_PU_ON_FSD_MASK			BIT(7)
> +#define TPS65219_MFP_2_EN				0
> +#define TPS65219_MFP_2_PB				BIT(4)
> +#define TPS65219_MFP_2_VSENSE				BIT(5)
> +/* MASK_UV Config */
> +#define TPS65219_REG_MASK_UV_LDO1_UV_MASK		BIT(0)
> +#define TPS65219_REG_MASK_UV_LDO2_UV_MASK		BIT(1)
> +#define TPS65219_REG_MASK_UV_LDO3_UV_MASK		BIT(2)
> +#define TPS65219_REG_MASK_UV_LDO4_UV_MASK		BIT(3)
> +#define TPS65219_REG_MASK_UV_BUCK1_UV_MASK		BIT(4)
> +#define TPS65219_REG_MASK_UV_BUCK2_UV_MASK		BIT(5)
> +#define TPS65219_REG_MASK_UV_BUCK3_UV_MASK		BIT(6)
> +#define TPS65219_REG_MASK_UV_RETRY_MASK			BIT(7)
> +/* MASK Config */
> +// SENSOR_N_WARM_MASK already defined in Thermal
> +#define TPS65219_REG_MASK_INT_FOR_RV_MASK		BIT(4)
> +#define TPS65219_REG_MASK_EFFECT_MASK			GENMASK(2, 1)
> +#define TPS65219_REG_MASK_INT_FOR_PB_MASK		BIT(7)
> +/* UnderVoltage - Short to GND - OverCurrent*/
> +/* LDO3-4 */
> +#define TPS65219_INT_LDO3_SCG_MASK			BIT(0)
> +#define TPS65219_INT_LDO3_OC_MASK			BIT(1)
> +#define TPS65219_INT_LDO3_UV_MASK			BIT(2)
> +#define TPS65219_INT_LDO4_SCG_MASK			BIT(3)
> +#define TPS65219_INT_LDO4_OC_MASK			BIT(4)
> +#define TPS65219_INT_LDO4_UV_MASK			BIT(5)
> +/* LDO1-2 */
> +#define TPS65219_INT_LDO1_SCG_MASK			BIT(0)
> +#define TPS65219_INT_LDO1_OC_MASK			BIT(1)
> +#define TPS65219_INT_LDO1_UV_MASK			BIT(2)
> +#define TPS65219_INT_LDO2_SCG_MASK			BIT(3)
> +#define TPS65219_INT_LDO2_OC_MASK			BIT(4)
> +#define TPS65219_INT_LDO2_UV_MASK			BIT(5)
> +/* BUCK3 */
> +#define TPS65219_INT_BUCK3_SCG_MASK			BIT(0)
> +#define TPS65219_INT_BUCK3_OC_MASK			BIT(1)
> +#define TPS65219_INT_BUCK3_NEG_OC_MASK			BIT(2)
> +#define TPS65219_INT_BUCK3_UV_MASK			BIT(3)
> +/* BUCK1-2 */
> +#define TPS65219_INT_BUCK1_SCG_MASK			BIT(0)
> +#define TPS65219_INT_BUCK1_OC_MASK			BIT(1)
> +#define TPS65219_INT_BUCK1_NEG_OC_MASK			BIT(2)
> +#define TPS65219_INT_BUCK1_UV_MASK			BIT(3)
> +#define TPS65219_INT_BUCK2_SCG_MASK			BIT(4)
> +#define TPS65219_INT_BUCK2_OC_MASK			BIT(5)
> +#define TPS65219_INT_BUCK2_NEG_OC_MASK			BIT(6)
> +#define TPS65219_INT_BUCK2_UV_MASK			BIT(7)
> +/* Thermal Sensor  */
> +#define TPS65219_INT_SENSOR_3_WARM_MASK			BIT(0)
> +#define TPS65219_INT_SENSOR_2_WARM_MASK			BIT(1)
> +#define TPS65219_INT_SENSOR_1_WARM_MASK			BIT(2)
> +#define TPS65219_INT_SENSOR_0_WARM_MASK			BIT(3)
> +#define TPS65219_INT_SENSOR_3_HOT_MASK			BIT(4)
> +#define TPS65219_INT_SENSOR_2_HOT_MASK			BIT(5)
> +#define TPS65219_INT_SENSOR_1_HOT_MASK			BIT(6)
> +#define TPS65219_INT_SENSOR_0_HOT_MASK			BIT(7)
> +/* Residual Voltage */
> +#define TPS65219_INT_BUCK1_RV_MASK			BIT(0)
> +#define TPS65219_INT_BUCK2_RV_MASK			BIT(1)
> +#define TPS65219_INT_BUCK3_RV_MASK			BIT(2)
> +#define TPS65219_INT_LDO1_RV_MASK			BIT(3)
> +#define TPS65219_INT_LDO2_RV_MASK			BIT(4)
> +#define TPS65219_INT_LDO3_RV_MASK			BIT(5)
> +#define TPS65219_INT_LDO4_RV_MASK			BIT(6)
> +/* Residual Voltage ShutDown */
> +#define TPS65219_INT_BUCK1_RV_SD_MASK			BIT(0)
> +#define TPS65219_INT_BUCK2_RV_SD_MASK			BIT(1)
> +#define TPS65219_INT_BUCK3_RV_SD_MASK			BIT(2)
> +#define TPS65219_INT_LDO1_RV_SD_MASK			BIT(3)
> +#define TPS65219_INT_LDO2_RV_SD_MASK			BIT(4)
> +#define TPS65219_INT_LDO3_RV_SD_MASK			BIT(5)
> +#define TPS65219_INT_LDO4_RV_SD_MASK			BIT(6)
> +#define TPS65219_INT_TIMEOUT_MASK			BIT(7)
> +/* Power Button */
> +#define TPS65219_INT_PB_FALLING_EDGE_DET_MASK		BIT(0)
> +#define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
> +#define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
> +
> +enum tps65219_regulator_id {
> +	/* DCDC's */
> +	TPS65219_BUCK_1,
> +	TPS65219_BUCK_2,
> +	TPS65219_BUCK_3,
> +	/* LDOs */
> +	TPS65219_LDO_1,
> +	TPS65219_LDO_2,
> +	TPS65219_LDO_3,
> +	TPS65219_LDO_4,
> +};
> +
> +#define TPS65219_MAX_REG_ID		TPS65219_LDO_4
> +
> +/* Number of step-down converters available */
> +#define TPS65219_NUM_DCDC		3
> +/* Number of LDO voltage regulators available */
> +#define TPS65219_NUM_LDO		4
> +/* Number of total regulators available */
> +#define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
> +
> +/**
> + * struct tps65219 - tps65219 sub-driver chip access routines
> + *
> + * Device data may be used to access the TPS65219 chip
> + */

This is not a complete kerneldoc header.

Please compile test with W=1.

> +struct tps65219 {
> +	struct device *dev;
> +	unsigned int id;
> +	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
> +	struct regmap *regmap;
> +	struct notifier_block nb;
> +};
> +
> +#endif /*  __LINUX_MFD_TPS65219_H */

-- 
DEPRECATED: Please use lee@kernel.org

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 07/11] mfd: drivers: Add interrupts support to TI TPS65219 PMIC
  2022-07-26 10:33   ` Jerome Neanne
@ 2022-08-08 15:57     ` Lee Jones
  -1 siblings, 0 replies; 36+ messages in thread
From: Lee Jones @ 2022-08-08 15:57 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	msp, j-keerthy, linux-kernel, devicetree, linux-arm-kernel,
	Lee Jones

On Tue, 26 Jul 2022, Jerome Neanne wrote:

> Add TPS65219 support for interrupts through regmap_irq_chip

Why is this separate to the original patch?

> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  drivers/mfd/tps65219.c       | 217 ++++++++++++++++++++++++++++++++++-
>  include/linux/mfd/tps65219.h | 113 ++++++++++++++++++
>  2 files changed, 328 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
> index c3bf975ea6c7..7366f251c21d 100644
> --- a/drivers/mfd/tps65219.c
> +++ b/drivers/mfd/tps65219.c
> @@ -107,8 +107,73 @@ static void pmic_do_poweroff(void)
>  	tps65219_soft_shutdown(tps);
>  }
>  
> -static const struct mfd_cell tps65219_cells[] = {
> -	{ .name = "tps65219-regulator", },
> +static const struct resource tps65219_pwrbutton_resources[] = {
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
> +};
> +
> +static const struct resource tps65219_regulator_resources[] = {
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_UV, "LDO3_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_SCG, "LDO4_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_OC, "LDO4_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_UV, "LDO4_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV, "LDO2_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV, "LDO3_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV, "LDO4_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV_SD, "LDO3_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV_SD, "LDO4_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
> +};
> +
> +#define TPS65219_MAX_CELLS 2

Where is this even used?

> +static const struct mfd_cell tps65219_regulator_cell = {
> +	.name = "tps65219-regulator",
> +	.resources = tps65219_regulator_resources,
> +	.num_resources = ARRAY_SIZE(tps65219_regulator_resources),
> +};
> +
> +static const struct mfd_cell tps65219_pwrbutton_cell = {
> +	.name = "tps65219-pwrbutton",
> +	.resources = tps65219_pwrbutton_resources,
> +	.num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
>  };
>  
>  static const struct regmap_config tps65219_regmap_config = {
> @@ -117,6 +182,147 @@ static const struct regmap_config tps65219_regmap_config = {
>  	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
>  };
>  
> +/*
> + * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
> + * access corect sub-IRQ registers based on bits that are set in main IRQ
> + * register.
> + */
> +/* Timeout Residual Voltage Shutdown */
> +static unsigned int bit0_offsets[] = {TPS65219_TO_RV_POS};
> +static unsigned int bit1_offsets[] = {TPS65219_RV_POS};	/* Residual Voltage */
> +static unsigned int bit2_offsets[] = {TPS65219_SYS_POS};	/* System */
> +static unsigned int bit3_offsets[] = {TPS65219_BUCK_1_2_POS};	/* Buck 1-2 */
> +static unsigned int bit4_offsets[] = {TPS65219_BUCK_3_POS};	/* Buck 3 */
> +static unsigned int bit5_offsets[] = {TPS65219_LDO_1_2_POS};	/* LDO 1-2 */
> +static unsigned int bit6_offsets[] = {TPS65219_LDO_3_4_POS};	/* LDO 3-4 */
> +static unsigned int bit7_offsets[] = {TPS65219_PB_POS};	/* Power Button */

Well this is a pretty miserable interface.

You probably need spaces after { and before }.

> +static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
> +};
> +
> +static struct regmap_irq tps65219_irqs[] = {
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO3_SCG_MASK),

One line please.

> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC,
> +		       TPS65219_LDO_3_4_POS, TPS65219_INT_LDO3_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_UV, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO3_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_SCG, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO4_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_OC, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO4_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_UV, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO4_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG,
> +		       TPS65219_LDO_1_2_POS, TPS65219_INT_LDO1_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO1_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO1_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO2_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO2_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO2_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_NEG_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_NEG_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_NEG_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM,
> +		       TPS65219_SYS_POS, TPS65219_INT_SENSOR_3_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_2_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_1_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_0_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_3_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_2_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_1_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_0_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_BUCK1_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_BUCK2_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_BUCK3_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO1_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO2_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO3_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO4_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD,
> +		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK1_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD,
> +		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK2_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_BUCK3_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_LDO1_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_LDO2_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV_SD,
> +		       TPS65219_TO_RV_POS, TPS65219_INT_LDO3_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_LDO4_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_TIMEOUT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT,
> +		       TPS65219_PB_POS, TPS65219_INT_PB_FALLING_EDGE_DET_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_PB_POS,
> +		       TPS65219_INT_PB_RISING_EDGE_DET_MASK),
> +};
> +
> +static struct regmap_irq_chip tps65219_irq_chip = {
> +	.name = "tps65219_irq",
> +	.main_status = TPS65219_REG_INT_SOURCE,
> +	.num_main_regs = 1,
> +	.num_main_status_bits = 8,
> +	.irqs = tps65219_irqs,
> +	.num_irqs = ARRAY_SIZE(tps65219_irqs),
> +	.status_base = TPS65219_REG_INT_LDO_3_4,
> +	.ack_base = TPS65219_REG_INT_LDO_3_4,
> +	.clear_ack = 1,
> +	.num_regs = 8,
> +	.sub_reg_offsets = &tps65219_sub_irq_offsets[0],
> +};
> +
>  static const struct of_device_id of_tps65219_match_table[] = {
>  	{ .compatible = "ti,tps65219", },
>  	{}
> @@ -137,6 +343,7 @@ static int tps65219_probe(struct i2c_client *client,
>  
>  	i2c_set_clientdata(client, tps);
>  	tps->dev = &client->dev;
> +	tps->irq = client->irq;

Is this used again beyond devm_regmap_add_irq_chip()?

>  	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
>  	if (IS_ERR(tps->regmap)) {
>  		ret = PTR_ERR(tps->regmap);
> @@ -145,6 +352,12 @@ static int tps65219_probe(struct i2c_client *client,
>  		return ret;
>  	}
>  
> +	ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, tps->irq,
> +				       IRQF_ONESHOT, 0, &tps65219_irq_chip,
> +				       &tps->irq_data);

2 lines.

> +	if (ret)
> +		return ret;
> +
>  	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
>  	if (ret) {
>  		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
> diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
> index e9197ab8bc75..8cecaf9bc682 100644
> --- a/include/linux/mfd/tps65219.h
> +++ b/include/linux/mfd/tps65219.h
> @@ -214,6 +214,104 @@
>  #define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
>  #define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
>  
> +/* Masks for main IRQ register bits */
> +enum {
> +	TPS65219_INT_TIMEOUT_RV_SD,
> +#define TPS65219_INT_TIMEOUT_RV_SD_MASK BIT(TPS65219_INT_TIMEOUT_RV_SD)
> +	TPS65219_INT_RV,
> +#define TPS65219_INT_RV_MASK BIT(TPS65219_INT_RV)
> +	TPS65219_INT_SYSTEM,
> +#define TPS65219_INT_SYSTEM_MASK BIT(TPS65219_INT_SYSTEM)
> +	TPS65219_INT_BUCK_1_2,
> +#define TPS65219_INT_BUCK_1_2_MASK BIT(TPS65219_INT_BUCK_1_2)
> +	TPS65219_INT_BUCK_3,
> +#define TPS65219_INT_BUCK_3_MASK BIT(TPS65219_INT_BUCK_3)
> +	TPS65219_INT_LDO_1_2,
> +#define TPS65219_INT_LDO_1_2_MASK BIT(TPS65219_INT_LDO_1_2)
> +	TPS65219_INT_LDO_3_4,
> +#define TPS65219_INT_LDO_3_4_MASK BIT(TPS65219_LDO_3_4)
> +	TPS65219_INT_PB,
> +#define TPS65219_INT_PB_MASK BIT(TPS65219_INT_PB)

Where are these horrid defines used?

Can't you just use the BIT() macros.  We know what they mean.

> +};
> +
> +/* Timeout Residual Voltage Shutdown */

If you used nice nomenclature, you wouldn't need the comments.

> +#define TPS65219_TO_RV_POS 6
> +/* Residual Voltage */
> +#define TPS65219_RV_POS 5
> +/* System */
> +#define TPS65219_SYS_POS 4
> +/* Buck 1-2 */
> +#define TPS65219_BUCK_1_2_POS 3
> +/* Buck 3 */
> +#define TPS65219_BUCK_3_POS 2
> +/* LDO 1-2 */
> +#define TPS65219_LDO_1_2_POS 1
> +/* LDO 3-4 */
> +#define TPS65219_LDO_3_4_POS 0
> +/* Power Button */
> +#define TPS65219_PB_POS 7
> +
> +/* IRQs */
> +enum {
> +	/* LDO3-4 register IRQs */
> +	TPS65219_INT_LDO3_SCG,
> +	TPS65219_INT_LDO3_OC,
> +	TPS65219_INT_LDO3_UV,
> +	TPS65219_INT_LDO4_SCG,
> +	TPS65219_INT_LDO4_OC,
> +	TPS65219_INT_LDO4_UV,
> +	/* LDO1-2 */
> +	TPS65219_INT_LDO1_SCG,
> +	TPS65219_INT_LDO1_OC,
> +	TPS65219_INT_LDO1_UV,
> +	TPS65219_INT_LDO2_SCG,
> +	TPS65219_INT_LDO2_OC,
> +	TPS65219_INT_LDO2_UV,
> +	/* BUCK3 */
> +	TPS65219_INT_BUCK3_SCG,
> +	TPS65219_INT_BUCK3_OC,
> +	TPS65219_INT_BUCK3_NEG_OC,
> +	TPS65219_INT_BUCK3_UV,
> +	/* BUCK1-2 */
> +	TPS65219_INT_BUCK1_SCG,
> +	TPS65219_INT_BUCK1_OC,
> +	TPS65219_INT_BUCK1_NEG_OC,
> +	TPS65219_INT_BUCK1_UV,
> +	TPS65219_INT_BUCK2_SCG,
> +	TPS65219_INT_BUCK2_OC,
> +	TPS65219_INT_BUCK2_NEG_OC,
> +	TPS65219_INT_BUCK2_UV,
> +	/* Thermal Sensor  */
> +	TPS65219_INT_SENSOR_3_WARM,
> +	TPS65219_INT_SENSOR_2_WARM,
> +	TPS65219_INT_SENSOR_1_WARM,
> +	TPS65219_INT_SENSOR_0_WARM,
> +	TPS65219_INT_SENSOR_3_HOT,
> +	TPS65219_INT_SENSOR_2_HOT,
> +	TPS65219_INT_SENSOR_1_HOT,
> +	TPS65219_INT_SENSOR_0_HOT,
> +	/* Residual Voltage */
> +	TPS65219_INT_BUCK1_RV,
> +	TPS65219_INT_BUCK2_RV,
> +	TPS65219_INT_BUCK3_RV,
> +	TPS65219_INT_LDO1_RV,
> +	TPS65219_INT_LDO2_RV,
> +	TPS65219_INT_LDO3_RV,
> +	TPS65219_INT_LDO4_RV,
> +	/* Residual Voltage ShutDown */
> +	TPS65219_INT_BUCK1_RV_SD,
> +	TPS65219_INT_BUCK2_RV_SD,
> +	TPS65219_INT_BUCK3_RV_SD,
> +	TPS65219_INT_LDO1_RV_SD,
> +	TPS65219_INT_LDO2_RV_SD,
> +	TPS65219_INT_LDO3_RV_SD,
> +	TPS65219_INT_LDO4_RV_SD,
> +	TPS65219_INT_TIMEOUT,
> +	/* Power Button */
> +	TPS65219_INT_PB_FALLING_EDGE_DETECT,
> +	TPS65219_INT_PB_RISING_EDGE_DETECT,
> +};
> +
>  enum tps65219_regulator_id {
>  	/* DCDC's */
>  	TPS65219_BUCK_1,
> @@ -235,6 +333,19 @@ enum tps65219_regulator_id {
>  /* Number of total regulators available */
>  #define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
>  
> +/* Define the TPS65219 IRQ numbers */
> +enum tps65219_irqs {
> +	/* INT source registers */
> +	TPS65219_TO_RV_SD_SET_IRQ,
> +	TPS65219_RV_SET_IRQ,
> +	TPS65219_SYS_SET_IRQ,
> +	TPS65219_BUCK_1_2_SET_IRQ,
> +	TPS65219_BUCK_3_SET_IRQ,
> +	TPS65219_LDO_1_2_SET_IRQ,
> +	TPS65219_LDO_3_4_SET_IRQ,
> +	TPS65219_PB_SET_IRQ,
> +};
> +
>  /**
>   * struct tps65219 - tps65219 sub-driver chip access routines
>   *
> @@ -243,6 +354,8 @@ enum tps65219_regulator_id {
>  struct tps65219 {
>  	struct device *dev;
>  	unsigned int id;
> +	int irq;
> +	struct regmap_irq_chip_data *irq_data;
>  	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
>  	struct regmap *regmap;
>  	struct notifier_block nb;

-- 
DEPRECATED: Please use lee@kernel.org

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 07/11] mfd: drivers: Add interrupts support to TI TPS65219 PMIC
@ 2022-08-08 15:57     ` Lee Jones
  0 siblings, 0 replies; 36+ messages in thread
From: Lee Jones @ 2022-08-08 15:57 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	msp, j-keerthy, linux-kernel, devicetree, linux-arm-kernel,
	Lee Jones

On Tue, 26 Jul 2022, Jerome Neanne wrote:

> Add TPS65219 support for interrupts through regmap_irq_chip

Why is this separate to the original patch?

> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  drivers/mfd/tps65219.c       | 217 ++++++++++++++++++++++++++++++++++-
>  include/linux/mfd/tps65219.h | 113 ++++++++++++++++++
>  2 files changed, 328 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
> index c3bf975ea6c7..7366f251c21d 100644
> --- a/drivers/mfd/tps65219.c
> +++ b/drivers/mfd/tps65219.c
> @@ -107,8 +107,73 @@ static void pmic_do_poweroff(void)
>  	tps65219_soft_shutdown(tps);
>  }
>  
> -static const struct mfd_cell tps65219_cells[] = {
> -	{ .name = "tps65219-regulator", },
> +static const struct resource tps65219_pwrbutton_resources[] = {
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
> +};
> +
> +static const struct resource tps65219_regulator_resources[] = {
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_UV, "LDO3_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_SCG, "LDO4_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_OC, "LDO4_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_UV, "LDO4_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV, "LDO2_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV, "LDO3_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV, "LDO4_RV"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV_SD, "LDO3_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV_SD, "LDO4_RV_SD"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
> +	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
> +};
> +
> +#define TPS65219_MAX_CELLS 2

Where is this even used?

> +static const struct mfd_cell tps65219_regulator_cell = {
> +	.name = "tps65219-regulator",
> +	.resources = tps65219_regulator_resources,
> +	.num_resources = ARRAY_SIZE(tps65219_regulator_resources),
> +};
> +
> +static const struct mfd_cell tps65219_pwrbutton_cell = {
> +	.name = "tps65219-pwrbutton",
> +	.resources = tps65219_pwrbutton_resources,
> +	.num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
>  };
>  
>  static const struct regmap_config tps65219_regmap_config = {
> @@ -117,6 +182,147 @@ static const struct regmap_config tps65219_regmap_config = {
>  	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
>  };
>  
> +/*
> + * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
> + * access corect sub-IRQ registers based on bits that are set in main IRQ
> + * register.
> + */
> +/* Timeout Residual Voltage Shutdown */
> +static unsigned int bit0_offsets[] = {TPS65219_TO_RV_POS};
> +static unsigned int bit1_offsets[] = {TPS65219_RV_POS};	/* Residual Voltage */
> +static unsigned int bit2_offsets[] = {TPS65219_SYS_POS};	/* System */
> +static unsigned int bit3_offsets[] = {TPS65219_BUCK_1_2_POS};	/* Buck 1-2 */
> +static unsigned int bit4_offsets[] = {TPS65219_BUCK_3_POS};	/* Buck 3 */
> +static unsigned int bit5_offsets[] = {TPS65219_LDO_1_2_POS};	/* LDO 1-2 */
> +static unsigned int bit6_offsets[] = {TPS65219_LDO_3_4_POS};	/* LDO 3-4 */
> +static unsigned int bit7_offsets[] = {TPS65219_PB_POS};	/* Power Button */

Well this is a pretty miserable interface.

You probably need spaces after { and before }.

> +static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
> +	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
> +};
> +
> +static struct regmap_irq tps65219_irqs[] = {
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO3_SCG_MASK),

One line please.

> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC,
> +		       TPS65219_LDO_3_4_POS, TPS65219_INT_LDO3_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_UV, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO3_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_SCG, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO4_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_OC, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO4_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_UV, TPS65219_LDO_3_4_POS,
> +		       TPS65219_INT_LDO4_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG,
> +		       TPS65219_LDO_1_2_POS, TPS65219_INT_LDO1_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO1_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO1_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO2_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO2_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65219_LDO_1_2_POS,
> +		       TPS65219_INT_LDO2_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_NEG_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_BUCK_3_POS,
> +		       TPS65219_INT_BUCK3_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_NEG_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK2_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_SCG_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_NEG_OC_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_BUCK_1_2_POS,
> +		       TPS65219_INT_BUCK1_UV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM,
> +		       TPS65219_SYS_POS, TPS65219_INT_SENSOR_3_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_2_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_1_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_0_WARM_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_3_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_2_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_1_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_SYS_POS,
> +		       TPS65219_INT_SENSOR_0_HOT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_BUCK1_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_BUCK2_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_BUCK3_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO1_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO2_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO3_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV, TPS65219_RV_POS,
> +		       TPS65219_INT_LDO4_RV_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD,
> +		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK1_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD,
> +		       TPS65219_TO_RV_POS, TPS65219_INT_BUCK2_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_BUCK3_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_LDO1_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_LDO2_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV_SD,
> +		       TPS65219_TO_RV_POS, TPS65219_INT_LDO3_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV_SD, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_LDO4_RV_SD_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_TO_RV_POS,
> +		       TPS65219_INT_TIMEOUT_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT,
> +		       TPS65219_PB_POS, TPS65219_INT_PB_FALLING_EDGE_DET_MASK),
> +	REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_PB_POS,
> +		       TPS65219_INT_PB_RISING_EDGE_DET_MASK),
> +};
> +
> +static struct regmap_irq_chip tps65219_irq_chip = {
> +	.name = "tps65219_irq",
> +	.main_status = TPS65219_REG_INT_SOURCE,
> +	.num_main_regs = 1,
> +	.num_main_status_bits = 8,
> +	.irqs = tps65219_irqs,
> +	.num_irqs = ARRAY_SIZE(tps65219_irqs),
> +	.status_base = TPS65219_REG_INT_LDO_3_4,
> +	.ack_base = TPS65219_REG_INT_LDO_3_4,
> +	.clear_ack = 1,
> +	.num_regs = 8,
> +	.sub_reg_offsets = &tps65219_sub_irq_offsets[0],
> +};
> +
>  static const struct of_device_id of_tps65219_match_table[] = {
>  	{ .compatible = "ti,tps65219", },
>  	{}
> @@ -137,6 +343,7 @@ static int tps65219_probe(struct i2c_client *client,
>  
>  	i2c_set_clientdata(client, tps);
>  	tps->dev = &client->dev;
> +	tps->irq = client->irq;

Is this used again beyond devm_regmap_add_irq_chip()?

>  	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
>  	if (IS_ERR(tps->regmap)) {
>  		ret = PTR_ERR(tps->regmap);
> @@ -145,6 +352,12 @@ static int tps65219_probe(struct i2c_client *client,
>  		return ret;
>  	}
>  
> +	ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, tps->irq,
> +				       IRQF_ONESHOT, 0, &tps65219_irq_chip,
> +				       &tps->irq_data);

2 lines.

> +	if (ret)
> +		return ret;
> +
>  	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
>  	if (ret) {
>  		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
> diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
> index e9197ab8bc75..8cecaf9bc682 100644
> --- a/include/linux/mfd/tps65219.h
> +++ b/include/linux/mfd/tps65219.h
> @@ -214,6 +214,104 @@
>  #define TPS65219_INT_PB_RISING_EDGE_DET_MASK		BIT(1)
>  #define TPS65219_INT_PB_REAL_TIME_STATUS_MASK		BIT(2)
>  
> +/* Masks for main IRQ register bits */
> +enum {
> +	TPS65219_INT_TIMEOUT_RV_SD,
> +#define TPS65219_INT_TIMEOUT_RV_SD_MASK BIT(TPS65219_INT_TIMEOUT_RV_SD)
> +	TPS65219_INT_RV,
> +#define TPS65219_INT_RV_MASK BIT(TPS65219_INT_RV)
> +	TPS65219_INT_SYSTEM,
> +#define TPS65219_INT_SYSTEM_MASK BIT(TPS65219_INT_SYSTEM)
> +	TPS65219_INT_BUCK_1_2,
> +#define TPS65219_INT_BUCK_1_2_MASK BIT(TPS65219_INT_BUCK_1_2)
> +	TPS65219_INT_BUCK_3,
> +#define TPS65219_INT_BUCK_3_MASK BIT(TPS65219_INT_BUCK_3)
> +	TPS65219_INT_LDO_1_2,
> +#define TPS65219_INT_LDO_1_2_MASK BIT(TPS65219_INT_LDO_1_2)
> +	TPS65219_INT_LDO_3_4,
> +#define TPS65219_INT_LDO_3_4_MASK BIT(TPS65219_LDO_3_4)
> +	TPS65219_INT_PB,
> +#define TPS65219_INT_PB_MASK BIT(TPS65219_INT_PB)

Where are these horrid defines used?

Can't you just use the BIT() macros.  We know what they mean.

> +};
> +
> +/* Timeout Residual Voltage Shutdown */

If you used nice nomenclature, you wouldn't need the comments.

> +#define TPS65219_TO_RV_POS 6
> +/* Residual Voltage */
> +#define TPS65219_RV_POS 5
> +/* System */
> +#define TPS65219_SYS_POS 4
> +/* Buck 1-2 */
> +#define TPS65219_BUCK_1_2_POS 3
> +/* Buck 3 */
> +#define TPS65219_BUCK_3_POS 2
> +/* LDO 1-2 */
> +#define TPS65219_LDO_1_2_POS 1
> +/* LDO 3-4 */
> +#define TPS65219_LDO_3_4_POS 0
> +/* Power Button */
> +#define TPS65219_PB_POS 7
> +
> +/* IRQs */
> +enum {
> +	/* LDO3-4 register IRQs */
> +	TPS65219_INT_LDO3_SCG,
> +	TPS65219_INT_LDO3_OC,
> +	TPS65219_INT_LDO3_UV,
> +	TPS65219_INT_LDO4_SCG,
> +	TPS65219_INT_LDO4_OC,
> +	TPS65219_INT_LDO4_UV,
> +	/* LDO1-2 */
> +	TPS65219_INT_LDO1_SCG,
> +	TPS65219_INT_LDO1_OC,
> +	TPS65219_INT_LDO1_UV,
> +	TPS65219_INT_LDO2_SCG,
> +	TPS65219_INT_LDO2_OC,
> +	TPS65219_INT_LDO2_UV,
> +	/* BUCK3 */
> +	TPS65219_INT_BUCK3_SCG,
> +	TPS65219_INT_BUCK3_OC,
> +	TPS65219_INT_BUCK3_NEG_OC,
> +	TPS65219_INT_BUCK3_UV,
> +	/* BUCK1-2 */
> +	TPS65219_INT_BUCK1_SCG,
> +	TPS65219_INT_BUCK1_OC,
> +	TPS65219_INT_BUCK1_NEG_OC,
> +	TPS65219_INT_BUCK1_UV,
> +	TPS65219_INT_BUCK2_SCG,
> +	TPS65219_INT_BUCK2_OC,
> +	TPS65219_INT_BUCK2_NEG_OC,
> +	TPS65219_INT_BUCK2_UV,
> +	/* Thermal Sensor  */
> +	TPS65219_INT_SENSOR_3_WARM,
> +	TPS65219_INT_SENSOR_2_WARM,
> +	TPS65219_INT_SENSOR_1_WARM,
> +	TPS65219_INT_SENSOR_0_WARM,
> +	TPS65219_INT_SENSOR_3_HOT,
> +	TPS65219_INT_SENSOR_2_HOT,
> +	TPS65219_INT_SENSOR_1_HOT,
> +	TPS65219_INT_SENSOR_0_HOT,
> +	/* Residual Voltage */
> +	TPS65219_INT_BUCK1_RV,
> +	TPS65219_INT_BUCK2_RV,
> +	TPS65219_INT_BUCK3_RV,
> +	TPS65219_INT_LDO1_RV,
> +	TPS65219_INT_LDO2_RV,
> +	TPS65219_INT_LDO3_RV,
> +	TPS65219_INT_LDO4_RV,
> +	/* Residual Voltage ShutDown */
> +	TPS65219_INT_BUCK1_RV_SD,
> +	TPS65219_INT_BUCK2_RV_SD,
> +	TPS65219_INT_BUCK3_RV_SD,
> +	TPS65219_INT_LDO1_RV_SD,
> +	TPS65219_INT_LDO2_RV_SD,
> +	TPS65219_INT_LDO3_RV_SD,
> +	TPS65219_INT_LDO4_RV_SD,
> +	TPS65219_INT_TIMEOUT,
> +	/* Power Button */
> +	TPS65219_INT_PB_FALLING_EDGE_DETECT,
> +	TPS65219_INT_PB_RISING_EDGE_DETECT,
> +};
> +
>  enum tps65219_regulator_id {
>  	/* DCDC's */
>  	TPS65219_BUCK_1,
> @@ -235,6 +333,19 @@ enum tps65219_regulator_id {
>  /* Number of total regulators available */
>  #define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
>  
> +/* Define the TPS65219 IRQ numbers */
> +enum tps65219_irqs {
> +	/* INT source registers */
> +	TPS65219_TO_RV_SD_SET_IRQ,
> +	TPS65219_RV_SET_IRQ,
> +	TPS65219_SYS_SET_IRQ,
> +	TPS65219_BUCK_1_2_SET_IRQ,
> +	TPS65219_BUCK_3_SET_IRQ,
> +	TPS65219_LDO_1_2_SET_IRQ,
> +	TPS65219_LDO_3_4_SET_IRQ,
> +	TPS65219_PB_SET_IRQ,
> +};
> +
>  /**
>   * struct tps65219 - tps65219 sub-driver chip access routines
>   *
> @@ -243,6 +354,8 @@ enum tps65219_regulator_id {
>  struct tps65219 {
>  	struct device *dev;
>  	unsigned int id;
> +	int irq;
> +	struct regmap_irq_chip_data *irq_data;
>  	struct regulator_desc desc[TPS65219_NUM_REGULATOR];
>  	struct regmap *regmap;
>  	struct notifier_block nb;

-- 
DEPRECATED: Please use lee@kernel.org

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 08/11] mfd: tps65219: Add power-button support
  2022-07-26 10:33   ` Jerome Neanne
@ 2022-08-08 16:05     ` Lee Jones
  -1 siblings, 0 replies; 36+ messages in thread
From: Lee Jones @ 2022-08-08 16:05 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	msp, j-keerthy, linux-kernel, devicetree, linux-arm-kernel,
	Lee Jones

On Tue, 26 Jul 2022, Jerome Neanne wrote:

> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> Using a power-button on the EN/PB/VSENSE pin of TPS65219 is optional, so
> this driver adds the mfd cell for tps65219-pwrbutton only if needed. Two
> interrupts are passed to the driver.

Power button support was already added in the previous patch.

> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  drivers/mfd/tps65219.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
> index 7366f251c21d..e1c30a49bf08 100644
> --- a/drivers/mfd/tps65219.c
> +++ b/drivers/mfd/tps65219.c
> @@ -335,7 +335,10 @@ static int tps65219_probe(struct i2c_client *client,
>  	struct tps65219 *tps;
>  	int ret;
>  	unsigned int chipid;
> +	bool pwr_button;
>  	bool sys_pwr;
> +	struct mfd_cell cells[TPS65219_MAX_CELLS];
> +	int nr_cells = 0;
>  
>  	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
>  	if (!tps)
> @@ -364,9 +367,16 @@ static int tps65219_probe(struct i2c_client *client,
>  		return ret;
>  	}
>  
> -	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
> -				   ARRAY_SIZE(tps65219_cells), NULL, 0,
> -				   NULL);
> +	memcpy(&cells[nr_cells++], &tps65219_regulator_cell,
> +	       sizeof(tps65219_regulator_cell));
> +	pwr_button = of_property_read_bool(tps->dev->of_node, "power-button");
> +	if (pwr_button)
> +		memcpy(&cells[nr_cells++], &tps65219_pwrbutton_cell,
> +		       sizeof(tps65219_pwrbutton_cell));

Gross, no way.

Please call devm_mfd_add_devices() twice.

> +	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, cells,
> +				   nr_cells, NULL, 0,
> +				   regmap_irq_get_domain(tps->irq_data));
>  	if (ret) {
>  		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
>  		return ret;

-- 
DEPRECATED: Please use lee@kernel.org

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 08/11] mfd: tps65219: Add power-button support
@ 2022-08-08 16:05     ` Lee Jones
  0 siblings, 0 replies; 36+ messages in thread
From: Lee Jones @ 2022-08-08 16:05 UTC (permalink / raw)
  To: Jerome Neanne
  Cc: lgirdwood, broonie, robh+dt, nm, kristo, khilman, narmstrong,
	msp, j-keerthy, linux-kernel, devicetree, linux-arm-kernel,
	Lee Jones

On Tue, 26 Jul 2022, Jerome Neanne wrote:

> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> Using a power-button on the EN/PB/VSENSE pin of TPS65219 is optional, so
> this driver adds the mfd cell for tps65219-pwrbutton only if needed. Two
> interrupts are passed to the driver.

Power button support was already added in the previous patch.

> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> ---
>  drivers/mfd/tps65219.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
> index 7366f251c21d..e1c30a49bf08 100644
> --- a/drivers/mfd/tps65219.c
> +++ b/drivers/mfd/tps65219.c
> @@ -335,7 +335,10 @@ static int tps65219_probe(struct i2c_client *client,
>  	struct tps65219 *tps;
>  	int ret;
>  	unsigned int chipid;
> +	bool pwr_button;
>  	bool sys_pwr;
> +	struct mfd_cell cells[TPS65219_MAX_CELLS];
> +	int nr_cells = 0;
>  
>  	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
>  	if (!tps)
> @@ -364,9 +367,16 @@ static int tps65219_probe(struct i2c_client *client,
>  		return ret;
>  	}
>  
> -	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65219_cells,
> -				   ARRAY_SIZE(tps65219_cells), NULL, 0,
> -				   NULL);
> +	memcpy(&cells[nr_cells++], &tps65219_regulator_cell,
> +	       sizeof(tps65219_regulator_cell));
> +	pwr_button = of_property_read_bool(tps->dev->of_node, "power-button");
> +	if (pwr_button)
> +		memcpy(&cells[nr_cells++], &tps65219_pwrbutton_cell,
> +		       sizeof(tps65219_pwrbutton_cell));

Gross, no way.

Please call devm_mfd_add_devices() twice.

> +	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, cells,
> +				   nr_cells, NULL, 0,
> +				   regmap_irq_get_domain(tps->irq_data));
>  	if (ret) {
>  		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
>  		return ret;

-- 
DEPRECATED: Please use lee@kernel.org

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support
  2022-08-08 15:49     ` Lee Jones
@ 2022-08-25  9:17       ` Markus Schneider-Pargmann
  -1 siblings, 0 replies; 36+ messages in thread
From: Markus Schneider-Pargmann @ 2022-08-25  9:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Jerome Neanne, lgirdwood, broonie, robh+dt, nm, kristo, khilman,
	narmstrong, j-keerthy, linux-kernel, devicetree,
	linux-arm-kernel, Lee Jones

Hi Lee,

thanks for your comments. I am pushing the next version v4 for Jerome
and fixed most of your comments. Some inline comments.

On Mon, Aug 08, 2022 at 04:49:57PM +0100, Lee Jones wrote:
> On Tue, 26 Jul 2022, Jerome Neanne wrote:
> 
> > The TPS65219 is a power management IC PMIC designed
> > to supply a wide range of SoCs
> > in both portable and stationary applications.
> > Any SoC can control TPS65219 over a standard I2C interface.
> 
> Really odd line break choices here.
> 
> > It contains the following components:
> > - Regulators.
> > - Over Temperature warning and Shut down.
> > - GPIOs
> > - Multi Function Pins (MFP)
> > 
> > This patch adds support for tps65219 mfd device. At this time only
> 
> No such thing as an MFD device, what is it?  PMIC, no?
> 
> > the functionalities listed below are made available:
> > 
> > - Regulators probe and functionalities
> > - warm and cold reset support
> > - SW shutdown support
> > 
> > Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> > ---
> >  MAINTAINERS                  |   1 +
> >  drivers/mfd/Kconfig          |  15 +++
> >  drivers/mfd/Makefile         |   1 +
> >  drivers/mfd/tps65219.c       | 214 +++++++++++++++++++++++++++++
> >  include/linux/mfd/tps65219.h | 251 +++++++++++++++++++++++++++++++++++
> >  5 files changed, 482 insertions(+)
> >  create mode 100644 drivers/mfd/tps65219.c
> >  create mode 100644 include/linux/mfd/tps65219.h
> > 

...

> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> > index 858cacf659d6..a8ff3d6ea3ab 100644
> > --- a/drivers/mfd/Makefile
> > +++ b/drivers/mfd/Makefile

...

> 
> > +//
> > +// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> > +//
> > +// This implementation derived from tps65218 authored by
> > +// "J Keerthy <j-keerthy@ti.com>"
> 
> Which he probably copied from elsewhere.
> 
> Please drop this line.
> 
> > +//
> 
> Drop this empty comment
> 
> Only C++ for the SPDX line please.

Mark Brown wanted this the other way around:

"Please make the entire comment a C++ one so things look more
intentional."
https://lore.kernel.org/all/YtayikFdidxXXubS@sirena.org.uk/

Let me know what I should do here.

...

> 
> > +		if (pm_power_off)
> > +			dev_warn(tps->dev, "Setup as system-power-controller but pm_power_off function already registered, overwriting\n");
> 
> Is that really what you want?
> 
> What about the other driver that thinks it's the
> system-power-controller? Seems wrong.

I am now not overwriting pm_power_off but print an error and probe
successfully.

...

> > diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
> > new file mode 100644
> > index 000000000000..e9197ab8bc75
> > --- /dev/null
> > +++ b/include/linux/mfd/tps65219.h
> > @@ -0,0 +1,251 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * linux/mfd/tps65219.h
> 
> No filenames please.  They tend to become unsynced.
> 
> > + * Functions to access TPS65219 power management chip.
> 
> As above.
> 
> > + * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> > + */
> > +
> > +#ifndef __LINUX_MFD_TPS65219_H
> > +#define __LINUX_MFD_TPS65219_H
> 
> LINUX?

This seems to be quite common in include/linux/mfd/*.h to have
__LINUX_MFD_ as prefix (probably for the directory they are in). I am
assuming that's not the right style. What should be used instead?
__MFD_TPS65219_H or MFD_TPS65219_H or maybe something else?

...

> > +
> > +/**
> > + * struct tps65219 - tps65219 sub-driver chip access routines
> > + *
> > + * Device data may be used to access the TPS65219 chip
> > + */
> 
> This is not a complete kerneldoc header.
> 
> Please compile test with W=1.

I didn't see any errors reported for this struct with W=1. I am assuming
you meant missing field descriptions and added them.

Thanks,
Markus

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support
@ 2022-08-25  9:17       ` Markus Schneider-Pargmann
  0 siblings, 0 replies; 36+ messages in thread
From: Markus Schneider-Pargmann @ 2022-08-25  9:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Jerome Neanne, lgirdwood, broonie, robh+dt, nm, kristo, khilman,
	narmstrong, j-keerthy, linux-kernel, devicetree,
	linux-arm-kernel, Lee Jones

Hi Lee,

thanks for your comments. I am pushing the next version v4 for Jerome
and fixed most of your comments. Some inline comments.

On Mon, Aug 08, 2022 at 04:49:57PM +0100, Lee Jones wrote:
> On Tue, 26 Jul 2022, Jerome Neanne wrote:
> 
> > The TPS65219 is a power management IC PMIC designed
> > to supply a wide range of SoCs
> > in both portable and stationary applications.
> > Any SoC can control TPS65219 over a standard I2C interface.
> 
> Really odd line break choices here.
> 
> > It contains the following components:
> > - Regulators.
> > - Over Temperature warning and Shut down.
> > - GPIOs
> > - Multi Function Pins (MFP)
> > 
> > This patch adds support for tps65219 mfd device. At this time only
> 
> No such thing as an MFD device, what is it?  PMIC, no?
> 
> > the functionalities listed below are made available:
> > 
> > - Regulators probe and functionalities
> > - warm and cold reset support
> > - SW shutdown support
> > 
> > Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
> > ---
> >  MAINTAINERS                  |   1 +
> >  drivers/mfd/Kconfig          |  15 +++
> >  drivers/mfd/Makefile         |   1 +
> >  drivers/mfd/tps65219.c       | 214 +++++++++++++++++++++++++++++
> >  include/linux/mfd/tps65219.h | 251 +++++++++++++++++++++++++++++++++++
> >  5 files changed, 482 insertions(+)
> >  create mode 100644 drivers/mfd/tps65219.c
> >  create mode 100644 include/linux/mfd/tps65219.h
> > 

...

> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> > index 858cacf659d6..a8ff3d6ea3ab 100644
> > --- a/drivers/mfd/Makefile
> > +++ b/drivers/mfd/Makefile

...

> 
> > +//
> > +// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> > +//
> > +// This implementation derived from tps65218 authored by
> > +// "J Keerthy <j-keerthy@ti.com>"
> 
> Which he probably copied from elsewhere.
> 
> Please drop this line.
> 
> > +//
> 
> Drop this empty comment
> 
> Only C++ for the SPDX line please.

Mark Brown wanted this the other way around:

"Please make the entire comment a C++ one so things look more
intentional."
https://lore.kernel.org/all/YtayikFdidxXXubS@sirena.org.uk/

Let me know what I should do here.

...

> 
> > +		if (pm_power_off)
> > +			dev_warn(tps->dev, "Setup as system-power-controller but pm_power_off function already registered, overwriting\n");
> 
> Is that really what you want?
> 
> What about the other driver that thinks it's the
> system-power-controller? Seems wrong.

I am now not overwriting pm_power_off but print an error and probe
successfully.

...

> > diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
> > new file mode 100644
> > index 000000000000..e9197ab8bc75
> > --- /dev/null
> > +++ b/include/linux/mfd/tps65219.h
> > @@ -0,0 +1,251 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * linux/mfd/tps65219.h
> 
> No filenames please.  They tend to become unsynced.
> 
> > + * Functions to access TPS65219 power management chip.
> 
> As above.
> 
> > + * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
> > + */
> > +
> > +#ifndef __LINUX_MFD_TPS65219_H
> > +#define __LINUX_MFD_TPS65219_H
> 
> LINUX?

This seems to be quite common in include/linux/mfd/*.h to have
__LINUX_MFD_ as prefix (probably for the directory they are in). I am
assuming that's not the right style. What should be used instead?
__MFD_TPS65219_H or MFD_TPS65219_H or maybe something else?

...

> > +
> > +/**
> > + * struct tps65219 - tps65219 sub-driver chip access routines
> > + *
> > + * Device data may be used to access the TPS65219 chip
> > + */
> 
> This is not a complete kerneldoc header.
> 
> Please compile test with W=1.

I didn't see any errors reported for this struct with W=1. I am assuming
you meant missing field descriptions and added them.

Thanks,
Markus

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2022-08-25  9:18 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-26 10:33 [PATCH v2 00/11] Add support for TI TPS65219 PMIC Jerome Neanne
2022-07-26 10:33 ` Jerome Neanne
2022-07-26 10:33 ` [PATCH v2 01/11] DONOTMERGE: arm64: dts: ti: Add TI TPS65219 PMIC support for AM642 SK board Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 10:33 ` [PATCH v2 02/11] DONOTMERGE: arm64: dts: ti: Add pinmux and irq mapping for TPS65219 external interrupts Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 10:33 ` [PATCH v2 03/11] DONOTMERGE: arm64: dts: ti: k3-am642-sk: Enable tps65219 power-button Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 10:33 ` [PATCH v2 04/11] MAINTAINERS: OMAP2+ support, add tps65218-pwrbutton Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 14:30   ` Markus Schneider-Pargmann
2022-07-26 14:30     ` Markus Schneider-Pargmann
2022-07-26 10:33 ` [PATCH v2 05/11] regulator: dt-bindings: Add TI TPS65219 PMIC bindings Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 12:56   ` Markus Schneider-Pargmann
2022-07-26 12:56     ` Markus Schneider-Pargmann
2022-07-26 10:33 ` [PATCH v2 06/11] mfd: drivers: Add TI TPS65219 PMIC support Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-08-08 15:49   ` Lee Jones
2022-08-08 15:49     ` Lee Jones
2022-08-25  9:17     ` Markus Schneider-Pargmann
2022-08-25  9:17       ` Markus Schneider-Pargmann
2022-07-26 10:33 ` [PATCH v2 07/11] mfd: drivers: Add interrupts support to TI TPS65219 PMIC Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-08-08 15:57   ` Lee Jones
2022-08-08 15:57     ` Lee Jones
2022-07-26 10:33 ` [PATCH v2 08/11] mfd: tps65219: Add power-button support Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-08-08 16:05   ` Lee Jones
2022-08-08 16:05     ` Lee Jones
2022-07-26 10:33 ` [PATCH v2 09/11] regulator: drivers: Add TI TPS65219 PMIC regulators support Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 10:33 ` [PATCH v2 10/11] Input: Add tps65219 interrupt driven powerbutton Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne
2022-07-26 10:33 ` [PATCH v2 11/11] arm64: defconfig: Add tps65219 as modules Jerome Neanne
2022-07-26 10:33   ` Jerome Neanne

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.