Merge remote-tracking branches 'regulator/topic/lp8755', 'regulator/topic/max14577', 'regulator/topic/max77693', 'regulator/topic/max77843' and 'regulator/topic/max8973' into regulator-next

This commit is contained in:
Mark Brown 2015-06-22 11:19:55 +01:00
7 changed files with 320 additions and 209 deletions

View File

@ -2,12 +2,30 @@
Required properties: Required properties:
- compatible: must be "maxim,max8973" - compatible: must be one of following:
"maxim,max8973"
"maxim,max77621".
- reg: the i2c slave address of the regulator. It should be 0x1b. - reg: the i2c slave address of the regulator. It should be 0x1b.
Any standard regulator properties can be used to configure the single max8973 Any standard regulator properties can be used to configure the single max8973
DCDC. DCDC.
Optional properties:
-maxim,externally-enable: boolean, externally control the regulator output
enable/disable.
-maxim,enable-gpio: GPIO for enable control. If the valid GPIO is provided
then externally enable control will be considered.
-maxim,dvs-gpio: GPIO which is connected to DVS pin of device.
-maxim,dvs-default-state: Default state of GPIO during initialisation.
1 for HIGH and 0 for LOW.
-maxim,enable-remote-sense: boolean, enable reote sense.
-maxim,enable-falling-slew-rate: boolean, enable falling slew rate.
-maxim,enable-active-discharge: boolean: enable active discharge.
-maxim,enable-frequency-shift: boolean, enable 9% frequency shift.
-maxim,enable-bias-control: boolean, enable bias control. By enabling this
startup delay can be reduce to 20us from 220us.
Example: Example:
max8973@1b { max8973@1b {

View File

@ -419,20 +419,16 @@ static int lp8755_int_config(struct lp8755_chip *pchip)
} }
ret = lp8755_read(pchip, 0x0F, &regval); ret = lp8755_read(pchip, 0x0F, &regval);
if (ret < 0) if (ret < 0) {
goto err_i2c; dev_err(pchip->dev, "i2c acceess error %s\n", __func__);
pchip->irqmask = regval;
ret = request_threaded_irq(pchip->irq, NULL, lp8755_irq_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"lp8755-irq", pchip);
if (ret)
return ret; return ret;
}
return ret; pchip->irqmask = regval;
return devm_request_threaded_irq(pchip->dev, pchip->irq, NULL,
err_i2c: lp8755_irq_handler,
dev_err(pchip->dev, "i2c acceess error %s\n", __func__); IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
return ret; "lp8755-irq", pchip);
} }
static const struct regmap_config lp8755_regmap = { static const struct regmap_config lp8755_regmap = {
@ -514,9 +510,6 @@ static int lp8755_remove(struct i2c_client *client)
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
lp8755_write(pchip, icnt, 0x00); lp8755_write(pchip, icnt, 0x00);
if (pchip->irq != 0)
free_irq(pchip->irq, pchip);
return 0; return 0;
} }

View File

