From 0a10dc6861f3d18487b042634a12610d9216bb27 Mon Sep 17 00:00:00 2001
From: Yann Gautier <yann.gautier@st.com>
Date: Tue, 7 May 2019 15:16:57 +0200
Subject: [PATCH] pmic: stm32mp_pmic: add regulator enable/disable functions

These functions will be used through the stm32mp_regulator framework.
The plat_bind_regulator function is updated to manage PMIC.

Change-Id: I7d92eb1c4765dc3048c7290a6e3e013b2c5b4203
Signed-off-by: Yann Gautier <yann.gautier@st.com>
---
 drivers/st/pmic/stm32mp_pmic.c      | 56 +++++++++++++++++++++++++++++
 include/drivers/st/stm32mp_pmic.h   |  5 +++
 plat/st/stm32mp1/stm32mp1_private.c | 11 ++++++
 3 files changed, 72 insertions(+)

diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index b2bb482f9..371cb80fc 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -245,6 +245,62 @@ static void register_pmic_shared_peripherals(void)
 	}
 }
 
+static int pmic_regulator_enable(struct stm32mp_regulator *regu)
+{
+	void *fdt;
+	const char *node_name;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node_name = fdt_get_name(fdt, fdt_node_offset_by_phandle(fdt, regu->id),
+				 NULL);
+
+	return stpmic1_regulator_enable(node_name);
+}
+
+static int pmic_regulator_disable(struct stm32mp_regulator *regu)
+{
+	void *fdt;
+	const char *node_name;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node_name = fdt_get_name(fdt, fdt_node_offset_by_phandle(fdt, regu->id),
+				 NULL);
+
+	return stpmic1_regulator_disable(node_name);
+}
+
+static const struct stm32mp_regulator_ops pmic_regu_ops = {
+	.enable = pmic_regulator_enable,
+	.disable = pmic_regulator_disable,
+};
+
+bool is_pmic_regulator(struct stm32mp_regulator *regu)
+{
+	void *fdt;
+	int parent_node;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return false;
+	}
+
+	parent_node = fdt_parent_offset(fdt,
+					fdt_node_offset_by_phandle(fdt,
+								   regu->id));
+	return (fdt_node_check_compatible(fdt, parent_node,
+					  "st,stpmic1-regulators") == 0);
+}
+
+void bind_pmic_regulator(struct stm32mp_regulator *regu)
+{
+	regu->ops = &pmic_regu_ops;
+}
+
 void initialize_pmic(void)
 {
 	unsigned long pmic_version;
diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h
index 984cd6014..57475c093 100644
--- a/include/drivers/st/stm32mp_pmic.h
+++ b/include/drivers/st/stm32mp_pmic.h
@@ -11,6 +11,8 @@
 
 #include <platform_def.h>
 
+#include <drivers/st/stm32mp_regulator.h>
+
 /*
  * dt_pmic_status - Check PMIC status from device tree
  *
@@ -41,6 +43,9 @@ bool initialize_pmic_i2c(void);
  */
 void initialize_pmic(void);
 
+bool is_pmic_regulator(struct stm32mp_regulator *regu);
+void bind_pmic_regulator(struct stm32mp_regulator *regu);
+
 /*
  * pmic_ddr_power_init - Initialize regulators required for DDR
  *
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index c9b71cc2b..db54e6c0a 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -11,6 +11,8 @@
 #include <platform_def.h>
 
 #include <drivers/st/stm32_iwdg.h>
+#include <drivers/st/stm32mp_pmic.h>
+#include <drivers/st/stm32mp_regulator.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 /* Internal layout of the 32bit OTP word board_id */
@@ -505,6 +507,15 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
 }
 #endif
 
+int plat_bind_regulator(struct stm32mp_regulator *regu)
+{
+	if ((dt_pmic_status() > 0) && is_pmic_regulator(regu)) {
+		bind_pmic_regulator(regu);
+	}
+
+	return 0;
+}
+
 /* Get the non-secure DDR size */
 uint32_t stm32mp_get_ddr_ns_size(void)
 {
-- 
GitLab