regulator: stf7110: Add regulator support for JH7110 evb
authormason.huo <mason.huo@starfivetech.com>
Fri, 25 Mar 2022 06:12:28 +0000 (14:12 +0800)
committermason.huo <mason.huo@starfivetech.com>
Tue, 7 Jun 2022 10:33:16 +0000 (18:33 +0800)
Add 7 regulators base on regulator framework for
JH7110 evb HW design.

Signed-off-by: mason.huo <mason.huo@starfivetech.com>
arch/riscv/boot/dts/starfive/jh7110-evb.dts
arch/riscv/configs/starfive_jh7110_defconfig
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/stf7110-regulator.c [new file with mode: 0644]
include/linux/regulator/stf7110.h [new file with mode: 0644]

index 4155a95..2e9f6dd 100755 (executable)
        model = "StarFive JH7110 EVB";
        compatible = "starfive,jh7110-evb", "starfive,jh7110";
 };
+
+
+&i2c5 {
+       pmic: stf7110_evb_reg@50 {
+               compatible = "stf,jh7110-evb-regulator";
+               reg = <0x50>;
+
+               regulators {
+                       hdmi_1p8: LDO_REG1 {
+                               regulator-name = "hdmi_1p8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+                       mipitx_1p8: LDO_REG2 {
+                               regulator-name = "mipitx_1p8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+                       mipirx_1p8: LDO_REG3 {
+                               regulator-name = "mipirx_1p8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+                       hdmi_0p9: LDO_REG4 {
+                               regulator-name = "hdmi_0p9";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                       };
+                       mipitx_0p9: LDO_REG5 {
+                               regulator-name = "mipitx_0p9";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                       };
+                       mipirx_0p9: LDO_REG6 {
+                               regulator-name = "mipirx_0p9";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                       };
+                       sdio_vdd: LDO_REG7 {
+                               regulator-name = "sdio_vdd";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+       };
+};
index d93b589..8031f95 100644 (file)
@@ -277,3 +277,5 @@ CONFIG_RCU_EQS_DEBUG=y
 # CONFIG_FTRACE is not set
 # CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_MEMTEST=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_STF7110=y
index 4fd13b0..1aa54d7 100644 (file)
@@ -1137,6 +1137,16 @@ config REGULATOR_SLG51000
          The SLG51000 is seven compact and customizable low dropout
          regulators.
 
+config REGULATOR_STF7110
+       tristate "Starfive JH7110 PMIC"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         Say y here to select this option to enable the power regulator of
+         Starfive JH7110 PMIC.
+         This driver supports the control of different power rails of device
+         through regulator interface.
+
 config REGULATOR_STM32_BOOSTER
        tristate "STMicroelectronics STM32 BOOSTER"
        depends on ARCH_STM32 || COMPILE_TEST
index 9e382b5..f0d0b7b 100644 (file)
@@ -136,6 +136,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
+obj-$(CONFIG_REGULATOR_STF7110) += stf7110-regulator.o
 obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
 obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
 obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
diff --git a/drivers/regulator/stf7110-regulator.c b/drivers/regulator/stf7110-regulator.c
new file mode 100644 (file)
index 0000000..121666f
--- /dev/null
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Starfive Technology Co., Ltd.
+ * Author: Mason Huo <mason.huo@starfivetech.com>
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/stf7110.h>
+#include <linux/slab.h>
+
+#define STF7110_PM_POWER_SW_0          0x80
+#define STF7110_PM_POWER_SW_1          0x81
+#define ENABLE_MASK(id)                        BIT(id)
+
+
+static const struct regmap_config stf7110_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = STF7110_PM_POWER_SW_1,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regulator_ops stf7110_ldo_ops = {
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+};
+
+#define STF7110_LDO(_id, _name, en_reg, en_mask) \
+{\
+       .name = (_name),\
+       .ops = &stf7110_ldo_ops,\
+       .of_match = of_match_ptr(_name),\
+       .regulators_node = of_match_ptr("regulators"),\
+       .type = REGULATOR_VOLTAGE,\
+       .id = STF7110_ID_##_id,\
+       .owner = THIS_MODULE,\
+       .enable_reg = STF7110_PM_POWER_SW_##en_reg,\
+       .enable_mask = ENABLE_MASK(en_mask),\
+}
+
+static const struct regulator_desc stf7110_regulators[] = {
+       STF7110_LDO(LDO_REG1, "hdmi_1p8", 0, 0),
+       STF7110_LDO(LDO_REG2, "mipitx_1p8", 0, 1),
+       STF7110_LDO(LDO_REG3, "mipirx_1p8", 0, 2),
+       STF7110_LDO(LDO_REG4, "hdmi_0p9", 0, 3),
+       STF7110_LDO(LDO_REG5, "mipitx_0p9", 0, 4),
+       STF7110_LDO(LDO_REG6, "mipirx_0p9", 0, 5),
+       STF7110_LDO(LDO_REG7, "sdio_vdd", 1, 0),
+};
+
+static int stf7110_i2c_probe(struct i2c_client *i2c)
+{
+       struct regulator_config config = { };
+       struct regulator_dev *rdev;
+       struct regulator_init_data *init_data;
+       struct regmap *regmap;
+       int i, ret;
+
+       regmap = devm_regmap_init_i2c(i2c, &stf7110_regmap_config);
+       if (IS_ERR(regmap)) {
+               ret = PTR_ERR(regmap);
+               dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
+
+       init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node, NULL);
+       if (!init_data)
+               return -ENOMEM;
+       config.init_data = init_data;
+
+       for (i = 0; i < STF7110_MAX_REGULATORS; i++) {
+               config.dev = &i2c->dev;
+               config.regmap = regmap;
+
+               rdev = devm_regulator_register(&i2c->dev,
+                       &stf7110_regulators[i], &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(&i2c->dev,
+                               "Failed to register STF7110 regulator\n");
+                       return PTR_ERR(rdev);
+               }
+       }
+
+       return 0;
+}
+
+static const struct i2c_device_id stf7110_i2c_id[] = {
+       {"stf7110_evb_reg", 0},
+       {},
+};
+MODULE_DEVICE_TABLE(i2c, stf7110_i2c_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id stf7110_dt_ids[] = {
+       { .compatible = "stf,jh7110-evb-regulator",
+         .data = &stf7110_i2c_id[0] },
+       {},
+};
+MODULE_DEVICE_TABLE(of, stf7110_dt_ids);
+#endif
+
+static struct i2c_driver stf7110_regulator_driver = {
+       .driver = {
+               .name = "stf7110-evb-regulator",
+               .of_match_table = of_match_ptr(stf7110_dt_ids),
+       },
+       .probe_new = stf7110_i2c_probe,
+       .id_table = stf7110_i2c_id,
+};
+
+module_i2c_driver(stf7110_regulator_driver);
+
+MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
+MODULE_DESCRIPTION("Regulator device driver for Starfive STF7110");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regulator/stf7110.h b/include/linux/regulator/stf7110.h
new file mode 100644 (file)
index 0000000..12d872e
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Starfive Technology Co., Ltd.
+ * Author: Mason Huo <mason.huo@starfivetech.com>
+ */
+
+#ifndef __LINUX_REGULATOR_STF7110_H
+#define __LINUX_REGULATOR_STF7110_H
+
+#define STF7110_MAX_REGULATORS 7
+
+
+enum stf7110_reg_id {
+       STF7110_ID_LDO_REG1 = 0,
+       STF7110_ID_LDO_REG2,
+       STF7110_ID_LDO_REG3,
+       STF7110_ID_LDO_REG4,
+       STF7110_ID_LDO_REG5,
+       STF7110_ID_LDO_REG6,
+       STF7110_ID_LDO_REG7,
+};
+
+
+#endif /* __LINUX_REGULATOR_STF7110_H */