@ -100,31 +100,34 @@ static struct regulator_ops max14577_charger_ops = {
.set_current_limit = max14577_reg_set_current_limit, .set_current_limit = max14577_reg_set_current_limit,
}; };
#define MAX14577_SAFEOUT_REG { \
.name = "SAFEOUT", \
.of_match = of_match_ptr("SAFEOUT"), \
.regulators_node = of_match_ptr("regulators"), \
.id = MAX14577_SAFEOUT, \
.ops = &max14577_safeout_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.n_voltages = 1, \
.min_uV = MAX14577_REGULATOR_SAFEOUT_VOLTAGE, \
.enable_reg = MAX14577_REG_CONTROL2, \
.enable_mask = CTRL2_SFOUTORD_MASK, \
}
#define MAX14577_CHARGER_REG { \
.name = "CHARGER", \
.of_match = of_match_ptr("CHARGER"), \
.regulators_node = of_match_ptr("regulators"), \
.id = MAX14577_CHARGER, \
.ops = &max14577_charger_ops, \
.type = REGULATOR_CURRENT, \
.owner = THIS_MODULE, \
.enable_reg = MAX14577_CHG_REG_CHG_CTRL2, \
.enable_mask = CHGCTRL2_MBCHOSTEN_MASK, \
}
static const struct regulator_desc max14577_supported_regulators[] = { static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_SAFEOUT] = { [MAX14577_SAFEOUT] = MAX14577_SAFEOUT_REG,
.name = "SAFEOUT", [MAX14577_CHARGER] = MAX14577_CHARGER_REG,
.of_match = of_match_ptr("SAFEOUT"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = 1,
.min_uV = MAX14577_REGULATOR_SAFEOUT_VOLTAGE,
.enable_reg = MAX14577_REG_CONTROL2,
.enable_mask = CTRL2_SFOUTORD_MASK,
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.enable_reg = MAX14577_CHG_REG_CHG_CTRL2,
.enable_mask = CHGCTRL2_MBCHOSTEN_MASK,
},
}; };
static struct regulator_ops max77836_ldo_ops = { static struct regulator_ops max77836_ldo_ops = {
@ -138,63 +141,28 @@ static struct regulator_ops max77836_ldo_ops = {
/* TODO: add .set_suspend_mode */ /* TODO: add .set_suspend_mode */
}; };
#define MAX77836_LDO_REG(num) { \
.name = "LDO" # num, \
.of_match = of_match_ptr("LDO" # num), \
.regulators_node = of_match_ptr("regulators"), \
.id = MAX77836_LDO ## num, \
.ops = &max77836_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.n_voltages = MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM, \
.min_uV = MAX77836_REGULATOR_LDO_VOLTAGE_MIN, \
.uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP, \
.enable_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
.enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK, \
.vsel_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
.vsel_mask = MAX77836_CNFG1_LDO_TV_MASK, \
}
static const struct regulator_desc max77836_supported_regulators[] = { static const struct regulator_desc max77836_supported_regulators[] = {
[MAX14577_SAFEOUT] = { [MAX14577_SAFEOUT] = MAX14577_SAFEOUT_REG,
.name = "SAFEOUT", [MAX14577_CHARGER] = MAX14577_CHARGER_REG,
.of_match = of_match_ptr("SAFEOUT"), [MAX77836_LDO1] = MAX77836_LDO_REG(1),
.regulators_node = of_match_ptr("regulators"), [MAX77836_LDO2] = MAX77836_LDO_REG(2),
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = 1,
.min_uV = MAX14577_REGULATOR_SAFEOUT_VOLTAGE,
.enable_reg = MAX14577_REG_CONTROL2,
.enable_mask = CTRL2_SFOUTORD_MASK,
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.enable_reg = MAX14577_CHG_REG_CHG_CTRL2,
.enable_mask = CHGCTRL2_MBCHOSTEN_MASK,
},
[MAX77836_LDO1] = {
.name = "LDO1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO1,
.ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM,
.min_uV = MAX77836_REGULATOR_LDO_VOLTAGE_MIN,
.uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP,
.enable_reg = MAX77836_LDO_REG_CNFG1_LDO1,
.enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK,
.vsel_reg = MAX77836_LDO_REG_CNFG1_LDO1,
.vsel_mask = MAX77836_CNFG1_LDO_TV_MASK,
},
[MAX77836_LDO2] = {
.name = "LDO2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO2,
.ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM,
.min_uV = MAX77836_REGULATOR_LDO_VOLTAGE_MIN,
.uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP,
.enable_reg = MAX77836_LDO_REG_CNFG1_LDO2,
.enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK,
.vsel_reg = MAX77836_LDO_REG_CNFG1_LDO2,
.vsel_mask = MAX77836_CNFG1_LDO_TV_MASK,
},
}; };
#ifdef CONFIG_OF #ifdef CONFIG_OF

View File

@ -35,20 +35,6 @@
#define CHGIN_ILIM_STEP_20mA 20000 #define CHGIN_ILIM_STEP_20mA 20000
/* CHARGER regulator ops */
/* CHARGER regulator uses two bits for enabling */
static int max77693_chg_is_enabled(struct regulator_dev *rdev)
{
int ret;
unsigned int val;
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret)
return ret;
return (val & rdev->desc->enable_mask) == rdev->desc->enable_mask;
}
/* /*
* CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
* 0x00, 0x01, 0x2, 0x03 = 60 mA * 0x00, 0x01, 0x2, 0x03 = 60 mA
@ -118,7 +104,7 @@ static struct regulator_ops max77693_safeout_ops = {
}; };
static struct regulator_ops max77693_charger_ops = { static struct regulator_ops max77693_charger_ops = {
.is_enabled = max77693_chg_is_enabled, .is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap, .enable = regulator_enable_regmap,
.disable = regulator_disable_regmap, .disable = regulator_disable_regmap,
.get_current_limit = max77693_chg_get_current_limit, .get_current_limit = max77693_chg_get_current_limit,
@ -155,6 +141,7 @@ static const struct regulator_desc regulators[] = {
.enable_reg = MAX77693_CHG_REG_CHG_CNFG_00, .enable_reg = MAX77693_CHG_REG_CHG_CNFG_00,
.enable_mask = CHG_CNFG_00_CHG_MASK | .enable_mask = CHG_CNFG_00_CHG_MASK |
CHG_CNFG_00_BUCK_MASK, CHG_CNFG_00_BUCK_MASK,
.enable_val = CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK,
}, },
}; };

View File

@ -33,21 +33,6 @@ static const unsigned int max77843_safeout_voltage_table[] = {
3300000, 3300000,
}; };
static int max77843_reg_is_enabled(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev->regmap;
int ret;
unsigned int reg;
ret = regmap_read(regmap, rdev->desc->enable_reg, &reg);
if (ret) {
dev_err(&rdev->dev, "Fialed to read charger register\n");
return ret;
}
return (reg & rdev->desc->enable_mask) == rdev->desc->enable_mask;
}
static int max77843_reg_get_current_limit(struct regulator_dev *rdev) static int max77843_reg_get_current_limit(struct regulator_dev *rdev)
{ {
struct regmap *regmap = rdev->regmap; struct regmap *regmap = rdev->regmap;
@ -96,7 +81,7 @@ static int max77843_reg_set_current_limit(struct regulator_dev *rdev,
} }
static struct regulator_ops max77843_charger_ops = { static struct regulator_ops max77843_charger_ops = {
.is_enabled = max77843_reg_is_enabled, .is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap, .enable = regulator_enable_regmap,
.disable = regulator_disable_regmap, .disable = regulator_disable_regmap,
.get_current_limit = max77843_reg_get_current_limit, .get_current_limit = max77843_reg_get_current_limit,
@ -112,37 +97,25 @@ static struct regulator_ops max77843_regulator_ops = {
.set_voltage_sel = regulator_set_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[] = { static const struct regulator_desc max77843_supported_regulators[] = {
[MAX77843_SAFEOUT1] = { [MAX77843_SAFEOUT1] = MAX77843_SAFEOUT(1),
.name = "SAFEOUT1", [MAX77843_SAFEOUT2] = MAX77843_SAFEOUT(2),
.id = MAX77843_SAFEOUT1,
.ops = &max77843_regulator_ops,
.of_match = of_match_ptr("SAFEOUT1"),
.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_ENSAFEOUT1,
.vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
.vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT1_MASK,
},
[MAX77843_SAFEOUT2] = {
.name = "SAFEOUT2",
.id = MAX77843_SAFEOUT2,
.ops = &max77843_regulator_ops,
.of_match = of_match_ptr("SAFEOUT2"),
.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_ENSAFEOUT2,
.vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
.vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT2_MASK,
},
[MAX77843_CHARGER] = { [MAX77843_CHARGER] = {
.name = "CHARGER", .name = "CHARGER",
.id = MAX77843_CHARGER, .id = MAX77843_CHARGER,
@ -152,7 +125,8 @@ static const struct regulator_desc max77843_supported_regulators[] = {
.type = REGULATOR_CURRENT, .type = REGULATOR_CURRENT,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.enable_reg = MAX77843_CHG_REG_CHG_CNFG_00, .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
.enable_mask = MAX77843_CHG_MASK, .enable_mask = MAX77843_CHG_MASK | MAX77843_CHG_BUCK_MASK,
.enable_val = MAX77843_CHG_MASK | MAX77843_CHG_BUCK_MASK,
}, },
}; };

View File

@ -27,12 +27,14 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/max8973-regulator.h> #include <linux/regulator/max8973-regulator.h>
#include <linux/regulator/of_regulator.h> #include <linux/regulator/of_regulator.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/regmap.h> #include <linux/regmap.h>
@ -66,6 +68,7 @@
#define MAX8973_RAMP_25mV_PER_US 0x1 #define MAX8973_RAMP_25mV_PER_US 0x1
#define MAX8973_RAMP_50mV_PER_US 0x2 #define MAX8973_RAMP_50mV_PER_US 0x2
#define MAX8973_RAMP_200mV_PER_US 0x3 #define MAX8973_RAMP_200mV_PER_US 0x3
#define MAX8973_RAMP_MASK 0x3
/* MAX8973_CONTROL2 */ /* MAX8973_CONTROL2 */
#define MAX8973_WDTMR_ENABLE BIT(6) #define MAX8973_WDTMR_ENABLE BIT(6)
@ -89,19 +92,25 @@
#define MAX8973_VOLATGE_STEP 6250 #define MAX8973_VOLATGE_STEP 6250
#define MAX8973_BUCK_N_VOLTAGE 0x80 #define MAX8973_BUCK_N_VOLTAGE 0x80
enum device_id {
MAX8973,
MAX77621
};
/* Maxim 8973 chip information */ /* Maxim 8973 chip information */
struct max8973_chip { struct max8973_chip {
struct device *dev; struct device *dev;
struct regulator_desc desc; struct regulator_desc desc;
struct regmap *regmap; struct regmap *regmap;
bool enable_external_control; bool enable_external_control;
int enable_gpio;
int dvs_gpio; int dvs_gpio;
int lru_index[MAX8973_MAX_VOUT_REG]; int lru_index[MAX8973_MAX_VOUT_REG];
int curr_vout_val[MAX8973_MAX_VOUT_REG]; int curr_vout_val[MAX8973_MAX_VOUT_REG];
int curr_vout_reg; int curr_vout_reg;
int curr_gpio_val; int curr_gpio_val;
bool valid_dvs_gpio;
struct regulator_ops ops; struct regulator_ops ops;
enum device_id id;
}; };
/* /*
@ -174,7 +183,7 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
* If gpios are available to select the VOUT register then least * If gpios are available to select the VOUT register then least
* recently used register for new configuration. * recently used register for new configuration.
*/ */
if (max->valid_dvs_gpio) if (gpio_is_valid(max->dvs_gpio))
found = find_voltage_set_register(max, vsel, found = find_voltage_set_register(max, vsel,
&vout_reg, &gpio_val); &vout_reg, &gpio_val);
@ -191,7 +200,7 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
} }
/* Select proper VOUT register vio gpios */ /* Select proper VOUT register vio gpios */
if (max->valid_dvs_gpio) { if (gpio_is_valid(max->dvs_gpio)) {
gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1); gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
max->curr_gpio_val = gpio_val; max->curr_gpio_val = gpio_val;
} }
@ -242,12 +251,45 @@ static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
} }
static int max8973_set_ramp_delay(struct regulator_dev *rdev,
int ramp_delay)
{
struct max8973_chip *max = rdev_get_drvdata(rdev);
unsigned int control;
int ret;
int ret_val;
/* Set ramp delay */
if (ramp_delay < 25000) {
control = MAX8973_RAMP_12mV_PER_US;
ret_val = 12000;
} else if (ramp_delay < 50000) {
control = MAX8973_RAMP_25mV_PER_US;
ret_val = 25000;
} else if (ramp_delay < 200000) {
control = MAX8973_RAMP_50mV_PER_US;
ret_val = 50000;
} else {
control = MAX8973_RAMP_200mV_PER_US;
ret_val = 200000;
}
ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1,
MAX8973_RAMP_MASK, control);
if (ret < 0)
dev_err(max->dev, "register %d update failed, %d",
MAX8973_CONTROL1, ret);
return ret;
}
static const struct regulator_ops max8973_dcdc_ops = { static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel, .get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel, .set_voltage_sel = max8973_dcdc_set_voltage_sel,
.list_voltage = regulator_list_voltage_linear, .list_voltage = regulator_list_voltage_linear,
.set_mode = max8973_dcdc_set_mode, .set_mode = max8973_dcdc_set_mode,
.get_mode = max8973_dcdc_get_mode, .get_mode = max8973_dcdc_get_mode,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max8973_set_ramp_delay,
}; };
static int max8973_init_dcdc(struct max8973_chip *max, static int max8973_init_dcdc(struct max8973_chip *max,
@ -256,6 +298,29 @@ static int max8973_init_dcdc(struct max8973_chip *max,
int ret; int ret;
uint8_t control1 = 0; uint8_t control1 = 0;
uint8_t control2 = 0; uint8_t control2 = 0;
unsigned int data;
ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data);
if (ret < 0) {
dev_err(max->dev, "register %d read failed, err = %d",
MAX8973_CONTROL1, ret);
return ret;
}
control1 = data & MAX8973_RAMP_MASK;
switch (control1) {
case MAX8973_RAMP_12mV_PER_US:
max->desc.ramp_delay = 12000;
break;
case MAX8973_RAMP_25mV_PER_US:
max->desc.ramp_delay = 25000;
break;
case MAX8973_RAMP_50mV_PER_US:
max->desc.ramp_delay = 50000;
break;
case MAX8973_RAMP_200mV_PER_US:
max->desc.ramp_delay = 200000;
break;
}
if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE) if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE)
control1 |= MAX8973_SNS_ENABLE; control1 |= MAX8973_SNS_ENABLE;
@ -266,28 +331,16 @@ static int max8973_init_dcdc(struct max8973_chip *max,
if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE) if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE)
control1 |= MAX8973_AD_ENABLE; control1 |= MAX8973_AD_ENABLE;
if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE) if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE) {
control1 |= MAX8973_BIAS_ENABLE; control1 |= MAX8973_BIAS_ENABLE;
max->desc.enable_time = 20;
} else {
max->desc.enable_time = 240;
}
if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE) if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
control1 |= MAX8973_FREQSHIFT_9PER; control1 |= MAX8973_FREQSHIFT_9PER;
/* Set ramp delay */
if (pdata->reg_init_data &&
pdata->reg_init_data->constraints.ramp_delay) {
if (pdata->reg_init_data->constraints.ramp_delay < 25000)
control1 |= MAX8973_RAMP_12mV_PER_US;
else if (pdata->reg_init_data->constraints.ramp_delay < 50000)
control1 |= MAX8973_RAMP_25mV_PER_US;
else if (pdata->reg_init_data->constraints.ramp_delay < 200000)
control1 |= MAX8973_RAMP_50mV_PER_US;
else
control1 |= MAX8973_RAMP_200mV_PER_US;
} else {
control1 |= MAX8973_RAMP_12mV_PER_US;
max->desc.ramp_delay = 12500;
}
if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE)) if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
control2 |= MAX8973_DISCH_ENBABLE; control2 |= MAX8973_DISCH_ENBABLE;
@ -344,7 +397,7 @@ static int max8973_init_dcdc(struct max8973_chip *max,
} }
/* If external control is enabled then disable EN bit */ /* If external control is enabled then disable EN bit */
if (max->enable_external_control) { if (max->enable_external_control && (max->id == MAX8973)) {
ret = regmap_update_bits(max->regmap, MAX8973_VOUT, ret = regmap_update_bits(max->regmap, MAX8973_VOUT,
MAX8973_VOUT_ENABLE, 0); MAX8973_VOUT_ENABLE, 0);
if (ret < 0) if (ret < 0)
@ -361,22 +414,82 @@ static const struct regmap_config max8973_regmap_config = {
.cache_type = REGCACHE_RBTREE, .cache_type = REGCACHE_RBTREE,
}; };
static struct max8973_regulator_platform_data *max8973_parse_dt(
struct device *dev)
{
struct max8973_regulator_platform_data *pdata;
struct device_node *np = dev->of_node;
int ret;
u32 pval;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
pdata->enable_ext_control = of_property_read_bool(np,
"maxim,externally-enable");
pdata->enable_gpio = of_get_named_gpio(np, "maxim,enable-gpio", 0);
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)
pdata->dvs_def_state = pval;
if (of_property_read_bool(np, "maxim,enable-remote-sense"))
pdata->control_flags |= MAX8973_CONTROL_REMOTE_SENSE_ENABLE;
if (of_property_read_bool(np, "maxim,enable-falling-slew-rate"))
pdata->control_flags |=
MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE;
if (of_property_read_bool(np, "maxim,enable-active-discharge"))
pdata->control_flags |=
MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE;
if (of_property_read_bool(np, "maxim,enable-frequency-shift"))
pdata->control_flags |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE;
if (of_property_read_bool(np, "maxim,enable-bias-control"))
pdata->control_flags |= MAX8973_BIAS_ENABLE;
return pdata;
}
static const struct of_device_id of_max8973_match_tbl[] = {
{ .compatible = "maxim,max8973", .data = (void *)MAX8973, },
{ .compatible = "maxim,max77621", .data = (void *)MAX77621, },
{ },
};
MODULE_DEVICE_TABLE(of, of_max8973_match_tbl);
static int max8973_probe(struct i2c_client *client, static int max8973_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct max8973_regulator_platform_data *pdata; struct max8973_regulator_platform_data *pdata;
struct regulator_init_data *ridata;
struct regulator_config config = { }; struct regulator_config config = { };
struct regulator_dev *rdev; struct regulator_dev *rdev;
struct max8973_chip *max; struct max8973_chip *max;
bool pdata_from_dt = false;
unsigned int chip_id;
int ret; int ret;
pdata = dev_get_platdata(&client->dev); pdata = dev_get_platdata(&client->dev);
if (!pdata && !client->dev.of_node) { if (!pdata && client->dev.of_node) {
pdata = max8973_parse_dt(&client->dev);
pdata_from_dt = true;
}
if (!pdata) {
dev_err(&client->dev, "No Platform data"); dev_err(&client->dev, "No Platform data");
return -EIO; return -EIO;
} }
if ((pdata->dvs_gpio == -EPROBE_DEFER) ||
(pdata->enable_gpio == -EPROBE_DEFER))
return -EPROBE_DEFER;
max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
if (!max) if (!max)
return -ENOMEM; return -ENOMEM;
@ -388,6 +501,27 @@ static int max8973_probe(struct i2c_client *client,
return ret; return ret;
} }
if (client->dev.of_node) {
const struct of_device_id *match;
match = of_match_device(of_match_ptr(of_max8973_match_tbl),
&client->dev);
if (!match)
return -ENODATA;
max->id = (u32)((uintptr_t)match->data);
} else {
max->id = id->driver_data;
}
ret = regmap_read(max->regmap, MAX8973_CHIPID1, &chip_id);
if (ret < 0) {
dev_err(&client->dev, "register CHIPID1 read failed, %d", ret);
return ret;
}
dev_info(&client->dev, "CHIP-ID OTP: 0x%02x ID_M: 0x%02x\n",
(chip_id >> 4) & 0xF, (chip_id >> 1) & 0x7);
i2c_set_clientdata(client, max); i2c_set_clientdata(client, max);
max->ops = max8973_dcdc_ops; max->ops = max8973_dcdc_ops;
max->dev = &client->dev; max->dev = &client->dev;
@ -400,23 +534,14 @@ static int max8973_probe(struct i2c_client *client,
max->desc.uV_step = MAX8973_VOLATGE_STEP; max->desc.uV_step = MAX8973_VOLATGE_STEP;
max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE; max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
if (!pdata || !pdata->enable_ext_control) { max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
max->desc.enable_reg = MAX8973_VOUT; max->enable_gpio = (pdata->enable_gpio) ? pdata->enable_gpio : -EINVAL;
max->desc.enable_mask = MAX8973_VOUT_ENABLE; max->enable_external_control = pdata->enable_ext_control;
max->ops.enable = regulator_enable_regmap; max->curr_gpio_val = pdata->dvs_def_state;
max->ops.disable = regulator_disable_regmap; max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
max->ops.is_enabled = regulator_is_enabled_regmap;
}
if (pdata) { if (gpio_is_valid(max->enable_gpio))
max->dvs_gpio = pdata->dvs_gpio; max->enable_external_control = true;
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;
} else {
max->dvs_gpio = -EINVAL;
max->curr_vout_reg = MAX8973_VOUT;
}
max->lru_index[0] = max->curr_vout_reg; max->lru_index[0] = max->curr_vout_reg;
@ -434,7 +559,6 @@ static int max8973_probe(struct i2c_client *client,
max->dvs_gpio, ret); max->dvs_gpio, ret);
return ret; return ret;
} }
max->valid_dvs_gpio = true;
/* /*
* Initialize the lru index with vout_reg id * Initialize the lru index with vout_reg id
@ -444,22 +568,64 @@ static int max8973_probe(struct i2c_client *client,
max->lru_index[i] = i; max->lru_index[i] = i;
max->lru_index[0] = max->curr_vout_reg; max->lru_index[0] = max->curr_vout_reg;
max->lru_index[max->curr_vout_reg] = 0; max->lru_index[max->curr_vout_reg] = 0;
} else {
max->valid_dvs_gpio = false;
} }
if (pdata) { if (pdata_from_dt)
ret = max8973_init_dcdc(max, pdata); pdata->reg_init_data = of_get_regulator_init_data(&client->dev,
if (ret < 0) { client->dev.of_node, &max->desc);
dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
return ret; ridata = pdata->reg_init_data;
switch (max->id) {
case MAX8973:
if (!pdata->enable_ext_control) {
max->desc.enable_reg = MAX8973_VOUT;
max->desc.enable_mask = MAX8973_VOUT_ENABLE;
max->ops.enable = regulator_enable_regmap;
max->ops.disable = regulator_disable_regmap;
max->ops.is_enabled = regulator_is_enabled_regmap;
break;
} }
if (gpio_is_valid(max->enable_gpio)) {
config.ena_gpio_flags = GPIOF_OUT_INIT_LOW;
if (ridata && (ridata->constraints.always_on ||
ridata->constraints.boot_on))
config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
config.ena_gpio = max->enable_gpio;
}
break;
case MAX77621:
if (gpio_is_valid(max->enable_gpio)) {
ret = devm_gpio_request_one(&client->dev,
max->enable_gpio, GPIOF_OUT_INIT_HIGH,
"max8973-en-gpio");
if (ret) {
dev_err(&client->dev,
"gpio_request for gpio %d failed: %d\n",
max->enable_gpio, ret);
return ret;
}
}
max->desc.enable_reg = MAX8973_VOUT;
max->desc.enable_mask = MAX8973_VOUT_ENABLE;
max->ops.enable = regulator_enable_regmap;
max->ops.disable = regulator_disable_regmap;
max->ops.is_enabled = regulator_is_enabled_regmap;
break;
default:
break;
}
ret = max8973_init_dcdc(max, pdata);
if (ret < 0) {
dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
return ret;
} }
config.dev = &client->dev; config.dev = &client->dev;
config.init_data = pdata ? pdata->reg_init_data : config.init_data = pdata->reg_init_data;
of_get_regulator_init_data(&client->dev, client->dev.of_node,
&max->desc);
config.driver_data = max; config.driver_data = max;
config.of_node = client->dev.of_node; config.of_node = client->dev.of_node;
config.regmap = max->regmap; config.regmap = max->regmap;
@ -476,15 +642,16 @@ static int max8973_probe(struct i2c_client *client,
} }
static const struct i2c_device_id max8973_id[] = { static const struct i2c_device_id max8973_id[] = {
{.name = "max8973",}, {.name = "max8973", .driver_data = MAX8973},
{.name = "max77621", .driver_data = MAX77621},
{}, {},
}; };
MODULE_DEVICE_TABLE(i2c, max8973_id); MODULE_DEVICE_TABLE(i2c, max8973_id);
static struct i2c_driver max8973_i2c_driver = { static struct i2c_driver max8973_i2c_driver = {
.driver = { .driver = {
.name = "max8973", .name = "max8973",
.of_match_table = of_max8973_match_tbl,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = max8973_probe, .probe = max8973_probe,

View File

@ -58,6 +58,9 @@
* control signal from EN input pin. If it is false then * control signal from EN input pin. If it is false then
* voltage output will be enabled/disabled through EN bit of * voltage output will be enabled/disabled through EN bit of
* device register. * device register.
* @enable_gpio: Enable GPIO. If EN pin is controlled through GPIO from host
* then GPIO number can be provided. If no GPIO controlled then
* it should be -1.
* @dvs_gpio: GPIO for dvs. It should be -1 if this is tied with fixed logic. * @dvs_gpio: GPIO for dvs. It should be -1 if this is tied with fixed logic.
* @dvs_def_state: Default state of dvs. 1 if it is high else 0. * @dvs_def_state: Default state of dvs. 1 if it is high else 0.
*/ */
@ -65,6 +68,7 @@ struct max8973_regulator_platform_data {
struct regulator_init_data *reg_init_data; struct regulator_init_data *reg_init_data;
unsigned long control_flags; unsigned long control_flags;
bool enable_ext_control; bool enable_ext_control;
int enable_gpio;
int dvs_gpio; int dvs_gpio;
unsigned dvs_def_state:1; unsigned dvs_def_state:1;
}; };