Commit 95daa868 authored by Linus Walleij's avatar Linus Walleij Committed by Mark Brown

regulator: lp8788-buck: Fully convert to GPIO descriptors

This converts the LP8788 BUCK regulator driver to use GPIO
descriptors.

BUCK1 can use one DVS GPIO and BUCK2 can use two DVS GPIOS,
and no more so just hardcode two GPIO descriptors into
the per-DVS state containers.

Obtain the descriptors from each regulators subdevice.

As there are no in-tree users, board files need to populate
descriptor tables for the buck regulator devices when
they want to use this driver. BUCK1 need a GPIO descriptor
at index 0 and BUCK2 needs two GPIO descriptors at
indices 0 and 1.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://msgid.link/r/20240220-descriptors-regulators-v1-3-097f608694be@linaro.orgAcked-by: default avatarLee Jones <lee@kernel.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent e450a2b3
......@@ -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->gpio1))
return PTR_ERR(buck->gpio1);
gpiod_set_consumer_name(buck->gpio1, "LP8788_B2_DVS2");
buck->dvs = pdata->buck2_dvs;
break;
default:
......
......@@ -10,7 +10,6 @@
#ifndef __MFD_LP8788_H__
#define __MFD_LP8788_H__
#include <linux/gpio.h>
#include <linux/irqdomain.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
......@@ -159,21 +158,17 @@ struct lp8788;
/*
* lp8788_buck1_dvs
* @gpio : gpio pin number for dvs control
* @vsel : dvs selector for buck v1 register
*/
struct lp8788_buck1_dvs {
int gpio;
enum lp8788_dvs_sel vsel;
};
/*
* lp8788_buck2_dvs
* @gpio : two gpio pin numbers are used for dvs
* @vsel : dvs selector for buck v2 register
*/
struct lp8788_buck2_dvs {
int gpio[LP8788_NUM_BUCK2_DVS];
enum lp8788_dvs_sel vsel;
};
......@@ -268,8 +263,8 @@ struct lp8788_vib_platform_data {
* @buck_data : regulator initial data for buck
* @dldo_data : regulator initial data for digital ldo
* @aldo_data : regulator initial data for analog ldo
* @buck1_dvs : gpio configurations for buck1 dvs
* @buck2_dvs : gpio configurations for buck2 dvs
* @buck1_dvs : configurations for buck1 dvs
* @buck2_dvs : configurations for buck2 dvs
* @chg_pdata : platform data for charger driver
* @alarm_sel : rtc alarm selection (1 or 2)
* @bl_pdata : configurable data for backlight driver
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment