static int _spm_regulator_set_voltage(struct regulator_dev *rdev) { struct spm_vreg *vreg = rdev_get_drvdata(rdev); int rc; if (vreg->vlevel == vreg->last_set_vlevel) return 0; if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM) && vreg->uV > vreg->last_set_uV) { /* */ rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_PWM); if (rc) return rc; } rc = msm_spm_set_vdd(0, vreg->vlevel); /* */ if (rc) { pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->rdesc.name, rc); return rc; } if (vreg->uV > vreg->last_set_uV) { /* */ udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV, vreg->step_rate)); } if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM) && vreg->uV > vreg->last_set_uV) { /* */ udelay(QPNP_FTS2_MODE_CHANGE_DELAY - QPNP_SPMI_WRITE_MIN_DELAY); /* */ rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_AUTO); if (rc) return rc; } vreg->last_set_uV = vreg->uV; vreg->last_set_vlevel = vreg->vlevel; return rc; }
static int _set_voltage(struct regulator_dev *rdev) { struct saw_vreg *vreg = rdev_get_drvdata(rdev); int rc; rc = msm_spm_set_vdd(rdev_get_id(rdev), vreg->vlevel); if (!rc) { if (vreg->uV > vreg->last_set_uV) { udelay((vreg->uV - vreg->last_set_uV) / REGULATOR_SLEW_RATE); } vreg->last_set_uV = vreg->uV; } else { pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc); vreg->uV = vreg->last_set_uV; } return rc; }
static int spm_regulator_write_voltage(struct spm_vreg *vreg, int uV) { unsigned vlevel = spm_regulator_uv_to_vlevel(vreg, uV); bool spm_failed = false; int rc = 0; u8 reg; if (likely(!vreg->bypass_spm)) { /* Set voltage control register via SPM. */ rc = msm_spm_set_vdd(vreg->cpu_num, vlevel); if (rc) { pr_debug("%s: msm_spm_set_vdd failed, rc=%d; falling back on SPMI write\n", vreg->rdesc.name, rc); spm_failed = true; } } if (unlikely(vreg->bypass_spm || spm_failed)) { /* Set voltage control register via SPMI. */ reg = vlevel; rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid, vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT, ®, 1); if (rc) { pr_err("%s: spmi_ext_register_writel failed, rc=%d\n", vreg->rdesc.name, rc); return rc; } } if (uV > vreg->last_set_uV) { /* Wait for voltage stepping to complete. */ udelay(DIV_ROUND_UP(uV - vreg->last_set_uV, vreg->step_rate)); } vreg->last_set_uV = uV; vreg->last_set_vlevel = vlevel; return rc; }
static int qpnp_smps_init_voltage(struct spm_vreg *vreg) { int rc; rc = qpnp_smps_read_voltage(vreg); if (rc) { pr_err("%s: voltage read failed, rc=%d\n", vreg->rdesc.name, rc); return rc; } vreg->vlevel = vreg->last_set_vlevel; vreg->uV = vreg->last_set_uV; /* Initialize SAW voltage control register */ if (!vreg->bypass_spm) { rc = msm_spm_set_vdd(vreg->cpu_num, vreg->vlevel); if (rc) pr_err("%s: msm_spm_set_vdd failed, rc=%d\n", vreg->rdesc.name, rc); } return 0; }
static int saw_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct saw_vreg *vreg = rdev_get_drvdata(rdev); int uV = min_uV; int rc; u8 vprog, band; if (uV < FTSMPS_BAND1_UV_MIN && max_uV >= FTSMPS_BAND1_UV_MIN) uV = FTSMPS_BAND1_UV_MIN; if (uV < FTSMPS_BAND1_UV_MIN || uV > FTSMPS_BAND3_UV_MAX) { pr_err("%s: request v=[%d, %d] is outside possible " "v=[%d, %d]\n", vreg->name, min_uV, max_uV, FTSMPS_BAND1_UV_MIN, FTSMPS_BAND3_UV_MAX); return -EINVAL; } /* Round up for set points in the gaps between bands. */ if (uV > FTSMPS_BAND1_UV_MAX && uV < FTSMPS_BAND2_UV_MIN) uV = FTSMPS_BAND2_UV_MIN; else if (uV > FTSMPS_BAND2_UV_MAX && uV < FTSMPS_BAND3_UV_SET_POINT_MIN) uV = FTSMPS_BAND3_UV_SET_POINT_MIN; if (uV > FTSMPS_BAND2_UV_MAX) { vprog = (uV - FTSMPS_BAND3_UV_MIN + FTSMPS_BAND3_UV_STEP - 1) / FTSMPS_BAND3_UV_STEP; band = FTSMPS_VCTRL_BAND_3; uV = FTSMPS_BAND3_UV_MIN + vprog * FTSMPS_BAND3_UV_STEP; } else if (uV > FTSMPS_BAND1_UV_MAX) { vprog = (uV - FTSMPS_BAND2_UV_MIN + FTSMPS_BAND2_UV_STEP - 1) / FTSMPS_BAND2_UV_STEP; band = FTSMPS_VCTRL_BAND_2; uV = FTSMPS_BAND2_UV_MIN + vprog * FTSMPS_BAND2_UV_STEP; } else { vprog = (uV - FTSMPS_BAND1_UV_MIN + FTSMPS_BAND1_UV_LOG_STEP - 1) / FTSMPS_BAND1_UV_LOG_STEP; uV = FTSMPS_BAND1_UV_MIN + vprog * FTSMPS_BAND1_UV_LOG_STEP; vprog *= FTSMPS_BAND1_UV_LOG_STEP / FTSMPS_BAND1_UV_PHYS_STEP; band = FTSMPS_VCTRL_BAND_1; } if (uV > max_uV) { pr_err("%s: request v=[%d, %d] cannot be met by any setpoint\n", vreg->name, min_uV, max_uV); return -EINVAL; } rc = msm_spm_set_vdd(rdev_get_id(rdev), band | vprog); if (!rc) { if (uV > vreg->uV) { /* Wait for voltage to stabalize. */ udelay((uV - vreg->uV) / REGULATOR_SLEW_RATE); } vreg->uV = uV; } else { pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc); } return rc; }
static int _spm_regulator_set_voltage(struct regulator_dev *rdev) { struct spm_vreg *vreg = rdev_get_drvdata(rdev); bool spm_failed = false; int rc = 0; u8 reg; if (vreg->vlevel == vreg->last_set_vlevel) return 0; if ((vreg->regulator_type == QPNP_TYPE_FTS2) && !(vreg->init_mode & QPNP_SMPS_MODE_PWM) && vreg->uV > vreg->last_set_uV) { /* Switch to PWM mode so that voltage ramping is fast. */ rc = qpnp_smps_set_mode(vreg, QPNP_SMPS_MODE_PWM); if (rc) return rc; } if (likely(!vreg->bypass_spm)) { /* Set voltage control register via SPM. */ rc = msm_spm_set_vdd(vreg->cpu_num, vreg->vlevel); if (rc) { pr_debug("%s: msm_spm_set_vdd failed, rc=%d; falling back on SPMI write\n", vreg->rdesc.name, rc); spm_failed = true; } } if (unlikely(vreg->bypass_spm || spm_failed)) { /* Set voltage control register via SPMI. */ reg = vreg->vlevel; rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid, vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT, ®, 1); if (rc) { pr_err("%s: spmi_ext_register_writel failed, rc=%d\n", vreg->rdesc.name, rc); return rc; } } if (vreg->uV > vreg->last_set_uV) { /* Wait for voltage stepping to complete. */ udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV, vreg->step_rate)); } if ((vreg->regulator_type == QPNP_TYPE_FTS2) && !(vreg->init_mode & QPNP_SMPS_MODE_PWM) && vreg->uV > vreg->last_set_uV) { /* Wait for mode transition to complete. */ udelay(QPNP_FTS2_MODE_CHANGE_DELAY - QPNP_SPMI_WRITE_MIN_DELAY); /* Switch to AUTO mode so that power consumption is lowered. */ rc = qpnp_smps_set_mode(vreg, QPNP_FTS2_MODE_AUTO); if (rc) return rc; } vreg->last_set_uV = vreg->uV; vreg->last_set_vlevel = vreg->vlevel; return rc; }