* [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers
@ 2025-05-16 18:29 Samuel Kayode
2025-05-16 18:47 ` [PATCH v2 1/9] dt-bindings: power: supply: add pf1550 Samuel Kayode
` (8 more replies)
0 siblings, 9 replies; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:29 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
This series adds support for pf1550 PMIC. It provides the core mfd driver and a
set of three sub-drivers for the regulator, power supply and input subsystems.
Patches 1-4 add the DT binding documents. Patches 5-8 add all drivers. Last
patch adds a MAINTAINERS entry for this device.
Changes since v1 [1]:
1. DT bindings for all devices included
2. Add onkey driver
3. Add driver for the regulators
4. Ensure charger is activated as some variants have it off by default
5. Update mfd and charger driver per feedback from eballetbo@gmail.com
6. Add myself as maintainer for these drivers
[1]: v1: https://lore.kernel.org/1523974819-8711-1-git-send-email-abel.vesa@nxp.com/
Samuel Kayode (9):
dt-bindings: power: supply: add pf1550
dt-bindings: regulator: add pf1550
dt-bindings: input: add pf1550
dt-bindings: mfd: add pf1550
mfd: pf1550: add core mfd driver
regulator: pf1550: add support for regulator
input: pf1550: add onkey support
power: supply: pf1550: add battery charger support
MAINTAINERS: add an entry for pf1550 mfd driver
.../bindings/input/pf1550_onkey.yaml | 31 +
.../devicetree/bindings/mfd/pf1550.yaml | 122 ++++
.../bindings/power/supply/pf1550_charger.yaml | 44 ++
.../devicetree/bindings/regulator/pf1550.yaml | 35 +
MAINTAINERS | 11 +
drivers/input/keyboard/Kconfig | 8 +
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/pf1550_onkey.c | 200 ++++++
drivers/mfd/Kconfig | 14 +
drivers/mfd/Makefile | 2 +
drivers/mfd/pf1550.c | 254 +++++++
drivers/power/supply/Kconfig | 6 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/pf1550_charger.c | 656 ++++++++++++++++++
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/pf1550.c | 380 ++++++++++
include/linux/mfd/pf1550.h | 246 +++++++
18 files changed, 2019 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/pf1550_onkey.yaml
create mode 100644 Documentation/devicetree/bindings/mfd/pf1550.yaml
create mode 100644 Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
create mode 100644 Documentation/devicetree/bindings/regulator/pf1550.yaml
create mode 100644 drivers/input/keyboard/pf1550_onkey.c
create mode 100644 drivers/mfd/pf1550.c
create mode 100644 drivers/power/supply/pf1550_charger.c
create mode 100644 drivers/regulator/pf1550.c
create mode 100644 include/linux/mfd/pf1550.h
base-commit: b1d8766052eb0534b27edda8af1865d53621bd6a
--
2.49.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 1/9] dt-bindings: power: supply: add pf1550
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
@ 2025-05-16 18:47 ` Samuel Kayode
2025-05-17 11:12 ` Krzysztof Kozlowski
2025-05-16 18:50 ` [PATCH v2 2/9] dt-bindings: regulator: " Samuel Kayode
` (7 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:47 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add the DT binding document for the battery charger module of pf1550.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
.../bindings/power/supply/pf1550_charger.yaml | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
diff --git a/Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml b/Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
new file mode 100644
index 000000000000..10fc0b35917c
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/supply/pf1550_charger.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Battery charger driver for PF1550 PMIC from NXP.
+
+maintainers:
+ - Samuel Kayode <samuel.kayode@savoirfairelinux.com>
+
+description: |
+ This module is part of the PF1550 MFD device. For more details
+ see Documentation/devicetree/bindings/mfd/pf1550.yaml.
+
+ The charger is represented as a sub-node of the PMIC node on the device tree.
+
+properties:
+ compatible:
+ const: fsl,pf1550-charger
+
+ fsl,constant-microvolt:
+ description:
+ Constant charge voltage (in microvolts).
+ minimum: 3500000
+ maximum: 4400000
+
+ fsl,min-system-microvolt:
+ description:
+ Minimum charge voltage (in microvolts).
+ enum: [ 3500000, 3700000, 4300000 ]
+
+ fsl,thermal-regulation:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Temperature (in degrees Celsius) threshold past which the charging
+ current is reduced.
+ enum: [ 60, 75, 90, 105 ]
+
+required:
+ - compatible
+additionalProperties: false
+
+...
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 2/9] dt-bindings: regulator: add pf1550
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
2025-05-16 18:47 ` [PATCH v2 1/9] dt-bindings: power: supply: add pf1550 Samuel Kayode
@ 2025-05-16 18:50 ` Samuel Kayode
2025-05-17 11:13 ` Krzysztof Kozlowski
2025-05-16 18:52 ` [PATCH v2 3/9] dt-bindings: input: " Samuel Kayode
` (6 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:50 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokho,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add the DT binding document for pf1550 regulators.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
.../devicetree/bindings/regulator/pf1550.yaml | 35 +++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/pf1550.yaml
diff --git a/Documentation/devicetree/bindings/regulator/pf1550.yaml b/Documentation/devicetree/bindings/regulator/pf1550.yaml
new file mode 100644
index 000000000000..a684ab974496
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/pf1550.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/pf1550.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Regulators for PF1550 PMIC from NXP.
+
+maintainers:
+ - Samuel Kayode <samuel.kayode@savoirfairelinux.com>
+
+description: |
+ This module is part of the PF1550 MFD device. For more details
+ see Documentation/devicetree/bindings/mfd/pf1550.yaml.
+
+ The regulator controller is represented as a sub-node of the PMIC node
+ on the device tree.
+
+ The device has three LDO regulators, three buck converters and a DDR
+ termination reference voltage.
+
+properties:
+ compatible:
+ const: fsl,pf1550-regulator
+
+patternProperties:
+ "^(LDO[1-3]|SW[1-3]|VREFADDR)$":
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+required:
+ - compatible
+additionalProperties: false
+
+...
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 3/9] dt-bindings: input: add pf1550
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
2025-05-16 18:47 ` [PATCH v2 1/9] dt-bindings: power: supply: add pf1550 Samuel Kayode
2025-05-16 18:50 ` [PATCH v2 2/9] dt-bindings: regulator: " Samuel Kayode
@ 2025-05-16 18:52 ` Samuel Kayode
2025-05-17 11:14 ` Krzysztof Kozlowski
2025-05-16 18:53 ` [PATCH v2 4/9] dt-bindings: mfd: " Samuel Kayode
` (5 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:52 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add the DT binding document for the onkey module of pf1550.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
.../bindings/input/pf1550_onkey.yaml | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/pf1550_onkey.yaml
diff --git a/Documentation/devicetree/bindings/input/pf1550_onkey.yaml b/Documentation/devicetree/bindings/input/pf1550_onkey.yaml
new file mode 100644
index 000000000000..7079f5284b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/pf1550_onkey.yaml
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/pf1550_onkey.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Onkey for PF1550 PMIC from NXP.
+
+maintainers:
+ - Samuel Kayode <samuel.kayode@savoirfairelinux.com>
+
+description: |
+ This module is part of the pf1550 MFD device. For more details
+ see Documentation/devicetree/bindings/mfd/pf1550.yaml.
+
+allOf:
+ - $ref: input.yaml#
+
+properties:
+ compatible:
+ const: fsl,pf1550-onkey
+
+ linux,keycodes:
+ description: Keycode to emit
+ default: 116 # KEY_POWER
+
+required:
+ - compatible
+additionalProperties: false
+
+...
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 4/9] dt-bindings: mfd: add pf1550
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
` (2 preceding siblings ...)
2025-05-16 18:52 ` [PATCH v2 3/9] dt-bindings: input: " Samuel Kayode
@ 2025-05-16 18:53 ` Samuel Kayode
2025-05-17 11:16 ` Krzysztof Kozlowski
2025-05-16 18:54 ` [PATCH v2 5/9] mfd: pf1550: add core mfd driver Samuel Kayode
` (4 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:53 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, inux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add a DT binding document for pf1550 PMIC. This describes the core mfd
device.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
.../devicetree/bindings/mfd/pf1550.yaml | 122 ++++++++++++++++++
1 file changed, 122 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/pf1550.yaml
diff --git a/Documentation/devicetree/bindings/mfd/pf1550.yaml b/Documentation/devicetree/bindings/mfd/pf1550.yaml
new file mode 100644
index 000000000000..461bc13513eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/pf1550.yaml
@@ -0,0 +1,122 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/pf1550.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PF1550 low power PMIC from NXP.
+
+maintainers:
+ - Samuel Kayode <samuel.kayode@savoirfairelinux.com>
+
+description: |
+ PF1550 is a low power PMIC providing battery charging and power supply for
+ low power IoT and wearable applications.
+
+ For device-tree bindings of other sub-modules (regulator, power supply and
+ onkey) refer to the binding documents under the respective sub-system
+ directories.
+
+properties:
+ compatible:
+ const: fsl,pf1550
+
+ reg:
+ description:
+ I2C device address.
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ regulators:
+ $ref: /schemas/regulator/pf1550.yaml
+
+ charger:
+ $ref: /schemas/power/supply/pf1550_charger.yaml
+
+ onkey:
+ $ref: /schemas/input/pf1550_onkey.yaml
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/input/linux-event-codes.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@8 {
+ compatible = "fsl,pf1550";
+ reg = <0x8>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+ onkey {
+ compatible = "fsl,pf1550-onkey";
+ linux,keycodes = <KEY_POWER>;
+ };
+
+ charger {
+ compatible = "fsl,pf1550-charger";
+
+ fsl,min-system-microvolt = <3700000>;
+ fsl,thermal-regulation = <75>;
+ };
+
+ regulators {
+ compatible = "fsl,pf1550-regulator";
+
+ sw1_reg: SW1 {
+ regulator-name = "SW1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1387500>;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: SW2 {
+ regulator-name = "SW2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1387500>;
+ regulator-always-on;
+ };
+
+ sw3_reg: SW3 {
+ regulator-name = "SW3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo1_reg: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo2_reg: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vldo3_reg: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+ };
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 5/9] mfd: pf1550: add core mfd driver
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
` (3 preceding siblings ...)
2025-05-16 18:53 ` [PATCH v2 4/9] dt-bindings: mfd: " Samuel Kayode
@ 2025-05-16 18:54 ` Samuel Kayode
2025-05-17 11:18 ` Krzysztof Kozlowski
2025-05-20 13:25 ` kernel test robot
2025-05-16 18:55 ` [PATCH v2 6/9] regulator: pf1550: add support for regulator Samuel Kayode
` (3 subsequent siblings)
8 siblings, 2 replies; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:54 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add the core mfd driver for pf1550 PMIC. There are 3 subdevices for
which the drivers will be added in subsequent patches.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
drivers/mfd/Kconfig | 14 ++
drivers/mfd/Makefile | 2 +
drivers/mfd/pf1550.c | 254 +++++++++++++++++++++++++++++++++++++
include/linux/mfd/pf1550.h | 246 +++++++++++++++++++++++++++++++++++
4 files changed, 516 insertions(+)
create mode 100644 drivers/mfd/pf1550.c
create mode 100644 include/linux/mfd/pf1550.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 22b936310039..e2c2d1d798f3 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -558,6 +558,20 @@ config MFD_MX25_TSADC
i.MX25 processors. They consist of a conversion queue for general
purpose ADC and a queue for Touchscreens.
+config MFD_PF1550
+ tristate "Freescale Semiconductor PF1550 PMIC Support"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ Say yes here to add support for Freescale Semiconductor PF1550.
+ This is a companion Power Management IC with regulators, ONKEY,
+ and charger control on chip.
+ This driver provides common support for accessing the device;
+ additional drivers must be enabled in order to use the functionality
+ of the device.
+
config MFD_HI6421_PMIC
tristate "HiSilicon Hi6421 PMU/Codec IC"
depends on OF
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 948cbdf42a18..c4f270c5538a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -120,6 +120,8 @@ obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
+obj-$(CONFIG_MFD_PF1550) += pf1550.o
+
obj-$(CONFIG_MFD_CORE) += mfd-core.o
ocelot-soc-objs := ocelot-core.o ocelot-spi.o
diff --git a/drivers/mfd/pf1550.c b/drivers/mfd/pf1550.c
new file mode 100644
index 000000000000..6b5bdd9a1630
--- /dev/null
+++ b/drivers/mfd/pf1550.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pf1550.c - mfd core driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.com>
+ *
+ * This driver is based on max77693.c
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell pf1550_devs[] = {
+ {
+ .name = "pf1550-regulator",
+ .of_compatible = "fsl,pf1550-regulator",
+ },
+ {
+ .name = "pf1550-onkey",
+ .of_compatible = "fsl,pf1550-onkey",
+ },
+ {
+ .name = "pf1550-charger",
+ .of_compatible = "fsl,pf1550-charger",
+ },
+};
+
+static const struct regmap_config pf1550_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = PF1550_PMIC_REG_END,
+};
+
+static const struct regmap_irq pf1550_regulator_irqs[] = {
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW1_LS, 0, PMIC_IRQ_SW1_LS),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW2_LS, 0, PMIC_IRQ_SW2_LS),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW3_LS, 0, PMIC_IRQ_SW3_LS),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW1_HS, 3, PMIC_IRQ_SW1_HS),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW2_HS, 3, PMIC_IRQ_SW2_HS),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW3_HS, 3, PMIC_IRQ_SW3_HS),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_LDO1_FAULT, 16, PMIC_IRQ_LDO1_FAULT),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_LDO2_FAULT, 16, PMIC_IRQ_LDO2_FAULT),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_LDO3_FAULT, 16, PMIC_IRQ_LDO3_FAULT),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_TEMP_110, 22, PMIC_IRQ_TEMP_110),
+ REGMAP_IRQ_REG(PF1550_PMIC_IRQ_TEMP_125, 22, PMIC_IRQ_TEMP_125),
+};
+
+static const struct regmap_irq_chip pf1550_regulator_irq_chip = {
+ .name = "pf1550-regulator",
+ .status_base = PF1550_PMIC_REG_SW_INT_STAT0,
+ .mask_base = PF1550_PMIC_REG_SW_INT_MASK0,
+ .num_regs = 23,
+ .irqs = pf1550_regulator_irqs,
+ .num_irqs = ARRAY_SIZE(pf1550_regulator_irqs)
+};
+
+static const struct regmap_irq pf1550_onkey_irqs[] = {
+ REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_PUSHI, 0, ONKEY_IRQ_PUSHI),
+ REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_1SI, 0, ONKEY_IRQ_1SI),
+ REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_2SI, 0, ONKEY_IRQ_2SI),
+ REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_3SI, 0, ONKEY_IRQ_3SI),
+ REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_4SI, 0, ONKEY_IRQ_4SI),
+ REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_8SI, 0, ONKEY_IRQ_8SI),
+};
+
+static const struct regmap_irq_chip pf1550_onkey_irq_chip = {
+ .name = "pf1550-onkey",
+ .status_base = PF1550_PMIC_REG_ONKEY_INT_STAT0,
+ .ack_base = PF1550_PMIC_REG_ONKEY_INT_STAT0,
+ .mask_base = PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ .use_ack = 1,
+ .init_ack_masked = 1,
+ .num_regs = 1,
+ .irqs = pf1550_onkey_irqs,
+ .num_irqs = ARRAY_SIZE(pf1550_onkey_irqs),
+};
+
+static const struct regmap_irq pf1550_charger_irqs[] = {
+ REGMAP_IRQ_REG(PF1550_CHARG_IRQ_BAT2SOCI, 0, CHARG_IRQ_BAT2SOCI),
+ REGMAP_IRQ_REG(PF1550_CHARG_IRQ_BATI, 0, CHARG_IRQ_BATI),
+ REGMAP_IRQ_REG(PF1550_CHARG_IRQ_CHGI, 0, CHARG_IRQ_CHGI),
+ REGMAP_IRQ_REG(PF1550_CHARG_IRQ_VBUSI, 0, CHARG_IRQ_VBUSI),
+ REGMAP_IRQ_REG(PF1550_CHARG_IRQ_THMI, 0, CHARG_IRQ_THMI),
+};
+
+static const struct regmap_irq_chip pf1550_charger_irq_chip = {
+ .name = "pf1550-charger",
+ .status_base = PF1550_CHARG_REG_CHG_INT,
+ .mask_base = PF1550_CHARG_REG_CHG_INT_MASK,
+ .num_regs = 1,
+ .irqs = pf1550_charger_irqs,
+ .num_irqs = ARRAY_SIZE(pf1550_charger_irqs),
+};
+
+int pf1550_read_otp(struct pf1550_dev *pf1550, unsigned int index,
+ unsigned int *val)
+{
+ int ret = 0;
+
+ ret = regmap_write(pf1550->regmap, PF1550_PMIC_REG_KEY, 0x15);
+ if (ret)
+ goto read_err;
+ ret = regmap_write(pf1550->regmap, PF1550_CHARG_REG_CHGR_KEY2, 0x50);
+ if (ret)
+ goto read_err;
+ ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_KEY3, 0xAB);
+ if (ret)
+ goto read_err;
+ ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_FMRADDR, index);
+ if (ret)
+ goto read_err;
+ ret = regmap_read(pf1550->regmap, PF1550_TEST_REG_FMRDATA, val);
+ if (ret)
+ goto read_err;
+
+ return 0;
+
+read_err:
+ dev_err(pf1550->dev, "read otp reg %x found!\n", index);
+ return ret;
+}
+
+static int pf1550_i2c_probe(struct i2c_client *i2c)
+{
+ struct pf1550_dev *pf1550;
+ unsigned int reg_data = 0;
+ int ret = 0;
+
+ pf1550 = devm_kzalloc(&i2c->dev,
+ sizeof(struct pf1550_dev), GFP_KERNEL);
+ if (!pf1550)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, pf1550);
+ pf1550->dev = &i2c->dev;
+ pf1550->i2c = i2c;
+ pf1550->irq = i2c->irq;
+
+ pf1550->regmap = devm_regmap_init_i2c(i2c, &pf1550_regmap_config);
+ if (IS_ERR(pf1550->regmap)) {
+ ret = PTR_ERR(pf1550->regmap);
+ dev_err(pf1550->dev, "failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = regmap_read(pf1550->regmap, PF1550_PMIC_REG_DEVICE_ID, ®_data);
+ if (ret < 0 || reg_data != PF1550_DEVICE_ID) {
+ dev_err(pf1550->dev, "device not found!\n");
+ return ret;
+ }
+
+ pf1550->type = PF1550;
+ dev_info(pf1550->dev, "pf1550 found.\n");
+
+ ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap,
+ pf1550->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &pf1550_regulator_irq_chip,
+ &pf1550->irq_data_regulator);
+ if (ret) {
+ dev_err(pf1550->dev, "failed to add irq1 chip: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap,
+ pf1550->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &pf1550_onkey_irq_chip,
+ &pf1550->irq_data_onkey);
+ if (ret) {
+ dev_err(pf1550->dev, "failed to add irq3 chip: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap,
+ pf1550->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &pf1550_charger_irq_chip,
+ &pf1550->irq_data_charger);
+ if (ret) {
+ dev_err(pf1550->dev, "failed to add irq4 chip: %d\n", ret);
+ return ret;
+ }
+
+ return devm_mfd_add_devices(pf1550->dev, -1, pf1550_devs,
+ ARRAY_SIZE(pf1550_devs), NULL, 0, NULL);
+}
+
+static const struct i2c_device_id pf1550_i2c_id[] = {
+ { "pf1550", PF1550 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, pf1550_i2c_id);
+
+static int pf1550_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
+
+ if (device_may_wakeup(dev)) {
+ enable_irq_wake(pf1550->irq);
+ disable_irq(pf1550->irq);
+ }
+
+ return 0;
+}
+
+static int pf1550_resume(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
+
+ if (device_may_wakeup(dev)) {
+ disable_irq_wake(pf1550->irq);
+ enable_irq(pf1550->irq);
+ }
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(pf1550_pm, pf1550_suspend, pf1550_resume);
+
+static const struct of_device_id pf1550_dt_match[] = {
+ { .compatible = "fsl,pf1550" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pf1550_dt_match);
+
+static struct i2c_driver pf1550_i2c_driver = {
+ .driver = {
+ .name = "pf1550",
+ .pm = pm_sleep_ptr(&pf1550_pm),
+ .of_match_table = of_match_ptr(pf1550_dt_match),
+ },
+ .probe = pf1550_i2c_probe,
+ .id_table = pf1550_i2c_id,
+};
+
+module_i2c_driver(pf1550_i2c_driver);
+
+MODULE_DESCRIPTION("Freescale PF1550 multi-function core driver");
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/pf1550.h b/include/linux/mfd/pf1550.h
new file mode 100644
index 000000000000..41de05c00b3d
--- /dev/null
+++ b/include/linux/mfd/pf1550.h
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * pf1550.h - mfd head file for PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.com>
+ */
+
+#ifndef __LINUX_MFD_PF1550_H
+#define __LINUX_MFD_PF1550_H
+
+#include <linux/i2c.h>
+
+enum chips { PF1550 = 1, };
+
+enum pf1550_pmic_reg {
+ /* PMIC regulator part */
+ PF1550_PMIC_REG_DEVICE_ID = 0x00,
+ PF1550_PMIC_REG_OTP_FLAVOR = 0x01,
+ PF1550_PMIC_REG_SILICON_REV = 0x02,
+
+ PF1550_PMIC_REG_INT_CATEGORY = 0x06,
+ PF1550_PMIC_REG_SW_INT_STAT0 = 0x08,
+ PF1550_PMIC_REG_SW_INT_MASK0 = 0x09,
+ PF1550_PMIC_REG_SW_INT_SENSE0 = 0x0A,
+ PF1550_PMIC_REG_SW_INT_STAT1 = 0x0B,
+ PF1550_PMIC_REG_SW_INT_MASK1 = 0x0C,
+ PF1550_PMIC_REG_SW_INT_SENSE1 = 0x0D,
+ PF1550_PMIC_REG_SW_INT_STAT2 = 0x0E,
+ PF1550_PMIC_REG_SW_INT_MASK2 = 0x0F,
+ PF1550_PMIC_REG_SW_INT_SENSE2 = 0x10,
+ PF1550_PMIC_REG_LDO_INT_STAT0 = 0x18,
+ PF1550_PMIC_REG_LDO_INT_MASK0 = 0x19,
+ PF1550_PMIC_REG_LDO_INT_SENSE0 = 0x1A,
+ PF1550_PMIC_REG_TEMP_INT_STAT0 = 0x20,
+ PF1550_PMIC_REG_TEMP_INT_MASK0 = 0x21,
+ PF1550_PMIC_REG_TEMP_INT_SENSE0 = 0x22,
+ PF1550_PMIC_REG_ONKEY_INT_STAT0 = 0x24,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0 = 0x25,
+ PF1550_PMIC_REG_ONKEY_INT_SENSE0 = 0x26,
+ PF1550_PMIC_REG_MISC_INT_STAT0 = 0x28,
+ PF1550_PMIC_REG_MISC_INT_MASK0 = 0x29,
+ PF1550_PMIC_REG_MISC_INT_SENSE0 = 0x2A,
+
+ PF1550_PMIC_REG_COINCELL_CONTROL = 0x30,
+
+ PF1550_PMIC_REG_SW1_VOLT = 0x32,
+ PF1550_PMIC_REG_SW1_STBY_VOLT = 0x33,
+ PF1550_PMIC_REG_SW1_SLP_VOLT = 0x34,
+ PF1550_PMIC_REG_SW1_CTRL = 0x35,
+ PF1550_PMIC_REG_SW1_CTRL1 = 0x36,
+ PF1550_PMIC_REG_SW2_VOLT = 0x38,
+ PF1550_PMIC_REG_SW2_STBY_VOLT = 0x39,
+ PF1550_PMIC_REG_SW2_SLP_VOLT = 0x3A,
+ PF1550_PMIC_REG_SW2_CTRL = 0x3B,
+ PF1550_PMIC_REG_SW2_CTRL1 = 0x3C,
+ PF1550_PMIC_REG_SW3_VOLT = 0x3E,
+ PF1550_PMIC_REG_SW3_STBY_VOLT = 0x3F,
+ PF1550_PMIC_REG_SW3_SLP_VOLT = 0x40,
+ PF1550_PMIC_REG_SW3_CTRL = 0x41,
+ PF1550_PMIC_REG_SW3_CTRL1 = 0x42,
+ PF1550_PMIC_REG_VSNVS_CTRL = 0x48,
+ PF1550_PMIC_REG_VREFDDR_CTRL = 0x4A,
+ PF1550_PMIC_REG_LDO1_VOLT = 0x4C,
+ PF1550_PMIC_REG_LDO1_CTRL = 0x4D,
+ PF1550_PMIC_REG_LDO2_VOLT = 0x4F,
+ PF1550_PMIC_REG_LDO2_CTRL = 0x50,
+ PF1550_PMIC_REG_LDO3_VOLT = 0x52,
+ PF1550_PMIC_REG_LDO3_CTRL = 0x53,
+ PF1550_PMIC_REG_PWRCTRL0 = 0x58,
+ PF1550_PMIC_REG_PWRCTRL1 = 0x59,
+ PF1550_PMIC_REG_PWRCTRL2 = 0x5A,
+ PF1550_PMIC_REG_PWRCTRL3 = 0x5B,
+ PF1550_PMIC_REG_SW1_PWRDN_SEQ = 0x5F,
+ PF1550_PMIC_REG_SW2_PWRDN_SEQ = 0x60,
+ PF1550_PMIC_REG_SW3_PWRDN_SEQ = 0x61,
+ PF1550_PMIC_REG_LDO1_PWRDN_SEQ = 0x62,
+ PF1550_PMIC_REG_LDO2_PWRDN_SEQ = 0x63,
+ PF1550_PMIC_REG_LDO3_PWRDN_SEQ = 0x64,
+ PF1550_PMIC_REG_VREFDDR_PWRDN_SEQ = 0x65,
+
+ PF1550_PMIC_REG_STATE_INFO = 0x67,
+ PF1550_PMIC_REG_I2C_ADDR = 0x68,
+ PF1550_PMIC_REG_IO_DRV0 = 0x69,
+ PF1550_PMIC_REG_IO_DRV1 = 0x6A,
+ PF1550_PMIC_REG_RC_16MHZ = 0x6B,
+ PF1550_PMIC_REG_KEY = 0x6F,
+
+ /* charger part */
+ PF1550_CHARG_REG_CHG_INT = 0x80,
+ PF1550_CHARG_REG_CHG_INT_MASK = 0x82,
+ PF1550_CHARG_REG_CHG_INT_OK = 0x84,
+ PF1550_CHARG_REG_VBUS_SNS = 0x86,
+ PF1550_CHARG_REG_CHG_SNS = 0x87,
+ PF1550_CHARG_REG_BATT_SNS = 0x88,
+ PF1550_CHARG_REG_CHG_OPER = 0x89,
+ PF1550_CHARG_REG_CHG_TMR = 0x8A,
+ PF1550_CHARG_REG_CHG_EOC_CNFG = 0x8D,
+ PF1550_CHARG_REG_CHG_CURR_CNFG = 0x8E,
+ PF1550_CHARG_REG_BATT_REG = 0x8F,
+ PF1550_CHARG_REG_BATFET_CNFG = 0x91,
+ PF1550_CHARG_REG_THM_REG_CNFG = 0x92,
+ PF1550_CHARG_REG_VBUS_INLIM_CNFG = 0x94,
+ PF1550_CHARG_REG_VBUS_LIN_DPM = 0x95,
+ PF1550_CHARG_REG_USB_PHY_LDO_CNFG = 0x96,
+ PF1550_CHARG_REG_DBNC_DELAY_TIME = 0x98,
+ PF1550_CHARG_REG_CHG_INT_CNFG = 0x99,
+ PF1550_CHARG_REG_THM_ADJ_SETTING = 0x9A,
+ PF1550_CHARG_REG_VBUS2SYS_CNFG = 0x9B,
+ PF1550_CHARG_REG_LED_PWM = 0x9C,
+ PF1550_CHARG_REG_FAULT_BATFET_CNFG = 0x9D,
+ PF1550_CHARG_REG_LED_CNFG = 0x9E,
+ PF1550_CHARG_REG_CHGR_KEY2 = 0x9F,
+
+ PF1550_TEST_REG_FMRADDR = 0xC4,
+ PF1550_TEST_REG_FMRDATA = 0xC5,
+ PF1550_TEST_REG_KEY3 = 0xDF,
+
+ PF1550_PMIC_REG_END = 0xff,
+};
+
+#define PF1550_DEVICE_ID 0x7c
+
+#define PF1550_CHG_TURNON 0x2
+
+#define PF1550_CHG_PRECHARGE 0
+#define PF1550_CHG_CONSTANT_CURRENT 1
+#define PF1550_CHG_CONSTANT_VOL 2
+#define PF1550_CHG_EOC 3
+#define PF1550_CHG_DONE 4
+#define PF1550_CHG_TIMER_FAULT 6
+#define PF1550_CHG_SUSPEND 7
+#define PF1550_CHG_OFF_INV 8
+#define PF1550_CHG_BAT_OVER 9
+#define PF1550_CHG_OFF_TEMP 10
+#define PF1550_CHG_LINEAR_ONLY 12
+#define PF1550_CHG_SNS_MASK 0xf
+#define PF1550_CHG_INT_MASK 0x51
+
+#define PF1550_BAT_NO_VBUS 0
+#define PF1550_BAT_LOW_THAN_PRECHARG 1
+#define PF1550_BAT_CHARG_FAIL 2
+#define PF1550_BAT_HIGH_THAN_PRECHARG 4
+#define PF1550_BAT_OVER_VOL 5
+#define PF1550_BAT_NO_DETECT 6
+#define PF1550_BAT_SNS_MASK 0x7
+
+#define PF1550_VBUS_UVLO BIT(2)
+#define PF1550_VBUS_IN2SYS BIT(3)
+#define PF1550_VBUS_OVLO BIT(4)
+#define PF1550_VBUS_VALID BIT(5)
+
+#define PF1550_CHARG_REG_BATT_REG_CHGCV_MASK 0x3f
+#define PF1550_CHARG_REG_BATT_REG_VMINSYS_SHIFT 6
+#define PF1550_CHARG_REG_BATT_REG_VMINSYS_MASK (0x3 << 6)
+#define PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_SHIFT 2
+#define PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_MASK (0x3 << 2)
+
+#define PMIC_IRQ_SW1_LS BIT(0)
+#define PMIC_IRQ_SW2_LS BIT(1)
+#define PMIC_IRQ_SW3_LS BIT(2)
+#define PMIC_IRQ_SW1_HS BIT(0)
+#define PMIC_IRQ_SW2_HS BIT(1)
+#define PMIC_IRQ_SW3_HS BIT(2)
+#define PMIC_IRQ_LDO1_FAULT BIT(0)
+#define PMIC_IRQ_LDO2_FAULT BIT(1)
+#define PMIC_IRQ_LDO3_FAULT BIT(2)
+#define PMIC_IRQ_TEMP_110 BIT(0)
+#define PMIC_IRQ_TEMP_125 BIT(1)
+
+#define ONKEY_IRQ_PUSHI BIT(0)
+#define ONKEY_IRQ_1SI BIT(1)
+#define ONKEY_IRQ_2SI BIT(2)
+#define ONKEY_IRQ_3SI BIT(3)
+#define ONKEY_IRQ_4SI BIT(4)
+#define ONKEY_IRQ_8SI BIT(5)
+
+#define CHARG_IRQ_BAT2SOCI BIT(1)
+#define CHARG_IRQ_BATI BIT(2)
+#define CHARG_IRQ_CHGI BIT(3)
+#define CHARG_IRQ_VBUSI BIT(5)
+#define CHARG_IRQ_DPMI BIT(6)
+#define CHARG_IRQ_THMI BIT(7)
+
+enum pf1550_pmic_irq {
+ PF1550_PMIC_IRQ_SW1_LS,
+ PF1550_PMIC_IRQ_SW2_LS,
+ PF1550_PMIC_IRQ_SW3_LS,
+ PF1550_PMIC_IRQ_SW1_HS,
+ PF1550_PMIC_IRQ_SW2_HS,
+ PF1550_PMIC_IRQ_SW3_HS,
+ PF1550_PMIC_IRQ_LDO1_FAULT,
+ PF1550_PMIC_IRQ_LDO2_FAULT,
+ PF1550_PMIC_IRQ_LDO3_FAULT,
+ PF1550_PMIC_IRQ_TEMP_110,
+ PF1550_PMIC_IRQ_TEMP_125,
+};
+
+enum pf1550_onkey_irq {
+ PF1550_ONKEY_IRQ_PUSHI,
+ PF1550_ONKEY_IRQ_1SI,
+ PF1550_ONKEY_IRQ_2SI,
+ PF1550_ONKEY_IRQ_3SI,
+ PF1550_ONKEY_IRQ_4SI,
+ PF1550_ONKEY_IRQ_8SI,
+};
+
+enum pf1550_charg_irq {
+ PF1550_CHARG_IRQ_BAT2SOCI,
+ PF1550_CHARG_IRQ_BATI,
+ PF1550_CHARG_IRQ_CHGI,
+ PF1550_CHARG_IRQ_VBUSI,
+ PF1550_CHARG_IRQ_THMI,
+};
+
+enum pf1550_regulators {
+ PF1550_SW1,
+ PF1550_SW2,
+ PF1550_SW3,
+ PF1550_VREFDDR,
+ PF1550_LDO1,
+ PF1550_LDO2,
+ PF1550_LDO3,
+};
+
+struct pf1550_irq_info {
+ unsigned int irq;
+ const char *name;
+ unsigned int virq;
+};
+
+struct pf1550_dev {
+ struct device *dev;
+ struct i2c_client *i2c;
+ int type;
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *irq_data_regulator;
+ struct regmap_irq_chip_data *irq_data_onkey;
+ struct regmap_irq_chip_data *irq_data_charger;
+ int irq;
+};
+
+int pf1550_read_otp(struct pf1550_dev *pf1550, unsigned int index,
+ unsigned int *val);
+
+#endif /* __LINUX_MFD_PF1550_H */
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 6/9] regulator: pf1550: add support for regulator
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
` (4 preceding siblings ...)
2025-05-16 18:54 ` [PATCH v2 5/9] mfd: pf1550: add core mfd driver Samuel Kayode
@ 2025-05-16 18:55 ` Samuel Kayode
2025-05-17 20:13 ` kernel test robot
2025-05-16 18:57 ` [PATCH v2 7/9] input: pf1550: add onkey support Samuel Kayode
` (2 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:55 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add regulator support for the pf1550 PMIC.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/pf1550.c | 380 +++++++++++++++++++++++++++++++++++++
3 files changed, 388 insertions(+)
create mode 100644 drivers/regulator/pf1550.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 05e32d764028..cdce1658957f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1038,6 +1038,13 @@ config REGULATOR_PV88090
Say y here to support the voltage regulators and convertors
on PV88090
+config REGULATOR_PF1550
+ tristate "Freescale PF1550 regulator"
+ depends on MFD_PF1550
+ help
+ This driver controls a PF1550 regulator via I2C bus.
+ The regulators include three switch and three ldo.
+
config REGULATOR_PWM
tristate "PWM voltage regulator"
depends on PWM
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 524e026c0273..2d11c069b0ca 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PCA9450) += pca9450-regulator.o
obj-$(CONFIG_REGULATOR_PF9453) += pf9453-regulator.o
+obj-$(CONFIG_REGULATOR_PF1550) += pf1550.o
obj-$(CONFIG_REGULATOR_PF8X00) += pf8x00-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o
diff --git a/drivers/regulator/pf1550.c b/drivers/regulator/pf1550.c
new file mode 100644
index 000000000000..e7a9c3b43c12
--- /dev/null
+++ b/drivers/regulator/pf1550.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pf1550.c - regulator driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.com>
+ *
+ * This driver is based on pfuze100-regulator.c
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
+#include <linux/platform_device.h>
+
+#define PF1550_MAX_REGULATOR 7
+
+struct pf1550_desc {
+ struct regulator_desc desc;
+ unsigned char stby_reg;
+ unsigned char stby_mask;
+};
+
+struct pf1550_regulator_info {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ struct pf1550_desc regulator_descs[PF1550_MAX_REGULATOR];
+ int irq;
+};
+
+static struct pf1550_irq_info pf1550_regulator_irqs[] = {
+ { PF1550_PMIC_IRQ_SW1_LS, "sw1-lowside" },
+ { PF1550_PMIC_IRQ_SW2_LS, "sw2-lowside" },
+ { PF1550_PMIC_IRQ_SW3_LS, "sw3-lowside" },
+
+ { PF1550_PMIC_IRQ_SW1_HS, "sw1-highside" },
+ { PF1550_PMIC_IRQ_SW2_HS, "sw2-highside" },
+ { PF1550_PMIC_IRQ_SW3_HS, "sw3-highside" },
+
+ { PF1550_PMIC_IRQ_LDO1_FAULT, "ldo1-fault" },
+ { PF1550_PMIC_IRQ_LDO2_FAULT, "ldo2-fault" },
+ { PF1550_PMIC_IRQ_LDO3_FAULT, "ldo3-fault" },
+
+ { PF1550_PMIC_IRQ_TEMP_110, "temp-110" },
+ { PF1550_PMIC_IRQ_TEMP_125, "temp-125" },
+};
+
+static const int pf1550_sw12_volts[] = {
+ 1100000, 1200000, 1350000, 1500000, 1800000, 2500000, 3000000, 3300000,
+};
+
+static const int pf1550_ldo13_volts[] = {
+ 750000, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000,
+ 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
+ 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
+ 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
+};
+
+static int pf1550_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+ int id = rdev_get_id(rdev);
+ unsigned int ramp_bits;
+ int ret;
+
+ if (id > PF1550_VREFDDR)
+ return -EACCES;
+
+ ramp_delay = 6250 / ramp_delay;
+ ramp_bits = ramp_delay >> 1;
+ ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg + 4, 0x10,
+ ramp_bits << 4);
+ if (ret < 0)
+ dev_err(&rdev->dev, "ramp failed, err %d\n", ret);
+
+ return ret;
+}
+
+static const struct regulator_ops pf1550_sw1_ops = {
+ .list_voltage = regulator_list_voltage_table,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_ramp_delay = pf1550_set_ramp_delay,
+};
+
+static const struct regulator_ops pf1550_sw2_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_ramp_delay = pf1550_set_ramp_delay,
+};
+
+static const struct regulator_ops pf1550_ldo1_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_ascend,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static const struct regulator_ops pf1550_ldo2_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static const struct regulator_ops pf1550_fixed_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+};
+
+#define PF_VREF(_chip, _name, voltage) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = 1, \
+ .ops = &pf1550_fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (voltage), \
+ .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .enable_mask = 0x1, \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .stby_mask = 0x2, \
+}
+
+#define PF_SW1(_chip, _name, mask, voltages) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ARRAY_SIZE(voltages), \
+ .ops = &pf1550_sw1_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .volt_table = voltages, \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _STBY_VOLT, \
+ .stby_mask = (mask), \
+}
+
+#define PF_SW3(_chip, _name, min, max, mask, step) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pf1550_sw2_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _STBY_VOLT, \
+ .stby_mask = (mask), \
+}
+
+#define PF_LDO1(_chip, _name, mask, voltages) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ARRAY_SIZE(voltages), \
+ .ops = &pf1550_ldo1_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .volt_table = voltages, \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .enable_mask = 0x1, \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .stby_mask = 0x2, \
+}
+
+#define PF_LDO2(_chip, _name, mask, min, max, step) { \
+ .desc = { \
+ .name = #_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pf1550_ldo2_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \
+ .vsel_mask = (mask), \
+ .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .enable_mask = 0x1, \
+ }, \
+ .stby_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \
+ .stby_mask = 0x2, \
+}
+
+static struct pf1550_desc pf1550_regulators[] = {
+ PF_SW3(PF1550, SW1, 600000, 1387500, 0x3f, 12500),
+ PF_SW3(PF1550, SW2, 600000, 1387500, 0x3f, 12500),
+ PF_SW3(PF1550, SW3, 1800000, 3300000, 0xf, 100000),
+ PF_VREF(PF1550, VREFDDR, 1200000),
+ PF_LDO1(PF1550, LDO1, 0x1f, pf1550_ldo13_volts),
+ PF_LDO2(PF1550, LDO2, 0xf, 1800000, 3300000, 100000),
+ PF_LDO1(PF1550, LDO3, 0x1f, pf1550_ldo13_volts),
+};
+
+static irqreturn_t pf1550_regulator_irq_handler(int irq, void *data)
+{
+ struct pf1550_regulator_info *info = data;
+ int i, irq_type = -1;
+
+ info->irq = irq;
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulator_irqs); i++)
+ if (info->irq == pf1550_regulator_irqs[i].virq)
+ irq_type = pf1550_regulator_irqs[i].irq;
+
+ switch (irq_type) {
+ case PF1550_PMIC_IRQ_SW1_LS:
+ case PF1550_PMIC_IRQ_SW2_LS:
+ case PF1550_PMIC_IRQ_SW3_LS:
+ dev_info(info->dev, "lowside interrupt triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ case PF1550_PMIC_IRQ_SW1_HS:
+ case PF1550_PMIC_IRQ_SW2_HS:
+ case PF1550_PMIC_IRQ_SW3_HS:
+ dev_info(info->dev, "highside interrupt triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ case PF1550_PMIC_IRQ_LDO1_FAULT:
+ case PF1550_PMIC_IRQ_LDO2_FAULT:
+ case PF1550_PMIC_IRQ_LDO3_FAULT:
+ dev_info(info->dev, "ldo fault triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ case PF1550_PMIC_IRQ_TEMP_110:
+ case PF1550_PMIC_IRQ_TEMP_125:
+ dev_info(info->dev, "thermal exception triggered! irq_type=%d\n",
+ irq_type);
+ break;
+ default:
+ dev_err(info->dev, "regulator interrupt: irq %d occurred\n",
+ irq_type);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int pf1550_regulator_probe(struct platform_device *pdev)
+{
+ struct pf1550_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *np = pdev->dev.of_node;
+ struct pf1550_regulator_info *info;
+ int i, ret = 0;
+ struct regulator_config config = { };
+
+ if (!np)
+ return -ENODEV;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(struct pf1550_regulator_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ config.dev = iodev->dev;
+ config.regmap = iodev->regmap;
+ info->dev = &pdev->dev;
+ info->pf1550 = iodev;
+
+ memcpy(info->regulator_descs, pf1550_regulators,
+ sizeof(info->regulator_descs));
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulators); i++) {
+ struct regulator_dev *rdev;
+ struct regulator_desc *desc;
+ unsigned int val;
+
+ desc = &info->regulator_descs[i].desc;
+
+ if (desc->id == PF1550_SW2) {
+ pf1550_read_otp(info->pf1550, 0x1f, &val);
+ /* OTP_SW2_DVS_ENB == 1? */
+ if ((val & 0x8)) {
+ desc->volt_table = pf1550_sw12_volts;
+ desc->n_voltages = ARRAY_SIZE(pf1550_sw12_volts);
+ desc->ops = &pf1550_sw1_ops;
+ }
+ }
+
+ rdev = devm_regulator_register(&pdev->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev,
+ "Failed to initialize regulator-%d\n", i);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ platform_set_drvdata(pdev, info);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_regulator_irqs); i++) {
+ struct pf1550_irq_info *regulator_irq =
+ &pf1550_regulator_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(iodev->irq_data_regulator,
+ regulator_irq->irq);
+
+ if (!virq)
+ return -EINVAL;
+ regulator_irq->virq = virq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_regulator_irq_handler,
+ IRQF_NO_SUSPEND,
+ regulator_irq->name, info);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ regulator_irq->irq, ret);
+ return ret;
+ }
+ }
+
+ /* unmask all exception interrupts for regulators */
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_SW_INT_MASK0, 0);
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_SW_INT_MASK1, 0);
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_LDO_INT_MASK0, 0);
+ regmap_write(info->pf1550->regmap, PF1550_PMIC_REG_TEMP_INT_MASK0, 0);
+
+ return 0;
+}
+
+static const struct platform_device_id pf1550_regulator_id[] = {
+ {"pf1550-regulator", PF1550},
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(platform, pf1550_regulator_id);
+
+static struct platform_driver pf1550_regulator_driver = {
+ .driver = {
+ .name = "pf1550-regulator",
+ },
+ .probe = pf1550_regulator_probe,
+ .id_table = pf1550_regulator_id,
+};
+
+module_platform_driver(pf1550_regulator_driver);
+
+MODULE_DESCRIPTION("Freescale PF1550 regulator driver");
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_LICENSE("GPL v2");
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 7/9] input: pf1550: add onkey support
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
` (5 preceding siblings ...)
2025-05-16 18:55 ` [PATCH v2 6/9] regulator: pf1550: add support for regulator Samuel Kayode
@ 2025-05-16 18:57 ` Samuel Kayode
2025-05-16 22:55 ` Dmitry Torokhov
2025-05-18 16:03 ` kernel test robot
2025-05-16 18:58 ` [PATCH v2 8/9] power: supply: pf1550: add battery charger support Samuel Kayode
2025-05-16 18:59 ` [PATCH v2 9/9] MAINTAINERS: add an entry for pf1550 mfd driver Samuel Kayode
8 siblings, 2 replies; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:57 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add support for the onkey of the pf1550 PMIC.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
drivers/input/keyboard/Kconfig | 8 ++
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/pf1550_onkey.c | 200 ++++++++++++++++++++++++++
3 files changed, 209 insertions(+)
create mode 100644 drivers/input/keyboard/pf1550_onkey.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 721ab69e84ac..b01decc03ab9 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -444,6 +444,14 @@ config KEYBOARD_SNVS_PWRKEY
To compile this driver as a module, choose M here; the
module will be called snvs_pwrkey.
+config KEYBOARD_PF1550_ONKEY
+ tristate "PF1550 OnKey Driver"
+ depends on MFD_PF1550
+ depends on OF
+ help
+ This is onkey driver for PF1550 pmic, onkey can trigger release
+ and 1s(push hold), 2s, 3s, 4s, 8s interrupt for long press detect
+
config KEYBOARD_IMX
tristate "IMX keypad support"
depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 1e0721c30709..8a6feae3ddb1 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o
+obj-$(CONFIG_KEYBOARD_PF1550_ONKEY) += pf1550_onkey.o
obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
diff --git a/drivers/input/keyboard/pf1550_onkey.c b/drivers/input/keyboard/pf1550_onkey.c
new file mode 100644
index 000000000000..b0601acf893d
--- /dev/null
+++ b/drivers/input/keyboard/pf1550_onkey.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the PF1550 ON_KEY
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/pf1550.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct onkey_drv_data {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ int irq;
+ int keycode;
+ int wakeup;
+ struct input_dev *input;
+};
+
+static struct pf1550_irq_info pf1550_onkey_irqs[] = {
+ { PF1550_ONKEY_IRQ_PUSHI, "release" },
+ { PF1550_ONKEY_IRQ_1SI, "1S" },
+ { PF1550_ONKEY_IRQ_2SI, "2S" },
+ { PF1550_ONKEY_IRQ_3SI, "3S" },
+ { PF1550_ONKEY_IRQ_4SI, "4S" },
+ { PF1550_ONKEY_IRQ_8SI, "8S" },
+};
+
+static irqreturn_t pf1550_onkey_irq_handler(int irq, void *data)
+{
+ struct onkey_drv_data *onkey = data;
+ int i, state, irq_type = -1;
+
+ onkey->irq = irq;
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++)
+ if (onkey->irq == pf1550_onkey_irqs[i].virq)
+ irq_type = pf1550_onkey_irqs[i].irq;
+ switch (irq_type) {
+ case PF1550_ONKEY_IRQ_PUSHI:
+ state = 0;
+ break;
+ case PF1550_ONKEY_IRQ_1SI:
+ case PF1550_ONKEY_IRQ_2SI:
+ case PF1550_ONKEY_IRQ_3SI:
+ case PF1550_ONKEY_IRQ_4SI:
+ case PF1550_ONKEY_IRQ_8SI:
+ state = 1;
+ break;
+ default:
+ dev_err(onkey->dev, "onkey interrupt: irq %d occurred\n",
+ irq_type);
+ return IRQ_HANDLED;
+ }
+
+ input_event(onkey->input, EV_KEY, onkey->keycode, state);
+ input_sync(onkey->input);
+
+ return IRQ_HANDLED;
+}
+
+static int pf1550_onkey_probe(struct platform_device *pdev)
+{
+ struct onkey_drv_data *onkey;
+ struct input_dev *input = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
+ int i, error;
+
+ if (!np)
+ return -ENODEV;
+
+ onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
+ if (!onkey)
+ return -ENOMEM;
+
+ if (of_property_read_u32(np, "linux,keycodes", &onkey->keycode)) {
+ onkey->keycode = KEY_POWER;
+ dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+ }
+
+ onkey->wakeup = of_property_read_bool(np, "wakeup-source");
+
+ input = devm_input_allocate_device(&pdev->dev);
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "pf1550-onkey/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, onkey->keycode);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
+ struct pf1550_irq_info *onkey_irq =
+ &pf1550_onkey_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
+ onkey_irq->irq);
+ if (!virq)
+ return -EINVAL;
+
+ onkey_irq->virq = virq;
+
+ error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_onkey_irq_handler,
+ IRQF_NO_SUSPEND,
+ onkey_irq->name, onkey);
+ if (error) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ onkey_irq->irq, error);
+ return error;
+ }
+ }
+
+ error = input_register_device(input);
+ if (error < 0) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ input_free_device(input);
+ return error;
+ }
+
+ onkey->input = input;
+ onkey->pf1550 = pf1550;
+ platform_set_drvdata(pdev, onkey);
+
+ device_init_wakeup(&pdev->dev, onkey->wakeup);
+
+ return 0;
+}
+
+static int pf1550_onkey_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
+
+ if (!device_may_wakeup(&pdev->dev))
+ regmap_write(onkey->pf1550->regmap,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
+ ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI);
+ else
+ enable_irq_wake(onkey->pf1550->irq);
+
+ return 0;
+}
+
+static int pf1550_onkey_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
+
+ if (!device_may_wakeup(&pdev->dev))
+ regmap_write(onkey->pf1550->regmap,
+ PF1550_PMIC_REG_ONKEY_INT_MASK0,
+ ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
+ ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
+ else
+ disable_irq_wake(onkey->pf1550->irq);
+
+ return 0;
+}
+
+static const struct of_device_id pf1550_onkey_ids[] = {
+ { .compatible = "fsl,pf1550-onkey" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pf1550_onkey_ids);
+
+static SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend,
+ pf1550_onkey_resume);
+
+static struct platform_driver pf1550_onkey_driver = {
+ .driver = {
+ .name = "pf1550-onkey",
+ .pm = &pf1550_onkey_pm_ops,
+ .of_match_table = pf1550_onkey_ids,
+ },
+ .probe = pf1550_onkey_probe,
+};
+module_platform_driver(pf1550_onkey_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("PF1550 onkey Driver");
+MODULE_LICENSE("GPL v2");
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 8/9] power: supply: pf1550: add battery charger support
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
` (6 preceding siblings ...)
2025-05-16 18:57 ` [PATCH v2 7/9] input: pf1550: add onkey support Samuel Kayode
@ 2025-05-16 18:58 ` Samuel Kayode
2025-05-17 11:20 ` Krzysztof Kozlowski
2025-05-16 18:59 ` [PATCH v2 9/9] MAINTAINERS: add an entry for pf1550 mfd driver Samuel Kayode
8 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:58 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add support for the battery charger for pf1550 PMIC.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
drivers/power/supply/Kconfig | 6 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/pf1550_charger.c | 656 ++++++++++++++++++++++++++
3 files changed, 663 insertions(+)
create mode 100644 drivers/power/supply/pf1550_charger.c
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 79ddb006e2da..5a2b694561b9 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -471,6 +471,12 @@ config CHARGER_88PM860X
help
Say Y here to enable charger for Marvell 88PM860x chip.
+config CHARGER_PF1550
+ tristate "Freescale PF1550 battery charger driver"
+ depends on MFD_PF1550
+ help
+ Say Y to enable support for the Freescale PF1550 battery charger.
+
config BATTERY_RX51
tristate "Nokia RX-51 (N900) battery driver"
depends on TWL4030_MADC
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 4f5f8e3507f8..e7dd9fb41d4e 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_CHARGER_RT9467) += rt9467-charger.o
obj-$(CONFIG_CHARGER_RT9471) += rt9471.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
+obj-$(CONFIG_CHARGER_PF1550) += pf1550_charger.o
obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o ab8500_chargalg.o
obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o
diff --git a/drivers/power/supply/pf1550_charger.c b/drivers/power/supply/pf1550_charger.c
new file mode 100644
index 000000000000..48fd9a07bb47
--- /dev/null
+++ b/drivers/power/supply/pf1550_charger.c
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pf1550_charger.c - regulator driver for the PF1550
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Robin Gong <yibin.gong@freescale.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/mfd/pf1550.h>
+
+#define PF1550_CHARGER_NAME "pf1550-charger"
+#define PF1550_DEFAULT_CONSTANT_VOLT 4200000
+#define PF1550_DEFAULT_MIN_SYSTEM_VOLT 3500000
+#define PF1550_DEFAULT_THERMAL_TEMP 75
+
+static const char *pf1550_charger_model = "PF1550";
+static const char *pf1550_charger_manufacturer = "Freescale";
+
+struct pf1550_charger {
+ struct device *dev;
+ struct pf1550_dev *pf1550;
+ struct power_supply *charger;
+ struct power_supply_desc psy_desc;
+ int irq;
+ struct delayed_work irq_work;
+ struct mutex mutex;
+
+ u32 constant_volt;
+ u32 min_system_volt;
+ u32 thermal_regulation_temp;
+};
+
+static struct pf1550_irq_info pf1550_charger_irqs[] = {
+ { PF1550_CHARG_IRQ_BAT2SOCI, "BAT2SOC" },
+ { PF1550_CHARG_IRQ_BATI, "BAT" },
+ { PF1550_CHARG_IRQ_CHGI, "CHG" },
+ { PF1550_CHARG_IRQ_VBUSI, "VBUS" },
+ { PF1550_CHARG_IRQ_THMI, "THM" },
+};
+
+static int pf1550_get_charger_state(struct regmap *regmap, int *val)
+{
+ int ret;
+ unsigned int data;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_CHG_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_CHG_SNS_MASK;
+
+ switch (data) {
+ case PF1550_CHG_PRECHARGE:
+ case PF1550_CHG_CONSTANT_CURRENT:
+ *val = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case PF1550_CHG_CONSTANT_VOL:
+ *val = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case PF1550_CHG_EOC:
+ *val = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case PF1550_CHG_DONE:
+ *val = POWER_SUPPLY_STATUS_FULL;
+ break;
+ case PF1550_CHG_TIMER_FAULT:
+ case PF1550_CHG_SUSPEND:
+ *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ case PF1550_CHG_OFF_INV:
+ case PF1550_CHG_OFF_TEMP:
+ case PF1550_CHG_LINEAR_ONLY:
+ *val = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ default:
+ *val = POWER_SUPPLY_STATUS_UNKNOWN;
+ }
+
+ return 0;
+}
+
+static int pf1550_get_charge_type(struct regmap *regmap, int *val)
+{
+ int ret;
+ unsigned int data;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_CHG_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_CHG_SNS_MASK;
+
+ switch (data) {
+ case PF1550_CHG_SNS_MASK:
+ *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ break;
+ case PF1550_CHG_CONSTANT_CURRENT:
+ case PF1550_CHG_CONSTANT_VOL:
+ case PF1550_CHG_EOC:
+ *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ break;
+ case PF1550_CHG_DONE:
+ case PF1550_CHG_TIMER_FAULT:
+ case PF1550_CHG_SUSPEND:
+ case PF1550_CHG_OFF_INV:
+ case PF1550_CHG_BAT_OVER:
+ case PF1550_CHG_OFF_TEMP:
+ case PF1550_CHG_LINEAR_ONLY:
+ *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ break;
+ default:
+ *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+ }
+
+ return 0;
+}
+
+/*
+ * Supported health statuses:
+ * - POWER_SUPPLY_HEALTH_DEAD
+ * - POWER_SUPPLY_HEALTH_GOOD
+ * - POWER_SUPPLY_HEALTH_OVERVOLTAGE
+ * - POWER_SUPPLY_HEALTH_UNKNOWN
+ */
+static int pf1550_get_battery_health(struct regmap *regmap, int *val)
+{
+ int ret;
+ unsigned int data;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_BATT_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_BAT_SNS_MASK;
+
+ switch (data) {
+ case PF1550_BAT_NO_DETECT:
+ *val = POWER_SUPPLY_HEALTH_DEAD;
+ break;
+ case PF1550_BAT_NO_VBUS:
+ case PF1550_BAT_LOW_THAN_PRECHARG:
+ case PF1550_BAT_CHARG_FAIL:
+ case PF1550_BAT_HIGH_THAN_PRECHARG:
+ *val = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+ case PF1550_BAT_OVER_VOL:
+ *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ break;
+ default:
+ *val = POWER_SUPPLY_HEALTH_UNKNOWN;
+ break;
+ }
+
+ return 0;
+}
+
+static int pf1550_get_present(struct regmap *regmap, int *val)
+{
+ unsigned int data;
+ int ret;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_BATT_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ data &= PF1550_BAT_SNS_MASK;
+ *val = (data == PF1550_BAT_NO_DETECT) ? 0 : 1;
+
+ return 0;
+}
+
+static int pf1550_get_online(struct regmap *regmap, int *val)
+{
+ unsigned int data;
+ int ret;
+
+ ret = regmap_read(regmap, PF1550_CHARG_REG_VBUS_SNS, &data);
+ if (ret < 0)
+ return ret;
+
+ *val = (data & PF1550_VBUS_VALID) ? 1 : 0;
+
+ return 0;
+}
+
+static void pf1550_chg_bat_isr(struct pf1550_charger *chg)
+{
+ unsigned int data;
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_BATT_SNS, &data)) {
+ dev_err(chg->dev, "Read BATT_SNS error.\n");
+ return;
+ }
+
+ switch (data & PF1550_BAT_SNS_MASK) {
+ case PF1550_BAT_NO_VBUS:
+ dev_dbg(chg->dev, "No valid VBUS input.\n");
+ break;
+ case PF1550_BAT_LOW_THAN_PRECHARG:
+ dev_dbg(chg->dev, "VBAT < VPRECHG.LB.\n");
+ break;
+ case PF1550_BAT_CHARG_FAIL:
+ dev_dbg(chg->dev, "Battery charging failed.\n");
+ break;
+ case PF1550_BAT_HIGH_THAN_PRECHARG:
+ dev_dbg(chg->dev, "VBAT > VPRECHG.LB.\n");
+ break;
+ case PF1550_BAT_OVER_VOL:
+ dev_dbg(chg->dev, "VBAT > VBATOV.\n");
+ break;
+ case PF1550_BAT_NO_DETECT:
+ dev_dbg(chg->dev, "Battery not detected.\n");
+ break;
+ default:
+ dev_err(chg->dev, "Unknown value read:%x\n",
+ data & PF1550_CHG_SNS_MASK);
+ }
+}
+
+static void pf1550_chg_chg_isr(struct pf1550_charger *chg)
+{
+ unsigned int data;
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_SNS, &data)) {
+ dev_err(chg->dev, "Read CHG_SNS error.\n");
+ return;
+ }
+
+ switch (data & PF1550_CHG_SNS_MASK) {
+ case PF1550_CHG_PRECHARGE:
+ dev_dbg(chg->dev, "In pre-charger mode.\n");
+ break;
+ case PF1550_CHG_CONSTANT_CURRENT:
+ dev_dbg(chg->dev, "In fast-charge constant current mode.\n");
+ break;
+ case PF1550_CHG_CONSTANT_VOL:
+ dev_dbg(chg->dev, "In fast-charge constant voltage mode.\n");
+ break;
+ case PF1550_CHG_EOC:
+ dev_dbg(chg->dev, "In EOC mode.\n");
+ break;
+ case PF1550_CHG_DONE:
+ dev_dbg(chg->dev, "In DONE mode.\n");
+ break;
+ case PF1550_CHG_TIMER_FAULT:
+ dev_info(chg->dev, "In timer fault mode.\n");
+ break;
+ case PF1550_CHG_SUSPEND:
+ dev_info(chg->dev, "In thermistor suspend mode.\n");
+ break;
+ case PF1550_CHG_OFF_INV:
+ dev_info(chg->dev, "Input invalid, charger off.\n");
+ break;
+ case PF1550_CHG_BAT_OVER:
+ dev_info(chg->dev, "Battery over-voltage.\n");
+ break;
+ case PF1550_CHG_OFF_TEMP:
+ dev_info(chg->dev, "Temp high, charger off.\n");
+ break;
+ case PF1550_CHG_LINEAR_ONLY:
+ dev_dbg(chg->dev, "In Linear mode, not charging.\n");
+ break;
+ default:
+ dev_err(chg->dev, "Unknown value read:%x\n",
+ data & PF1550_CHG_SNS_MASK);
+ }
+}
+
+static void pf1550_chg_vbus_isr(struct pf1550_charger *chg)
+{
+ enum power_supply_type old_type;
+ unsigned int data;
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_VBUS_SNS, &data)) {
+ dev_err(chg->dev, "Read VBUS_SNS error.\n");
+ return;
+ }
+
+ old_type = chg->psy_desc.type;
+
+ if (data & PF1550_VBUS_UVLO) {
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+ dev_dbg(chg->dev, "VBUS deattached.\n");
+ }
+ if (data & PF1550_VBUS_IN2SYS)
+ dev_dbg(chg->dev, "VBUS_IN2SYS_SNS.\n");
+ if (data & PF1550_VBUS_OVLO)
+ dev_dbg(chg->dev, "VBUS_OVLO_SNS.\n");
+ if (data & PF1550_VBUS_VALID) {
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
+ dev_dbg(chg->dev, "VBUS attached.\n");
+ }
+
+ if (old_type != chg->psy_desc.type)
+ power_supply_changed(chg->charger);
+}
+
+static irqreturn_t pf1550_charger_irq_handler(int irq, void *data)
+{
+ struct pf1550_charger *chg = data;
+
+ chg->irq = irq;
+ schedule_delayed_work(&chg->irq_work, msecs_to_jiffies(10));
+
+ return IRQ_HANDLED;
+}
+
+static void pf1550_charger_irq_work(struct work_struct *work)
+{
+ struct pf1550_charger *chg = container_of(to_delayed_work(work),
+ struct pf1550_charger,
+ irq_work);
+ int i, irq_type = -1;
+ unsigned int status;
+
+ if (!chg->charger)
+ return;
+
+ mutex_lock(&chg->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_charger_irqs); i++)
+ if (chg->irq == pf1550_charger_irqs[i].virq)
+ irq_type = pf1550_charger_irqs[i].irq;
+
+ switch (irq_type) {
+ case PF1550_CHARG_IRQ_BAT2SOCI:
+ dev_info(chg->dev, "BAT to SYS Overcurrent interrupt.\n");
+ break;
+ case PF1550_CHARG_IRQ_BATI:
+ pf1550_chg_bat_isr(chg);
+ break;
+ case PF1550_CHARG_IRQ_CHGI:
+ pf1550_chg_chg_isr(chg);
+ break;
+ case PF1550_CHARG_IRQ_VBUSI:
+ pf1550_chg_vbus_isr(chg);
+ break;
+ case PF1550_CHARG_IRQ_THMI:
+ dev_info(chg->dev, "Thermal interrupt.\n");
+ break;
+ default:
+ dev_err(chg->dev, "unknown interrupt occurred.\n");
+ }
+
+ if (regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_INT, &status))
+ dev_err(chg->dev, "Read CHG_INT error.\n");
+ if (regmap_write(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_INT, status))
+ dev_err(chg->dev, "clear CHG_INT error.\n");
+
+ mutex_unlock(&chg->mutex);
+}
+
+static enum power_supply_property pf1550_charger_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static int pf1550_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pf1550_charger *chg = power_supply_get_drvdata(psy);
+ struct regmap *regmap = chg->pf1550->regmap;
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ ret = pf1550_get_charger_state(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ ret = pf1550_get_charge_type(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ ret = pf1550_get_battery_health(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ ret = pf1550_get_present(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ ret = pf1550_get_online(regmap, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = pf1550_charger_model;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = pf1550_charger_manufacturer;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int pf1550_set_constant_volt(struct pf1550_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ if (uvolt >= 3500000 && uvolt <= 4440000) {
+ data = 8 + (uvolt - 3500000) / 20000;
+ } else {
+ dev_err(chg->dev, "Wrong value for constant voltage\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(chg->dev, "Charging constant voltage: %u (0x%x)\n", uvolt,
+ data);
+
+ return regmap_update_bits(chg->pf1550->regmap,
+ PF1550_CHARG_REG_BATT_REG,
+ PF1550_CHARG_REG_BATT_REG_CHGCV_MASK, data);
+}
+
+static int pf1550_set_min_system_volt(struct pf1550_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ switch (uvolt) {
+ case 3500000:
+ data = 0x0;
+ break;
+ case 3700000:
+ data = 0x1;
+ break;
+ case 4300000:
+ data = 0x2;
+ break;
+ default:
+ dev_err(chg->dev, "Wrong value for minimum system voltage\n");
+ return -EINVAL;
+ }
+
+ data <<= PF1550_CHARG_REG_BATT_REG_VMINSYS_SHIFT;
+
+ dev_dbg(chg->dev, "Minimum system regulation voltage: %u (0x%x)\n",
+ uvolt, data);
+
+ return regmap_update_bits(chg->pf1550->regmap,
+ PF1550_CHARG_REG_BATT_REG,
+ PF1550_CHARG_REG_BATT_REG_VMINSYS_MASK, data);
+}
+
+static int pf1550_set_thermal_regulation_temp(struct pf1550_charger *chg,
+ unsigned int cels)
+{
+ unsigned int data;
+
+ switch (cels) {
+ case 60:
+ data = 0x0;
+ break;
+ case 75:
+ data = 0x1;
+ break;
+ case 90:
+ data = 0x2;
+ break;
+ case 105:
+ data = 0x3;
+ break;
+ default:
+ dev_err(chg->dev, "Wrong value for thermal temperature\n");
+ return -EINVAL;
+ }
+
+ data <<= PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_SHIFT;
+
+ dev_dbg(chg->dev, "Thermal regulation loop temperature: %u (0x%x)\n",
+ cels, data);
+
+ return regmap_update_bits(chg->pf1550->regmap,
+ PF1550_CHARG_REG_THM_REG_CNFG,
+ PF1550_CHARG_REG_THM_REG_CNFG_REGTEMP_MASK, data);
+}
+
+/*
+ * Sets charger registers to proper and safe default values.
+ */
+static int pf1550_reg_init(struct pf1550_charger *chg)
+{
+ int ret;
+ unsigned int data;
+
+ /* Unmask charger interrupt, mask DPMI and reserved bit */
+ ret = regmap_write(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_INT_MASK,
+ PF1550_CHG_INT_MASK);
+ if (ret) {
+ dev_err(chg->dev, "Error unmask charger interrupt: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_read(chg->pf1550->regmap, PF1550_CHARG_REG_VBUS_SNS,
+ &data);
+ if (ret) {
+ dev_err(chg->dev, "Read charg vbus_sns error: %d\n", ret);
+ return ret;
+ }
+
+ if (data & PF1550_VBUS_VALID)
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
+
+ ret = pf1550_set_constant_volt(chg, chg->constant_volt);
+ if (ret)
+ return ret;
+
+ ret = pf1550_set_min_system_volt(chg, chg->min_system_volt);
+ if (ret)
+ return ret;
+
+ ret = pf1550_set_thermal_regulation_temp(chg,
+ chg->thermal_regulation_temp);
+ if (ret)
+ return ret;
+
+ /* Turn on charger */
+ ret = regmap_write(chg->pf1550->regmap, PF1550_CHARG_REG_CHG_OPER,
+ PF1550_CHG_TURNON);
+ if (ret) {
+ dev_err(chg->dev, "Error turn on charger: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int pf1550_dt_init(struct device *dev, struct pf1550_charger *chg)
+{
+ struct device_node *np = dev->of_node;
+
+ if (!np) {
+ dev_err(dev, "no charger OF node\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(np, "fsl,constant-microvolt",
+ &chg->constant_volt))
+ chg->constant_volt = PF1550_DEFAULT_CONSTANT_VOLT;
+
+ if (of_property_read_u32(np, "fsl,min-system-microvolt",
+ &chg->min_system_volt))
+ chg->min_system_volt = PF1550_DEFAULT_MIN_SYSTEM_VOLT;
+
+ if (of_property_read_u32(np, "fsl,thermal-regulation",
+ &chg->thermal_regulation_temp))
+ chg->thermal_regulation_temp = PF1550_DEFAULT_THERMAL_TEMP;
+
+ return 0;
+}
+
+static int pf1550_charger_probe(struct platform_device *pdev)
+{
+ struct pf1550_charger *chg;
+ struct power_supply_config psy_cfg = {};
+ struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
+ int i, ret;
+
+ chg = devm_kzalloc(&pdev->dev, sizeof(*chg), GFP_KERNEL);
+ if (!chg)
+ return -ENOMEM;
+
+ chg->dev = &pdev->dev;
+ chg->pf1550 = pf1550;
+
+ platform_set_drvdata(pdev, chg);
+
+ ret = pf1550_dt_init(&pdev->dev, chg);
+ if (ret)
+ return ret;
+
+ mutex_init(&chg->mutex);
+
+ INIT_DELAYED_WORK(&chg->irq_work, pf1550_charger_irq_work);
+
+ for (i = 0; i < ARRAY_SIZE(pf1550_charger_irqs); i++) {
+ struct pf1550_irq_info *charger_irq =
+ &pf1550_charger_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(pf1550->irq_data_charger,
+ charger_irq->irq);
+ if (!virq)
+ return -EINVAL;
+
+ charger_irq->virq = virq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ pf1550_charger_irq_handler,
+ IRQF_NO_SUSPEND,
+ charger_irq->name, chg);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d, error :%d)\n",
+ charger_irq->irq, ret);
+ return ret;
+ }
+ }
+
+ psy_cfg.drv_data = chg;
+
+ chg->psy_desc.name = PF1550_CHARGER_NAME;
+ chg->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+ chg->psy_desc.get_property = pf1550_charger_get_property;
+ chg->psy_desc.properties = pf1550_charger_props;
+ chg->psy_desc.num_properties = ARRAY_SIZE(pf1550_charger_props);
+
+ chg->charger = devm_power_supply_register(&pdev->dev, &chg->psy_desc,
+ &psy_cfg);
+ if (IS_ERR(chg->charger)) {
+ dev_err(&pdev->dev, "failed: power supply register\n");
+ ret = PTR_ERR(chg->charger);
+ return ret;
+ }
+
+ ret = pf1550_reg_init(chg);
+
+ return ret;
+}
+
+static void pf1550_charger_remove(struct platform_device *pdev)
+{
+ struct pf1550_charger *chg = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&chg->irq_work);
+}
+
+static const struct platform_device_id pf1550_charger_id[] = {
+ { "pf1550-charger", 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, pf1550_charger_id);
+
+static struct platform_driver pf1550_charger_driver = {
+ .driver = {
+ .name = "pf1550-charger",
+ },
+ .probe = pf1550_charger_probe,
+ .remove = pf1550_charger_remove,
+ .id_table = pf1550_charger_id,
+};
+module_platform_driver(pf1550_charger_driver);
+
+MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
+MODULE_DESCRIPTION("PF1550 charger driver");
+MODULE_LICENSE("GPL v2");
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 9/9] MAINTAINERS: add an entry for pf1550 mfd driver
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
` (7 preceding siblings ...)
2025-05-16 18:58 ` [PATCH v2 8/9] power: supply: pf1550: add battery charger support Samuel Kayode
@ 2025-05-16 18:59 ` Samuel Kayode
8 siblings, 0 replies; 23+ messages in thread
From: Samuel Kayode @ 2025-05-16 18:59 UTC (permalink / raw)
To: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
Add MAINTAINERS entry for pf1550 PMIC.
Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
---
MAINTAINERS | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4084fb7c496b..62d121380f7f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17477,6 +17477,17 @@ F: Documentation/devicetree/bindings/clock/imx*
F: drivers/clk/imx/
F: include/dt-bindings/clock/imx*
+NXP PF1550 PMIC MFD DRIVER
+M: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
+S: Maintained
+F: Documentation/devicetree/bindings/*/*pf1550.yaml
+F: Documentation/devicetree/bindings/*/pf1550*.yaml
+F: drivers/input/keyboard/pf1550_onkey.c
+F: drivers/mfd/pf1550.c
+F: drivers/power/supply/pf1550_charger.c
+F: drivers/regulator/pf1550_regulator.c
+F: include/linux/mfd/pfd1550.h
+
NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
M: Jagan Teki <jagan@amarulasolutions.com>
S: Maintained
--
2.49.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v2 7/9] input: pf1550: add onkey support
2025-05-16 18:57 ` [PATCH v2 7/9] input: pf1550: add onkey support Samuel Kayode
@ 2025-05-16 22:55 ` Dmitry Torokhov
2025-05-21 21:00 ` Samuel Kayode
2025-05-18 16:03 ` kernel test robot
1 sibling, 1 reply; 23+ messages in thread
From: Dmitry Torokhov @ 2025-05-16 22:55 UTC (permalink / raw)
To: Samuel Kayode
Cc: Lee Jones, Liam Girdwood, Mark Brown, Sebastian Reichel,
Robin Gong, linux-kernel, linux-pm, linux-imx, linux-input,
Abel Vesa, Abel Vesa, Robin Gong, Enric Balletbo Serra
Hi Samuel,
On Fri, May 16, 2025 at 02:57:28PM -0400, Samuel Kayode wrote:
> Add support for the onkey of the pf1550 PMIC.
>
> Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> ---
> drivers/input/keyboard/Kconfig | 8 ++
> drivers/input/keyboard/Makefile | 1 +
> drivers/input/keyboard/pf1550_onkey.c | 200 ++++++++++++++++++++++++++
> 3 files changed, 209 insertions(+)
> create mode 100644 drivers/input/keyboard/pf1550_onkey.c
>
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 721ab69e84ac..b01decc03ab9 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -444,6 +444,14 @@ config KEYBOARD_SNVS_PWRKEY
> To compile this driver as a module, choose M here; the
> module will be called snvs_pwrkey.
With the exception of snvs-pwrkey, all other onkey/pwrkey drivers live
in drivers/input/misc, please move them there. drivers/input/keyboard is
really for real keyboard devices.
>
> +config KEYBOARD_PF1550_ONKEY
> + tristate "PF1550 OnKey Driver"
> + depends on MFD_PF1550
> + depends on OF
I do not think your driver has any direct dependencies on OF, especially
if you switch to using generic device properties (device_property_read_*).
> + help
> + This is onkey driver for PF1550 pmic, onkey can trigger release
> + and 1s(push hold), 2s, 3s, 4s, 8s interrupt for long press detect
> +
> config KEYBOARD_IMX
> tristate "IMX keypad support"
> depends on ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index 1e0721c30709..8a6feae3ddb1 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
> obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
> obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
> obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o
> +obj-$(CONFIG_KEYBOARD_PF1550_ONKEY) += pf1550_onkey.o
> obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
> obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
> obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
> diff --git a/drivers/input/keyboard/pf1550_onkey.c b/drivers/input/keyboard/pf1550_onkey.c
> new file mode 100644
> index 000000000000..b0601acf893d
> --- /dev/null
> +++ b/drivers/input/keyboard/pf1550_onkey.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for the PF1550 ON_KEY
> + * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
I don't think you actually need io.h
> +#include <linux/jiffies.h>
and neither jiffies.h. Please audit your includes.
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mfd/pf1550.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +struct onkey_drv_data {
> + struct device *dev;
> + struct pf1550_dev *pf1550;
> + int irq;
> + int keycode;
> + int wakeup;
> + struct input_dev *input;
> +};
> +
> +static struct pf1550_irq_info pf1550_onkey_irqs[] = {
> + { PF1550_ONKEY_IRQ_PUSHI, "release" },
> + { PF1550_ONKEY_IRQ_1SI, "1S" },
> + { PF1550_ONKEY_IRQ_2SI, "2S" },
> + { PF1550_ONKEY_IRQ_3SI, "3S" },
> + { PF1550_ONKEY_IRQ_4SI, "4S" },
> + { PF1550_ONKEY_IRQ_8SI, "8S" },
> +};
> +
> +static irqreturn_t pf1550_onkey_irq_handler(int irq, void *data)
> +{
> + struct onkey_drv_data *onkey = data;
> + int i, state, irq_type = -1;
> +
> + onkey->irq = irq;
> +
> + for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++)
> + if (onkey->irq == pf1550_onkey_irqs[i].virq)
> + irq_type = pf1550_onkey_irqs[i].irq;
> + switch (irq_type) {
> + case PF1550_ONKEY_IRQ_PUSHI:
> + state = 0;
> + break;
> + case PF1550_ONKEY_IRQ_1SI:
> + case PF1550_ONKEY_IRQ_2SI:
> + case PF1550_ONKEY_IRQ_3SI:
> + case PF1550_ONKEY_IRQ_4SI:
> + case PF1550_ONKEY_IRQ_8SI:
> + state = 1;
> + break;
> + default:
> + dev_err(onkey->dev, "onkey interrupt: irq %d occurred\n",
> + irq_type);
> + return IRQ_HANDLED;
> + }
> +
> + input_event(onkey->input, EV_KEY, onkey->keycode, state);
> + input_sync(onkey->input);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int pf1550_onkey_probe(struct platform_device *pdev)
> +{
> + struct onkey_drv_data *onkey;
> + struct input_dev *input = NULL;
This initialization is not needed.
> + struct device_node *np = pdev->dev.of_node;
Please switch to generic device properties and stop referencing of_node.
> + struct pf1550_dev *pf1550 = dev_get_drvdata(pdev->dev.parent);
> + int i, error;
> +
> + if (!np)
> + return -ENODEV;
> +
> + onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
> + if (!onkey)
> + return -ENOMEM;
> +
> + if (of_property_read_u32(np, "linux,keycodes", &onkey->keycode)) {
> + onkey->keycode = KEY_POWER;
> + dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
Maybe make this property mandatory?
> + }
> +
> + onkey->wakeup = of_property_read_bool(np, "wakeup-source");
> +
> + input = devm_input_allocate_device(&pdev->dev);
> + if (!input) {
> + dev_err(&pdev->dev, "failed to allocate the input device\n");
> + return -ENOMEM;
> + }
> +
> + input->name = pdev->name;
> + input->phys = "pf1550-onkey/input0";
> + input->id.bustype = BUS_HOST;
> +
> + input_set_capability(input, EV_KEY, onkey->keycode);
> +
> + for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
> + struct pf1550_irq_info *onkey_irq =
> + &pf1550_onkey_irqs[i];
> + unsigned int virq = 0;
> +
> + virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
> + onkey_irq->irq);
> + if (!virq)
> + return -EINVAL;
> +
> + onkey_irq->virq = virq;
I think this kind of mapping needs to be done in the core part of your
driver.
> +
> + error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
> + pf1550_onkey_irq_handler,
> + IRQF_NO_SUSPEND,
> + onkey_irq->name, onkey);
> + if (error) {
> + dev_err(&pdev->dev,
> + "failed: irq request (IRQ: %d, error :%d)\n",
> + onkey_irq->irq, error);
> + return error;
> + }
> + }
> +
> + error = input_register_device(input);
> + if (error < 0) {
Input API return 0 or negative, so simply "if (error) { ... }"
> + dev_err(&pdev->dev, "failed to register input device\n");
> + input_free_device(input);
You are using devm, so no need to free it manually.
> + return error;
> + }
> +
> + onkey->input = input;
You are too late. Interrupts are already active and you may dereference
onkey->input from your ISR.
> + onkey->pf1550 = pf1550;
> + platform_set_drvdata(pdev, onkey);
> +
> + device_init_wakeup(&pdev->dev, onkey->wakeup);
> +
> + return 0;
> +}
> +
> +static int pf1550_onkey_suspend(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
> +
> + if (!device_may_wakeup(&pdev->dev))
> + regmap_write(onkey->pf1550->regmap,
> + PF1550_PMIC_REG_ONKEY_INT_MASK0,
> + ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
> + ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI);
> + else
> + enable_irq_wake(onkey->pf1550->irq);
This is suspicious that you need to twiddle the state of the main
interrupt line. I'd expect you manipulate your own interrupts and this
all cascades up.
> +
> + return 0;
> +}
> +
> +static int pf1550_onkey_resume(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
> +
> + if (!device_may_wakeup(&pdev->dev))
> + regmap_write(onkey->pf1550->regmap,
> + PF1550_PMIC_REG_ONKEY_INT_MASK0,
> + ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
> + ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
> + else
> + disable_irq_wake(onkey->pf1550->irq);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id pf1550_onkey_ids[] = {
> + { .compatible = "fsl,pf1550-onkey" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, pf1550_onkey_ids);
> +
> +static SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend,
> + pf1550_onkey_resume);
> +
> +static struct platform_driver pf1550_onkey_driver = {
> + .driver = {
> + .name = "pf1550-onkey",
> + .pm = &pf1550_onkey_pm_ops,
> + .of_match_table = pf1550_onkey_ids,
> + },
> + .probe = pf1550_onkey_probe,
> +};
> +module_platform_driver(pf1550_onkey_driver);
> +
> +MODULE_AUTHOR("Freescale Semiconductor");
> +MODULE_DESCRIPTION("PF1550 onkey Driver");
> +MODULE_LICENSE("GPL v2");
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/9] dt-bindings: power: supply: add pf1550
2025-05-16 18:47 ` [PATCH v2 1/9] dt-bindings: power: supply: add pf1550 Samuel Kayode
@ 2025-05-17 11:12 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-17 11:12 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
On 16/05/2025 20:47, Samuel Kayode wrote:
> Add the DT binding document for the battery charger module of pf1550.
>
> Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> ---
> .../bindings/power/supply/pf1550_charger.yaml | 44 +++++++++++++++++++
> 1 file changed, 44 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
Filename matching compatible.
>
> diff --git a/Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml b/Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
> new file mode 100644
> index 000000000000..10fc0b35917c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/pf1550_charger.yaml
> @@ -0,0 +1,44 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/power/supply/pf1550_charger.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Battery charger driver for PF1550 PMIC from NXP.
Describe hardware, not driver.
Also drop full stop.
<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.
Please kindly resend and include all necessary To/Cc entries.
</form letter>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/9] dt-bindings: regulator: add pf1550
2025-05-16 18:50 ` [PATCH v2 2/9] dt-bindings: regulator: " Samuel Kayode
@ 2025-05-17 11:13 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-17 11:13 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokho, Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
On 16/05/2025 20:50, Samuel Kayode wrote:
> Add the DT binding document for pf1550 regulators.
>
> Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> ---
> .../devicetree/bindings/regulator/pf1550.yaml | 35 +++++++++++++++++++
> 1 file changed, 35 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/regulator/pf1550.yaml
>
> diff --git a/Documentation/devicetree/bindings/regulator/pf1550.yaml b/Documentation/devicetree/bindings/regulator/pf1550.yaml
> new file mode 100644
> index 000000000000..a684ab974496
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/pf1550.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/regulator/pf1550.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Regulators for PF1550 PMIC from NXP.
Same comments as for other patch.
> +
> +maintainers:
> + - Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> +
> +description: |
> + This module is part of the PF1550 MFD device. For more details
> + see Documentation/devicetree/bindings/mfd/pf1550.yaml.
> +
> + The regulator controller is represented as a sub-node of the PMIC node
> + on the device tree.
> +
> + The device has three LDO regulators, three buck converters and a DDR
> + termination reference voltage.
> +
> +properties:
> + compatible:
> + const: fsl,pf1550-regulator
This looks not needed.
> +
> +patternProperties:
> + "^(LDO[1-3]|SW[1-3]|VREFADDR)$":
Node names are lowercase.
> + $ref: regulator.yaml#
> + unevaluatedProperties: false
> +
> +required:
> + - compatible
Missing blank line
> +additionalProperties: false
> +
> +...
<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.
Please kindly resend and include all necessary To/Cc entries.
</form letter>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/9] dt-bindings: input: add pf1550
2025-05-16 18:52 ` [PATCH v2 3/9] dt-bindings: input: " Samuel Kayode
@ 2025-05-17 11:14 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-17 11:14 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
On 16/05/2025 20:52, Samuel Kayode wrote:
> Add the DT binding document for the onkey module of pf1550.
>
> Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> ---
> .../bindings/input/pf1550_onkey.yaml | 31 +++++++++++++++++++
Same comments as for other patch.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/9] dt-bindings: mfd: add pf1550
2025-05-16 18:53 ` [PATCH v2 4/9] dt-bindings: mfd: " Samuel Kayode
@ 2025-05-17 11:16 ` Krzysztof Kozlowski
2025-05-21 16:16 ` Samuel Kayode
0 siblings, 1 reply; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-17 11:16 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, inux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
On 16/05/2025 20:53, Samuel Kayode wrote:
> Add a DT binding document for pf1550 PMIC. This describes the core mfd
> device.
>
> Signed-off-by: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
You need to explain the dependencies in the cover letter. There is
nothing there but you have clear dependency and all bindings must go via
one tree, unless you re-do this to use compatibles.
> ---
> .../devicetree/bindings/mfd/pf1550.yaml | 122 ++++++++++++++++++
Same comments.
> 1 file changed, 122 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/pf1550.yaml
>
> diff --git a/Documentation/devicetree/bindings/mfd/pf1550.yaml b/Documentation/devicetree/bindings/mfd/pf1550.yaml
> new file mode 100644
> index 000000000000..461bc13513eb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/pf1550.yaml
> @@ -0,0 +1,122 @@
> +# SPDX-License-Identifier: GPL-2.0
No.
Please run scripts/checkpatch.pl on the patches and fix reported
warnings. After that, run also 'scripts/checkpatch.pl --strict' on the
patches and (probably) fix more warnings. Some warnings can be ignored,
especially from --strict run, but the code here looks like it needs a
fix. Feel free to get in touch if the warning is not clear.
<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.
Please kindly resend and include all necessary To/Cc entries.
</form letter>
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/pf1550.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PF1550 low power PMIC from NXP.
Same comments
> +
> +maintainers:
> + - Samuel Kayode <samuel.kayode@savoirfairelinux.com>
> +
> +description: |
> + PF1550 is a low power PMIC providing battery charging and power supply for
> + low power IoT and wearable applications.
> +
> + For device-tree bindings of other sub-modules (regulator, power supply and
> + onkey) refer to the binding documents under the respective sub-system
> + directories.
> +
> +properties:
> + compatible:
> + const: fsl,pf1550
> +
> + reg:
> + description:
> + I2C device address.
Drop
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + regulators:
> + $ref: /schemas/regulator/pf1550.yaml
> +
> + charger:
> + $ref: /schemas/power/supply/pf1550_charger.yaml
> +
> + onkey:
> + $ref: /schemas/input/pf1550_onkey.yaml
This makes merging via separate trees not possible...
Just fold everything here, drop compatibles and then put binding in the
regulator. Unless children are re-usable which would justify
compatibles, but then please provide arguments for that.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 5/9] mfd: pf1550: add core mfd driver
2025-05-16 18:54 ` [PATCH v2 5/9] mfd: pf1550: add core mfd driver Samuel Kayode
@ 2025-05-17 11:18 ` Krzysztof Kozlowski
2025-05-20 13:25 ` kernel test robot
1 sibling, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-17 11:18 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
On 16/05/2025 20:54, Samuel Kayode wrote:
> +
> +static int pf1550_i2c_probe(struct i2c_client *i2c)
> +{
> + struct pf1550_dev *pf1550;
> + unsigned int reg_data = 0;
> + int ret = 0;
> +
> + pf1550 = devm_kzalloc(&i2c->dev,
> + sizeof(struct pf1550_dev), GFP_KERNEL);
sizeof(*)
> + if (!pf1550)
> + return -ENOMEM;
> +
> + i2c_set_clientdata(i2c, pf1550);
> + pf1550->dev = &i2c->dev;
> + pf1550->i2c = i2c;
> + pf1550->irq = i2c->irq;
> +
> + pf1550->regmap = devm_regmap_init_i2c(i2c, &pf1550_regmap_config);
> + if (IS_ERR(pf1550->regmap)) {
> + ret = PTR_ERR(pf1550->regmap);
> + dev_err(pf1550->dev, "failed to allocate register map: %d\n",
> + ret);
Syntax is always: return dev_err_probe
> + return ret;
> + }
> +
> + ret = regmap_read(pf1550->regmap, PF1550_PMIC_REG_DEVICE_ID, ®_data);
> + if (ret < 0 || reg_data != PF1550_DEVICE_ID) {
> + dev_err(pf1550->dev, "device not found!\n");
> + return ret;
Syntax is always: return dev_err_probe
> + }
> +
> + pf1550->type = PF1550;
> + dev_info(pf1550->dev, "pf1550 found.\n");
Drop. Drivers should be silent. This is really useless and just pollutes
log. See also coding style.
> +
> + ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap,
> + pf1550->irq,
> + IRQF_ONESHOT | IRQF_SHARED |
> + IRQF_TRIGGER_FALLING, 0,
> + &pf1550_regulator_irq_chip,
> + &pf1550->irq_data_regulator);
> + if (ret) {
> + dev_err(pf1550->dev, "failed to add irq1 chip: %d\n", ret);
> + return ret;
Syntax is always: return dev_err_probe
> + }
> +
> + ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap,
> + pf1550->irq,
> + IRQF_ONESHOT | IRQF_SHARED |
> + IRQF_TRIGGER_FALLING, 0,
> + &pf1550_onkey_irq_chip,
> + &pf1550->irq_data_onkey);
> + if (ret) {
> + dev_err(pf1550->dev, "failed to add irq3 chip: %d\n", ret);
> + return ret;
Syntax is always: return dev_err_probe
> + }
> +
> + ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap,
> + pf1550->irq,
> + IRQF_ONESHOT | IRQF_SHARED |
> + IRQF_TRIGGER_FALLING, 0,
> + &pf1550_charger_irq_chip,
> + &pf1550->irq_data_charger);
> + if (ret) {
> + dev_err(pf1550->dev, "failed to add irq4 chip: %d\n", ret);
> + return ret;
Syntax is always: return dev_err_probe
> + }
> +
> + return devm_mfd_add_devices(pf1550->dev, -1, pf1550_devs,
> + ARRAY_SIZE(pf1550_devs), NULL, 0, NULL);
> +}
> +
> +static const struct i2c_device_id pf1550_i2c_id[] = {
> + { "pf1550", PF1550 },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(i2c, pf1550_i2c_id);
Table IDs are next to each other.
> +
> +static int pf1550_suspend(struct device *dev)
> +{
> + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
> + struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
> +
> + if (device_may_wakeup(dev)) {
> + enable_irq_wake(pf1550->irq);
> + disable_irq(pf1550->irq);
> + }
> +
> + return 0;
> +}
> +
> +static int pf1550_resume(struct device *dev)
> +{
> + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
> + struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
> +
> + if (device_may_wakeup(dev)) {
> + disable_irq_wake(pf1550->irq);
> + enable_irq(pf1550->irq);
> + }
> +
> + return 0;
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(pf1550_pm, pf1550_suspend, pf1550_resume);
> +
> +static const struct of_device_id pf1550_dt_match[] = {
> + { .compatible = "fsl,pf1550" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, pf1550_dt_match);
> +
> +static struct i2c_driver pf1550_i2c_driver = {
> + .driver = {
> + .name = "pf1550",
> + .pm = pm_sleep_ptr(&pf1550_pm),
> + .of_match_table = of_match_ptr(pf1550_dt_match),
Drop of_match_ptr, you have warnings here.
> + },
> + .probe = pf1550_i2c_probe,
> + .id_table = pf1550_i2c_id,
> +};
> +
> +module_i2c_driver(pf1550_i2c_driver);
> +
> +MODULE_DESCRIPTION("Freescale PF1550 multi-function core driver");
> +MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>");
> +MODULE_LICENSE("GPL v2");
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 8/9] power: supply: pf1550: add battery charger support
2025-05-16 18:58 ` [PATCH v2 8/9] power: supply: pf1550: add battery charger support Samuel Kayode
@ 2025-05-17 11:20 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-17 11:20 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: linux-kernel, linux-pm, linux-imx, linux-input, Abel Vesa,
Abel Vesa, Robin Gong, Enric Balletbo Serra
On 16/05/2025 20:58, Samuel Kayode wrote:
> +
> + chg->psy_desc.name = PF1550_CHARGER_NAME;
> + chg->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY;
> + chg->psy_desc.get_property = pf1550_charger_get_property;
> + chg->psy_desc.properties = pf1550_charger_props;
> + chg->psy_desc.num_properties = ARRAY_SIZE(pf1550_charger_props);
> +
> + chg->charger = devm_power_supply_register(&pdev->dev, &chg->psy_desc,
> + &psy_cfg);
> + if (IS_ERR(chg->charger)) {
> + dev_err(&pdev->dev, "failed: power supply register\n");
> + ret = PTR_ERR(chg->charger);
Same comments as on patches before.
> + return ret;
> + }
> +
> + ret = pf1550_reg_init(chg);
> +
> + return ret;
> +}
> +
> +static void pf1550_charger_remove(struct platform_device *pdev)
> +{
> + struct pf1550_charger *chg = platform_get_drvdata(pdev);
> +
> + cancel_delayed_work_sync(&chg->irq_work);
> +}
> +
> +static const struct platform_device_id pf1550_charger_id[] = {
> + { "pf1550-charger", 0 },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(platform, pf1550_charger_id);
> +
> +static struct platform_driver pf1550_charger_driver = {
> + .driver = {
> + .name = "pf1550-charger",
> + },
> + .probe = pf1550_charger_probe,
> + .remove = pf1550_charger_remove,
> + .id_table = pf1550_charger_id,
And this proves that your compatible in the binding is also useless. Not
used in the driver itself
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 6/9] regulator: pf1550: add support for regulator
2025-05-16 18:55 ` [PATCH v2 6/9] regulator: pf1550: add support for regulator Samuel Kayode
@ 2025-05-17 20:13 ` kernel test robot
0 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2025-05-17 20:13 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: oe-kbuild-all, linux-kernel, linux-pm, linux-imx, linux-input,
Abel Vesa, Enric Balletbo Serra
Hi Samuel,
kernel test robot noticed the following build warnings:
[auto build test WARNING on b1d8766052eb0534b27edda8af1865d53621bd6a]
url: https://github.com/intel-lab-lkp/linux/commits/Samuel-Kayode/dt-bindings-power-supply-add-pf1550/20250517-030259
base: b1d8766052eb0534b27edda8af1865d53621bd6a
patch link: https://lore.kernel.org/r/4dd316e06a66634b5af13f1faedc985753b061bc.1747409892.git.samuel.kayode%40savoirfairelinux.com
patch subject: [PATCH v2 6/9] regulator: pf1550: add support for regulator
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505180341.aMQhbUVJ-lkp@intel.com/
includecheck warnings: (new ones prefixed by >>)
>> drivers/regulator/pf1550.c: linux/regulator/machine.h is included more than once.
>> drivers/regulator/pf1550.c: linux/slab.h is included more than once.
vim +19 drivers/regulator/pf1550.c
> 19 #include <linux/regulator/machine.h>
20 #include <linux/regulator/of_regulator.h>
> 21 #include <linux/regulator/machine.h>
22 #include <linux/platform_device.h>
23
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 7/9] input: pf1550: add onkey support
2025-05-16 18:57 ` [PATCH v2 7/9] input: pf1550: add onkey support Samuel Kayode
2025-05-16 22:55 ` Dmitry Torokhov
@ 2025-05-18 16:03 ` kernel test robot
1 sibling, 0 replies; 23+ messages in thread
From: kernel test robot @ 2025-05-18 16:03 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: oe-kbuild-all, linux-kernel, linux-pm, linux-imx, linux-input,
Abel Vesa, Enric Balletbo Serra
Hi Samuel,
kernel test robot noticed the following build warnings:
[auto build test WARNING on b1d8766052eb0534b27edda8af1865d53621bd6a]
url: https://github.com/intel-lab-lkp/linux/commits/Samuel-Kayode/dt-bindings-power-supply-add-pf1550/20250517-030259
base: b1d8766052eb0534b27edda8af1865d53621bd6a
patch link: https://lore.kernel.org/r/7d80afedf1ad9e98c9739163751bcb2785009e74.1747409892.git.samuel.kayode%40savoirfairelinux.com
patch subject: [PATCH v2 7/9] input: pf1550: add onkey support
config: loongarch-allyesconfig (https://download.01.org/0day-ci/archive/20250518/202505182355.Of8g2bwa-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250518/202505182355.Of8g2bwa-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505182355.Of8g2bwa-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/input/keyboard/pf1550_onkey.c: In function 'pf1550_onkey_resume':
>> drivers/input/keyboard/pf1550_onkey.c:171:30: warning: conversion from 'long unsigned int' to 'unsigned int' changes value from '18446744073709551552' to '4294967232' [-Woverflow]
171 | ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172 | ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +171 drivers/input/keyboard/pf1550_onkey.c
162
163 static int pf1550_onkey_resume(struct device *dev)
164 {
165 struct platform_device *pdev = to_platform_device(dev);
166 struct onkey_drv_data *onkey = platform_get_drvdata(pdev);
167
168 if (!device_may_wakeup(&pdev->dev))
169 regmap_write(onkey->pf1550->regmap,
170 PF1550_PMIC_REG_ONKEY_INT_MASK0,
> 171 ~(ONKEY_IRQ_PUSHI | ONKEY_IRQ_1SI | ONKEY_IRQ_2SI |
172 ONKEY_IRQ_3SI | ONKEY_IRQ_4SI | ONKEY_IRQ_8SI));
173 else
174 disable_irq_wake(onkey->pf1550->irq);
175
176 return 0;
177 }
178
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 5/9] mfd: pf1550: add core mfd driver
2025-05-16 18:54 ` [PATCH v2 5/9] mfd: pf1550: add core mfd driver Samuel Kayode
2025-05-17 11:18 ` Krzysztof Kozlowski
@ 2025-05-20 13:25 ` kernel test robot
1 sibling, 0 replies; 23+ messages in thread
From: kernel test robot @ 2025-05-20 13:25 UTC (permalink / raw)
To: Samuel Kayode, Lee Jones, Liam Girdwood, Mark Brown,
Dmitry Torokhov, Sebastian Reichel, Robin Gong
Cc: oe-kbuild-all, linux-kernel, linux-pm, linux-imx, linux-input,
Abel Vesa, Enric Balletbo Serra
Hi Samuel,
kernel test robot noticed the following build warnings:
[auto build test WARNING on b1d8766052eb0534b27edda8af1865d53621bd6a]
url: https://github.com/intel-lab-lkp/linux/commits/Samuel-Kayode/dt-bindings-power-supply-add-pf1550/20250517-030259
base: b1d8766052eb0534b27edda8af1865d53621bd6a
patch link: https://lore.kernel.org/r/85004e02a5177aef6334fc30494bb3924a58f1de.1747409892.git.samuel.kayode%40savoirfairelinux.com
patch subject: [PATCH v2 5/9] mfd: pf1550: add core mfd driver
config: i386-randconfig-r072-20250520 (https://download.01.org/0day-ci/archive/20250520/202505202005.snxGxund-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250520/202505202005.snxGxund-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505202005.snxGxund-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/mfd/pf1550.c:234:34: warning: 'pf1550_dt_match' defined but not used [-Wunused-const-variable=]
234 | static const struct of_device_id pf1550_dt_match[] = {
| ^~~~~~~~~~~~~~~
vim +/pf1550_dt_match +234 drivers/mfd/pf1550.c
233
> 234 static const struct of_device_id pf1550_dt_match[] = {
235 { .compatible = "fsl,pf1550" },
236 { /* sentinel */ }
237 };
238 MODULE_DEVICE_TABLE(of, pf1550_dt_match);
239
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/9] dt-bindings: mfd: add pf1550
2025-05-17 11:16 ` Krzysztof Kozlowski
@ 2025-05-21 16:16 ` Samuel Kayode
2025-05-21 16:22 ` Krzysztof Kozlowski
0 siblings, 1 reply; 23+ messages in thread
From: Samuel Kayode @ 2025-05-21 16:16 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong, linux-kernel, linux-pm, linux-imx,
linux-input, Abel Vesa, Abel Vesa, Robin Gong,
Enric Balletbo Serra, Conor Dooley, devicetree, Rob Herring
On Sat, May 17, 2025 at 01:16:38PM +0200, Krzysztof Kozlowski wrote:
> > + maxItems: 1
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + regulators:
> > + $ref: /schemas/regulator/pf1550.yaml
> > +
> > + charger:
> > + $ref: /schemas/power/supply/pf1550_charger.yaml
> > +
> > + onkey:
> > + $ref: /schemas/input/pf1550_onkey.yaml
>
> This makes merging via separate trees not possible...
>
> Just fold everything here, drop compatibles and then put binding in the
> regulator. Unless children are re-usable which would justify
> compatibles, but then please provide arguments for that.
Yes, compatibles are not needed for the children. For adding binding to the
regulator, did you mean for all children: charger and onkey included? So,
replacing the separate yaml for all children with bindings in the mfd yaml?
Thanks,
Sam
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/9] dt-bindings: mfd: add pf1550
2025-05-21 16:16 ` Samuel Kayode
@ 2025-05-21 16:22 ` Krzysztof Kozlowski
0 siblings, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-21 16:22 UTC (permalink / raw)
To: Samuel Kayode
Cc: Lee Jones, Liam Girdwood, Mark Brown, Dmitry Torokhov,
Sebastian Reichel, Robin Gong, linux-kernel, linux-pm, linux-imx,
linux-input, Abel Vesa, Abel Vesa, Robin Gong,
Enric Balletbo Serra, Conor Dooley, devicetree, Rob Herring
On 21/05/2025 18:16, Samuel Kayode wrote:
> On Sat, May 17, 2025 at 01:16:38PM +0200, Krzysztof Kozlowski wrote:
>>> + maxItems: 1
>>> +
>>> + interrupts:
>>> + maxItems: 1
>>> +
>>> + regulators:
>>> + $ref: /schemas/regulator/pf1550.yaml
>>> +
>>> + charger:
>>> + $ref: /schemas/power/supply/pf1550_charger.yaml
>>> +
>>> + onkey:
>>> + $ref: /schemas/input/pf1550_onkey.yaml
>>
>> This makes merging via separate trees not possible...
>>
>> Just fold everything here, drop compatibles and then put binding in the
>> regulator. Unless children are re-usable which would justify
>> compatibles, but then please provide arguments for that.
>
> Yes, compatibles are not needed for the children. For adding binding to the
> regulator, did you mean for all children: charger and onkey included? So,
> replacing the separate yaml for all children with bindings in the mfd yaml?
Up to you. Onkey looks small so could be folded for sure, but other
bindings are not big either, so I would personally fold everything.
Otherwise you will need to be sure MFD is not applied before they reach
mainline.
Due to lack of testing I did not review charger patch, but just after
quick glance I see already that you miss power supply ref, thus it seems
you duplicate some of the existing properties from monitored-battery.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 7/9] input: pf1550: add onkey support
2025-05-16 22:55 ` Dmitry Torokhov
@ 2025-05-21 21:00 ` Samuel Kayode
0 siblings, 0 replies; 23+ messages in thread
From: Samuel Kayode @ 2025-05-21 21:00 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Lee Jones, Liam Girdwood, Mark Brown, Sebastian Reichel,
Robin Gong, linux-kernel, linux-pm, linux-imx, linux-input,
Abel Vesa, Abel Vesa, Robin Gong, Enric Balletbo Serra,
Krzysztof Kozlowski, devicetree, Conor Dooley, Rob Herring
On Fri, May 16, 2025 at 03:55:02PM -0700, Dmitry Torokhov wrote:
> > + input->name = pdev->name;
> > + input->phys = "pf1550-onkey/input0";
> > + input->id.bustype = BUS_HOST;
> > +
> > + input_set_capability(input, EV_KEY, onkey->keycode);
> > +
> > + for (i = 0; i < ARRAY_SIZE(pf1550_onkey_irqs); i++) {
> > + struct pf1550_irq_info *onkey_irq =
> > + &pf1550_onkey_irqs[i];
> > + unsigned int virq = 0;
> > +
> > + virq = regmap_irq_get_virq(pf1550->irq_data_onkey,
> > + onkey_irq->irq);
> > + if (!virq)
> > + return -EINVAL;
> > +
> > + onkey_irq->virq = virq;
>
> I think this kind of mapping needs to be done in the core part of your
> driver.
>
Without doing the mapping in the MFD children, a list of all virqs for the PMIC
would have to be maintained in addition to the (regmap_irq) irqs. Perhaps,
there is a better way to implement this?
> > +
> > + error = devm_request_threaded_irq(&pdev->dev, virq, NULL,
> > + pf1550_onkey_irq_handler,
> > + IRQF_NO_SUSPEND,
> > + onkey_irq->name, onkey);
Thanks,
Sam
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2025-05-21 21:00 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-16 18:29 [PATCH v2 0/9] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
2025-05-16 18:47 ` [PATCH v2 1/9] dt-bindings: power: supply: add pf1550 Samuel Kayode
2025-05-17 11:12 ` Krzysztof Kozlowski
2025-05-16 18:50 ` [PATCH v2 2/9] dt-bindings: regulator: " Samuel Kayode
2025-05-17 11:13 ` Krzysztof Kozlowski
2025-05-16 18:52 ` [PATCH v2 3/9] dt-bindings: input: " Samuel Kayode
2025-05-17 11:14 ` Krzysztof Kozlowski
2025-05-16 18:53 ` [PATCH v2 4/9] dt-bindings: mfd: " Samuel Kayode
2025-05-17 11:16 ` Krzysztof Kozlowski
2025-05-21 16:16 ` Samuel Kayode
2025-05-21 16:22 ` Krzysztof Kozlowski
2025-05-16 18:54 ` [PATCH v2 5/9] mfd: pf1550: add core mfd driver Samuel Kayode
2025-05-17 11:18 ` Krzysztof Kozlowski
2025-05-20 13:25 ` kernel test robot
2025-05-16 18:55 ` [PATCH v2 6/9] regulator: pf1550: add support for regulator Samuel Kayode
2025-05-17 20:13 ` kernel test robot
2025-05-16 18:57 ` [PATCH v2 7/9] input: pf1550: add onkey support Samuel Kayode
2025-05-16 22:55 ` Dmitry Torokhov
2025-05-21 21:00 ` Samuel Kayode
2025-05-18 16:03 ` kernel test robot
2025-05-16 18:58 ` [PATCH v2 8/9] power: supply: pf1550: add battery charger support Samuel Kayode
2025-05-17 11:20 ` Krzysztof Kozlowski
2025-05-16 18:59 ` [PATCH v2 9/9] MAINTAINERS: add an entry for pf1550 mfd driver Samuel Kayode
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).