提交 7fe0bf90 编写于 作者: L Linus Torvalds

Merge tag 'regulator-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "Another fairly quiet release, some new drivers with generic handling
  for minor features but nothing that makes a substantial difference
  outside of the subsystem or for most boards:

   - support for a bunch of new parameters which are present on enough
     regulators to be worth having generic handling for in the
     framework.

   - fixes for some issues with printing constraints during boot which
     should probably have gone in for v4.1 but didn't.

   - new drivers for Dialog DA9062, Maxim MAX77621 and Qualcomm SPMI
     regulators"

* tag 'regulator-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (45 commits)
  regulator: qcom_spmi: Fix calculating number of voltages
  regulator: qcom_spmi: Add missing braces for aligned code
  regulator: fix simple_return.cocci warnings
  regulator: Add QCOM SPMI regulator driver
  regulator: Add docbook for soft start
  regulator: Add input current limit support
  regulator: Add soft start support
  regulator: Add pull down support
  regulator: Add system_load constraint
  regulator: max8973: Fix up ramp_delay for MAX8973_RAMP_25mV_PER_US case
  regulator: core: replace sprintf with scnprintf
  regulator: core: fix constraints output buffer
  regulator: core: Don't corrupt display when printing uV offsets
  regulator: max8973: add support for MAX77621
  regulator: max8973: configure ramp delay through callback
  regulator: pwm-regulator: Diffientiate between dev (device) and rdev (regulator_dev)
  regulator: pwm-regulator: Remove superfluous is_enabled check
  regulator: pwm-regulator: Remove unnecessary descriptor attribute from ddata
  regulator: core: Don't spew backtraces on duplicate sysfs
  regulator: da9063: Fix up irq leak
  ...
