Merge "regulator: spm: check min/max voltages against HW configuration"
This commit is contained in:
commit
019955f7cd
1 changed files with 106 additions and 0 deletions
|
@ -95,6 +95,7 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
|
||||||
#define QPNP_SMPS_REG_VOLTAGE_SETPOINT 0x41
|
#define QPNP_SMPS_REG_VOLTAGE_SETPOINT 0x41
|
||||||
#define QPNP_SMPS_REG_MODE 0x45
|
#define QPNP_SMPS_REG_MODE 0x45
|
||||||
#define QPNP_SMPS_REG_STEP_CTRL 0x61
|
#define QPNP_SMPS_REG_STEP_CTRL 0x61
|
||||||
|
#define QPNP_SMPS_REG_UL_LL_CTRL 0x68
|
||||||
|
|
||||||
/* FTS426 voltage control registers */
|
/* FTS426 voltage control registers */
|
||||||
#define QPNP_FTS426_REG_VOLTAGE_LB 0x40
|
#define QPNP_FTS426_REG_VOLTAGE_LB 0x40
|
||||||
|
@ -102,6 +103,22 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
|
||||||
#define QPNP_FTS426_REG_VOLTAGE_VALID_LB 0x42
|
#define QPNP_FTS426_REG_VOLTAGE_VALID_LB 0x42
|
||||||
#define QPNP_FTS426_REG_VOLTAGE_VALID_UB 0x43
|
#define QPNP_FTS426_REG_VOLTAGE_VALID_UB 0x43
|
||||||
|
|
||||||
|
/* HF voltage limit registers */
|
||||||
|
#define QPNP_HF_REG_VOLTAGE_ULS 0x69
|
||||||
|
#define QPNP_HF_REG_VOLTAGE_LLS 0x6B
|
||||||
|
|
||||||
|
/* FTS voltage limit registers */
|
||||||
|
#define QPNP_FTS_REG_VOLTAGE_ULS_VALID 0x6A
|
||||||
|
#define QPNP_FTS_REG_VOLTAGE_LLS_VALID 0x6C
|
||||||
|
|
||||||
|
/* FTS426 voltage limit registers */
|
||||||
|
#define QPNP_FTS426_REG_VOLTAGE_ULS_LB 0x68
|
||||||
|
#define QPNP_FTS426_REG_VOLTAGE_ULS_UB 0x69
|
||||||
|
|
||||||
|
/* Common regulator UL & LL limits control register layout */
|
||||||
|
#define QPNP_COMMON_UL_EN_MASK 0x80
|
||||||
|
#define QPNP_COMMON_LL_EN_MASK 0x40
|
||||||
|
|
||||||
#define QPNP_SMPS_MODE_PWM 0x80
|
#define QPNP_SMPS_MODE_PWM 0x80
|
||||||
#define QPNP_SMPS_MODE_AUTO 0x40
|
#define QPNP_SMPS_MODE_AUTO 0x40
|
||||||
#define QPNP_FTS426_MODE_PWM 0x07
|
#define QPNP_FTS426_MODE_PWM 0x07
|
||||||
|
@ -924,6 +941,88 @@ static int qpnp_smps_init_step_rate(struct spm_vreg *vreg)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qpnp_smps_check_constraints(struct spm_vreg *vreg,
|
||||||
|
struct regulator_init_data *init_data)
|
||||||
|
{
|
||||||
|
int rc = 0, limit_min_uV, limit_max_uV;
|
||||||
|
u16 ul_reg, ll_reg;
|
||||||
|
u8 reg[2];
|
||||||
|
|
||||||
|
limit_min_uV = 0;
|
||||||
|
limit_max_uV = INT_MAX;
|
||||||
|
|
||||||
|
ul_reg = QPNP_FTS_REG_VOLTAGE_ULS_VALID;
|
||||||
|
ll_reg = QPNP_FTS_REG_VOLTAGE_LLS_VALID;
|
||||||
|
|
||||||
|
switch (vreg->regulator_type) {
|
||||||
|
case QPNP_TYPE_HF:
|
||||||
|
ul_reg = QPNP_HF_REG_VOLTAGE_ULS;
|
||||||
|
ll_reg = QPNP_HF_REG_VOLTAGE_LLS;
|
||||||
|
case QPNP_TYPE_FTS2:
|
||||||
|
case QPNP_TYPE_FTS2p5:
|
||||||
|
rc = regmap_bulk_read(vreg->regmap, vreg->spmi_base_addr
|
||||||
|
+ QPNP_SMPS_REG_UL_LL_CTRL, reg, 1);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&vreg->pdev->dev, "%s: UL_LL register read failed, rc=%d\n",
|
||||||
|
__func__, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg[0] & QPNP_COMMON_UL_EN_MASK) {
|
||||||
|
rc = regmap_bulk_read(vreg->regmap, vreg->spmi_base_addr
|
||||||
|
+ ul_reg, ®[1], 1);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&vreg->pdev->dev, "%s: ULS register read failed, rc=%d\n",
|
||||||
|
__func__, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit_max_uV = spm_regulator_vlevel_to_uv(vreg, reg[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg[0] & QPNP_COMMON_LL_EN_MASK) {
|
||||||
|
rc = regmap_bulk_read(vreg->regmap, vreg->spmi_base_addr
|
||||||
|
+ ll_reg, ®[1], 1);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&vreg->pdev->dev, "%s: LLS register read failed, rc=%d\n",
|
||||||
|
__func__, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit_min_uV = spm_regulator_vlevel_to_uv(vreg, reg[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case QPNP_TYPE_FTS426:
|
||||||
|
rc = regmap_bulk_read(vreg->regmap, vreg->spmi_base_addr
|
||||||
|
+ QPNP_FTS426_REG_VOLTAGE_ULS_LB,
|
||||||
|
reg, 2);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&vreg->pdev->dev, "%s: could not read voltage limit registers, rc=%d\n",
|
||||||
|
__func__, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit_max_uV = spm_regulator_vlevel_to_uv(vreg,
|
||||||
|
((unsigned)reg[1] << 8) | reg[0]);
|
||||||
|
break;
|
||||||
|
case QPNP_TYPE_ULT_HF:
|
||||||
|
/* no HW voltage limit configuration */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_data->constraints.min_uV < limit_min_uV
|
||||||
|
|| init_data->constraints.max_uV > limit_max_uV) {
|
||||||
|
dev_err(&vreg->pdev->dev, "regulator min/max(%d/%d) constraints do not fit within HW configured min/max(%d/%d) constraints\n",
|
||||||
|
init_data->constraints.min_uV,
|
||||||
|
init_data->constraints.max_uV, limit_min_uV,
|
||||||
|
limit_max_uV);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static bool spm_regulator_using_range0(struct spm_vreg *vreg)
|
static bool spm_regulator_using_range0(struct spm_vreg *vreg)
|
||||||
{
|
{
|
||||||
return vreg->range == &fts2_range0 || vreg->range == &fts2p5_range0
|
return vreg->range == &fts2_range0 || vreg->range == &fts2p5_range0
|
||||||
|
@ -1105,6 +1204,13 @@ static int spm_regulator_probe(struct platform_device *pdev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = qpnp_smps_check_constraints(vreg, init_data);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&pdev->dev, "%s: regulator constraints check failed, rc=%d\n",
|
||||||
|
__func__, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
vreg->rdesc.name = init_data->constraints.name;
|
vreg->rdesc.name = init_data->constraints.name;
|
||||||
vreg->rdesc.type = REGULATOR_VOLTAGE;
|
vreg->rdesc.type = REGULATOR_VOLTAGE;
|
||||||
vreg->rdesc.owner = THIS_MODULE;
|
vreg->rdesc.owner = THIS_MODULE;
|
||||||
|
|
Loading…
Add table
Reference in a new issue