summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorFrieder Schrempf <frieder.schrempf@kontron.de>2022-06-27 13:00:58 +0200
committerStefano Babic <sbabic@denx.de>2022-06-28 15:24:31 +0200
commit2add0511757e2c5897a88b57c5ea8c912140e60f (patch)
tree502b207387a572dc8514772b68f4cfef66c67302 /drivers/power
parent6b5ecb829391331bc1125c2b2033344b870ea5c3 (diff)
downloadu-boot-2add0511757e2c5897a88b57c5ea8c912140e60f.tar.gz
pmic: pca9450: Add optional SD_VSEL GPIO for LDO5
LDO5 has two separate control registers. LDO5CTRL_L is used if the input signal SD_VSEL is low and LDO5CTRL_H if it is high. The current driver implementation only uses LDO5CTRL_H. To make this work on boards that have SD_VSEL connected to a GPIO, we add support for specifying an optional GPIO and setting it to high at probe time. In the future we might also want to add support for boards that have SD_VSEL set to a fixed low level. In this case we need to change the driver to be able to use the LDO5CTRL_L register. This is a port of the same change in the Linux kernel: 8c67a11bae88 ("regulator: pca9450: Add SD_VSEL GPIO for LDO5") Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> Reviewed-by: Fabio Estevam <festevam@denx.de> Tested-by: Fabio Estevam <festevam@denx.de>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/pmic/pca9450.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/power/pmic/pca9450.c b/drivers/power/pmic/pca9450.c
index 116ac49a8d..a186edc08d 100644
--- a/drivers/power/pmic/pca9450.c
+++ b/drivers/power/pmic/pca9450.c
@@ -7,9 +7,12 @@
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
+#include <dm/device_compat.h>
#include <i2c.h>
+#include <linux/err.h>
#include <log.h>
#include <asm/global_data.h>
+#include <asm-generic/gpio.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/pca9450.h>
@@ -26,6 +29,10 @@ static const struct pmic_child_info pmic_children_info[] = {
{ },
};
+struct pca9450_priv {
+ struct gpio_desc *sd_vsel_gpio;
+};
+
static int pca9450_reg_count(struct udevice *dev)
{
return PCA9450_REG_NUM;
@@ -76,6 +83,24 @@ static int pca9450_bind(struct udevice *dev)
return 0;
}
+static int pca9450_probe(struct udevice *dev)
+{
+ struct pca9450_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+
+ if (CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(DM_REGULATOR_PCA9450)) {
+ priv->sd_vsel_gpio = devm_gpiod_get_optional(dev, "sd-vsel",
+ GPIOD_IS_OUT |
+ GPIOD_IS_OUT_ACTIVE);
+ if (IS_ERR(priv->sd_vsel_gpio)) {
+ ret = PTR_ERR(priv->sd_vsel_gpio);
+ dev_err(dev, "Failed to request SD_VSEL GPIO: %d\n", ret);
+ }
+ }
+
+ return ret;
+}
+
static struct dm_pmic_ops pca9450_ops = {
.reg_count = pca9450_reg_count,
.read = pca9450_read,
@@ -94,5 +119,7 @@ U_BOOT_DRIVER(pmic_pca9450) = {
.id = UCLASS_PMIC,
.of_match = pca9450_ids,
.bind = pca9450_bind,
+ .probe = pca9450_probe,
.ops = &pca9450_ops,
+ .priv_auto = sizeof(struct pca9450_priv),
};