Loading drivers/regulator/spm-regulator.c +106 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading
drivers/regulator/spm-regulator.c +106 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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