mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
Merge remote-tracking branches 'regulator/topic/pwm', 'regulator/topic/qcom-spmi', 'regulator/topic/rk808' and 'regulator/topic/s2mps11' into regulator-next
This commit is contained in:
commit
39d652e066
@ -7,6 +7,7 @@ Qualcomm SPMI Regulators
|
||||
"qcom,pm8841-regulators"
|
||||
"qcom,pm8916-regulators"
|
||||
"qcom,pm8941-regulators"
|
||||
"qcom,pm8994-regulators"
|
||||
|
||||
- interrupts:
|
||||
Usage: optional
|
||||
@ -68,6 +69,37 @@ Qualcomm SPMI Regulators
|
||||
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_s5-supply:
|
||||
- vdd_s6-supply:
|
||||
- vdd_s7-supply:
|
||||
- vdd_s8-supply:
|
||||
- vdd_s9-supply:
|
||||
- vdd_s10-supply:
|
||||
- vdd_s11-supply:
|
||||
- vdd_s12-supply:
|
||||
- vdd_l1-supply:
|
||||
- vdd_l2_l26_l28-supply:
|
||||
- vdd_l3_l11-supply:
|
||||
- vdd_l4_l27_l31-supply:
|
||||
- vdd_l5_l7-supply:
|
||||
- vdd_l6_l12_l32-supply:
|
||||
- vdd_l8_l16_l30-supply:
|
||||
- vdd_l9_l10_l18_l22-supply:
|
||||
- vdd_l13_l19_l23_l24-supply:
|
||||
- vdd_l14_l15-supply:
|
||||
- vdd_l17_l29-supply:
|
||||
- vdd_l20_l21-supply:
|
||||
- vdd_l25-supply:
|
||||
- vdd_lvs_1_2-supply:
|
||||
Usage: optional (pm8994 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
|
||||
@ -85,6 +117,11 @@ pm8941:
|
||||
l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
|
||||
mvs1, mvs2
|
||||
|
||||
pm8994:
|
||||
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5,
|
||||
l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20,
|
||||
l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2
|
||||
|
||||
The content of each sub-node is defined by the standard binding for regulators -
|
||||
see regulator.txt - with additional custom properties described below:
|
||||
|
||||
|
@ -128,6 +128,13 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
|
||||
set_bit(PWMF_REQUESTED, &pwm->flags);
|
||||
pwm->label = label;
|
||||
|
||||
/*
|
||||
* FIXME: This should be removed once all PWM users properly make use
|
||||
* of struct pwm_args to initialize the PWM device. As long as this is
|
||||
* here, the PWM state and hardware state can get out of sync.
|
||||
*/
|
||||
pwm_apply_args(pwm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -146,12 +153,12 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
|
||||
if (IS_ERR(pwm))
|
||||
return pwm;
|
||||
|
||||
pwm_set_period(pwm, args->args[1]);
|
||||
pwm->args.period = args->args[1];
|
||||
|
||||
if (args->args[2] & PWM_POLARITY_INVERTED)
|
||||
pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
|
||||
pwm->args.polarity = PWM_POLARITY_INVERSED;
|
||||
else
|
||||
pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
|
||||
pwm->args.polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return pwm;
|
||||
}
|
||||
@ -172,7 +179,7 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
|
||||
if (IS_ERR(pwm))
|
||||
return pwm;
|
||||
|
||||
pwm_set_period(pwm, args->args[1]);
|
||||
pwm->args.period = args->args[1];
|
||||
|
||||
return pwm;
|
||||
}
|
||||
@ -747,13 +754,13 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
|
||||
if (!chip)
|
||||
goto out;
|
||||
|
||||
pwm->args.period = chosen->period;
|
||||
pwm->args.polarity = chosen->polarity;
|
||||
|
||||
pwm = pwm_request_from_chip(chip, chosen->index, con_id ?: dev_id);
|
||||
if (IS_ERR(pwm))
|
||||
goto out;
|
||||
|
||||
pwm_set_period(pwm, chosen->period);
|
||||
pwm_set_polarity(pwm, chosen->polarity);
|
||||
|
||||
out:
|
||||
mutex_unlock(&pwm_lookup_lock);
|
||||
return pwm;
|
||||
|
@ -60,7 +60,7 @@ static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
return -EINVAL;
|
||||
|
||||
/* Store constant period value */
|
||||
pwm_set_period(pwm, DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq));
|
||||
pwm->args.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
|
||||
if (IS_ERR(pwm))
|
||||
return pwm;
|
||||
|
||||
pwm_set_period(pwm, args->args[0]);
|
||||
pwm->args.period = args->args[0];
|
||||
|
||||
return pwm;
|
||||
}
|
||||
|
@ -59,18 +59,18 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
|
||||
unsigned int pwm_reg_period;
|
||||
struct pwm_args pargs;
|
||||
int dutycycle;
|
||||
int ret;
|
||||
|
||||
pwm_reg_period = pwm_get_period(drvdata->pwm);
|
||||
pwm_get_args(drvdata->pwm, &pargs);
|
||||
|
||||
dutycycle = (pwm_reg_period *
|
||||
dutycycle = (pargs.period *
|
||||
drvdata->duty_cycle_table[selector].dutycycle) / 100;
|
||||
|
||||
ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period);
|
||||
ret = pwm_config(drvdata->pwm, dutycycle, pargs.period);
|
||||
if (ret) {
|
||||
dev_err(&rdev->dev, "Failed to configure PWM\n");
|
||||
dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -113,18 +113,6 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev)
|
||||
return pwm_is_enabled(drvdata->pwm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continuous voltage call-backs
|
||||
*/
|
||||
static int pwm_voltage_to_duty_cycle_percentage(struct regulator_dev *rdev, int req_uV)
|
||||
{
|
||||
int min_uV = rdev->constraints->min_uV;
|
||||
int max_uV = rdev->constraints->max_uV;
|
||||
int diff = max_uV - min_uV;
|
||||
|
||||
return ((req_uV * 100) - (min_uV * 100)) / diff;
|
||||
}
|
||||
|
||||
static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
|
||||
@ -138,21 +126,42 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
{
|
||||
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
|
||||
unsigned int ramp_delay = rdev->constraints->ramp_delay;
|
||||
unsigned int period = pwm_get_period(drvdata->pwm);
|
||||
int duty_cycle;
|
||||
struct pwm_args pargs;
|
||||
unsigned int req_diff = min_uV - rdev->constraints->min_uV;
|
||||
unsigned int diff;
|
||||
unsigned int duty_pulse;
|
||||
u64 req_period;
|
||||
u32 rem;
|
||||
int ret;
|
||||
|
||||
duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV);
|
||||
pwm_get_args(drvdata->pwm, &pargs);
|
||||
diff = rdev->constraints->max_uV - rdev->constraints->min_uV;
|
||||
|
||||
ret = pwm_config(drvdata->pwm, (period / 100) * duty_cycle, period);
|
||||
/* First try to find out if we get the iduty cycle time which is
|
||||
* factor of PWM period time. If (request_diff_to_min * pwm_period)
|
||||
* is perfect divided by voltage_range_diff then it is possible to
|
||||
* get duty cycle time which is factor of PWM period. This will help
|
||||
* to get output voltage nearer to requested value as there is no
|
||||
* calculation loss.
|
||||
*/
|
||||
req_period = req_diff * pargs.period;
|
||||
div_u64_rem(req_period, diff, &rem);
|
||||
if (!rem) {
|
||||
do_div(req_period, diff);
|
||||
duty_pulse = (unsigned int)req_period;
|
||||
} else {
|
||||
duty_pulse = (pargs.period / 100) * ((req_diff * 100) / diff);
|
||||
}
|
||||
|
||||
ret = pwm_config(drvdata->pwm, duty_pulse, pargs.period);
|
||||
if (ret) {
|
||||
dev_err(&rdev->dev, "Failed to configure PWM\n");
|
||||
dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pwm_enable(drvdata->pwm);
|
||||
if (ret) {
|
||||
dev_err(&rdev->dev, "Failed to enable PWM\n");
|
||||
dev_err(&rdev->dev, "Failed to enable PWM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
drvdata->volt_uV = min_uV;
|
||||
@ -200,8 +209,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
|
||||
|
||||
if ((length < sizeof(*duty_cycle_table)) ||
|
||||
(length % sizeof(*duty_cycle_table))) {
|
||||
dev_err(&pdev->dev,
|
||||
"voltage-table length(%d) is invalid\n",
|
||||
dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
|
||||
length);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -214,7 +222,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
|
||||
(u32 *)duty_cycle_table,
|
||||
length / sizeof(u32));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to read voltage-table\n");
|
||||
dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -277,16 +285,24 @@ static int pwm_regulator_probe(struct platform_device *pdev)
|
||||
|
||||
drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(drvdata->pwm)) {
|
||||
dev_err(&pdev->dev, "Failed to get PWM\n");
|
||||
return PTR_ERR(drvdata->pwm);
|
||||
ret = PTR_ERR(drvdata->pwm);
|
||||
dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: pwm_apply_args() should be removed when switching to the
|
||||
* atomic PWM API.
|
||||
*/
|
||||
pwm_apply_args(drvdata->pwm);
|
||||
|
||||
regulator = devm_regulator_register(&pdev->dev,
|
||||
&drvdata->desc, &config);
|
||||
if (IS_ERR(regulator)) {
|
||||
dev_err(&pdev->dev, "Failed to register regulator %s\n",
|
||||
drvdata->desc.name);
|
||||
return PTR_ERR(regulator);
|
||||
ret = PTR_ERR(regulator);
|
||||
dev_err(&pdev->dev, "Failed to register regulator %s: %d\n",
|
||||
drvdata->desc.name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -246,6 +246,7 @@ enum spmi_common_control_register_index {
|
||||
|
||||
/* Minimum voltage stepper delay for each step. */
|
||||
#define SPMI_FTSMPS_STEP_DELAY 8
|
||||
#define SPMI_DEFAULT_STEP_DELAY 20
|
||||
|
||||
/*
|
||||
* The ratio SPMI_FTSMPS_STEP_MARGIN_NUM/SPMI_FTSMPS_STEP_MARGIN_DEN is used to
|
||||
@ -254,13 +255,6 @@ enum spmi_common_control_register_index {
|
||||
#define SPMI_FTSMPS_STEP_MARGIN_NUM 4
|
||||
#define SPMI_FTSMPS_STEP_MARGIN_DEN 5
|
||||
|
||||
/*
|
||||
* This voltage in uV is returned by get_voltage functions when there is no way
|
||||
* to determine the current voltage level. It is needed because the regulator
|
||||
* framework treats a 0 uV voltage as an error.
|
||||
*/
|
||||
#define VOLTAGE_UNKNOWN 1
|
||||
|
||||
/* VSET value to decide the range of ULT SMPS */
|
||||
#define ULT_SMPS_RANGE_SPLIT 0x60
|
||||
|
||||
@ -539,12 +533,12 @@ static int spmi_regulator_common_disable(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
||||
int min_uV, int max_uV, u8 *range_sel, u8 *voltage_sel,
|
||||
unsigned *selector)
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
const struct spmi_voltage_range *range;
|
||||
int uV = min_uV;
|
||||
int lim_min_uV, lim_max_uV, i, range_id, range_max_uV;
|
||||
int selector, voltage_sel;
|
||||
|
||||
/* Check if request voltage is outside of physically settable range. */
|
||||
lim_min_uV = vreg->set_points->range[0].set_point_min_uV;
|
||||
@ -570,14 +564,13 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
||||
|
||||
range_id = i;
|
||||
range = &vreg->set_points->range[range_id];
|
||||
*range_sel = range->range_sel;
|
||||
|
||||
/*
|
||||
* Force uV to be an allowed set point by applying a ceiling function to
|
||||
* the uV value.
|
||||
*/
|
||||
*voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
||||
uV = *voltage_sel * range->step_uV + range->min_uV;
|
||||
voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
||||
uV = voltage_sel * range->step_uV + range->min_uV;
|
||||
|
||||
if (uV > max_uV) {
|
||||
dev_err(vreg->dev,
|
||||
@ -587,12 +580,48 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*selector = 0;
|
||||
selector = 0;
|
||||
for (i = 0; i < range_id; i++)
|
||||
*selector += vreg->set_points->range[i].n_voltages;
|
||||
*selector += (uV - range->set_point_min_uV) / range->step_uV;
|
||||
selector += vreg->set_points->range[i].n_voltages;
|
||||
selector += (uV - range->set_point_min_uV) / range->step_uV;
|
||||
|
||||
return 0;
|
||||
return selector;
|
||||
}
|
||||
|
||||
static int spmi_sw_selector_to_hw(struct spmi_regulator *vreg,
|
||||
unsigned selector, u8 *range_sel,
|
||||
u8 *voltage_sel)
|
||||
{
|
||||
const struct spmi_voltage_range *range, *end;
|
||||
|
||||
range = vreg->set_points->range;
|
||||
end = range + vreg->set_points->count;
|
||||
|
||||
for (; range < end; range++) {
|
||||
if (selector < range->n_voltages) {
|
||||
*voltage_sel = selector;
|
||||
*range_sel = range->range_sel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
selector -= range->n_voltages;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int spmi_hw_selector_to_sw(struct spmi_regulator *vreg, u8 hw_sel,
|
||||
const struct spmi_voltage_range *range)
|
||||
{
|
||||
int sw_sel = hw_sel;
|
||||
const struct spmi_voltage_range *r = vreg->set_points->range;
|
||||
|
||||
while (r != range) {
|
||||
sw_sel += r->n_voltages;
|
||||
r++;
|
||||
}
|
||||
|
||||
return sw_sel;
|
||||
}
|
||||
|
||||
static const struct spmi_voltage_range *
|
||||
@ -614,12 +643,11 @@ spmi_regulator_find_range(struct spmi_regulator *vreg)
|
||||
}
|
||||
|
||||
static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
||||
int min_uV, int max_uV, u8 *range_sel, u8 *voltage_sel,
|
||||
unsigned *selector)
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
const struct spmi_voltage_range *range;
|
||||
int uV = min_uV;
|
||||
int i;
|
||||
int i, selector;
|
||||
|
||||
range = spmi_regulator_find_range(vreg);
|
||||
if (!range)
|
||||
@ -637,8 +665,8 @@ static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
||||
* Force uV to be an allowed set point by applying a ceiling function to
|
||||
* the uV value.
|
||||
*/
|
||||
*voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
||||
uV = *voltage_sel * range->step_uV + range->min_uV;
|
||||
uV = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
|
||||
uV = uV * range->step_uV + range->min_uV;
|
||||
|
||||
if (uV > max_uV) {
|
||||
/*
|
||||
@ -648,43 +676,49 @@ static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
|
||||
goto different_range;
|
||||
}
|
||||
|
||||
*selector = 0;
|
||||
selector = 0;
|
||||
for (i = 0; i < vreg->set_points->count; i++) {
|
||||
if (uV >= vreg->set_points->range[i].set_point_min_uV
|
||||
&& uV <= vreg->set_points->range[i].set_point_max_uV) {
|
||||
*selector +=
|
||||
selector +=
|
||||
(uV - vreg->set_points->range[i].set_point_min_uV)
|
||||
/ vreg->set_points->range[i].step_uV;
|
||||
break;
|
||||
}
|
||||
|
||||
*selector += vreg->set_points->range[i].n_voltages;
|
||||
selector += vreg->set_points->range[i].n_voltages;
|
||||
}
|
||||
|
||||
if (*selector >= vreg->set_points->n_voltages)
|
||||
if (selector >= vreg->set_points->n_voltages)
|
||||
goto different_range;
|
||||
|
||||
return 0;
|
||||
return selector;
|
||||
|
||||
different_range:
|
||||
return spmi_regulator_select_voltage(vreg, min_uV, max_uV,
|
||||
range_sel, voltage_sel, selector);
|
||||
return spmi_regulator_select_voltage(vreg, min_uV, max_uV);
|
||||
}
|
||||
|
||||
static int spmi_regulator_common_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
static int spmi_regulator_common_map_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
|
||||
/*
|
||||
* Favor staying in the current voltage range if possible. This avoids
|
||||
* voltage spikes that occur when changing the voltage range.
|
||||
*/
|
||||
return spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV);
|
||||
}
|
||||
|
||||
static int
|
||||
spmi_regulator_common_set_voltage(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
u8 range_sel, voltage_sel;
|
||||
|
||||
/*
|
||||
* Favor staying in the current voltage range if possible. This avoids
|
||||
* voltage spikes that occur when changing the voltage range.
|
||||
*/
|
||||
ret = spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV,
|
||||
&range_sel, &voltage_sel, selector);
|
||||
ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -719,24 +753,24 @@ static int spmi_regulator_common_get_voltage(struct regulator_dev *rdev)
|
||||
|
||||
range = spmi_regulator_find_range(vreg);
|
||||
if (!range)
|
||||
return VOLTAGE_UNKNOWN;
|
||||
return -EINVAL;
|
||||
|
||||
return range->step_uV * voltage_sel + range->min_uV;
|
||||
return spmi_hw_selector_to_sw(vreg, voltage_sel, range);
|
||||
}
|
||||
|
||||
static int spmi_regulator_single_map_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
|
||||
return spmi_regulator_select_voltage(vreg, min_uV, max_uV);
|
||||
}
|
||||
|
||||
static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
unsigned selector)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
u8 range_sel, sel;
|
||||
|
||||
ret = spmi_regulator_select_voltage(vreg, min_uV, max_uV, &range_sel,
|
||||
&sel, selector);
|
||||
if (ret) {
|
||||
dev_err(vreg->dev, "could not set voltage, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
u8 sel = selector;
|
||||
|
||||
/*
|
||||
* Certain types of regulators do not have a range select register so
|
||||
@ -748,27 +782,24 @@ static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev,
|
||||
static int spmi_regulator_single_range_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
const struct spmi_voltage_range *range = vreg->set_points->range;
|
||||
u8 voltage_sel;
|
||||
u8 selector;
|
||||
int ret;
|
||||
|
||||
spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_SET, &voltage_sel, 1);
|
||||
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_SET, &selector, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return range->step_uV * voltage_sel + range->min_uV;
|
||||
return selector;
|
||||
}
|
||||
|
||||
static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
unsigned selector)
|
||||
{
|
||||
struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
u8 range_sel, voltage_sel;
|
||||
|
||||
/*
|
||||
* Favor staying in the current voltage range if possible. This avoids
|
||||
* voltage spikes that occur when changing the voltage range.
|
||||
*/
|
||||
ret = spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV,
|
||||
&range_sel, &voltage_sel, selector);
|
||||
ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -783,7 +814,7 @@ static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,
|
||||
voltage_sel |= ULT_SMPS_RANGE_SPLIT;
|
||||
|
||||
return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_VOLTAGE_SET,
|
||||
voltage_sel, 0xff);
|
||||
voltage_sel, 0xff);
|
||||
}
|
||||
|
||||
static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)
|
||||
@ -796,12 +827,12 @@ static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)
|
||||
|
||||
range = spmi_regulator_find_range(vreg);
|
||||
if (!range)
|
||||
return VOLTAGE_UNKNOWN;
|
||||
return -EINVAL;
|
||||
|
||||
if (range->range_sel == 1)
|
||||
voltage_sel &= ~ULT_SMPS_RANGE_SPLIT;
|
||||
|
||||
return range->step_uV * voltage_sel + range->min_uV;
|
||||
return spmi_hw_selector_to_sw(vreg, voltage_sel, range);
|
||||
}
|
||||
|
||||
static int spmi_regulator_common_list_voltage(struct regulator_dev *rdev,
|
||||
@ -1007,8 +1038,10 @@ static struct regulator_ops spmi_smps_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_common_set_voltage,
|
||||
.get_voltage = spmi_regulator_common_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_common_set_voltage,
|
||||
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
||||
.get_voltage_sel = spmi_regulator_common_get_voltage,
|
||||
.map_voltage = spmi_regulator_common_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
@ -1020,8 +1053,9 @@ static struct regulator_ops spmi_ldo_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_common_set_voltage,
|
||||
.get_voltage = spmi_regulator_common_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_common_set_voltage,
|
||||
.get_voltage_sel = spmi_regulator_common_get_voltage,
|
||||
.map_voltage = spmi_regulator_common_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
@ -1036,8 +1070,9 @@ static struct regulator_ops spmi_ln_ldo_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_common_set_voltage,
|
||||
.get_voltage = spmi_regulator_common_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_common_set_voltage,
|
||||
.get_voltage_sel = spmi_regulator_common_get_voltage,
|
||||
.map_voltage = spmi_regulator_common_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_bypass = spmi_regulator_common_set_bypass,
|
||||
.get_bypass = spmi_regulator_common_get_bypass,
|
||||
@ -1056,8 +1091,9 @@ static struct regulator_ops spmi_boost_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_single_range_set_voltage,
|
||||
.get_voltage = spmi_regulator_single_range_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_single_range_set_voltage,
|
||||
.get_voltage_sel = spmi_regulator_single_range_get_voltage,
|
||||
.map_voltage = spmi_regulator_single_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_input_current_limit = spmi_regulator_set_ilim,
|
||||
};
|
||||
@ -1066,9 +1102,10 @@ static struct regulator_ops spmi_ftsmps_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_common_set_voltage,
|
||||
.set_voltage_sel = spmi_regulator_common_set_voltage,
|
||||
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
||||
.get_voltage = spmi_regulator_common_get_voltage,
|
||||
.get_voltage_sel = spmi_regulator_common_get_voltage,
|
||||
.map_voltage = spmi_regulator_common_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
@ -1080,8 +1117,9 @@ static struct regulator_ops spmi_ult_lo_smps_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_ult_lo_smps_set_voltage,
|
||||
.get_voltage = spmi_regulator_ult_lo_smps_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_ult_lo_smps_set_voltage,
|
||||
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
||||
.get_voltage_sel = spmi_regulator_ult_lo_smps_get_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
@ -1093,8 +1131,10 @@ static struct regulator_ops spmi_ult_ho_smps_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_single_range_set_voltage,
|
||||
.get_voltage = spmi_regulator_single_range_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_single_range_set_voltage,
|
||||
.set_voltage_time_sel = spmi_regulator_set_voltage_time_sel,
|
||||
.get_voltage_sel = spmi_regulator_single_range_get_voltage,
|
||||
.map_voltage = spmi_regulator_single_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
@ -1106,8 +1146,9 @@ static struct regulator_ops spmi_ult_ldo_ops = {
|
||||
.enable = spmi_regulator_common_enable,
|
||||
.disable = spmi_regulator_common_disable,
|
||||
.is_enabled = spmi_regulator_common_is_enabled,
|
||||
.set_voltage = spmi_regulator_single_range_set_voltage,
|
||||
.get_voltage = spmi_regulator_single_range_get_voltage,
|
||||
.set_voltage_sel = spmi_regulator_single_range_set_voltage,
|
||||
.get_voltage_sel = spmi_regulator_single_range_get_voltage,
|
||||
.map_voltage = spmi_regulator_single_map_voltage,
|
||||
.list_voltage = spmi_regulator_common_list_voltage,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
@ -1201,7 +1242,7 @@ static int spmi_regulator_match(struct spmi_regulator *vreg, u16 force_type)
|
||||
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_DIG_MAJOR_REV, version,
|
||||
ARRAY_SIZE(version));
|
||||
if (ret) {
|
||||
dev_err(vreg->dev, "could not read version registers\n");
|
||||
dev_dbg(vreg->dev, "could not read version registers\n");
|
||||
return ret;
|
||||
}
|
||||
dig_major_rev = version[SPMI_COMMON_REG_DIG_MAJOR_REV
|
||||
@ -1245,11 +1286,11 @@ found:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)
|
||||
static int spmi_regulator_init_slew_rate(struct spmi_regulator *vreg)
|
||||
{
|
||||
int ret;
|
||||
u8 reg = 0;
|
||||
int step, delay, slew_rate;
|
||||
int step, delay, slew_rate, step_delay;
|
||||
const struct spmi_voltage_range *range;
|
||||
|
||||
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_STEP_CTRL, ®, 1);
|
||||
@ -1262,6 +1303,15 @@ static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)
|
||||
if (!range)
|
||||
return -EINVAL;
|
||||
|
||||
switch (vreg->logical_type) {
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS:
|
||||
step_delay = SPMI_FTSMPS_STEP_DELAY;
|
||||
break;
|
||||
default:
|
||||
step_delay = SPMI_DEFAULT_STEP_DELAY;
|
||||
break;
|
||||
}
|
||||
|
||||
step = reg & SPMI_FTSMPS_STEP_CTRL_STEP_MASK;
|
||||
step >>= SPMI_FTSMPS_STEP_CTRL_STEP_SHIFT;
|
||||
|
||||
@ -1270,7 +1320,7 @@ static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)
|
||||
|
||||
/* slew_rate has units of uV/us */
|
||||
slew_rate = SPMI_FTSMPS_CLOCK_RATE * range->step_uV * (1 << step);
|
||||
slew_rate /= 1000 * (SPMI_FTSMPS_STEP_DELAY << delay);
|
||||
slew_rate /= 1000 * (step_delay << delay);
|
||||
slew_rate *= SPMI_FTSMPS_STEP_MARGIN_NUM;
|
||||
slew_rate /= SPMI_FTSMPS_STEP_MARGIN_DEN;
|
||||
|
||||
@ -1411,10 +1461,16 @@ static int spmi_regulator_of_parse(struct device_node *node,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vreg->logical_type == SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS) {
|
||||
ret = spmi_regulator_ftsmps_init_slew_rate(vreg);
|
||||
switch (vreg->logical_type) {
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS:
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS:
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS:
|
||||
case SPMI_REGULATOR_LOGICAL_TYPE_SMPS:
|
||||
ret = spmi_regulator_init_slew_rate(vreg);
|
||||
if (ret)
|
||||
return ret;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (vreg->logical_type != SPMI_REGULATOR_LOGICAL_TYPE_VS)
|
||||
@ -1510,10 +1566,61 @@ static const struct spmi_regulator_data pm8916_regulators[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct spmi_regulator_data pm8994_regulators[] = {
|
||||
{ "s1", 0x1400, "vdd_s1", },
|
||||
{ "s2", 0x1700, "vdd_s2", },
|
||||
{ "s3", 0x1a00, "vdd_s3", },
|
||||
{ "s4", 0x1d00, "vdd_s4", },
|
||||
{ "s5", 0x2000, "vdd_s5", },
|
||||
{ "s6", 0x2300, "vdd_s6", },
|
||||
{ "s7", 0x2600, "vdd_s7", },
|
||||
{ "s8", 0x2900, "vdd_s8", },
|
||||
{ "s9", 0x2c00, "vdd_s9", },
|
||||
{ "s10", 0x2f00, "vdd_s10", },
|
||||
{ "s11", 0x3200, "vdd_s11", },
|
||||
{ "s12", 0x3500, "vdd_s12", },
|
||||
{ "l1", 0x4000, "vdd_l1", },
|
||||
{ "l2", 0x4100, "vdd_l2_l26_l28", },
|
||||
{ "l3", 0x4200, "vdd_l3_l11", },
|
||||
{ "l4", 0x4300, "vdd_l4_l27_l31", },
|
||||
{ "l5", 0x4400, "vdd_l5_l7", },
|
||||
{ "l6", 0x4500, "vdd_l6_l12_l32", },
|
||||
{ "l7", 0x4600, "vdd_l5_l7", },
|
||||
{ "l8", 0x4700, "vdd_l8_l16_l30", },
|
||||
{ "l9", 0x4800, "vdd_l9_l10_l18_l22", },
|
||||
{ "l10", 0x4900, "vdd_l9_l10_l18_l22", },
|
||||
{ "l11", 0x4a00, "vdd_l3_l11", },
|
||||
{ "l12", 0x4b00, "vdd_l6_l12_l32", },
|
||||
{ "l13", 0x4c00, "vdd_l13_l19_l23_l24", },
|
||||
{ "l14", 0x4d00, "vdd_l14_l15", },
|
||||
{ "l15", 0x4e00, "vdd_l14_l15", },
|
||||
{ "l16", 0x4f00, "vdd_l8_l16_l30", },
|
||||
{ "l17", 0x5000, "vdd_l17_l29", },
|
||||
{ "l18", 0x5100, "vdd_l9_l10_l18_l22", },
|
||||
{ "l19", 0x5200, "vdd_l13_l19_l23_l24", },
|
||||
{ "l20", 0x5300, "vdd_l20_l21", },
|
||||
{ "l21", 0x5400, "vdd_l20_l21", },
|
||||
{ "l22", 0x5500, "vdd_l9_l10_l18_l22", },
|
||||
{ "l23", 0x5600, "vdd_l13_l19_l23_l24", },
|
||||
{ "l24", 0x5700, "vdd_l13_l19_l23_l24", },
|
||||
{ "l25", 0x5800, "vdd_l25", },
|
||||
{ "l26", 0x5900, "vdd_l2_l26_l28", },
|
||||
{ "l27", 0x5a00, "vdd_l4_l27_l31", },
|
||||
{ "l28", 0x5b00, "vdd_l2_l26_l28", },
|
||||
{ "l29", 0x5c00, "vdd_l17_l29", },
|
||||
{ "l30", 0x5d00, "vdd_l8_l16_l30", },
|
||||
{ "l31", 0x5e00, "vdd_l4_l27_l31", },
|
||||
{ "l32", 0x5f00, "vdd_l6_l12_l32", },
|
||||
{ "lvs1", 0x8000, "vdd_lvs_1_2", },
|
||||
{ "lvs2", 0x8100, "vdd_lvs_1_2", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct of_device_id qcom_spmi_regulator_match[] = {
|
||||
{ .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
|
||||
{ .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
|
||||
{ .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
|
||||
{ .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);
|
||||
@ -1573,7 +1680,7 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
|
||||
|
||||
ret = spmi_regulator_match(vreg, reg->force_type);
|
||||
if (ret)
|
||||
goto err;
|
||||
continue;
|
||||
|
||||
config.dev = dev;
|
||||
config.driver_data = vreg;
|
||||
|
@ -55,6 +55,42 @@
|
||||
/* max steps for increase voltage of Buck1/2, equal 100mv*/
|
||||
#define MAX_STEPS_ONE_TIME 8
|
||||
|
||||
#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _etime) \
|
||||
[_id] = { \
|
||||
.name = (_match), \
|
||||
.supply_name = (_supply), \
|
||||
.of_match = of_match_ptr(_match), \
|
||||
.regulators_node = of_match_ptr("regulators"), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = (_id), \
|
||||
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (_min) * 1000, \
|
||||
.uV_step = (_step) * 1000, \
|
||||
.vsel_reg = (_vreg), \
|
||||
.vsel_mask = (_vmask), \
|
||||
.enable_reg = (_ereg), \
|
||||
.enable_mask = (_emask), \
|
||||
.enable_time = (_etime), \
|
||||
.ops = &rk808_reg_ops, \
|
||||
}
|
||||
|
||||
#define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask) \
|
||||
[_id] = { \
|
||||
.name = (_match), \
|
||||
.supply_name = (_supply), \
|
||||
.of_match = of_match_ptr(_match), \
|
||||
.regulators_node = of_match_ptr("regulators"), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = (_id), \
|
||||
.enable_reg = (_ereg), \
|
||||
.enable_mask = (_emask), \
|
||||
.owner = THIS_MODULE, \
|
||||
.ops = &rk808_switch_ops \
|
||||
}
|
||||
|
||||
|
||||
struct rk808_regulator_data {
|
||||
struct gpio_desc *dvs_gpio[2];
|
||||
};
|
||||
@ -66,27 +102,11 @@ static const int rk808_buck_config_regs[] = {
|
||||
RK808_BUCK4_CONFIG_REG,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(712500, 0, 63, 12500),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000),
|
||||
};
|
||||
|
||||
static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
|
||||
@ -240,6 +260,21 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||
}
|
||||
|
||||
static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
unsigned int reg;
|
||||
int sel = regulator_map_voltage_linear(rdev, uv, uv);
|
||||
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
rdev->desc->vsel_mask,
|
||||
sel);
|
||||
}
|
||||
|
||||
static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
unsigned int reg;
|
||||
int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
|
||||
@ -277,8 +312,8 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
static struct regulator_ops rk808_buck1_2_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = rk808_buck1_2_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = rk808_buck1_2_set_voltage_sel,
|
||||
.set_voltage_time_sel = rk808_buck1_2_set_voltage_time_sel,
|
||||
@ -292,6 +327,19 @@ static struct regulator_ops rk808_buck1_2_ops = {
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_voltage = rk808_set_suspend_voltage,
|
||||
.set_suspend_enable = rk808_set_suspend_enable,
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_reg_ops_ranges = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
@ -299,7 +347,7 @@ static struct regulator_ops rk808_reg_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_voltage = rk808_set_suspend_voltage,
|
||||
.set_suspend_voltage = rk808_set_suspend_voltage_range,
|
||||
.set_suspend_enable = rk808_set_suspend_enable,
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
@ -316,12 +364,14 @@ static const struct regulator_desc rk808_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
.supply_name = "vcc1",
|
||||
.of_match = of_match_ptr("DCDC_REG1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK808_ID_DCDC1,
|
||||
.ops = &rk808_buck1_2_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 712500,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.linear_ranges = rk808_buck_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
|
||||
.vsel_reg = RK808_BUCK1_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK808_DCDC_EN_REG,
|
||||
@ -330,12 +380,14 @@ static const struct regulator_desc rk808_reg[] = {
|
||||
}, {
|
||||
.name = "DCDC_REG2",
|
||||
.supply_name = "vcc2",
|
||||
.of_match = of_match_ptr("DCDC_REG2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK808_ID_DCDC2,
|
||||
.ops = &rk808_buck1_2_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 712500,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.linear_ranges = rk808_buck_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
|
||||
.vsel_reg = RK808_BUCK2_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK808_DCDC_EN_REG,
|
||||
@ -344,6 +396,8 @@ static const struct regulator_desc rk808_reg[] = {
|
||||
}, {
|
||||
.name = "DCDC_REG3",
|
||||
.supply_name = "vcc3",
|
||||
.of_match = of_match_ptr("DCDC_REG3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK808_ID_DCDC3,
|
||||
.ops = &rk808_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
@ -351,55 +405,23 @@ static const struct regulator_desc rk808_reg[] = {
|
||||
.enable_reg = RK808_DCDC_EN_REG,
|
||||
.enable_mask = BIT(2),
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "DCDC_REG4",
|
||||
.supply_name = "vcc4",
|
||||
.id = RK808_ID_DCDC4,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 16,
|
||||
.linear_ranges = rk808_buck4_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges),
|
||||
.vsel_reg = RK808_BUCK4_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_BUCK4_VSEL_MASK,
|
||||
.enable_reg = RK808_DCDC_EN_REG,
|
||||
.enable_mask = BIT(3),
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG1",
|
||||
.supply_name = "vcc6",
|
||||
.id = RK808_ID_LDO1,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 17,
|
||||
.linear_ranges = rk808_ldo_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO1_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(0),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG2",
|
||||
.supply_name = "vcc6",
|
||||
.id = RK808_ID_LDO2,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 17,
|
||||
.linear_ranges = rk808_ldo_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO2_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(1),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
},
|
||||
RK8XX_DESC(RK808_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3300, 100,
|
||||
RK808_BUCK4_ON_VSEL_REG, RK808_BUCK4_VSEL_MASK,
|
||||
RK808_DCDC_EN_REG, BIT(3), 0),
|
||||
RK8XX_DESC(RK808_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
|
||||
RK808_LDO1_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(0), 400),
|
||||
RK8XX_DESC(RK808_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
|
||||
RK808_LDO2_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(1), 400),
|
||||
{
|
||||
.name = "LDO_REG3",
|
||||
.supply_name = "vcc7",
|
||||
.of_match = of_match_ptr("LDO_REG3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK808_ID_LDO3,
|
||||
.ops = &rk808_reg_ops,
|
||||
.ops = &rk808_reg_ops_ranges,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 16,
|
||||
.linear_ranges = rk808_ldo3_voltage_ranges,
|
||||
@ -410,117 +432,26 @@ static const struct regulator_desc rk808_reg[] = {
|
||||
.enable_mask = BIT(2),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG4",
|
||||
.supply_name = "vcc9",
|
||||
.id = RK808_ID_LDO4,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 17,
|
||||
.linear_ranges = rk808_ldo_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO4_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(3),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG5",
|
||||
.supply_name = "vcc9",
|
||||
.id = RK808_ID_LDO5,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 17,
|
||||
.linear_ranges = rk808_ldo_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO5_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(4),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG6",
|
||||
.supply_name = "vcc10",
|
||||
.id = RK808_ID_LDO6,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 18,
|
||||
.linear_ranges = rk808_ldo6_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO6_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(5),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG7",
|
||||
.supply_name = "vcc7",
|
||||
.id = RK808_ID_LDO7,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 18,
|
||||
.linear_ranges = rk808_ldo6_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO7_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(6),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "LDO_REG8",
|
||||
.supply_name = "vcc11",
|
||||
.id = RK808_ID_LDO8,
|
||||
.ops = &rk808_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 17,
|
||||
.linear_ranges = rk808_ldo_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
|
||||
.vsel_reg = RK808_LDO8_ON_VSEL_REG,
|
||||
.vsel_mask = RK808_LDO_VSEL_MASK,
|
||||
.enable_reg = RK808_LDO_EN_REG,
|
||||
.enable_mask = BIT(7),
|
||||
.enable_time = 400,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "SWITCH_REG1",
|
||||
.supply_name = "vcc8",
|
||||
.id = RK808_ID_SWITCH1,
|
||||
.ops = &rk808_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.enable_reg = RK808_DCDC_EN_REG,
|
||||
.enable_mask = BIT(5),
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "SWITCH_REG2",
|
||||
.supply_name = "vcc12",
|
||||
.id = RK808_ID_SWITCH2,
|
||||
.ops = &rk808_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.enable_reg = RK808_DCDC_EN_REG,
|
||||
.enable_mask = BIT(6),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct of_regulator_match rk808_reg_matches[] = {
|
||||
[RK808_ID_DCDC1] = { .name = "DCDC_REG1" },
|
||||
[RK808_ID_DCDC2] = { .name = "DCDC_REG2" },
|
||||
[RK808_ID_DCDC3] = { .name = "DCDC_REG3" },
|
||||
[RK808_ID_DCDC4] = { .name = "DCDC_REG4" },
|
||||
[RK808_ID_LDO1] = { .name = "LDO_REG1" },
|
||||
[RK808_ID_LDO2] = { .name = "LDO_REG2" },
|
||||
[RK808_ID_LDO3] = { .name = "LDO_REG3" },
|
||||
[RK808_ID_LDO4] = { .name = "LDO_REG4" },
|
||||
[RK808_ID_LDO5] = { .name = "LDO_REG5" },
|
||||
[RK808_ID_LDO6] = { .name = "LDO_REG6" },
|
||||
[RK808_ID_LDO7] = { .name = "LDO_REG7" },
|
||||
[RK808_ID_LDO8] = { .name = "LDO_REG8" },
|
||||
[RK808_ID_SWITCH1] = { .name = "SWITCH_REG1" },
|
||||
[RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" },
|
||||
RK8XX_DESC(RK808_ID_LDO4, "LDO_REG4", "vcc9", 1800, 3400, 100,
|
||||
RK808_LDO4_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(3), 400),
|
||||
RK8XX_DESC(RK808_ID_LDO5, "LDO_REG5", "vcc9", 1800, 3400, 100,
|
||||
RK808_LDO5_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(4), 400),
|
||||
RK8XX_DESC(RK808_ID_LDO6, "LDO_REG6", "vcc10", 800, 2500, 100,
|
||||
RK808_LDO6_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(5), 400),
|
||||
RK8XX_DESC(RK808_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
|
||||
RK808_LDO7_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(6), 400),
|
||||
RK8XX_DESC(RK808_ID_LDO8, "LDO_REG8", "vcc11", 1800, 3400, 100,
|
||||
RK808_LDO8_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
|
||||
BIT(7), 400),
|
||||
RK8XX_DESC_SWITCH(RK808_ID_SWITCH1, "SWITCH_REG1", "vcc8",
|
||||
RK808_DCDC_EN_REG, BIT(5)),
|
||||
RK8XX_DESC_SWITCH(RK808_ID_SWITCH2, "SWITCH_REG2", "vcc12",
|
||||
RK808_DCDC_EN_REG, BIT(6)),
|
||||
};
|
||||
|
||||
static int rk808_regulator_dt_parse_pdata(struct device *dev,
|
||||
@ -529,17 +460,12 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
|
||||
struct rk808_regulator_data *pdata)
|
||||
{
|
||||
struct device_node *np;
|
||||
int tmp, ret, i;
|
||||
int tmp, ret = 0, i;
|
||||
|
||||
np = of_get_child_by_name(client_dev->of_node, "regulators");
|
||||
if (!np)
|
||||
return -ENXIO;
|
||||
|
||||
ret = of_regulator_match(dev, np, rk808_reg_matches,
|
||||
RK808_NUM_REGULATORS);
|
||||
if (ret < 0)
|
||||
goto dt_parse_end;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) {
|
||||
pdata->dvs_gpio[i] =
|
||||
devm_gpiod_get_index_optional(client_dev, "dvs", i,
|
||||
@ -586,18 +512,12 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, pdata);
|
||||
|
||||
config.dev = &client->dev;
|
||||
config.driver_data = pdata;
|
||||
config.regmap = rk808->regmap;
|
||||
|
||||
/* Instantiate the regulators */
|
||||
for (i = 0; i < RK808_NUM_REGULATORS; i++) {
|
||||
if (!rk808_reg_matches[i].init_data ||
|
||||
!rk808_reg_matches[i].of_node)
|
||||
continue;
|
||||
|
||||
config.dev = &client->dev;
|
||||
config.driver_data = pdata;
|
||||
config.regmap = rk808->regmap;
|
||||
config.of_node = rk808_reg_matches[i].of_node;
|
||||
config.init_data = rk808_reg_matches[i].init_data;
|
||||
|
||||
rk808_rdev = devm_regulator_register(&pdev->dev,
|
||||
&rk808_reg[i], &config);
|
||||
if (IS_ERR(rk808_rdev)) {
|
||||
|
@ -267,6 +267,7 @@ static struct regulator_ops s2mps11_buck_ops = {
|
||||
.ops = &s2mps11_ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.ramp_delay = RAMP_DELAY_12_MVUS, \
|
||||
.min_uV = MIN_800_MV, \
|
||||
.uV_step = step, \
|
||||
.n_voltages = S2MPS11_LDO_N_VOLTAGES, \
|
||||
@ -1237,17 +1238,7 @@ static struct platform_driver s2mps11_pmic_driver = {
|
||||
.id_table = s2mps11_pmic_id,
|
||||
};
|
||||
|
||||
static int __init s2mps11_pmic_init(void)
|
||||
{
|
||||
return platform_driver_register(&s2mps11_pmic_driver);
|
||||
}
|
||||
subsys_initcall(s2mps11_pmic_init);
|
||||
|
||||
static void __exit s2mps11_pmic_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s2mps11_pmic_driver);
|
||||
}
|
||||
module_exit(s2mps11_pmic_exit);
|
||||
module_platform_driver(s2mps11_pmic_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
|
@ -30,6 +30,9 @@
|
||||
#define MIN_600_MV 600000
|
||||
#define MIN_500_MV 500000
|
||||
|
||||
/* Ramp delay in uV/us */
|
||||
#define RAMP_DELAY_12_MVUS 12000
|
||||
|
||||
/* Macros to represent steps for LDO/BUCK */
|
||||
#define STEP_50_MV 50000
|
||||
#define STEP_25_MV 25000
|
||||
|
@ -74,6 +74,24 @@ enum pwm_polarity {
|
||||
PWM_POLARITY_INVERSED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pwm_args - board-dependent PWM arguments
|
||||
* @period: reference period
|
||||
* @polarity: reference polarity
|
||||
*
|
||||
* This structure describes board-dependent arguments attached to a PWM
|
||||
* device. These arguments are usually retrieved from the PWM lookup table or
|
||||
* device tree.
|
||||
*
|
||||
* Do not confuse this with the PWM state: PWM arguments represent the initial
|
||||
* configuration that users want to use on this PWM device rather than the
|
||||
* current PWM hardware state.
|
||||
*/
|
||||
struct pwm_args {
|
||||
unsigned int period;
|
||||
enum pwm_polarity polarity;
|
||||
};
|
||||
|
||||
enum {
|
||||
PWMF_REQUESTED = 1 << 0,
|
||||
PWMF_ENABLED = 1 << 1,
|
||||
@ -92,6 +110,7 @@ enum {
|
||||
* @period: period of the PWM signal (in nanoseconds)
|
||||
* @duty_cycle: duty cycle of the PWM signal (in nanoseconds)
|
||||
* @polarity: polarity of the PWM signal
|
||||
* @args: PWM arguments
|
||||
*/
|
||||
struct pwm_device {
|
||||
const char *label;
|
||||
@ -105,6 +124,8 @@ struct pwm_device {
|
||||
unsigned int period;
|
||||
unsigned int duty_cycle;
|
||||
enum pwm_polarity polarity;
|
||||
|
||||
struct pwm_args args;
|
||||
};
|
||||
|
||||
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
|
||||
@ -144,6 +165,18 @@ static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
|
||||
return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
|
||||
}
|
||||
|
||||
static inline void pwm_get_args(const struct pwm_device *pwm,
|
||||
struct pwm_args *args)
|
||||
{
|
||||
*args = pwm->args;
|
||||
}
|
||||
|
||||
static inline void pwm_apply_args(struct pwm_device *pwm)
|
||||
{
|
||||
pwm_set_period(pwm, pwm->args.period);
|
||||
pwm_set_polarity(pwm, pwm->args.polarity);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct pwm_ops - PWM controller operations
|
||||
* @request: optional hook for requesting a PWM
|
||||
|
Loading…
Reference in New Issue
Block a user