summaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-03-13 11:05:20 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-03-13 11:05:20 -0700
commit21ac5a96513c6588c9a71bffa16d665675930a60 (patch)
treefea87f88d0255b1ff5eec33527325282dfafa050 /drivers/regulator
parentb30f2db0b79055149ee115fb7b3c86add4d9596a (diff)
parente6f0b08a036734552628ab788ecb528ca53814ab (diff)
downloadlinux-21ac5a96513c6588c9a71bffa16d665675930a60.tar.gz
linux-21ac5a96513c6588c9a71bffa16d665675930a60.tar.bz2
linux-21ac5a96513c6588c9a71bffa16d665675930a60.zip
Merge tag 'regulator-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown: "This has been a very quiet release, mostly cleanups, API updates and simple device additions. I messed up slightly and there are a couple of duplicated commits resulting from me leaving things in my inbox which didn't seem worth removing by the time I noticed them. - Conversion of several drivers to GPIO descriptors - Build out the features of of the MP8859 driver - Support for Qualcomm PM4125 and PM6150" * tag 'regulator-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (31 commits) regulator: lp8788-buck: fix copy and paste bug in lp8788_dvs_gpio_request() regulator: core: make regulator_class constant regulator: da9121: Remove unused of_gpio.h regulator: userspace-consumer: add module device table regulator: dt-bindings: gpio-regulator: Fix "gpios-states" and "states" array bounds regulator: mp8859: Implement set_current_limit() regulator: mp8859: Report slew rate regulator: mp8859: Support status and error readback regulator: mp8859: Support active discharge control regulator: mp8859: Support mode operations regulator: mp8859: Support enable control regulator: mp8859: Validate and log device identifier information regulator: mp8859: Specify register accessibility and enable caching regulator: max8998: Convert to GPIO descriptors regulator: max8997: Convert to GPIO descriptors regulator: lp8788-buck: Fully convert to GPIO descriptors regulator: da9055: Fully convert to GPIO descriptors regulator: max8973: Finalize switch to GPIO descriptors regulator: dt-bindings: qcom,usb-vbus-regulator: add support for PM4125 regulator: dt-bindings: qcom,usb-vbus-regulator: add support for PM4125 ...
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/core.c3
-rw-r--r--drivers/regulator/da9055-regulator.c48
-rw-r--r--drivers/regulator/da9121-regulator.c1
-rw-r--r--drivers/regulator/fixed-helper.c4
-rw-r--r--drivers/regulator/internal.h2
-rw-r--r--drivers/regulator/lp873x-regulator.c3
-rw-r--r--drivers/regulator/lp87565-regulator.c3
-rw-r--r--drivers/regulator/lp8788-buck.c64
-rw-r--r--drivers/regulator/max8973-regulator.c36
-rw-r--r--drivers/regulator/max8997-regulator.c85
-rw-r--r--drivers/regulator/max8998.c150
-rw-r--r--drivers/regulator/mp8859.c252
-rw-r--r--drivers/regulator/pwm-regulator.c40
-rw-r--r--drivers/regulator/qcom_smd-regulator.c19
-rw-r--r--drivers/regulator/userspace-consumer.c1
15 files changed, 428 insertions, 283 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index a968dabb48f5..d019ca6dee9b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3932,7 +3932,6 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev,
if (ret < 0)
return ret;
- possible_uV = desired_min_uV;
done = true;
goto finish;
@@ -5891,7 +5890,7 @@ static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
};
#endif
-struct class regulator_class = {
+const struct class regulator_class = {
.name = "regulator",
.dev_release = regulator_dev_release,
.dev_groups = regulator_dev_groups,
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c
index 8fd9ac787588..352547c375bd 100644
--- a/drivers/regulator/da9055-regulator.c
+++ b/drivers/regulator/da9055-regulator.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
@@ -413,31 +412,35 @@ static struct da9055_regulator_info da9055_regulator_info[] = {
* GPIO can control regulator state and/or select the regulator register
* set A/B for voltage ramping.
*/
-static int da9055_gpio_init(struct da9055_regulator *regulator,
+static int da9055_gpio_init(struct device *dev,
+ struct da9055_regulator *regulator,
struct regulator_config *config,
struct da9055_pdata *pdata, int id)
{
struct da9055_regulator_info *info = regulator->info;
+ struct gpio_desc *ren;
+ struct gpio_desc *ena;
+ struct gpio_desc *rsel;
int ret = 0;
- if (!pdata)
- return 0;
+ /* Look for "regulator-enable-gpios" GPIOs in the regulator node */
+ ren = devm_gpiod_get_optional(dev, "regulator-enable", GPIOD_IN);
+ if (IS_ERR(ren))
+ return PTR_ERR(ren);
- if (pdata->gpio_ren && pdata->gpio_ren[id]) {
- char name[18];
- int gpio_mux = pdata->gpio_ren[id];
+ if (ren) {
+ /* This GPIO is not optional at this point */
+ ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(ena))
+ return PTR_ERR(ena);
- config->ena_gpiod = pdata->ena_gpiods[id];
+ config->ena_gpiod = ena;
/*
* GPI pin is muxed with regulator to control the
* regulator state.
*/
- sprintf(name, "DA9055 GPI %d", gpio_mux);
- ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
- name);
- if (ret < 0)
- goto err;
+ gpiod_set_consumer_name(ren, "DA9055 ren GPI");
/*
* Let the regulator know that its state is controlled
@@ -448,24 +451,22 @@ static int da9055_gpio_init(struct da9055_regulator *regulator,
pdata->reg_ren[id]
<< DA9055_E_GPI_SHIFT);
if (ret < 0)
- goto err;
+ return ret;
}
- if (pdata->gpio_rsel && pdata->gpio_rsel[id]) {
- char name[18];
- int gpio_mux = pdata->gpio_rsel[id];
+ /* Look for "regulator-select-gpios" GPIOs in the regulator node */
+ rsel = devm_gpiod_get_optional(dev, "regulator-select", GPIOD_IN);
+ if (IS_ERR(rsel))
+ return PTR_ERR(rsel);
+ if (rsel) {
regulator->reg_rselect = pdata->reg_rsel[id];
/*
* GPI pin is muxed with regulator to select the
* regulator register set A/B for voltage ramping.
*/
- sprintf(name, "DA9055 GPI %d", gpio_mux);
- ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
- name);
- if (ret < 0)
- goto err;
+ gpiod_set_consumer_name(rsel, "DA9055 rsel GPI");
/*
* Let the regulator know that its register set A/B
@@ -477,7 +478,6 @@ static int da9055_gpio_init(struct da9055_regulator *regulator,
<< DA9055_V_GPI_SHIFT);
}
-err:
return ret;
}
@@ -532,7 +532,7 @@ static int da9055_regulator_probe(struct platform_device *pdev)
if (pdata)
config.init_data = pdata->regulators[pdev->id];
- ret = da9055_gpio_init(regulator, &config, pdata, pdev->id);
+ ret = da9055_gpio_init(&pdev->dev, regulator, &config, pdata, pdev->id);
if (ret < 0)
return ret;
diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
index b551a400bdd1..5ee76b533576 100644
--- a/drivers/regulator/da9121-regulator.c
+++ b/drivers/regulator/da9121-regulator.c
@@ -14,7 +14,6 @@
// Copyright (C) 2020 Dialog Semiconductor
#include <linux/of.h>
-#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c
index 0eb2442456f0..2d5a42b2b3d8 100644
--- a/drivers/regulator/fixed-helper.c
+++ b/drivers/regulator/fixed-helper.c
@@ -15,7 +15,7 @@ static void regulator_fixed_release(struct device *dev)
{
struct fixed_regulator_data *data = container_of(dev,
struct fixed_regulator_data, pdev.dev);
- kfree(data->cfg.supply_name);
+ kfree_const(data->cfg.supply_name);
kfree(data);
}
@@ -36,7 +36,7 @@ struct platform_device *regulator_register_always_on(int id, const char *name,
if (!data)
return NULL;
- data->cfg.supply_name = kstrdup(name, GFP_KERNEL);
+ data->cfg.supply_name = kstrdup_const(name, GFP_KERNEL);
if (!data->cfg.supply_name) {
kfree(data);
return NULL;
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h
index fb4433068d29..77a502141089 100644
--- a/drivers/regulator/internal.h
+++ b/drivers/regulator/internal.h
@@ -58,7 +58,7 @@ struct regulator {
struct dentry *debugfs;
};
-extern struct class regulator_class;
+extern const struct class regulator_class;
static inline struct regulator_dev *dev_to_rdev(struct device *dev)
{
diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c
index 8dfdd1db2070..84a134cfcd9c 100644
--- a/drivers/regulator/lp873x-regulator.c
+++ b/drivers/regulator/lp873x-regulator.c
@@ -5,6 +5,7 @@
* Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
*/
+#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -93,7 +94,7 @@ static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev,
ret = regmap_update_bits(lp873->regmap, regulators[id].ctrl2_reg,
LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE,
- reg << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE));
+ FIELD_PREP(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE, reg));
if (ret) {
dev_err(lp873->dev, "SLEW RATE write failed: %d\n", ret);
return ret;
diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c
index 61ee5cf3f241..1259b5d20153 100644
--- a/drivers/regulator/lp87565-regulator.c
+++ b/drivers/regulator/lp87565-regulator.c
@@ -5,6 +5,7 @@
* Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
*/
+#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -99,7 +100,7 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg,
LP87565_BUCK_CTRL_2_SLEW_RATE,
- reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE));
+ FIELD_PREP(LP87565_BUCK_CTRL_2_SLEW_RATE, reg));
if (ret) {
dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret);
return ret;
diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c
index e97ade09dede..2ade249ab6df 100644
--- a/drivers/regulator/lp8788-buck.c
+++ b/drivers/regulator/lp8788-buck.c
@@ -13,7 +13,7 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/mfd/lp8788.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
/* register address */
#define LP8788_EN_BUCK 0x0C
@@ -69,8 +69,8 @@
#define BUCK_FPWM_SHIFT(x) (x)
enum lp8788_dvs_state {
- DVS_LOW = GPIOF_OUT_INIT_LOW,
- DVS_HIGH = GPIOF_OUT_INIT_HIGH,
+ DVS_LOW = 0,
+ DVS_HIGH = 1,
};
enum lp8788_dvs_mode {
@@ -89,6 +89,8 @@ struct lp8788_buck {
struct lp8788 *lp;
struct regulator_dev *regulator;
void *dvs;
+ struct gpio_desc *gpio1;
+ struct gpio_desc *gpio2; /* Only used on BUCK2 */
};
/* BUCK 1 ~ 4 voltage ranges */
@@ -106,8 +108,7 @@ static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
return;
pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH;
- if (gpio_is_valid(dvs->gpio))
- gpio_set_value(dvs->gpio, pinstate);
+ gpiod_set_value(buck->gpio1, pinstate);
}
static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
@@ -139,11 +140,8 @@ static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
return;
}
- if (gpio_is_valid(dvs->gpio[0]))
- gpio_set_value(dvs->gpio[0], pin1);
-
- if (gpio_is_valid(dvs->gpio[1]))
- gpio_set_value(dvs->gpio[1], pin2);
+ gpiod_set_value(buck->gpio1, pin1);
+ gpiod_set_value(buck->gpio2, pin2);
}
static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
@@ -202,19 +200,13 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
enum lp8788_buck_id id)
{
enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id);
- struct lp8788_buck1_dvs *b1_dvs;
- struct lp8788_buck2_dvs *b2_dvs;
u8 val, idx, addr;
int pin1, pin2;
switch (id) {
case BUCK1:
if (mode == EXTPIN) {
- b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs;
- if (!b1_dvs)
- goto err;
-
- idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0;
+ idx = gpiod_get_value(buck->gpio1);
} else {
lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
@@ -223,12 +215,8 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
break;
case BUCK2:
if (mode == EXTPIN) {
- b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs;
- if (!b2_dvs)
- goto err;
-
- pin1 = gpio_get_value(b2_dvs->gpio[0]);
- pin2 = gpio_get_value(b2_dvs->gpio[1]);
+ pin1 = gpiod_get_value(buck->gpio1);
+ pin2 = gpiod_get_value(buck->gpio2);
if (pin1 == PIN_LOW && pin2 == PIN_LOW)
idx = 0;
@@ -424,28 +412,28 @@ static int lp8788_dvs_gpio_request(struct platform_device *pdev,
enum lp8788_buck_id id)
{
struct lp8788_platform_data *pdata = buck->lp->pdata;
- char *b1_name = "LP8788_B1_DVS";
- char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" };
- int i, gpio, ret;
+ struct device *dev = &pdev->dev;
switch (id) {
case BUCK1:
- gpio = pdata->buck1_dvs->gpio;
- ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW,
- b1_name);
- if (ret)
- return ret;
+ buck->gpio1 = devm_gpiod_get(dev, "dvs", GPIOD_OUT_LOW);
+ if (IS_ERR(buck->gpio1))
+ return PTR_ERR(buck->gpio1);
+ gpiod_set_consumer_name(buck->gpio1, "LP8788_B1_DVS");
buck->dvs = pdata->buck1_dvs;
break;
case BUCK2:
- for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) {
- gpio = pdata->buck2_dvs->gpio[i];
- ret = devm_gpio_request_one(&pdev->dev, gpio,
- DVS_LOW, b2_name[i]);
- if (ret)
- return ret;
- }
+ buck->gpio1 = devm_gpiod_get_index(dev, "dvs", 0, GPIOD_OUT_LOW);
+ if (IS_ERR(buck->gpio1))
+ return PTR_ERR(buck->gpio1);
+ gpiod_set_consumer_name(buck->gpio1, "LP8788_B2_DVS1");
+
+ buck->gpio2 = devm_gpiod_get_index(dev, "dvs", 1, GPIOD_OUT_LOW);
+ if (IS_ERR(buck->gpio2))
+ return PTR_ERR(buck->gpio2);
+ gpiod_set_consumer_name(buck->gpio2, "LP8788_B2_DVS2");
+
buck->dvs = pdata->buck2_dvs;
break;
default:
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 8d5193207552..f8bb6828feef 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -20,9 +20,7 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/max8973-regulator.h>
#include <linux/regulator/of_regulator.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
-#include <linux/of_gpio.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regmap.h>
@@ -102,7 +100,7 @@ struct max8973_chip {
struct regulator_desc desc;
struct regmap *regmap;
bool enable_external_control;
- int dvs_gpio;
+ struct gpio_desc *dvs_gpiod;
int lru_index[MAX8973_MAX_VOUT_REG];
int curr_vout_val[MAX8973_MAX_VOUT_REG];
int curr_vout_reg;
@@ -184,7 +182,7 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
* If gpios are available to select the VOUT register then least
* recently used register for new configuration.
*/
- if (gpio_is_valid(max->dvs_gpio))
+ if (max->dvs_gpiod)
found = find_voltage_set_register(max, vsel,
&vout_reg, &gpio_val);
@@ -201,8 +199,8 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
}
/* Select proper VOUT register vio gpios */
- if (gpio_is_valid(max->dvs_gpio)) {
- gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
+ if (max->dvs_gpiod) {
+ gpiod_set_value_cansleep(max->dvs_gpiod, gpio_val & 0x1);
max->curr_gpio_val = gpio_val;
}
return 0;
@@ -531,7 +529,6 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
pdata->enable_ext_control = of_property_read_bool(np,
"maxim,externally-enable");
- pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0);
ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval);
if (!ret)
@@ -612,13 +609,17 @@ static int max8973_probe(struct i2c_client *client)
return -EIO;
}
- if (pdata->dvs_gpio == -EPROBE_DEFER)
- return -EPROBE_DEFER;
-
max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
if (!max)
return -ENOMEM;
+ max->dvs_gpiod = devm_gpiod_get_optional(&client->dev, "maxim,dvs",
+ (pdata->dvs_def_state) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW);
+ if (IS_ERR(max->dvs_gpiod))
+ return dev_err_probe(&client->dev, PTR_ERR(max->dvs_gpiod),
+ "failed to obtain dvs gpio\n");
+ gpiod_set_consumer_name(max->dvs_gpiod, "max8973-dvs");
+
max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config);
if (IS_ERR(max->regmap)) {
ret = PTR_ERR(max->regmap);
@@ -663,7 +664,6 @@ static int max8973_probe(struct i2c_client *client)
max->desc.ramp_delay_table = max8973_buck_ramp_table;
max->desc.n_ramp_values = ARRAY_SIZE(max8973_buck_ramp_table);
- max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
max->enable_external_control = pdata->enable_ext_control;
max->curr_gpio_val = pdata->dvs_def_state;
max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
@@ -671,21 +671,9 @@ static int max8973_probe(struct i2c_client *client)
max->lru_index[0] = max->curr_vout_reg;
- if (gpio_is_valid(max->dvs_gpio)) {
- int gpio_flags;
+ if (max->dvs_gpiod) {
int i;
- gpio_flags = (pdata->dvs_def_state) ?
- GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
- ret = devm_gpio_request_one(&client->dev, max->dvs_gpio,
- gpio_flags, "max8973-dvs");
- if (ret) {
- dev_err(&client->dev,
- "gpio_request for gpio %d failed, err = %d\n",
- max->dvs_gpio, ret);
- return ret;
- }
-
/*
* Initialize the lru index with vout_reg id
* The index 0 will be most recently used and
diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c
index 0b38eaa73597..5f201ee9a5b8 100644
--- a/drivers/regulator/max8997-regulator.c
+++ b/drivers/regulator/max8997-regulator.c
@@ -9,8 +9,7 @@
#include <linux/bug.h>
#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -32,7 +31,7 @@ struct max8997_data {
u8 buck1_vol[8];
u8 buck2_vol[8];
u8 buck5_vol[8];
- int buck125_gpios[3];
+ struct gpio_desc *buck125_gpiods[3];
int buck125_gpioindex;
bool ignore_gpiodvs_side_effect;
@@ -52,9 +51,9 @@ static inline void max8997_set_gpio(struct max8997_data *max8997)
int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1;
int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1;
- gpio_set_value(max8997->buck125_gpios[0], set1);
- gpio_set_value(max8997->buck125_gpios[1], set2);
- gpio_set_value(max8997->buck125_gpios[2], set3);
+ gpiod_set_value(max8997->buck125_gpiods[0], set1);
+ gpiod_set_value(max8997->buck125_gpiods[1], set2);
+ gpiod_set_value(max8997->buck125_gpiods[2], set3);
}
struct voltage_map_desc {
@@ -873,31 +872,13 @@ static struct regulator_desc regulators[] = {
};
#ifdef CONFIG_OF
-static int max8997_pmic_dt_parse_dvs_gpio(struct platform_device *pdev,
- struct max8997_platform_data *pdata,
- struct device_node *pmic_np)
-{
- int i, gpio;
-
- for (i = 0; i < 3; i++) {
- gpio = of_get_named_gpio(pmic_np,
- "max8997,pmic-buck125-dvs-gpios", i);
- if (!gpio_is_valid(gpio)) {
- dev_err(&pdev->dev, "invalid gpio[%d]: %d\n", i, gpio);
- return -EINVAL;
- }
- pdata->buck125_gpios[i] = gpio;
- }
- return 0;
-}
-
static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
struct max8997_platform_data *pdata)
{
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct device_node *pmic_np, *regulators_np, *reg_np;
struct max8997_regulator_data *rdata;
- unsigned int i, dvs_voltage_nr = 1, ret;
+ unsigned int i, dvs_voltage_nr = 1;
pmic_np = iodev->dev->of_node;
if (!pmic_np) {
@@ -949,10 +930,6 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
pdata->buck5_gpiodvs) {
- ret = max8997_pmic_dt_parse_dvs_gpio(pdev, pdata, pmic_np);
- if (ret)
- return -EINVAL;
-
if (of_property_read_u32(pmic_np,
"max8997,pmic-buck125-default-dvs-idx",
&pdata->buck125_default_idx)) {
@@ -1039,7 +1016,6 @@ static int max8997_pmic_probe(struct platform_device *pdev)
max8997->buck1_gpiodvs = pdata->buck1_gpiodvs;
max8997->buck2_gpiodvs = pdata->buck2_gpiodvs;
max8997->buck5_gpiodvs = pdata->buck5_gpiodvs;
- memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3);
max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect;
nr_dvs = (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
@@ -1110,38 +1086,27 @@ static int max8997_pmic_probe(struct platform_device *pdev)
*/
if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
pdata->buck5_gpiodvs) {
+ const char *gpio_names[3] = {"MAX8997 SET1", "MAX8997 SET2", "MAX8997 SET3"};
- if (!gpio_is_valid(pdata->buck125_gpios[0]) ||
- !gpio_is_valid(pdata->buck125_gpios[1]) ||
- !gpio_is_valid(pdata->buck125_gpios[2])) {
- dev_err(&pdev->dev, "GPIO NOT VALID\n");
- return -EINVAL;
- }
+ for (i = 0; i < 3; i++) {
+ enum gpiod_flags flags;
- ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[0],
- "MAX8997 SET1");
- if (ret)
- return ret;
-
- ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[1],
- "MAX8997 SET2");
- if (ret)
- return ret;
-
- ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[2],
- "MAX8997 SET3");
- if (ret)
- return ret;
-
- gpio_direction_output(pdata->buck125_gpios[0],
- (max8997->buck125_gpioindex >> 2)
- & 0x1); /* SET1 */
- gpio_direction_output(pdata->buck125_gpios[1],
- (max8997->buck125_gpioindex >> 1)
- & 0x1); /* SET2 */
- gpio_direction_output(pdata->buck125_gpios[2],
- (max8997->buck125_gpioindex >> 0)
- & 0x1); /* SET3 */
+ if (max8997->buck125_gpioindex & BIT(2 - i))
+ flags = GPIOD_OUT_HIGH;
+ else
+ flags = GPIOD_OUT_LOW;
+
+ max8997->buck125_gpiods[i] = devm_gpiod_get_index(iodev->dev,
+ "max8997,pmic-buck125-dvs",
+ i,
+ flags);
+ if (IS_ERR(max8997->buck125_gpiods[i])) {
+ ret = PTR_ERR(max8997->buck125_gpiods[i]);
+ return dev_err_probe(iodev->dev, ret, "cant get GPIO %d (%d)\n",
+ i, ret);
+ }
+ gpiod_set_consumer_name(max8997->buck125_gpiods[i], gpio_names[i]);
+ }
}
/* DVS-GPIO disabled */
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index fadb4717384a..254a77887f66 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -10,12 +10,12 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/bits.h>
+#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
@@ -31,6 +31,9 @@ struct max8998_data {
unsigned int buck1_idx; /* index to last changed voltage */
/* value in a set */
unsigned int buck2_idx;
+ struct gpio_desc *buck1_gpio1;
+ struct gpio_desc *buck1_gpio2;
+ struct gpio_desc *buck2_gpio;
};
static const unsigned int charger_current_table[] = {
@@ -227,15 +230,15 @@ static int max8998_set_voltage_ldo_sel(struct regulator_dev *rdev,
return ret;
}
-static inline void buck1_gpio_set(int gpio1, int gpio2, int v)
+static inline void buck1_gpio_set(struct gpio_desc *gpio1, struct gpio_desc *gpio2, int v)
{
- gpio_set_value(gpio1, v & 0x1);
- gpio_set_value(gpio2, (v >> 1) & 0x1);
+ gpiod_set_value(gpio1, v & 0x1);
+ gpiod_set_value(gpio2, (v >> 1) & 0x1);
}
-static inline void buck2_gpio_set(int gpio, int v)
+static inline void buck2_gpio_set(struct gpio_desc *gpio, int v)
{
- gpio_set_value(gpio, v & 0x1);
+ gpiod_set_value(gpio, v & 0x1);
}
static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
@@ -260,16 +263,15 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
selector, max8998->buck1_vol[0], max8998->buck1_vol[1],
max8998->buck1_vol[2], max8998->buck1_vol[3]);
- if (gpio_is_valid(pdata->buck1_set1) &&
- gpio_is_valid(pdata->buck1_set2)) {
+ if (max8998->buck1_gpio1 && max8998->buck1_gpio2) {
/* check if requested voltage */
/* value is already defined */
for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) {
if (max8998->buck1_vol[j] == selector) {
max8998->buck1_idx = j;
- buck1_gpio_set(pdata->buck1_set1,
- pdata->buck1_set2, j);
+ buck1_gpio_set(max8998->buck1_gpio1,
+ max8998->buck1_gpio2, j);
goto buck1_exit;
}
}
@@ -286,13 +288,13 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
&shift,
&mask);
ret = max8998_write_reg(i2c, reg, selector);
- buck1_gpio_set(pdata->buck1_set1,
- pdata->buck1_set2, max8998->buck1_idx);
+ buck1_gpio_set(max8998->buck1_gpio1,
+ max8998->buck1_gpio2, max8998->buck1_idx);
buck1_last_val++;
buck1_exit:
dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n",
- i2c->name, gpio_get_value(pdata->buck1_set1),
- gpio_get_value(pdata->buck1_set2));
+ i2c->name, gpiod_get_value(max8998->buck1_gpio1),
+ gpiod_get_value(max8998->buck1_gpio2));
break;
} else {
ret = max8998_write_reg(i2c, reg, selector);
@@ -303,14 +305,13 @@ buck1_exit:
dev_dbg(max8998->dev,
"BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n",
selector, max8998->buck2_vol[0], max8998->buck2_vol[1]);
- if (gpio_is_valid(pdata->buck2_set3)) {
-
+ if (max8998->buck2_gpio) {
/* check if requested voltage */
/* value is already defined */
for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) {
if (max8998->buck2_vol[j] == selector) {
max8998->buck2_idx = j;
- buck2_gpio_set(pdata->buck2_set3, j);
+ buck2_gpio_set(max8998->buck2_gpio, j);
goto buck2_exit;
}
}
@@ -322,10 +323,10 @@ buck1_exit:
&reg, &shift, &mask);
ret = max8998_write_reg(i2c, reg, selector);
max8998->buck2_vol[max8998->buck2_idx] = selector;
- buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx);
+ buck2_gpio_set(max8998->buck2_gpio, max8998->buck2_idx);
buck2_exit:
dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name,
- gpio_get_value(pdata->buck2_set3));
+ gpiod_get_value(max8998->buck2_gpio));
} else {
ret = max8998_write_reg(i2c, reg, selector);
}
@@ -539,36 +540,6 @@ static const struct regulator_desc regulators[] = {
charger_current_table, MAX8998_REG_CHGR1, 0x7),
};
-static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev,
- struct max8998_platform_data *pdata,
- struct device_node *pmic_np)
-{
- int gpio;
-
- gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 0);
- if (!gpio_is_valid(gpio)) {
- dev_err(iodev->dev, "invalid buck1 gpio[0]: %d\n", gpio);
- return -EINVAL;
- }
- pdata->buck1_set1 = gpio;
-
- gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 1);
- if (!gpio_is_valid(gpio)) {
- dev_err(iodev->dev, "invalid buck1 gpio[1]: %d\n", gpio);
- return -EINVAL;
- }
- pdata->buck1_set2 = gpio;
-
- gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck2-dvs-gpio", 0);
- if (!gpio_is_valid(gpio)) {
- dev_err(iodev->dev, "invalid buck 2 gpio: %d\n", gpio);
- return -EINVAL;
- }
- pdata->buck2_set3 = gpio;
-
- return 0;
-}
-
static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
struct max8998_platform_data *pdata)
{
@@ -614,10 +585,6 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
of_node_put(reg_np);
of_node_put(regulators_np);
- ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
- if (ret)
- return -EINVAL;
-
pdata->buck_voltage_lock = of_property_read_bool(pmic_np, "max8998,pmic-buck-voltage-lock");
ret = of_property_read_u32(pmic_np,
@@ -665,6 +632,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct max8998_data *max8998;
struct i2c_client *i2c;
+ enum gpiod_flags flags;
int i, ret;
unsigned int v;
@@ -693,37 +661,38 @@ static int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_idx = pdata->buck1_default_idx;
max8998->buck2_idx = pdata->buck2_default_idx;
- /* NOTE: */
- /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */
- /* will be displayed */
-
/* Check if MAX8998 voltage selection GPIOs are defined */
- if (gpio_is_valid(pdata->buck1_set1) &&
- gpio_is_valid(pdata->buck1_set2)) {
- /* Check if SET1 is not equal to 0 */
- if (!pdata->buck1_set1) {
- dev_err(&pdev->dev,
- "MAX8998 SET1 GPIO defined as 0 !\n");
- WARN_ON(!pdata->buck1_set1);
- return -EIO;
- }
- /* Check if SET2 is not equal to 0 */
- if (!pdata->buck1_set2) {
- dev_err(&pdev->dev,
- "MAX8998 SET2 GPIO defined as 0 !\n");
- WARN_ON(!pdata->buck1_set2);
- return -EIO;
- }
-
- gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
- gpio_direction_output(pdata->buck1_set1,
- max8998->buck1_idx & 0x1);
-
-
- gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2");
- gpio_direction_output(pdata->buck1_set2,
- (max8998->buck1_idx >> 1) & 0x1);
-
+ flags = (max8998->buck1_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
+ max8998->buck1_gpio1 = devm_gpiod_get_index_optional(iodev->dev,
+ "max8998,pmic-buck1-dvs",
+ 0,
+ flags);
+ if (IS_ERR(max8998->buck1_gpio1))
+ return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio1),
+ "could not get BUCK1 GPIO1\n");
+ gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET1");
+
+ flags = (max8998->buck1_idx & BIT(1)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
+ max8998->buck1_gpio2 = devm_gpiod_get_index_optional(iodev->dev,
+ "max8998,pmic-buck1-dvs",
+ 1,
+ flags);
+ if (IS_ERR(max8998->buck1_gpio2))
+ return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio2),
+ "could not get BUCK1 GPIO2\n");
+ gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET2");
+
+ flags = (max8998->buck2_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
+ max8998->buck2_gpio = devm_gpiod_get_index_optional(iodev->dev,
+ "max8998,pmic-buck2-dvs",
+ 0,
+ flags);
+ if (IS_ERR(max8998->buck2_gpio))
+ return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck2_gpio),
+ "could not get BUCK2 GPIO\n");
+ gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK2_SET3");
+
+ if (max8998->buck1_gpio1 && max8998->buck1_gpio2) {
/* Set predefined values for BUCK1 registers */
for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
int index = MAX8998_BUCK1 - MAX8998_LDO2;
@@ -742,18 +711,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
}
}
- if (gpio_is_valid(pdata->buck2_set3)) {
- /* Check if SET3 is not equal to 0 */
- if (!pdata->buck2_set3) {
- dev_err(&pdev->dev,
- "MAX8998 SET3 GPIO defined as 0 !\n");
- WARN_ON(!pdata->buck2_set3);
- return -EIO;
- }
- gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
- gpio_direction_output(pdata->buck2_set3,
- max8998->buck2_idx & 0x1);
-
+ if (max8998->buck2_gpio) {
/* Set predefined values for BUCK2 registers */
for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
int index = MAX8998_BUCK2 - MAX8998_LDO2;
diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c
index b820bd6043e5..ab105ffd6a2e 100644
--- a/drivers/regulator/mp8859.c
+++ b/drivers/regulator/mp8859.c
@@ -35,6 +35,16 @@
#define MP8859_GO_BIT 0x01
+#define MP8859_IOUT_LIM_MASK 0x7f
+
+#define MP8859_ENABLE_MASK 0x80
+#define MP8859_DISCHG_EN_MASK 0x10
+#define MP8859_MODE_MASK 0x08
+
+#define MP8859_PG_MASK 0x80
+#define MP8859_OTP_MASK 0x40
+#define MP8859_OTW_MASK 0x20
+#define MP8859_CC_CV_MASK 0x10
static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
{
@@ -73,21 +83,221 @@ static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
return val;
}
+static int mp8859_set_voltage_time_sel(struct regulator_dev *rdev,
+ unsigned int from, unsigned int to)
+{
+ int change;
+
+ /* The voltage ramps at 1mV/uS, selectors are 10mV */
+ if (from > to)
+ change = from - to;
+ else
+ change = to - from;
+
+ return change * 10 * 1000;
+}
+
+static unsigned int mp8859_get_mode(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val);
+ if (ret != 0) {
+ dev_err(&rdev->dev, "Failed to read mode: %d\n", ret);
+ return 0;
+ }
+
+ if (val & MP8859_MODE_MASK)
+ return REGULATOR_MODE_FAST;
+ else
+ return REGULATOR_MODE_NORMAL;
+}
+
+static int mp8859_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ unsigned int val;
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ val = MP8859_MODE_MASK;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return regmap_update_bits(rdev->regmap, MP8859_CTL1_REG,
+ MP8859_MODE_MASK, val);
+}
+
+static int mp8859_set_current_limit(struct regulator_dev *rdev,
+ int min_uA, int max_uA)
+{
+ unsigned int cur_val, new_val;
+ int ret, i;
+
+ /* Steps of 50mA */
+ new_val = max_uA / 50000;
+ if (new_val > MP8859_IOUT_LIM_MASK)
+ return -EINVAL;
+ if (new_val == 0)
+ return -EINVAL;
+
+ /*
+ * If the regulator is limiting then ramp gradually as per
+ * datasheet, otherwise just set the value directly.
+ */
+ ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &cur_val);
+ if (ret != 0)
+ return ret;
+ if (!(cur_val & MP8859_CC_CV_MASK)) {
+ return regmap_update_bits(rdev->regmap, MP8859_IOUT_LIM_REG,
+ MP8859_IOUT_LIM_MASK, new_val);
+ }
+
+ ret = regmap_read(rdev->regmap, MP8859_IOUT_LIM_REG, &cur_val);
+ if (ret != 0)
+ return ret;
+
+ if (cur_val >= new_val) {
+ for (i = cur_val; i >= new_val; i--) {
+ ret = regmap_update_bits(rdev->regmap,
+ MP8859_IOUT_LIM_REG,
+ MP8859_IOUT_LIM_MASK,
+ cur_val - i);
+ if (ret != 0)
+ return ret;
+ }
+ } else {
+ for (i = cur_val; i <= new_val; i++) {
+ ret = regmap_update_bits(rdev->regmap,
+ MP8859_IOUT_LIM_REG,
+ MP8859_IOUT_LIM_MASK,
+ cur_val + i);
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int mp8859_get_status(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ int ret;
+
+ /* Output status is only meaingful when enabled */
+ ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val);
+ if (ret != 0)
+ return ret;
+ if (!(val & MP8859_ENABLE_MASK))
+ return REGULATOR_STATUS_UNDEFINED;
+
+ ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &val);
+ if (ret != 0)
+ return ret;
+
+ if (val & MP8859_PG_MASK)
+ return REGULATOR_STATUS_ON;
+ else
+ return REGULATOR_STATUS_ERROR;
+}
+
+static int mp8859_get_error_flags(struct regulator_dev *rdev,
+ unsigned int *flags)
+{
+ unsigned int status, enabled;
+ int ret;
+
+ *flags = 0;
+
+ /* Output status is only meaingful when enabled */
+ ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &enabled);
+ if (ret != 0)
+ return ret;
+ enabled &= MP8859_ENABLE_MASK;
+
+ ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &status);
+ if (ret != 0)
+ return ret;
+
+ if (enabled && !(status & MP8859_PG_MASK))
+ status |= REGULATOR_ERROR_FAIL;
+ if (status & MP8859_OTP_MASK)
+ status |= REGULATOR_ERROR_OVER_TEMP;
+ if (status & MP8859_OTW_MASK)
+ status |= REGULATOR_ERROR_OVER_TEMP_WARN;
+ if (status & MP8859_CC_CV_MASK)
+ status |= REGULATOR_ERROR_OVER_CURRENT;
+
+ return 0;
+}
+
static const struct linear_range mp8859_dcdc_ranges[] = {
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
};
+static bool mp8859_readable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MP8859_VOUT_L_REG:
+ case MP8859_VOUT_H_REG:
+ case MP8859_VOUT_GO_REG:
+ case MP8859_IOUT_LIM_REG:
+ case MP8859_CTL1_REG:
+ case MP8859_CTL2_REG:
+ case MP8859_STATUS_REG:
+ case MP8859_INTERRUPT_REG:
+ case MP8859_MASK_REG:
+ case MP8859_ID1_REG:
+ case MP8859_MFR_ID_REG:
+ case MP8859_DEV_ID_REG:
+ case MP8859_IC_REV_REG:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool mp8859_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MP8859_VOUT_GO_REG:
+ case MP8859_STATUS_REG:
+ case MP8859_INTERRUPT_REG:
+ return true;
+ default:
+ return false;
+ }
+}
+
static const struct regmap_config mp8859_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MP8859_MAX_REG,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
+ .readable_reg = mp8859_readable,
+ .volatile_reg = mp8859_volatile,
};
static const struct regulator_ops mp8859_ops = {
.set_voltage_sel = mp8859_set_voltage_sel,
.get_voltage_sel = mp8859_get_voltage_sel,
.list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_time_sel = mp8859_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_mode = mp8859_set_mode,
+ .get_mode = mp8859_get_mode,
+ .set_active_discharge = regulator_set_active_discharge_regmap,
+ .set_current_limit = mp8859_set_current_limit,
+ .get_status = mp8859_get_status,
+ .get_error_flags = mp8859_get_error_flags,
};
static const struct regulator_desc mp8859_regulators[] = {
@@ -100,6 +310,12 @@ static const struct regulator_desc mp8859_regulators[] = {
.n_voltages = VOL_MAX_IDX + 1,
.linear_ranges = mp8859_dcdc_ranges,
.n_linear_ranges = 1,
+ .enable_reg = MP8859_CTL1_REG,
+ .enable_mask = MP8859_ENABLE_MASK,
+ .enable_val = MP8859_ENABLE_MASK,
+ .active_discharge_reg = MP8859_CTL1_REG,
+ .active_discharge_on = MP8859_DISCHG_EN_MASK,
+ .active_discharge_mask = MP8859_DISCHG_EN_MASK,
.ops = &mp8859_ops,
.owner = THIS_MODULE,
},
@@ -111,12 +327,46 @@ static int mp8859_i2c_probe(struct i2c_client *i2c)
struct regulator_config config = {.dev = &i2c->dev};
struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap);
struct regulator_dev *rdev;
+ unsigned int val, rev;
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
+
+ ret = regmap_read(regmap, MP8859_MFR_ID_REG, &val);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read manufacturer ID: %d\n", ret);
+ return ret;
+ }
+ if (val != 0x9) {
+ dev_err(&i2c->dev, "Manufacturer ID %x != 9\n", val);
+ return -EINVAL;
+ }
+
+ ret = regmap_read(regmap, MP8859_DEV_ID_REG, &val);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read device ID: %d\n", ret);
+ return ret;
+ }
+ if (val != 0x58) {
+ dev_err(&i2c->dev, "Manufacturer ID %x != 0x58\n", val);
+ return -EINVAL;
+ }
+
+ ret = regmap_read(regmap, MP8859_IC_REV_REG, &rev);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read device revision: %d\n", ret);
+ return ret;
+ }
+ ret = regmap_read(regmap, MP8859_ID1_REG, &val);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read device ID1: %d\n", ret);
+ return ret;
+ }
+ dev_info(&i2c->dev, "MP8859-%04d revision %d\n", val, rev);
+
rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0],
&config);
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index 60cfcd741c2a..7434b6b22d32 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -271,11 +271,10 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
of_find_property(np, "voltage-table", &length);
if ((length < sizeof(*duty_cycle_table)) ||
- (length % sizeof(*duty_cycle_table))) {
- dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
- length);
- return -EINVAL;
- }
+ (length % sizeof(*duty_cycle_table)))
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "voltage-table length(%d) is invalid\n",
+ length);
duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
if (!duty_cycle_table)
@@ -284,10 +283,9 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
ret = of_property_read_u32_array(np, "voltage-table",
(u32 *)duty_cycle_table,
length / sizeof(u32));
- if (ret) {
- dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to read voltage-table\n");
drvdata->state = -ENOTRECOVERABLE;
drvdata->duty_cycle_table = duty_cycle_table;
@@ -359,10 +357,9 @@ static int pwm_regulator_probe(struct platform_device *pdev)
enum gpiod_flags gpio_flags;
int ret;
- if (!np) {
- dev_err(&pdev->dev, "Device Tree node missing\n");
- return -EINVAL;
- }
+ if (!np)
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "Device Tree node missing\n");
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
@@ -400,8 +397,7 @@ static int pwm_regulator_probe(struct platform_device *pdev)
gpio_flags);
if (IS_ERR(drvdata->enb_gpio)) {
ret = PTR_ERR(drvdata->enb_gpio);
- dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret);
- return ret;
+ return dev_err_probe(&pdev->dev, ret, "Failed to get enable GPIO\n");
}
ret = pwm_adjust_config(drvdata->pwm);
@@ -409,19 +405,17 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return ret;
ret = pwm_regulator_init_boot_on(pdev, drvdata, init_data);
- if (ret) {
- dev_err(&pdev->dev, "Failed to apply boot_on settings: %d\n",
- ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to apply boot_on settings\n");
regulator = devm_regulator_register(&pdev->dev,
&drvdata->desc, &config);
if (IS_ERR(regulator)) {
ret = PTR_ERR(regulator);
- dev_err(&pdev->dev, "Failed to register regulator %s: %d\n",
- drvdata->desc.name, ret);
- return ret;
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to register regulator %s\n",
+ drvdata->desc.name);
}
return 0;
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
index d1be9568025e..3b7e06b9f5ce 100644
--- a/drivers/regulator/qcom_smd-regulator.c
+++ b/drivers/regulator/qcom_smd-regulator.c
@@ -11,11 +11,10 @@
#include <linux/regulator/of_regulator.h>
#include <linux/soc/qcom/smd-rpm.h>
+struct qcom_smd_rpm *smd_vreg_rpm;
+
struct qcom_rpm_reg {
struct device *dev;
-
- struct qcom_smd_rpm *rpm;
-
u32 type;
u32 id;
@@ -70,7 +69,7 @@ static int rpm_reg_write_active(struct qcom_rpm_reg *vreg)
if (!reqlen)
return 0;
- ret = qcom_rpm_smd_write(vreg->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
+ ret = qcom_rpm_smd_write(smd_vreg_rpm, QCOM_SMD_RPM_ACTIVE_STATE,
vreg->type, vreg->id,
req, sizeof(req[0]) * reqlen);
if (!ret) {
@@ -1384,14 +1383,13 @@ MODULE_DEVICE_TABLE(of, rpm_of_match);
* @dev: Pointer to the top level qcom_smd-regulator PMIC device
* @node: Pointer to the individual qcom_smd-regulator resource
* device node
- * @rpm: Pointer to the rpm bus node
* @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator
* resources defined for the top level PMIC device
*
* Return: 0 on success, errno on failure
*/
static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev,
- struct device_node *node, struct qcom_smd_rpm *rpm,
+ struct device_node *node,
const struct rpm_regulator_data *pmic_rpm_data)
{
struct regulator_config config = {};
@@ -1409,7 +1407,6 @@ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev
}
vreg->dev = dev;
- vreg->rpm = rpm;
vreg->type = rpm_data->type;
vreg->id = rpm_data->id;
@@ -1449,6 +1446,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENODEV;
}
+ if (smd_vreg_rpm && rpm != smd_vreg_rpm)
+ return dev_err_probe(dev, -EINVAL, "RPM mismatch\n");
+
+ smd_vreg_rpm = rpm;
+
vreg_data = of_device_get_match_data(dev);
if (!vreg_data)
return -ENODEV;
@@ -1460,8 +1462,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENOMEM;
}
- ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data);
-
+ ret = rpm_regulator_init_vreg(vreg, dev, node, vreg_data);
if (ret < 0) {
of_node_put(node);
return ret;
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
index 53d1b9d6f69c..86a626a4f610 100644
--- a/drivers/regulator/userspace-consumer.c
+++ b/drivers/regulator/userspace-consumer.c
@@ -208,6 +208,7 @@ static const struct of_device_id regulator_userspace_consumer_of_match[] = {
{ .compatible = "regulator-output", },
{},
};
+MODULE_DEVICE_TABLE(of, regulator_userspace_consumer_of_match);
static struct platform_driver regulator_userspace_consumer_driver = {
.probe = regulator_userspace_consumer_probe,