Commit f25828a1 authored by Linus Walleij's avatar Linus Walleij Committed by Mark Brown
Browse files

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: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://msgid.link/r/20240220-descriptors-regulators-v1-5-097f608694be@linaro.org


Acked-by: default avatarLee Jones <lee@kernel.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 84618d5e
Loading
Loading
Loading
Loading
+54 −96
Original line number Diff line number Diff line
@@ -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 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
		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 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
					&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;
+0 −6
Original line number Diff line number Diff line
@@ -65,10 +65,7 @@ struct max8998_regulator_data {
 *   be other than the preset values.
 * @buck1_voltage: BUCK1 DVS mode 1 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
 * @buck2_set3: BUCK2 gpio pin to set output voltage
 * @buck2_default_idx: Default for BUCK2 gpio pin.
 * @wakeup: Allow to wake up from suspend
 * @rtc_delay: LP3974 RTC chip bug that requires delay after a register
@@ -91,10 +88,7 @@ struct max8998_platform_data {
	bool				buck_voltage_lock;
	int				buck1_voltage[4];
	int				buck2_voltage[2];
	int				buck1_set1;
	int				buck1_set2;
	int				buck1_default_idx;
	int				buck2_set3;
	int				buck2_default_idx;
	bool				wakeup;
	bool				rtc_delay;