mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 09:13:38 +00:00
regulator: max8998: Convert to GPIO descriptors
This rewrites the max8998 regulator driver to fetch the dvs regulators as descriptors. This will likely mostly come from the device tree since there are no in-tree users of the platform data, but supplying GPIO descriptor tables from board files is also possible if needed. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://msgid.link/r/20240220-descriptors-regulators-v1-5-097f608694be@linaro.org Acked-by: Lee Jones <lee@kernel.org> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
84618d5e31
commit
f25828a1ea
@ -10,12 +10,12 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/bits.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_gpio.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/regulator/driver.h>
|
#include <linux/regulator/driver.h>
|
||||||
#include <linux/regulator/of_regulator.h>
|
#include <linux/regulator/of_regulator.h>
|
||||||
@ -31,6 +31,9 @@ struct max8998_data {
|
|||||||
unsigned int buck1_idx; /* index to last changed voltage */
|
unsigned int buck1_idx; /* index to last changed voltage */
|
||||||
/* value in a set */
|
/* value in a set */
|
||||||
unsigned int buck2_idx;
|
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[] = {
|
static const unsigned int charger_current_table[] = {
|
||||||
@ -227,15 +230,15 @@ static int max8998_set_voltage_ldo_sel(struct regulator_dev *rdev,
|
|||||||
return ret;
|
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);
|
gpiod_set_value(gpio1, v & 0x1);
|
||||||
gpio_set_value(gpio2, (v >> 1) & 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,
|
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],
|
selector, max8998->buck1_vol[0], max8998->buck1_vol[1],
|
||||||
max8998->buck1_vol[2], max8998->buck1_vol[3]);
|
max8998->buck1_vol[2], max8998->buck1_vol[3]);
|
||||||
|
|
||||||
if (gpio_is_valid(pdata->buck1_set1) &&
|
if (max8998->buck1_gpio1 && max8998->buck1_gpio2) {
|
||||||
gpio_is_valid(pdata->buck1_set2)) {
|
|
||||||
|
|
||||||
/* check if requested voltage */
|
/* check if requested voltage */
|
||||||
/* value is already defined */
|
/* value is already defined */
|
||||||
for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) {
|
for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) {
|
||||||
if (max8998->buck1_vol[j] == selector) {
|
if (max8998->buck1_vol[j] == selector) {
|
||||||
max8998->buck1_idx = j;
|
max8998->buck1_idx = j;
|
||||||
buck1_gpio_set(pdata->buck1_set1,
|
buck1_gpio_set(max8998->buck1_gpio1,
|
||||||
pdata->buck1_set2, j);
|
max8998->buck1_gpio2, j);
|
||||||
goto buck1_exit;
|
goto buck1_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,13 +288,13 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
|
|||||||
&shift,
|
&shift,
|
||||||
&mask);
|
&mask);
|
||||||
ret = max8998_write_reg(i2c, reg, selector);
|
ret = max8998_write_reg(i2c, reg, selector);
|
||||||
buck1_gpio_set(pdata->buck1_set1,
|
buck1_gpio_set(max8998->buck1_gpio1,
|
||||||
pdata->buck1_set2, max8998->buck1_idx);
|
max8998->buck1_gpio2, max8998->buck1_idx);
|
||||||
buck1_last_val++;
|
buck1_last_val++;
|
||||||
buck1_exit:
|
buck1_exit:
|
||||||
dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n",
|
dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n",
|
||||||
i2c->name, gpio_get_value(pdata->buck1_set1),
|
i2c->name, gpiod_get_value(max8998->buck1_gpio1),
|
||||||
gpio_get_value(pdata->buck1_set2));
|
gpiod_get_value(max8998->buck1_gpio2));
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
ret = max8998_write_reg(i2c, reg, selector);
|
ret = max8998_write_reg(i2c, reg, selector);
|
||||||
@ -303,14 +305,13 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
|
|||||||
dev_dbg(max8998->dev,
|
dev_dbg(max8998->dev,
|
||||||
"BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n",
|
"BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n",
|
||||||
selector, max8998->buck2_vol[0], max8998->buck2_vol[1]);
|
selector, max8998->buck2_vol[0], max8998->buck2_vol[1]);
|
||||||
if (gpio_is_valid(pdata->buck2_set3)) {
|
if (max8998->buck2_gpio) {
|
||||||
|
|
||||||
/* check if requested voltage */
|
/* check if requested voltage */
|
||||||
/* value is already defined */
|
/* value is already defined */
|
||||||
for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) {
|
for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) {
|
||||||
if (max8998->buck2_vol[j] == selector) {
|
if (max8998->buck2_vol[j] == selector) {
|
||||||
max8998->buck2_idx = j;
|
max8998->buck2_idx = j;
|
||||||
buck2_gpio_set(pdata->buck2_set3, j);
|
buck2_gpio_set(max8998->buck2_gpio, j);
|
||||||
goto buck2_exit;
|
goto buck2_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,10 +323,10 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
|
|||||||
®, &shift, &mask);
|
®, &shift, &mask);
|
||||||
ret = max8998_write_reg(i2c, reg, selector);
|
ret = max8998_write_reg(i2c, reg, selector);
|
||||||
max8998->buck2_vol[max8998->buck2_idx] = 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:
|
buck2_exit:
|
||||||
dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name,
|
dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name,
|
||||||
gpio_get_value(pdata->buck2_set3));
|
gpiod_get_value(max8998->buck2_gpio));
|
||||||
} else {
|
} else {
|
||||||
ret = max8998_write_reg(i2c, reg, selector);
|
ret = max8998_write_reg(i2c, reg, selector);
|
||||||
}
|
}
|
||||||
@ -539,36 +540,6 @@ static const struct regulator_desc regulators[] = {
|
|||||||
charger_current_table, MAX8998_REG_CHGR1, 0x7),
|
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,
|
static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
|
||||||
struct max8998_platform_data *pdata)
|
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(reg_np);
|
||||||
of_node_put(regulators_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");
|
pdata->buck_voltage_lock = of_property_read_bool(pmic_np, "max8998,pmic-buck-voltage-lock");
|
||||||
|
|
||||||
ret = of_property_read_u32(pmic_np,
|
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 regulator_dev *rdev;
|
||||||
struct max8998_data *max8998;
|
struct max8998_data *max8998;
|
||||||
struct i2c_client *i2c;
|
struct i2c_client *i2c;
|
||||||
|
enum gpiod_flags flags;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
unsigned int v;
|
unsigned int v;
|
||||||
|
|
||||||
@ -693,37 +661,38 @@ static int max8998_pmic_probe(struct platform_device *pdev)
|
|||||||
max8998->buck1_idx = pdata->buck1_default_idx;
|
max8998->buck1_idx = pdata->buck1_default_idx;
|
||||||
max8998->buck2_idx = pdata->buck2_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 */
|
/* Check if MAX8998 voltage selection GPIOs are defined */
|
||||||
if (gpio_is_valid(pdata->buck1_set1) &&
|
flags = (max8998->buck1_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
||||||
gpio_is_valid(pdata->buck1_set2)) {
|
max8998->buck1_gpio1 = devm_gpiod_get_index_optional(iodev->dev,
|
||||||
/* Check if SET1 is not equal to 0 */
|
"max8998,pmic-buck1-dvs",
|
||||||
if (!pdata->buck1_set1) {
|
0,
|
||||||
dev_err(&pdev->dev,
|
flags);
|
||||||
"MAX8998 SET1 GPIO defined as 0 !\n");
|
if (IS_ERR(max8998->buck1_gpio1))
|
||||||
WARN_ON(!pdata->buck1_set1);
|
return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio1),
|
||||||
return -EIO;
|
"could not get BUCK1 GPIO1\n");
|
||||||
}
|
gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET1");
|
||||||
/* 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");
|
flags = (max8998->buck1_idx & BIT(1)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
||||||
gpio_direction_output(pdata->buck1_set1,
|
max8998->buck1_gpio2 = devm_gpiod_get_index_optional(iodev->dev,
|
||||||
max8998->buck1_idx & 0x1);
|
"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");
|
||||||
|
|
||||||
gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2");
|
if (max8998->buck1_gpio1 && max8998->buck1_gpio2) {
|
||||||
gpio_direction_output(pdata->buck1_set2,
|
|
||||||
(max8998->buck1_idx >> 1) & 0x1);
|
|
||||||
|
|
||||||
/* Set predefined values for BUCK1 registers */
|
/* Set predefined values for BUCK1 registers */
|
||||||
for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
|
for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
|
||||||
int index = MAX8998_BUCK1 - MAX8998_LDO2;
|
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)) {
|
if (max8998->buck2_gpio) {
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* Set predefined values for BUCK2 registers */
|
/* Set predefined values for BUCK2 registers */
|
||||||
for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
|
for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
|
||||||
int index = MAX8998_BUCK2 - MAX8998_LDO2;
|
int index = MAX8998_BUCK2 - MAX8998_LDO2;
|
||||||
|
@ -65,10 +65,7 @@ struct max8998_regulator_data {
|
|||||||
* be other than the preset values.
|
* be other than the preset values.
|
||||||
* @buck1_voltage: BUCK1 DVS mode 1 voltage registers
|
* @buck1_voltage: BUCK1 DVS mode 1 voltage registers
|
||||||
* @buck2_voltage: BUCK2 DVS mode 2 voltage registers
|
* @buck2_voltage: BUCK2 DVS mode 2 voltage registers
|
||||||
* @buck1_set1: BUCK1 gpio pin 1 to set output voltage
|
|
||||||
* @buck1_set2: BUCK1 gpio pin 2 to set output voltage
|
|
||||||
* @buck1_default_idx: Default for BUCK1 gpio pin 1, 2
|
* @buck1_default_idx: Default for BUCK1 gpio pin 1, 2
|
||||||
* @buck2_set3: BUCK2 gpio pin to set output voltage
|
|
||||||
* @buck2_default_idx: Default for BUCK2 gpio pin.
|
* @buck2_default_idx: Default for BUCK2 gpio pin.
|
||||||
* @wakeup: Allow to wake up from suspend
|
* @wakeup: Allow to wake up from suspend
|
||||||
* @rtc_delay: LP3974 RTC chip bug that requires delay after a register
|
* @rtc_delay: LP3974 RTC chip bug that requires delay after a register
|
||||||
@ -91,10 +88,7 @@ struct max8998_platform_data {
|
|||||||
bool buck_voltage_lock;
|
bool buck_voltage_lock;
|
||||||
int buck1_voltage[4];
|
int buck1_voltage[4];
|
||||||
int buck2_voltage[2];
|
int buck2_voltage[2];
|
||||||
int buck1_set1;
|
|
||||||
int buck1_set2;
|
|
||||||
int buck1_default_idx;
|
int buck1_default_idx;
|
||||||
int buck2_set3;
|
|
||||||
int buck2_default_idx;
|
int buck2_default_idx;
|
||||||
bool wakeup;
|
bool wakeup;
|
||||||
bool rtc_delay;
|
bool rtc_delay;
|
||||||
|
Loading…
Reference in New Issue
Block a user