summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig16
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/lp872x.c16
-rw-r--r--drivers/regulator/ltc3589.c3
-rw-r--r--drivers/regulator/max77693.c173
-rw-r--r--drivers/regulator/max77843.c201
-rw-r--r--drivers/regulator/max8973-regulator.c80
7 files changed, 246 insertions, 244 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 23496da101de..a7b81f0185b5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -407,13 +407,13 @@ config REGULATOR_MAX77686
Exynos-4 chips to control VARM and VINT voltages.
config REGULATOR_MAX77693
- tristate "Maxim MAX77693 regulator"
- depends on MFD_MAX77693
+ tristate "Maxim 77693/77843 regulator"
+ depends on (MFD_MAX77693 || MFD_MAX77843)
help
- This driver controls a Maxim 77693 regulator via I2C bus.
+ This driver controls a Maxim 77693/77843 regulators via I2C bus.
The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2'
and one current regulator 'CHARGER'. This is suitable for
- Exynos-4x12 chips.
+ Exynos-4x12 (MAX77693) or Exynos5433 (MAX77843) SoC chips.
config REGULATOR_MAX77802
tristate "Maxim 77802 regulator"
@@ -424,14 +424,6 @@ config REGULATOR_MAX77802
Exynos5420/Exynos5800 SoCs to control various voltages.
It includes support for control of voltage and ramp speed.
-config REGULATOR_MAX77843
- tristate "Maxim 77843 regulator"
- depends on MFD_MAX77843
- help
- This driver controls a Maxim 77843 regulator.
- The regulator include two 'SAFEOUT' for USB(Universal Serial Bus)
- This is suitable for Exynos5433 SoC chips.
-
config REGULATOR_MC13XXX_CORE
tristate
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 91bf76267404..6429e629dcb6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -56,7 +56,6 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
-obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 3de328ab41f3..8702e7384af7 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -849,7 +849,7 @@ static struct lp872x_platform_data
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
- goto out;
+ return ERR_PTR(-ENOMEM);
of_property_read_u8(np, "ti,general-config", &pdata->general_config);
if (of_find_property(np, "ti,update-config", NULL))
@@ -857,7 +857,7 @@ static struct lp872x_platform_data
pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
if (!pdata->dvs)
- goto out;
+ return ERR_PTR(-ENOMEM);
pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
@@ -903,15 +903,21 @@ static struct lp872x_platform_data
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
+ struct lp872x_platform_data *pdata;
int ret;
const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS,
};
- if (cl->dev.of_node)
- cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev,
+ if (cl->dev.of_node) {
+ pdata = lp872x_populate_pdata_from_dt(&cl->dev,
(enum lp872x_id)id->driver_data);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ } else {
+ pdata = dev_get_platdata(&cl->dev);
+ }
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
@@ -927,7 +933,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
}
lp->dev = &cl->dev;
- lp->pdata = dev_get_platdata(&cl->dev);
+ lp->pdata = pdata;
lp->chipid = id->driver_data;
i2c_set_clientdata(cl, lp);
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 0ce8e4e0fa73..cc22ac66c8fd 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -378,7 +378,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg)
return false;
}
-static struct reg_default ltc3589_reg_defaults[] = {
+static const struct reg_default ltc3589_reg_defaults[] = {
{ LTC3589_SCR1, 0x00 },
{ LTC3589_OVEN, 0x00 },
{ LTC3589_SCR2, 0x00 },
@@ -552,4 +552,3 @@ module_i2c_driver(ltc3589_driver);
MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC3589(-1,2)");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("i2c:ltc3589");
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
index 38722c8311a5..de730fd3f8a5 100644
--- a/drivers/regulator/max77693.c
+++ b/drivers/regulator/max77693.c
@@ -1,8 +1,9 @@
/*
- * max77693.c - Regulator driver for the Maxim 77693
+ * max77693.c - Regulator driver for the Maxim 77693 and 77843
*
- * Copyright (C) 2013 Samsung Electronics
+ * Copyright (C) 2013-2015 Samsung Electronics
* Jonghwa Lee <jonghwa3.lee@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,38 +30,64 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
+#include <linux/mfd/max77843-private.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
-#define CHGIN_ILIM_STEP_20mA 20000
+/*
+ * ID for MAX77843 regulators.
+ * There is no need for such for MAX77693.
+ */
+enum max77843_regulator_type {
+ MAX77843_SAFEOUT1 = 0,
+ MAX77843_SAFEOUT2,
+ MAX77843_CHARGER,
+
+ MAX77843_NUM,
+};
+
+/* Register differences between chargers: MAX77693 and MAX77843 */
+struct chg_reg_data {
+ unsigned int linear_reg;
+ unsigned int linear_mask;
+ unsigned int uA_step;
+ unsigned int min_sel;
+};
/*
- * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
+ * MAX77693 CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
* 0x00, 0x01, 0x2, 0x03 = 60 mA
* 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA
+ * Actually for MAX77693 the driver manipulates the maximum input current,
+ * not the fast charge current (output). This should be fixed.
+ *
+ * On MAX77843 the calculation formula is the same (except values).
+ * Fortunately it properly manipulates the fast charge current.
*/
static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
{
+ const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
unsigned int chg_min_uA = rdev->constraints->min_uA;
unsigned int chg_max_uA = rdev->constraints->max_uA;
unsigned int reg, sel;
unsigned int val;
int ret;
- ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, &reg);
+ ret = regmap_read(rdev->regmap, reg_data->linear_reg, &reg);
if (ret < 0)
return ret;
- sel = reg & CHG_CNFG_09_CHGIN_ILIM_MASK;
+ sel = reg & reg_data->linear_mask;
/* the first four codes for charger current are all 60mA */
- if (sel <= 3)
+ if (sel <= reg_data->min_sel)
sel = 0;
else
- sel -= 3;
+ sel -= reg_data->min_sel;
- val = chg_min_uA + CHGIN_ILIM_STEP_20mA * sel;
+ val = chg_min_uA + reg_data->uA_step * sel;
if (val > chg_max_uA)
return -EINVAL;
@@ -70,23 +97,43 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
+ const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
unsigned int chg_min_uA = rdev->constraints->min_uA;
int sel = 0;
- while (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel < min_uA)
+ while (chg_min_uA + reg_data->uA_step * sel < min_uA)
sel++;
- if (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel > max_uA)
+ if (chg_min_uA + reg_data->uA_step * sel > max_uA)
return -EINVAL;
/* the first four codes for charger current are all 60mA */
- sel += 3;
+ sel += reg_data->min_sel;
- return regmap_write(rdev->regmap,
- MAX77693_CHG_REG_CHG_CNFG_09, sel);
+ return regmap_write(rdev->regmap, reg_data->linear_reg, sel);
}
/* end of CHARGER regulator ops */
+/* Returns regmap suitable for given regulator on chosen device */
+static struct regmap *max77693_get_regmap(enum max77693_types type,
+ struct max77693_dev *max77693,
+ int reg_id)
+{
+ if (type == TYPE_MAX77693)
+ return max77693->regmap;
+
+ /* Else: TYPE_MAX77843 */
+ switch (reg_id) {
+ case MAX77843_SAFEOUT1:
+ case MAX77843_SAFEOUT2:
+ return max77693->regmap;
+ case MAX77843_CHARGER:
+ return max77693->regmap_chg;
+ default:
+ return max77693->regmap;
+ }
+}
+
static const unsigned int max77693_safeout_table[] = {
4850000,
4900000,
@@ -111,7 +158,7 @@ static struct regulator_ops max77693_charger_ops = {
.set_current_limit = max77693_chg_set_current_limit,
};
-#define regulator_desc_esafeout(_num) { \
+#define max77693_regulator_desc_esafeout(_num) { \
.name = "ESAFEOUT"#_num, \
.id = MAX77693_ESAFEOUT##_num, \
.of_match = of_match_ptr("ESAFEOUT"#_num), \
@@ -127,9 +174,9 @@ static struct regulator_ops max77693_charger_ops = {
.enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \
}
-static const struct regulator_desc regulators[] = {
- regulator_desc_esafeout(1),
- regulator_desc_esafeout(2),
+static const struct regulator_desc max77693_supported_regulators[] = {
+ max77693_regulator_desc_esafeout(1),
+ max77693_regulator_desc_esafeout(2),
{
.name = "CHARGER",
.id = MAX77693_CHARGER,
@@ -145,18 +192,86 @@ static const struct regulator_desc regulators[] = {
},
};
+static const struct chg_reg_data max77693_chg_reg_data = {
+ .linear_reg = MAX77693_CHG_REG_CHG_CNFG_09,
+ .linear_mask = CHG_CNFG_09_CHGIN_ILIM_MASK,
+ .uA_step = 20000,
+ .min_sel = 3,
+};
+
+#define max77843_regulator_desc_esafeout(num) { \
+ .name = "SAFEOUT" # num, \
+ .id = MAX77843_SAFEOUT ## num, \
+ .ops = &max77693_safeout_ops, \
+ .of_match = of_match_ptr("SAFEOUT" # num), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(max77693_safeout_table), \
+ .volt_table = max77693_safeout_table, \
+ .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
+ .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num, \
+ .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
+ .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \
+}
+
+static const struct regulator_desc max77843_supported_regulators[] = {
+ [MAX77843_SAFEOUT1] = max77843_regulator_desc_esafeout(1),
+ [MAX77843_SAFEOUT2] = max77843_regulator_desc_esafeout(2),
+ [MAX77843_CHARGER] = {
+ .name = "CHARGER",
+ .id = MAX77843_CHARGER,
+ .ops = &max77693_charger_ops,
+ .of_match = of_match_ptr("CHARGER"),
+ .regulators_node = of_match_ptr("regulators"),
+ .type = REGULATOR_CURRENT,
+ .owner = THIS_MODULE,
+ .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
+ .enable_mask = MAX77843_CHG_MASK,
+ .enable_val = MAX77843_CHG_MASK,
+ },
+};
+
+static const struct chg_reg_data max77843_chg_reg_data = {
+ .linear_reg = MAX77843_CHG_REG_CHG_CNFG_02,
+ .linear_mask = MAX77843_CHG_FAST_CHG_CURRENT_MASK,
+ .uA_step = MAX77843_CHG_FAST_CHG_CURRENT_STEP,
+ .min_sel = 2,
+};
+
static int max77693_pmic_probe(struct platform_device *pdev)
{
+ enum max77693_types type = platform_get_device_id(pdev)->driver_data;
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ const struct regulator_desc *regulators;
+ unsigned int regulators_size;
int i;
struct regulator_config config = { };
config.dev = iodev->dev;
- config.regmap = iodev->regmap;
- for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+ switch (type) {
+ case TYPE_MAX77693:
+ regulators = max77693_supported_regulators;
+ regulators_size = ARRAY_SIZE(max77693_supported_regulators);
+ config.driver_data = (void *)&max77693_chg_reg_data;
+ break;
+ case TYPE_MAX77843:
+ regulators = max77843_supported_regulators;
+ regulators_size = ARRAY_SIZE(max77843_supported_regulators);
+ config.driver_data = (void *)&max77843_chg_reg_data;
+ break;
+ default:
+ dev_err(&pdev->dev, "Unsupported device type: %u\n", type);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < regulators_size; i++) {
struct regulator_dev *rdev;
+ config.regmap = max77693_get_regmap(type, iodev,
+ regulators[i].id);
+
rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(rdev)) {
@@ -170,7 +285,8 @@ static int max77693_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77693_pmic_id[] = {
- {"max77693-pmic", 0},
+ { "max77693-pmic", TYPE_MAX77693 },
+ { "max77843-regulator", TYPE_MAX77843 },
{},
};
@@ -184,8 +300,19 @@ static struct platform_driver max77693_pmic_driver = {
.id_table = max77693_pmic_id,
};
-module_platform_driver(max77693_pmic_driver);
+static int __init max77693_pmic_init(void)
+{
+ return platform_driver_register(&max77693_pmic_driver);
+}
+subsys_initcall(max77693_pmic_init);
+
+static void __exit max77693_pmic_cleanup(void)
+{
+ platform_driver_unregister(&max77693_pmic_driver);
+}
+module_exit(max77693_pmic_cleanup);
-MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver");
+MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver");
MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
+MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski.k@gmail.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/max77843.c b/drivers/regulator/max77843.c
deleted file mode 100644
index f4fd0d3cfa6e..000000000000
--- a/drivers/regulator/max77843.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * max77843.c - Regulator driver for the Maxim MAX77843
- *
- * Copyright (C) 2015 Samsung Electronics
- * Author: Jaewon Kim <jaewon02.kim@samsung.com>
- * Author: Beomho Seo <beomho.seo@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/max77843-private.h>
-#include <linux/regulator/of_regulator.h>
-
-enum max77843_regulator_type {
- MAX77843_SAFEOUT1 = 0,
- MAX77843_SAFEOUT2,
- MAX77843_CHARGER,
-
- MAX77843_NUM,
-};
-
-static const unsigned int max77843_safeout_voltage_table[] = {
- 4850000,
- 4900000,
- 4950000,
- 3300000,
-};
-
-static int max77843_reg_get_current_limit(struct regulator_dev *rdev)
-{
- struct regmap *regmap = rdev->regmap;
- unsigned int chg_min_uA = rdev->constraints->min_uA;
- unsigned int chg_max_uA = rdev->constraints->max_uA;
- unsigned int val;
- int ret;
- unsigned int reg, sel;
-
- ret = regmap_read(regmap, MAX77843_CHG_REG_CHG_CNFG_02, &reg);
- if (ret) {
- dev_err(&rdev->dev, "Failed to read charger register\n");
- return ret;
- }
-
- sel = reg & MAX77843_CHG_FAST_CHG_CURRENT_MASK;
-
- if (sel < 0x03)
- sel = 0;
- else
- sel -= 2;
-
- val = chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel;
- if (val > chg_max_uA)
- return -EINVAL;
-
- return val;
-}
-
-static int max77843_reg_set_current_limit(struct regulator_dev *rdev,
- int min_uA, int max_uA)
-{
- struct regmap *regmap = rdev->regmap;
- unsigned int chg_min_uA = rdev->constraints->min_uA;
- int sel = 0;
-
- while (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel < min_uA)
- sel++;
-
- if (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel > max_uA)
- return -EINVAL;
-
- sel += 2;
-
- return regmap_write(regmap, MAX77843_CHG_REG_CHG_CNFG_02, sel);
-}
-
-static struct regulator_ops max77843_charger_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .get_current_limit = max77843_reg_get_current_limit,
- .set_current_limit = max77843_reg_set_current_limit,
-};
-
-static struct regulator_ops max77843_regulator_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .list_voltage = regulator_list_voltage_table,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
-};
-
-#define MAX77843_SAFEOUT(num) { \
- .name = "SAFEOUT" # num, \
- .id = MAX77843_SAFEOUT ## num, \
- .ops = &max77843_regulator_ops, \
- .of_match = of_match_ptr("SAFEOUT" # num), \
- .regulators_node = of_match_ptr("regulators"), \
- .type = REGULATOR_VOLTAGE, \
- .owner = THIS_MODULE, \
- .n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table), \
- .volt_table = max77843_safeout_voltage_table, \
- .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
- .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num, \
- .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
- .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \
-}
-
-static const struct regulator_desc max77843_supported_regulators[] = {
- [MAX77843_SAFEOUT1] = MAX77843_SAFEOUT(1),
- [MAX77843_SAFEOUT2] = MAX77843_SAFEOUT(2),
- [MAX77843_CHARGER] = {
- .name = "CHARGER",
- .id = MAX77843_CHARGER,
- .ops = &max77843_charger_ops,
- .of_match = of_match_ptr("CHARGER"),
- .regulators_node = of_match_ptr("regulators"),
- .type = REGULATOR_CURRENT,
- .owner = THIS_MODULE,
- .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
- .enable_mask = MAX77843_CHG_MASK | MAX77843_CHG_BUCK_MASK,
- .enable_val = MAX77843_CHG_MASK | MAX77843_CHG_BUCK_MASK,
- },
-};
-
-static struct regmap *max77843_get_regmap(struct max77843 *max77843, int reg_id)
-{
- switch (reg_id) {
- case MAX77843_SAFEOUT1:
- case MAX77843_SAFEOUT2:
- return max77843->regmap;
- case MAX77843_CHARGER:
- return max77843->regmap_chg;
- default:
- return max77843->regmap;
- }
-}
-
-static int max77843_regulator_probe(struct platform_device *pdev)
-{
- struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
- struct regulator_config config = {};
- int i;
-
- config.dev = max77843->dev;
- config.driver_data = max77843;
-
- for (i = 0; i < ARRAY_SIZE(max77843_supported_regulators); i++) {
- struct regulator_dev *regulator;
-
- config.regmap = max77843_get_regmap(max77843,
- max77843_supported_regulators[i].id);
-
- regulator = devm_regulator_register(&pdev->dev,
- &max77843_supported_regulators[i], &config);
- if (IS_ERR(regulator)) {
- dev_err(&pdev->dev,
- "Failed to regiser regulator-%d\n", i);
- return PTR_ERR(regulator);
- }
- }
-
- return 0;
-}
-
-static const struct platform_device_id max77843_regulator_id[] = {
- { "max77843-regulator", },
- { /* sentinel */ },
-};
-
-static struct platform_driver max77843_regulator_driver = {
- .driver = {
- .name = "max77843-regulator",
- },
- .probe = max77843_regulator_probe,
- .id_table = max77843_regulator_id,
-};
-
-static int __init max77843_regulator_init(void)
-{
- return platform_driver_register(&max77843_regulator_driver);
-}
-subsys_initcall(max77843_regulator_init);
-
-static void __exit max77843_regulator_exit(void)
-{
- platform_driver_unregister(&max77843_regulator_driver);
-}
-module_exit(max77843_regulator_exit);
-
-MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
-MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
-MODULE_DESCRIPTION("Maxim MAX77843 regulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index e94ddcf97722..8857cc02d9a8 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -75,6 +75,7 @@
#define MAX8973_DISCH_ENBABLE BIT(5)
#define MAX8973_FT_ENABLE BIT(4)
+#define MAX8973_CKKADV_TRIP_MASK 0xC
#define MAX8973_CKKADV_TRIP_DISABLE 0xC
#define MAX8973_CKKADV_TRIP_75mV_PER_US 0x0
#define MAX8973_CKKADV_TRIP_150mV_PER_US 0x4
@@ -282,6 +283,55 @@ static int max8973_set_ramp_delay(struct regulator_dev *rdev,
return ret;
}
+static int max8973_set_current_limit(struct regulator_dev *rdev,
+ int min_ua, int max_ua)
+{
+ struct max8973_chip *max = rdev_get_drvdata(rdev);
+ unsigned int val;
+ int ret;
+
+ if (max_ua <= 9000000)
+ val = MAX8973_CKKADV_TRIP_75mV_PER_US;
+ else if (max_ua <= 12000000)
+ val = MAX8973_CKKADV_TRIP_150mV_PER_US;
+ else
+ val = MAX8973_CKKADV_TRIP_DISABLE;
+
+ ret = regmap_update_bits(max->regmap, MAX8973_CONTROL2,
+ MAX8973_CKKADV_TRIP_MASK, val);
+ if (ret < 0) {
+ dev_err(max->dev, "register %d update failed: %d\n",
+ MAX8973_CONTROL2, ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int max8973_get_current_limit(struct regulator_dev *rdev)
+{
+ struct max8973_chip *max = rdev_get_drvdata(rdev);
+ unsigned int control2;
+ int ret;
+
+ ret = regmap_read(max->regmap, MAX8973_CONTROL2, &control2);
+ if (ret < 0) {
+ dev_err(max->dev, "register %d read failed: %d\n",
+ MAX8973_CONTROL2, ret);
+ return ret;
+ }
+ switch (control2 & MAX8973_CKKADV_TRIP_MASK) {
+ case MAX8973_CKKADV_TRIP_DISABLE:
+ return 15000000;
+ case MAX8973_CKKADV_TRIP_150mV_PER_US:
+ return 12000000;
+ case MAX8973_CKKADV_TRIP_75mV_PER_US:
+ return 9000000;
+ default:
+ break;
+ }
+ return 9000000;
+}
+
static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
@@ -421,6 +471,8 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
struct device_node *np = dev->of_node;
int ret;
u32 pval;
+ bool etr_enable;
+ bool etr_sensitivity_high;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -452,6 +504,23 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
if (of_property_read_bool(np, "maxim,enable-bias-control"))
pdata->control_flags |= MAX8973_CONTROL_BIAS_ENABLE;
+ etr_enable = of_property_read_bool(np, "maxim,enable-etr");
+ etr_sensitivity_high = of_property_read_bool(np,
+ "maxim,enable-high-etr-sensitivity");
+ if (etr_sensitivity_high)
+ etr_enable = true;
+
+ if (etr_enable) {
+ if (etr_sensitivity_high)
+ pdata->control_flags |=
+ MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US;
+ else
+ pdata->control_flags |=
+ MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US;
+ } else {
+ pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
+ }
+
return pdata;
}
@@ -568,6 +637,15 @@ static int max8973_probe(struct i2c_client *client,
max->lru_index[i] = i;
max->lru_index[0] = max->curr_vout_reg;
max->lru_index[max->curr_vout_reg] = 0;
+ } else {
+ /*
+ * If there is no DVS GPIO, the VOUT register
+ * address is fixed.
+ */
+ max->ops.set_voltage_sel = regulator_set_voltage_sel_regmap;
+ max->ops.get_voltage_sel = regulator_get_voltage_sel_regmap;
+ max->desc.vsel_reg = max->curr_vout_reg;
+ max->desc.vsel_mask = MAX8973_VOUT_MASK;
}
if (pdata_from_dt)
@@ -613,6 +691,8 @@ static int max8973_probe(struct i2c_client *client,
max->ops.enable = regulator_enable_regmap;
max->ops.disable = regulator_disable_regmap;
max->ops.is_enabled = regulator_is_enabled_regmap;
+ max->ops.set_current_limit = max8973_set_current_limit;
+ max->ops.get_current_limit = max8973_get_current_limit;
break;
default:
break;