The driver provides regulator set/get voltage
enable/disable functions for lp873x family of PMICs.
Signed-off-by: Keerthy
---
Changes in v2:
* Used pmic_reg_read/pmic_reg_write instead of direct i2c
read/write calls.
drivers/power/regulator/Kconfig| 8 +
drivers/power/regulator/Makefile | 1 +
drivers/power/regulator/lp873x_regulator.c | 357 +
3 files changed, 366 insertions(+)
create mode 100644 drivers/power/regulator/lp873x_regulator.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index adb710a..84cf914 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -123,3 +123,11 @@ config DM_REGULATOR_PALMAS
This enables implementation of driver-model regulator uclass
features for REGULATOR PALMAS and the family of PALMAS PMICs.
The driver implements get/set api for: value and enable.
+
+config DM_REGULATOR_LP873X
+ bool "Enable driver for LP873X PMIC regulators"
+depends on PMIC_LP873X
+ ---help---
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR LP873X and the family of LP873X PMICs.
+ The driver implements get/set api for: value and enable.
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 75080d4..2093048 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
diff --git a/drivers/power/regulator/lp873x_regulator.c
b/drivers/power/regulator/lp873x_regulator.c
new file mode 100644
index 000..dcb19ff
--- /dev/null
+++ b/drivers/power/regulator/lp873x_regulator.c
@@ -0,0 +1,357 @@
+/*
+ * (C) Copyright 2016
+ * Texas Instruments Incorporated,
+ *
+ * Keerthy
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char lp873x_buck_ctrl[LP873X_BUCK_NUM] = {0x2, 0x4};
+static const char lp873x_buck_volt[LP873X_BUCK_NUM] = {0x6, 0x7};
+static const char lp873x_ldo_ctrl[LP873X_LDO_NUM] = {0x8, 0x9};
+static const char lp873x_ldo_volt[LP873X_LDO_NUM] = {0xA, 0xB};
+
+static int lp873x_buck_enable(struct udevice *dev, int op, bool *enable)
+{
+ int ret;
+ unsigned int adr;
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ adr = uc_pdata->ctrl_reg;
+
+ ret = pmic_reg_read(dev->parent, adr);
+ if (ret < 0)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ ret &= LP873X_BUCK_MODE_MASK;
+
+ if (ret)
+ *enable = true;
+ else
+ *enable = false;
+
+ return 0;
+ } else if (op == PMIC_OP_SET) {
+ if (*enable)
+ ret |= LP873X_BUCK_MODE_MASK;
+ else
+ ret &= ~(LP873X_BUCK_MODE_MASK);
+ ret = pmic_reg_write(dev->parent, adr, ret);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int lp873x_buck_volt2hex(int uV)
+{
+ if (uV > LP873X_BUCK_VOLT_MAX)
+ return -EINVAL;
+ else if (uV > 140)
+ return (uV - 142) / 2 + 0x9E;
+ else if (uV > 73)
+ return (uV - 735000) / 5000 + 0x18;
+ else if (uV >= 70)
+ return (uV - 70) / 1 + 0x1;
+ else
+ return -EINVAL;
+}
+
+static int lp873x_buck_hex2volt(int hex)
+{
+ if (hex > LP873X_BUCK_VOLT_MAX_HEX)
+ return -EINVAL;
+ else if (hex > 0x9D)
+ return 140 + (hex - 0x9D) * 2;
+ else if (hex > 0x17)
+ return 73 + (hex - 0x17) * 5000;
+ else if (hex >= 0x14)
+ return 70 + (hex - 0x14) * 1;
+ else
+ return -EINVAL;
+}
+
+static int lp873x_buck_val(struct udevice *dev, int op, int *uV)
+{
+ unsigned int hex, adr;
+ int ret;
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ if (op == PMIC_OP_GET)
+ *uV = 0;
+
+ adr = uc_pdata->volt_reg;
+
+ ret = pmic_reg_read(dev->parent, adr);
+ if (ret < 0)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ ret &= LP873X_BUCK_VOLT_MASK;
+ ret = lp873x_buck_hex2volt(ret);
+ if (ret < 0)
+ return ret;
+ *uV = ret;
+
+