......@@ -2,12 +2,30 @@
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.
Any standard regulator properties can be used to configure the single max8973
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:
max8973@1b {
......
Qualcomm SPMI Regulators
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,pm8841-regulators"
"qcom,pm8916-regulators"
"qcom,pm8941-regulators"
- interrupts:
Usage: optional
Value type: <prop-encoded-array>
Definition: List of OCP interrupts.
- interrupt-names:
Usage: required if 'interrupts' property present
Value type: <string-array>
Definition: List of strings defining the names of the
interrupts in the 'interrupts' property 1-to-1.
Supported values are "ocp-<regulator_name>", where
<regulator_name> corresponds to a voltage switch
type regulator.
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
Usage: optional (pm8841 only)
Value type: <phandle>
Definition: Reference to regulator supplying the input pin, as
described in the data sheet.
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_l1_l3-supply:
- vdd_l2-supply:
- vdd_l4_l5_l6-supply:
- vdd_l7-supply:
- vdd_l8_l11_l14_l15_l16-supply:
- vdd_l9_l10_l12_l13_l17_l18-supply:
Usage: optional (pm8916 only)
Value type: <phandle>
Definition: Reference to regulator supplying the input pin, as
described in the data sheet.
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_l1_l3-supply:
- vdd_l2_lvs_1_2_3-supply:
- vdd_l4_l11-supply:
- vdd_l5_l7-supply:
- vdd_l6_l12_l14_l15-supply:
- vdd_l8_l16_l18_19-supply:
- vdd_l9_l10_l17_l22-supply:
- vdd_l13_l20_l23_l24-supply:
- vdd_l21-supply:
- vin_5vs-supply:
Usage: optional (pm8941 only)
Value type: <phandle>
Definition: Reference to regulator supplying the input pin, as
described in the data sheet.
The regulator node houses sub-nodes for each regulator within the device. Each
sub-node is identified using the node's name, with valid values listed for each
of the PMICs below.
pm8841:
s1, s2, s3, s4, s5, s6, s7, s8
pm8916:
s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13,
l14, l15, l16, l17, l18
pm8941:
s1, s2, s3, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14,
l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
mvs1, mvs2
The content of each sub-node is defined by the standard binding for regulators -
see regulator.txt - with additional custom properties described below:
- regulator-initial-mode:
Usage: optional
Value type: <u32>
Descrption: 1 = Set initial mode to high power mode (HPM), also referred
to as NPM. HPM consumes more ground current than LPM, but
it can source significantly higher load current. HPM is not
available on boost type regulators. For voltage switch type
regulators, HPM implies that over current protection and
soft start are active all the time. 0 = Set initial mode to
low power mode (LPM).
Example:
regulators {
compatible = "qcom,pm8941-regulators";
vdd_l1_l3-supply = <&s1>;
s1: s1 {
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <1400000>;
};
...
l1: l1 {
regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1300000>;
};
....
};
......@@ -7,18 +7,20 @@ Optional properties:
- regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops
- regulator-min-microamp: smallest current consumers may set
- regulator-max-microamp: largest current consumers may set
- regulator-input-current-limit-microamp: maximum input current regulator allows
- regulator-always-on: boolean, regulator should never be disabled
- regulator-boot-on: bootloader/firmware enabled regulator
- regulator-allow-bypass: allow the regulator to go into bypass mode
- <name>-supply: phandle to the parent supply/regulator node
- regulator-ramp-delay: ramp delay for regulator(in uV/uS)
For hardware which supports disabling ramp rate, it should be explicitly
intialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
initialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
- regulator-enable-ramp-delay: The time taken, in microseconds, for the supply
rail to reach the target voltage, plus/minus whatever tolerance the board
design requires. This property describes the total system ramp time
required due to the combination of internal ramping of the regulator itself,
and board design issues such as trace capacitance and load on the supply.
- regulator-soft-start: Enable soft start so that voltage ramps slowly
- regulator-state-mem sub-root node for Suspend-to-RAM mode
: suspend to memory, the device goes to sleep, but all data stored in memory,
only some external interrupt can wake the device.
......@@ -37,6 +39,9 @@ Optional properties:
- regulator-initial-mode: initial operating mode. The set of possible operating
modes depends on the capabilities of every hardware so each device binding
documentation explains which values the regulator supports.
- regulator-system-load: Load in uA present on regulator that is not captured by
any consumer request.
- regulator-pull-down: Enable pull down resistor when the regulator is disabled.
Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple
......
......@@ -404,7 +404,7 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
return 0;
}
static struct platform_device_id pm8607_regulator_driver_ids[] = {
static const struct platform_device_id pm8607_regulator_driver_ids[] = {
{
.name = "88pm860x-regulator",
.driver_data = 0,
......
......@@ -178,6 +178,16 @@ config REGULATOR_DA9055
This driver can also be built as a module. If so, the module
will be called da9055-regulator.
config REGULATOR_DA9062
tristate "Dialog Semiconductor DA9062 regulators"
depends on MFD_DA9062
help
Say y here to support the BUCKs and LDOs regulators found on
DA9062 PMICs.
This driver can also be built as a module. If so, the module
will be called da9062-regulator.
config REGULATOR_DA9063
tristate "Dialog Semiconductor DA9063 regulators"
depends on MFD_DA9063
......@@ -233,7 +243,7 @@ config REGULATOR_FAN53555
config REGULATOR_GPIO
tristate "GPIO regulator support"
depends on GPIOLIB
depends on GPIOLIB || COMPILE_TEST
help
This driver provides support for regulators that can be
controlled via gpios.
......@@ -512,6 +522,17 @@ config REGULATOR_QCOM_RPM
Qualcomm RPM as a module. The module will be named
"qcom_rpm-regulator".
config REGULATOR_QCOM_SPMI
tristate "Qualcomm SPMI regulator driver"
depends on SPMI || COMPILE_TEST
help
If you say yes to this option, support will be included for the
regulators found in Qualcomm SPMI PMICs.
Say M here if you want to include support for the regulators on the
Qualcomm SPMI PMICs as a module. The module will be named
"qcom_spmi-regulator".
config REGULATOR_RC5T583
tristate "RICOH RC5T583 Power regulators"
depends on MFD_RC5T583
......
......@@ -25,6 +25,7 @@ obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
obj-$(CONFIG_REGULATOR_DA9062) += da9062-regulator.o
obj-$(CONFIG_REGULATOR_DA9063) += da9063-regulator.o
obj-$(CONFIG_REGULATOR_DA9210) += da9210-regulator.o
obj-$(CONFIG_REGULATOR_DA9211) += da9211-regulator.o
......@@ -61,6 +62,7 @@ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o
......
......@@ -178,6 +178,16 @@ static const struct regulator_init_data arizona_ldo1_default = {
.num_consumer_supplies = 1,
};
static const struct regulator_init_data arizona_ldo1_wm5110 = {
.constraints = {
.min_uV = 1175000,
.max_uV = 1200000,
.valid_ops_mask = REGULATOR_CHANGE_STATUS |
REGULATOR_CHANGE_VOLTAGE,
},
.num_consumer_supplies = 1,
};
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
struct regulator_config *config,
const struct regulator_desc *desc)
......@@ -243,6 +253,11 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
desc = &arizona_ldo1_hc;
ldo1->init_data = arizona_ldo1_dvfs;
break;
case WM5110:
case WM8280:
desc = &arizona_ldo1;
ldo1->init_data = arizona_ldo1_wm5110;
break;
default:
desc = &arizona_ldo1;
ldo1->init_data = arizona_ldo1_default;
......
......@@ -678,6 +678,8 @@ static int drms_uA_update(struct regulator_dev *rdev)
list_for_each_entry(sibling, &rdev->consumer_list, list)
current_uA += sibling->uA_load;
current_uA += rdev->constraints->system_load;
if (rdev->desc->ops->set_load) {
/* set the optimum mode for our new total regulator load */
err = rdev->desc->ops->set_load(rdev, current_uA);
......@@ -779,59 +781,64 @@ static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
static void print_constraints(struct regulator_dev *rdev)
{
struct regulation_constraints *constraints = rdev->constraints;
char buf[80] = "";
char buf[160] = "";
size_t len = sizeof(buf) - 1;
int count = 0;
int ret;
if (constraints->min_uV && constraints->max_uV) {
if (constraints->min_uV == constraints->max_uV)
count += sprintf(buf + count, "%d mV ",
constraints->min_uV / 1000);
count += scnprintf(buf + count, len - count, "%d mV ",
constraints->min_uV / 1000);
else
count += sprintf(buf + count, "%d <--> %d mV ",
constraints->min_uV / 1000,
constraints->max_uV / 1000);
count += scnprintf(buf + count, len - count,
"%d <--> %d mV ",
constraints->min_uV / 1000,
constraints->max_uV / 1000);
}
if (!constraints->min_uV ||
constraints->min_uV != constraints->max_uV) {
ret = _regulator_get_voltage(rdev);
if (ret > 0)
count += sprintf(buf + count, "at %d mV ", ret / 1000);
count += scnprintf(buf + count, len - count,
"at %d mV ", ret / 1000);
}
if (constraints->uV_offset)
count += sprintf(buf, "%dmV offset ",
constraints->uV_offset / 1000);
count += scnprintf(buf + count, len - count, "%dmV offset ",
constraints->uV_offset / 1000);
if (constraints->min_uA && constraints->max_uA) {
if (constraints->min_uA == constraints->max_uA)
count += sprintf(buf + count, "%d mA ",
constraints->min_uA / 1000);
count += scnprintf(buf + count, len - count, "%d mA ",
constraints->min_uA / 1000);
else
count += sprintf(buf + count, "%d <--> %d mA ",
constraints->min_uA / 1000,
constraints->max_uA / 1000);
count += scnprintf(buf + count, len - count,
"%d <--> %d mA ",
constraints->min_uA / 1000,
constraints->max_uA / 1000);
}
if (!constraints->min_uA ||
constraints->min_uA != constraints->max_uA) {
ret = _regulator_get_current_limit(rdev);
if (ret > 0)
count += sprintf(buf + count, "at %d mA ", ret / 1000);
count += scnprintf(buf + count, len - count,
"at %d mA ", ret / 1000);
}
if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
count += sprintf(buf + count, "fast ");
count += scnprintf(buf + count, len - count, "fast ");
if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
count += sprintf(buf + count, "normal ");
count += scnprintf(buf + count, len - count, "normal ");
if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
count += sprintf(buf + count, "idle ");
count += scnprintf(buf + count, len - count, "idle ");
if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
count += sprintf(buf + count, "standby");
count += scnprintf(buf + count, len - count, "standby");
if (!count)
sprintf(buf, "no parameters");
scnprintf(buf, len, "no parameters");
rdev_dbg(rdev, "%s\n", buf);
......@@ -1006,6 +1013,15 @@ static int set_machine_constraints(struct regulator_dev *rdev,
if (ret != 0)
goto out;
if (rdev->constraints->ilim_uA && ops->set_input_current_limit) {
ret = ops->set_input_current_limit(rdev,
rdev->constraints->ilim_uA);
if (ret < 0) {
rdev_err(rdev, "failed to set input limit\n");
goto out;
}
}
/* do we need to setup our suspend state */
if (rdev->constraints->initial_state) {
ret = suspend_prepare(rdev, rdev->constraints->initial_state);
......@@ -1049,6 +1065,22 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
if (rdev->constraints->pull_down && ops->set_pull_down) {
ret = ops->set_pull_down(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to set pull down\n");
goto out;
}
}
if (rdev->constraints->soft_start && ops->set_soft_start) {
ret = ops->set_soft_start(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to set soft start\n");
goto out;
}
}
print_constraints(rdev);
return 0;
out:
......@@ -1192,10 +1224,10 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (regulator->supply_name == NULL)
goto overflow_err;
err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
buf);
if (err) {
rdev_warn(rdev, "could not add device link %s err %d\n",
rdev_dbg(rdev, "could not add device link %s err %d\n",
dev->kobj.name, err);
/* non-fatal */
}
......
此差异已折叠。
......@@ -117,9 +117,6 @@ struct da9063_regulator {
/* Encapsulates all information for the regulators driver */
struct da9063_regulators {
int irq_ldo_lim;
int irq_uvov;
unsigned n_regulators;
/* Array size to be defined during init. Keep at end. */
struct da9063_regulator regulator[0];
......@@ -867,35 +864,23 @@ static int da9063_regulator_probe(struct platform_device *pdev)
return irq;
}
ret = request_threaded_irq(irq,
ret = devm_request_threaded_irq(&pdev->dev, irq,
NULL, da9063_ldo_lim_event,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"LDO_LIM", regulators);
if (ret) {
dev_err(&pdev->dev,
"Failed to request LDO_LIM IRQ.\n");
regulators->irq_ldo_lim = -ENXIO;
dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n");
return ret;
}
return 0;
}
static int da9063_regulator_remove(struct platform_device *pdev)
{
struct da9063_regulators *regulators = platform_get_drvdata(pdev);
free_irq(regulators->irq_ldo_lim, regulators);
free_irq(regulators->irq_uvov, regulators);
return 0;
}
static struct platform_driver da9063_regulator_driver = {
.driver = {
.name = DA9063_DRVNAME_REGULATORS,
},
.probe = da9063_regulator_probe,
.remove = da9063_regulator_remove,
};
static int __init da9063_regulator_init(void)
......
......@@ -182,6 +182,7 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
static struct regulator_ops fan53555_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.map_voltage = regulator_map_voltage_linear,
.list_voltage = regulator_list_voltage_linear,
.set_suspend_voltage = fan53555_set_suspend_voltage,
......
......@@ -275,7 +275,7 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev,
EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
/**
* regulator_map_voltage_linear - map_voltage() for multiple linear ranges
* regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
......
......@@ -419,20 +419,16 @@ static int lp8755_int_config(struct lp8755_chip *pchip)
}
ret = lp8755_read(pchip, 0x0F, &regval);
if (ret < 0)
goto err_i2c;
pchip->irqmask = regval;
ret = request_threaded_irq(pchip->irq, NULL, lp8755_irq_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"lp8755-irq", pchip);
if (ret)
if (ret < 0) {
dev_err(pchip->dev, "i2c acceess error %s\n", __func__);
return ret;
}
return ret;
err_i2c:
dev_err(pchip->dev, "i2c acceess error %s\n", __func__);
return ret;
pchip->irqmask = regval;
return devm_request_threaded_irq(pchip->dev, pchip->irq, NULL,
lp8755_irq_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"lp8755-irq", pchip);
}
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++)
lp8755_write(pchip, icnt, 0x00);
if (pchip->irq != 0)
free_irq(pchip->irq, pchip);
return 0;
}
......
......@@ -100,31 +100,34 @@ static struct regulator_ops max14577_charger_ops = {
.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[] = {
[MAX14577_SAFEOUT] = {
.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,
},
[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,
},
[MAX14577_SAFEOUT] = MAX14577_SAFEOUT_REG,
[MAX14577_CHARGER] = MAX14577_CHARGER_REG,
};
static struct regulator_ops max77836_ldo_ops = {
......@@ -138,63 +141,28 @@ static struct regulator_ops max77836_ldo_ops = {
/* 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[] = {
[MAX14577_SAFEOUT] = {
.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,
},
[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,
},
[MAX14577_SAFEOUT] = MAX14577_SAFEOUT_REG,
[MAX14577_CHARGER] = MAX14577_CHARGER_REG,
[MAX77836_LDO1] = MAX77836_LDO_REG(1),
[MAX77836_LDO2] = MAX77836_LDO_REG(2),
};
#ifdef CONFIG_OF
......
......@@ -2,7 +2,7 @@
* max77686.c - Regulator driver for the Maxim 77686
*
* Copyright (C) 2012 Samsung Electronics
* Chiwoong Byun <woong.byun@smasung.com>
* Chiwoong Byun <woong.byun@samsung.com>
* Jonghwa Lee <jonghwa3.lee@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
......@@ -88,7 +88,7 @@ enum max77686_ramp_rate {
};
struct max77686_data {
u64 gpio_enabled:MAX77686_REGULATORS;
DECLARE_BITMAP(gpio_enabled, MAX77686_REGULATORS);
/* Array indexed by regulator id */
unsigned int opmode[MAX77686_REGULATORS];
......@@ -121,7 +121,7 @@ static unsigned int max77686_map_normal_mode(struct max77686_data *max77686,
case MAX77686_BUCK8:
case MAX77686_BUCK9:
case MAX77686_LDO20 ... MAX77686_LDO22:
if (max77686->gpio_enabled & (1 << id))
if (test_bit(id, max77686->gpio_enabled))
return MAX77686_GPIO_CONTROL;
}
......@@ -277,7 +277,7 @@ static int max77686_of_parse_cb(struct device_node *np,
}
if (gpio_is_valid(config->ena_gpio)) {
max77686->gpio_enabled |= (1 << desc->id);
set_bit(desc->id, max77686->gpio_enabled);
return regmap_update_bits(config->regmap, desc->enable_reg,
desc->enable_mask,
......
......@@ -35,20 +35,6 @@
#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
* 0x00, 0x01, 0x2, 0x03 = 60 mA
......@@ -118,7 +104,7 @@ static struct regulator_ops max77693_safeout_ops = {
};
static struct regulator_ops max77693_charger_ops = {
.is_enabled = max77693_chg_is_enabled,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.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_mask = CHG_CNFG_00_CHG_MASK |
CHG_CNFG_00_BUCK_MASK,
.enable_val = CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK,
},
};
......
......@@ -33,21 +33,6 @@ static const unsigned int max77843_safeout_voltage_table[] = {
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)
{
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 = {
.is_enabled = max77843_reg_is_enabled,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.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,
};
#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[] = {
[MAX77843_SAFEOUT1] = {
.name = "SAFEOUT1",
.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_SAFEOUT1] = MAX77843_SAFEOUT(1),
[MAX77843_SAFEOUT2] = MAX77843_SAFEOUT(2),
[MAX77843_CHARGER] = {
.name = "CHARGER",
.id = MAX77843_CHARGER,
......@@ -152,7 +125,8 @@ static const struct regulator_desc max77843_supported_regulators[] = {
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.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,
},
};
......
......@@ -27,12 +27,14 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max8973-regulator.h>
#include <linux/regulator/of_regulator.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regmap.h>
......@@ -66,6 +68,7 @@
#define MAX8973_RAMP_25mV_PER_US 0x1
#define MAX8973_RAMP_50mV_PER_US 0x2
#define MAX8973_RAMP_200mV_PER_US 0x3
#define MAX8973_RAMP_MASK 0x3
/* MAX8973_CONTROL2 */
#define MAX8973_WDTMR_ENABLE BIT(6)
......@@ -89,19 +92,25 @@
#define MAX8973_VOLATGE_STEP 6250
#define MAX8973_BUCK_N_VOLTAGE 0x80
enum device_id {
MAX8973,
MAX77621
};
/* Maxim 8973 chip information */
struct max8973_chip {
struct device *dev;
struct regulator_desc desc;
struct regmap *regmap;
bool enable_external_control;
int enable_gpio;
int dvs_gpio;
int lru_index[MAX8973_MAX_VOUT_REG];
int curr_vout_val[MAX8973_MAX_VOUT_REG];
int curr_vout_reg;
int curr_gpio_val;
bool valid_dvs_gpio;
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
* 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,
&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 */
if (max->valid_dvs_gpio) {
if (gpio_is_valid(max->dvs_gpio)) {
gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
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;
}
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 = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
.list_voltage = regulator_list_voltage_linear,
.set_mode = max8973_dcdc_set_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,
......@@ -256,6 +298,29 @@ static int max8973_init_dcdc(struct max8973_chip *max,
int ret;
uint8_t control1 = 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)
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)
control1 |= MAX8973_AD_ENABLE;
if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE)
if (pdata->control_flags & MAX8973_CONTROL_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)
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))
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 (max->enable_external_control) {
if (max->enable_external_control && (max->id == MAX8973)) {
ret = regmap_update_bits(max->regmap, MAX8973_VOUT,
MAX8973_VOUT_ENABLE, 0);
if (ret < 0)
......@@ -361,22 +414,82 @@ static const struct regmap_config max8973_regmap_config = {
.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,
const struct i2c_device_id *id)
{
struct max8973_regulator_platform_data *pdata;
struct regulator_init_data *ridata;
struct regulator_config config = { };
struct regulator_dev *rdev;
struct max8973_chip *max;
bool pdata_from_dt = false;
unsigned int chip_id;
int ret;
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");
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);
if (!max)
return -ENOMEM;
......@@ -388,6 +501,27 @@ static int max8973_probe(struct i2c_client *client,
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);
max->ops = max8973_dcdc_ops;
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.n_voltages = MAX8973_BUCK_N_VOLTAGE;
if (!pdata || !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;
}
max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
max->enable_gpio = (pdata->enable_gpio) ? pdata->enable_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;
if (pdata) {
max->dvs_gpio = pdata->dvs_gpio;
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;
}
if (gpio_is_valid(max->enable_gpio))
max->enable_external_control = true;
max->lru_index[0] = max->curr_vout_reg;
......@@ -434,7 +559,6 @@ static int max8973_probe(struct i2c_client *client,
max->dvs_gpio, ret);
return ret;
}
max->valid_dvs_gpio = true;
/*
* 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[0] = max->curr_vout_reg;
max->lru_index[max->curr_vout_reg] = 0;
} else {
max->valid_dvs_gpio = false;
}
if (pdata) {
ret = max8973_init_dcdc(max, pdata);
if (ret < 0) {
dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
return ret;
if (pdata_from_dt)
pdata->reg_init_data = of_get_regulator_init_data(&client->dev,
client->dev.of_node, &max->desc);
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.init_data = pdata ? pdata->reg_init_data :
of_get_regulator_init_data(&client->dev, client->dev.of_node,
&max->desc);
config.init_data = pdata->reg_init_data;
config.driver_data = max;
config.of_node = client->dev.of_node;
config.regmap = max->regmap;
......@@ -476,15 +642,16 @@ static int max8973_probe(struct i2c_client *client,
}
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);
static struct i2c_driver max8973_i2c_driver = {
.driver = {
.name = "max8973",
.of_match_table = of_max8973_match_tbl,
.owner = THIS_MODULE,
},
.probe = max8973_probe,
......
......@@ -58,6 +58,10 @@ static void of_get_regulation_constraints(struct device_node *np,
if (!of_property_read_u32(np, "regulator-max-microamp", &pval))
constraints->max_uA = pval;
if (!of_property_read_u32(np, "regulator-input-current-limit-microamp",
&pval))
constraints->ilim_uA = pval;
/* Current change possible? */
if (constraints->min_uA != constraints->max_uA)
constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
......@@ -67,6 +71,8 @@ static void of_get_regulation_constraints(struct device_node *np,
if (!constraints->always_on) /* status change should be possible. */
constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
constraints->pull_down = of_property_read_bool(np, "regulator-pull-down");
if (of_property_read_bool(np, "regulator-allow-bypass"))
constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS;
......@@ -82,6 +88,9 @@ static void of_get_regulation_constraints(struct device_node *np,
if (!ret)
constraints->enable_time = pval;
constraints->soft_start = of_property_read_bool(np,
"regulator-soft-start");
if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) {
if (desc && desc->of_map_mode) {
ret = desc->of_map_mode(pval);
......@@ -95,6 +104,9 @@ static void of_get_regulation_constraints(struct device_node *np,
}
}
if (!of_property_read_u32(np, "regulator-system-load", &pval))
constraints->system_load = pval;
for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
switch (i) {
case PM_SUSPEND_MEM:
......@@ -108,7 +120,7 @@ static void of_get_regulation_constraints(struct device_node *np,
case PM_SUSPEND_STANDBY:
default:
continue;
};
}
suspend_np = of_get_child_by_name(np, regulator_states[i]);
if (!suspend_np || !suspend_state)
......@@ -292,7 +304,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
return NULL;
}
for_each_child_of_node(search, child) {
for_each_available_child_of_node(search, child) {
name = of_get_property(child, "regulator-compatible", NULL);
if (!name)
name = child->name;
......
......@@ -21,10 +21,8 @@
#include <linux/pwm.h>
struct pwm_regulator_data {
struct regulator_desc desc;
struct pwm_voltages *duty_cycle_table;
struct pwm_device *pwm;
bool enabled;
int state;
};
......@@ -33,17 +31,17 @@ struct pwm_voltages {
unsigned int dutycycle;
};
static int pwm_regulator_get_voltage_sel(struct regulator_dev *dev)
static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
return drvdata->state;
}
static int pwm_regulator_set_voltage_sel(struct regulator_dev *dev,
static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
unsigned int pwm_reg_period;
int dutycycle;
int ret;
......@@ -55,30 +53,27 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *dev,
ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period);
if (ret) {
dev_err(&dev->dev, "Failed to configure PWM\n");
dev_err(&rdev->dev, "Failed to configure PWM\n");
return ret;
}
drvdata->state = selector;
if (!drvdata->enabled) {
ret = pwm_enable(drvdata->pwm);
if (ret) {
dev_err(&dev->dev, "Failed to enable PWM\n");
return ret;
}
drvdata->enabled = true;
ret = pwm_enable(drvdata->pwm);
if (ret) {
dev_err(&rdev->dev, "Failed to enable PWM\n");
return ret;
}
return 0;
}
static int pwm_regulator_list_voltage(struct regulator_dev *dev,
static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
unsigned selector)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
if (selector >= drvdata->desc.n_voltages)
if (selector >= rdev->desc->n_voltages)
return -EINVAL;
return drvdata->duty_cycle_table[selector].uV;
......@@ -91,7 +86,7 @@ static struct regulator_ops pwm_regulator_voltage_ops = {
.map_voltage = regulator_map_voltage_iterate,
};
static const struct regulator_desc pwm_regulator_desc = {
static struct regulator_desc pwm_regulator_desc = {
.name = "pwm-regulator",
.ops = &pwm_regulator_voltage_ops,
.type = REGULATOR_VOLTAGE,
......@@ -117,8 +112,6 @@ static int pwm_regulator_probe(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(pwm_regulator_desc));
/* determine the number of voltage-table */
prop = of_find_property(np, "voltage-table", &length);
if (!prop) {
......@@ -133,7 +126,7 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return -EINVAL;
}
drvdata->desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table);
pwm_regulator_desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table);
drvdata->duty_cycle_table = devm_kzalloc(&pdev->dev,
length, GFP_KERNEL);
......@@ -150,7 +143,7 @@ static int pwm_regulator_probe(struct platform_device *pdev)
}
config.init_data = of_get_regulator_init_data(&pdev->dev, np,
&drvdata->desc);
&pwm_regulator_desc);
if (!config.init_data)
return -ENOMEM;
......@@ -165,10 +158,10 @@ static int pwm_regulator_probe(struct platform_device *pdev)
}
regulator = devm_regulator_register(&pdev->dev,
&drvdata->desc, &config);
&pwm_regulator_desc, &config);
if (IS_ERR(regulator)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
drvdata->desc.name);
pwm_regulator_desc.name);
return PTR_ERR(regulator);
}
......
此差异已折叠。
......@@ -515,7 +515,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
break;
default:
return -EINVAL;
};
}
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val);
......@@ -538,7 +538,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
default:
state = S2MPS14_ENABLE_SUSPEND;
break;
};
}
break;
case S2MPU02:
switch (rdev_id) {
......@@ -552,11 +552,11 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
default:
state = S2MPU02_ENABLE_SUSPEND;
break;
};
}
break;
default:
return -EINVAL;
};
}
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret < 0)
......@@ -977,7 +977,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Invalid device type: %u\n",
s2mps11->dev_type);
return -EINVAL;
};
}
s2mps11->ext_control_gpio = devm_kmalloc(&pdev->dev,
sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num,
......
......@@ -533,7 +533,8 @@ static int wm831x_buckv_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
......@@ -543,7 +544,8 @@ static int wm831x_buckv_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC"));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_oc_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n",
irq, ret);
......@@ -669,7 +671,8 @@ static int wm831x_buckp_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
......@@ -785,7 +788,8 @@ static int wm831x_boostp_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dcdc->name,
dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
......
......@@ -204,7 +204,8 @@ static int wm831x_isink_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_isink_irq,
IRQF_TRIGGER_RISING, isink->name,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
isink->name,
isink);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n",
......
......@@ -287,7 +287,8 @@ static int wm831x_gp_ldo_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_ldo_uv_irq,
IRQF_TRIGGER_RISING, ldo->name,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
ldo->name,
ldo);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
......@@ -496,7 +497,8 @@ static int wm831x_aldo_probe(struct platform_device *pdev)
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_ldo_uv_irq,
IRQF_TRIGGER_RISING, ldo->name, ldo);
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
ldo->name, ldo);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
......
......@@ -91,6 +91,7 @@ struct regulator_linear_range {
* @set_current_limit: Configure a limit for a current-limited regulator.
* The driver should select the current closest to max_uA.
* @get_current_limit: Get the configured limit for a current-limited regulator.
* @set_input_current_limit: Configure an input limit.
*
* @set_mode: Set the configured operating mode for the regulator.
* @get_mode: Get the configured operating mode for the regulator.
......@@ -111,6 +112,7 @@ struct regulator_linear_range {
* to stabilise after being set to a new value, in microseconds.
* The function provides the from and to voltage selector, the
* function should return the worst case.
* @set_soft_start: Enable soft start for the regulator.
*
* @set_suspend_voltage: Set the voltage for the regulator when the system
* is suspended.
......@@ -121,6 +123,9 @@ struct regulator_linear_range {
* @set_suspend_mode: Set the operating mode for the regulator when the
* system is suspended.
*
* @set_pull_down: Configure the regulator to pull down when the regulator
* is disabled.
*
* This struct describes regulator operations which can be implemented by
* regulator chip drivers.
*/
......@@ -142,6 +147,8 @@ struct regulator_ops {
int min_uA, int max_uA);
int (*get_current_limit) (struct regulator_dev *);
int (*set_input_current_limit) (struct regulator_dev *, int lim_uA);
/* enable/disable regulator */
int (*enable) (struct regulator_dev *);
int (*disable) (struct regulator_dev *);
......@@ -158,6 +165,8 @@ struct regulator_ops {
unsigned int old_selector,
unsigned int new_selector);
int (*set_soft_start) (struct regulator_dev *);
/* report regulator status ... most other accessors report
* control inputs, this reports results of combining inputs
* from Linux (and other sources) with the actual load.
......@@ -187,6 +196,8 @@ struct regulator_ops {
/* set regulator suspend operating mode (defined in consumer.h) */
int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
int (*set_pull_down) (struct regulator_dev *);
};
/*
......
......@@ -75,6 +75,8 @@ struct regulator_state {
*
* @min_uA: Smallest current consumers may set.
* @max_uA: Largest current consumers may set.
* @ilim_uA: Maximum input current.
* @system_load: Load that isn't captured by any consumer requests.
*
* @valid_modes_mask: Mask of modes which may be configured by consumers.
* @valid_ops_mask: Operations which may be performed by consumers.
......@@ -86,6 +88,8 @@ struct regulator_state {
* applied.
* @apply_uV: Apply the voltage constraint when initialising.
* @ramp_disable: Disable ramp delay when initialising or when setting voltage.
* @soft_start: Enable soft start so that voltage ramps slowly.
* @pull_down: Enable pull down when regulator is disabled.
*
* @input_uV: Input voltage for regulator when supplied by another regulator.
*
......@@ -111,6 +115,9 @@ struct regulation_constraints {
/* current output range (inclusive) - for current control */
int min_uA;
int max_uA;
int ilim_uA;
int system_load;
/* valid regulator operating modes for this machine */
unsigned int valid_modes_mask;
......@@ -138,6 +145,8 @@ struct regulation_constraints {
unsigned boot_on:1; /* bootloader/firmware enabled regulator */
unsigned apply_uV:1; /* apply uV constraint if min == max */
unsigned ramp_disable:1; /* disable ramp delay */
unsigned soft_start:1; /* ramp voltage slowly */
unsigned pull_down:1; /* pull down resistor when regulator off */
};
/**
......
......@@ -58,6 +58,9 @@
* control signal from EN input pin. If it is false then
* voltage output will be enabled/disabled through EN bit of
* 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_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;
unsigned long control_flags;
bool enable_ext_control;
int enable_gpio;
int dvs_gpio;
unsigned dvs_def_state:1;
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册