static int s2m_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) { struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int reg_id = rdev_get_id(rdev); int ret; char name[16]; unsigned int voltage; /* voltage information logging to snapshot feature */ snprintf(name, sizeof(name), "LDO%d", (reg_id - S2MPS16_LDO1) + 1); voltage = ((sel & rdev->desc->vsel_mask) * S2MPS16_LDO_STEP2) + S2MPS16_LDO_MIN1; exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_IN); ret = sec_reg_update(s2mps16->iodev, rdev->desc->vsel_reg, sel, rdev->desc->vsel_mask); if (ret < 0) goto out; if (rdev->desc->apply_bit) ret = sec_reg_update(s2mps16->iodev, rdev->desc->apply_reg, rdev->desc->apply_bit, rdev->desc->apply_bit); exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_OUT); return ret; out: pr_warn("%s: failed to set voltage_sel_regmap\n", rdev->desc->name); exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_ON); return ret; }
int s2m_set_vth(struct regulator *reg, bool enable) { struct regulator_dev *rdev = reg->rdev; struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int ret; if(enable) ret = sec_reg_update(s2mps16->iodev, S2MPS16_REG_VTH_OFFSET, S2MPS16_UP_VTH, 0xFF); else ret = sec_reg_update(s2mps16->iodev, S2MPS16_REG_VTH_OFFSET, S2MPS16_DOWN_VTH, 0xFF); return ret; }
/* Some LDOs supports [LPM/Normal]ON mode during suspend state */ static int s2m_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); unsigned int val; int ret, id = rdev_get_id(rdev); switch (mode) { case SEC_OPMODE_SUSPEND: /* ON in Standby Mode */ val = 0x1 << S2MPS16_ENABLE_SHIFT; break; case SEC_OPMODE_MIF: /* ON in PWREN_MIF mode */ val = 0x2 << S2MPS16_ENABLE_SHIFT; break; case SEC_OPMODE_ON: /* ON in Normal Mode */ val = 0x3 << S2MPS16_ENABLE_SHIFT; break; default: pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", rdev->desc->name, mode); return -EINVAL; } ret = sec_reg_update(s2mps16->iodev, rdev->desc->enable_reg, val, rdev->desc->enable_mask); if (ret) return ret; s2mps16->opmode[id] = val; return 0; }
static void s2mps11_pmic_shutdown(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); /* PWR_HOLD bit-clear when power off */ sec_reg_update(iodev, S2MPS11_REG_CTRL1, 0x00, 0xff); dev_info(&pdev->dev, "%s : PWR_HOLD Clear Bit.\n",__func__); }
static int s2m_enable(struct regulator_dev *rdev) { struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int reg_id = rdev_get_id(rdev); /* disregard BUCK6 enable */ if (reg_id == S2MPS16_BUCK6 && s2mps16->g3d_en) return 0; return sec_reg_update(s2mps16->iodev, rdev->desc->enable_reg, s2mps16->opmode[rdev_get_id(rdev)], rdev->desc->enable_mask); }
static int s2m_set_fix_ldo_voltage(struct regulator_dev *rdev, bool fix_en) { int ret, old_sel, old_val; struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int reg_id = rdev_get_id(rdev); unsigned int buck2_sync_val = 0; char name[16]; if (s2mps16->cache_data && s2mps16->vsel_value[reg_id]) old_val = rdev->desc->min_uV + (s2mps16->vsel_value[reg_id] * rdev->desc->uV_step); else { ret = sec_reg_read(s2mps16->iodev, rdev->desc->vsel_reg, &old_sel); if (ret < 0) goto out; old_val = rdev->desc->min_uV + (rdev->desc->uV_step * old_sel); } snprintf(name, sizeof(name), "BUCK%d", (reg_id - S2MPS16_BUCK1) + 1); /* Set buck2 voltage BUCK2_SYNC_VOLTAGE(1150mV) */ buck2_sync_val = (BUCK2_SYNC_VOLTAGE - S2MPS16_BUCK_MIN1) / S2MPS16_BUCK_STEP1; exynos_ss_regulator(name, rdev->desc->vsel_reg, BUCK2_SYNC_VOLTAGE, ESS_FLAG_IN); s2mps16->vsel_value[reg_id] = buck2_sync_val; ret = sec_reg_write(s2mps16->iodev, rdev->desc->vsel_reg, buck2_sync_val); if (ret < 0) { exynos_ss_regulator(name, rdev->desc->vsel_reg, BUCK2_SYNC_VOLTAGE, ESS_FLAG_ON); goto out; } exynos_ss_regulator(name, rdev->desc->vsel_reg, BUCK2_SYNC_VOLTAGE, ESS_FLAG_OUT); if (BUCK2_SYNC_VOLTAGE > old_val) udelay(DIV_ROUND_UP((BUCK2_SYNC_VOLTAGE - old_val), rdev->constraints->ramp_delay)); if (reg_id == S2MPS16_BUCK2) { ret = sec_reg_update(s2mps16->iodev, S2MPS16_REG_LDO7_DVS, fix_en << 2, 0x1 << 2); if (ret < 0) goto out; s2mps16->buck2_sync = fix_en ? true : false; } return ret; out: pr_warn("%s: failed to fix_ldo_voltage\n", rdev->desc->name); return ret; }
static int s2m_disable_regmap(struct regulator_dev *rdev) { struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int reg_id = rdev_get_id(rdev); unsigned int val; /* disregard BUCK6 disable */ if (reg_id == S2MPS16_BUCK6 && s2mps16->g3d_en) return 0; if (rdev->desc->enable_is_inverted) val = rdev->desc->enable_mask; else val = 0; return sec_reg_update(s2mps16->iodev, rdev->desc->enable_reg, val, rdev->desc->enable_mask); }
static int s2m_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int ramp_shift, reg_id = rdev_get_id(rdev); int ramp_mask = 0x03; unsigned int ramp_value = 0; ramp_value = get_ramp_delay(ramp_delay/1000); if (ramp_value > 4) { pr_warn("%s: ramp_delay: %d not supported\n", rdev->desc->name, ramp_delay); } switch (reg_id) { case S2MPS16_BUCK2: case S2MPS16_BUCK4: case S2MPS16_BUCK5: ramp_shift = 6; break; case S2MPS16_BUCK1: case S2MPS16_BUCK3: case S2MPS16_BUCK6: ramp_shift = 4; break; case S2MPS16_BUCK7: case S2MPS16_BUCK11: ramp_shift = 2; break; case S2MPS16_BUCK8: case S2MPS16_BUCK9: case S2MPS16_BB1: ramp_shift = 0; break; default: return -EINVAL; } return sec_reg_update(s2mps16->iodev, S2MPS16_REG_BUCK_RAMP, ramp_value << ramp_shift, ramp_mask << ramp_shift); }
static int s2mps13_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = iodev->pdata; struct regulator_config config = { }; struct s2mps13_info *s2mps13; int i, ret; unsigned int s2mps13_desc_type; ret = sec_reg_read(iodev, S2MPS13_REG_ID, &iodev->rev_num); if (ret < 0) return ret; s2mps13_desc_type = SEC_PMIC_REV(iodev) ? S2MPS13_DESC_TYPE1 : S2MPS13_DESC_TYPE0; if (iodev->dev->of_node) { ret = s2mps13_pmic_dt_parse_pdata(iodev, pdata); if (ret) return ret; } if (!pdata) { dev_err(pdev->dev.parent, "Platform data not supplied\n"); return -ENODEV; } s2mps13 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps13_info), GFP_KERNEL); if (!s2mps13) return -ENOMEM; s2mps13->dvs_en = pdata->dvs_en; s2mps13->g3d_en = pdata->g3d_en; s2mps13->iodev = iodev; static_info = s2mps13; if (SEC_PMIC_REV(iodev) > 0x02 && gpio_is_valid(pdata->dvs_pin)) { if (!pdata->dvs_en) { /* Off DVS Control GPIO */ ret = devm_gpio_request(&pdev->dev, pdata->dvs_pin, "S2MPS13 DVS_PIN"); if (ret < 0) return ret; gpio_direction_output(pdata->dvs_pin, 0); } else { /* Set DVS Regulator Voltage */ ret = sec_reg_write(iodev, S2MPS13_REG_B6CTRL3, 0x28); if (ret < 0) return ret; if (!gpio_is_valid(pdata->dvs_pin)) { dev_err(&pdev->dev, "dvs_pin GPIO NOT VALID\n"); return -EINVAL; } } s2mps13->dvs_pin = pdata->dvs_pin; } platform_set_drvdata(pdev, s2mps13); for (i = 0; i < pdata->num_regulators; i++) { int id = pdata->regulators[i].id; config.dev = &pdev->dev; config.regmap = iodev->regmap; config.init_data = pdata->regulators[i].initdata; config.driver_data = s2mps13; config.of_node = pdata->regulators[i].reg_node; s2mps13->opmode[id] = regulators[s2mps13_desc_type][id].enable_mask; s2mps13->rdev[i] = regulator_register( ®ulators[s2mps13_desc_type][id], &config); if (IS_ERR(s2mps13->rdev[i])) { ret = PTR_ERR(s2mps13->rdev[i]); dev_err(&pdev->dev, "regulator init failed for %d\n", i); s2mps13->rdev[i] = NULL; goto err; } } if (pdata->g3d_en && SEC_PMIC_REV(iodev) > 0x02 && gpio_is_valid(pdata->g3d_pin)) { ret = devm_gpio_request(&pdev->dev, pdata->g3d_pin, "S2MPS13 G3D_PIN"); if (pdata->g3d_en) { gpio_direction_output(pdata->g3d_pin, 1); udelay(128); ret = sec_reg_update(iodev, S2MPS13_REG_B6CTRL1, 0x00, 0xC0); ret = sec_reg_update(iodev, S2MPS13_REG_LDO_DVS3, 0x02, 0x02); } else gpio_direction_output(pdata->g3d_pin, 0); s2mps13->g3d_pin = pdata->g3d_pin; } /* PMIC AVP(Adaptive Voltage Positioning) Configuration */ if (pdata->ap_buck_avp_en) { sec_reg_write(iodev, 0x91, 0x4F); /* Buck4 AVP level 11mV/A */ sec_reg_write(iodev, 0x99, 0x4D); /* Buck6 AVP level 7mV/A */ sec_reg_update(iodev, S2MPS13_REG_B4CTRL1, 0x02, 0x02); /* Buck4 AVP On */ sec_reg_update(iodev, S2MPS13_REG_B6CTRL1, 0x02, 0x02); /* Buck6 AVP On */ } if (pdata->sub_buck_avp_en) { sec_reg_write(iodev, 0xBA, 0x4C); /* Buck8 AVP level 90mV/A */ sec_reg_write(iodev, 0xBB, 0x6A); /* Buck9 AVP level 115mV/A */ sec_reg_write(iodev, 0xB1, 0x0A); /* Buck8 AVP amp offset code */ sec_reg_write(iodev, 0xB5, 0x2A); /* Buck9 AVP amp offset code */ sec_reg_update(iodev, S2MPS13_REG_B8CTRL1, 0x02, 0x02); /* Buck8 AVP On */ sec_reg_update(iodev, S2MPS13_REG_B9CTRL1, 0x02, 0x02); /* Buck9 AVP On */ } return 0; err: for (i = 0; i < S2MPS13_REGULATOR_MAX; i++) regulator_unregister(s2mps13->rdev[i]); return ret; }
static int s2m_set_voltage_sel_regmap_buck(struct regulator_dev *rdev, unsigned sel) { int ret; struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int reg_id = rdev_get_id(rdev); unsigned int voltage; char name[16]; int buck2_set_val, delta_val; /* If dvs_en = 0, dvs_pin = 1, occur BUG_ON */ if (reg_id == S2MPS16_BUCK6 && !s2mps16->dvs_en && gpio_is_valid(s2mps16->dvs_pin)) { BUG_ON(s2m_get_dvs_is_on()); } /* Save cached mode buffer */ if (reg_id == S2MPS16_BUCK1 || reg_id == S2MPS16_BUCK3) s2mps16->vsel_value[reg_id] = sel; if ((reg_id == S2MPS16_BUCK2 || reg_id == S2MPS16_BUCK4 || reg_id == S2MPS16_BUCK5) && !s2mps16->buck_dvs_on) s2mps16->vsel_value[reg_id] = sel; /* BUCK2 Control */ if (reg_id == S2MPS16_BUCK2 && s2mps16->buck_dvs_on) { mutex_lock(&s2mps16->lock); if (s2mps16->buck2_dvs == 0) delta_val = 100000; else if (s2mps16->buck2_dvs == 1) delta_val = 0; else if (s2mps16->buck2_dvs == 2) delta_val = 75000; else if (s2mps16->buck2_dvs == 3) delta_val = 50000; else delta_val = 0; buck2_set_val = rdev->desc->min_uV + (rdev->desc->uV_step * sel); if (delta_val + buck2_set_val <= BUCK2_ASV_MAX) { if (!s2mps16->buck2_sync) { ret = s2m_set_fix_ldo_voltage(rdev, 1); if (ret < 0) goto out; } } else { if (s2mps16->buck2_sync) { ret = s2m_set_fix_ldo_voltage(rdev, 0); if (ret < 0) goto out; } } snprintf(name, sizeof(name), "BUCK%d", (reg_id - S2MPS16_BUCK1) + 1); voltage = (sel * S2MPS16_BUCK_STEP1) + S2MPS16_BUCK_MIN1; exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_IN); s2mps16->vsel_value[reg_id] = sel; ret = sec_reg_write(s2mps16->iodev, rdev->desc->vsel_reg, sel); if (ret < 0) goto out; exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_OUT); mutex_unlock(&s2mps16->lock); return ret; } if ((reg_id == S2MPS16_BUCK4 || reg_id == S2MPS16_BUCK5) && s2mps16->buck_dvs_on) { mutex_lock(&s2mps16->lock); ret = s2m_set_max_int_voltage(rdev, sel); if (ret < 0) goto out; mutex_unlock(&s2mps16->lock); return ret; } /* voltage information logging to snapshot feature */ snprintf(name, sizeof(name), "BUCK%d", (reg_id - S2MPS16_BUCK1) + 1); if (reg_id == S2MPS16_BUCK8 || reg_id == S2MPS16_BUCK9){ voltage = (sel * S2MPS16_BUCK_STEP2) + S2MPS16_BUCK_MIN2; dev_info(&rdev->dev, ":BUCK%d voltage :%d \n", (reg_id - S2MPS16_BUCK1) + 1, voltage); } else voltage = (sel * S2MPS16_BUCK_STEP1) + S2MPS16_BUCK_MIN1; exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_IN); ret = sec_reg_write(s2mps16->iodev, rdev->desc->vsel_reg, sel); if (ret < 0) goto i2c_out; exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_OUT); if (rdev->desc->apply_bit) ret = sec_reg_update(s2mps16->iodev, rdev->desc->apply_reg, rdev->desc->apply_bit, rdev->desc->apply_bit); return ret; out: mutex_unlock(&s2mps16->lock); i2c_out: pr_warn("%s: failed to set voltage_sel_regmap\n", rdev->desc->name); exynos_ss_regulator(name, rdev->desc->vsel_reg, voltage, ESS_FLAG_ON); return ret; }
static int s2m_set_ldo_dvs_control(struct regulator_dev *rdev) { int ret; struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int reg_id = rdev_get_id(rdev); unsigned int sram_vthr, sram_delta, asv_info; int vthr_mask, delta_mask; int vthr_val, delta_val = 0; int dvs_reg; unsigned int ctrl_value; asv_info = cal_asv_pmic_info(); if (asv_info < 0) { pr_warn("Do not read asv pmic fuse value \n"); goto out; } switch (reg_id) { case S2MPS16_BUCK2: vthr_mask = 0x3; delta_mask = 0x3 << 2; sram_vthr = asv_info & vthr_mask; sram_delta = (asv_info & delta_mask) >> 2; s2mps16->buck2_dvs = sram_delta; dvs_reg = S2MPS16_REG_LDO7_DVS; break; case S2MPS16_BUCK3: vthr_mask = 0x3 << 4; delta_mask = 0x3 << 6; sram_vthr = (asv_info & vthr_mask) >> 4; sram_delta = (asv_info & delta_mask) >> 6; dvs_reg = S2MPS16_REG_LDO10_DVS; break; case S2MPS16_LDO8: vthr_mask = 0x3 << 12; delta_mask = 0x3 << 14; sram_vthr = (asv_info & vthr_mask) >> 12; sram_delta = (asv_info & delta_mask) >> 14; break; case S2MPS16_BUCK1: vthr_mask = 0x3 << 16; delta_mask = 0x3 << 18; sram_vthr = (asv_info & vthr_mask) >> 16; sram_delta = (asv_info & delta_mask) >> 18; dvs_reg = S2MPS16_REG_LDO9_DVS; break; default: dev_err(&rdev->dev, "%s, set invalid reg_id(%d)\n", __func__, reg_id); break; } switch (sram_vthr) { case 0x0: if (reg_id == S2MPS16_LDO8) s2mps16->int_vthr = 800000; else if (reg_id == S2MPS16_BUCK2) vthr_val = 0x6 << 5; else if ((reg_id == S2MPS16_BUCK3) || (reg_id == S2MPS16_BUCK1)) vthr_val = 0x4 << 5; break; case 0x1: if (reg_id == S2MPS16_LDO8) s2mps16->int_vthr = 750000; else if ((reg_id == S2MPS16_BUCK1) || (reg_id == S2MPS16_BUCK2) || (reg_id == S2MPS16_BUCK3)) vthr_val = 0x3 << 5; break; case 0x2: if (reg_id == S2MPS16_LDO8) s2mps16->int_vthr = 850000; else if ((reg_id == S2MPS16_BUCK1) || (reg_id == S2MPS16_BUCK2) || (reg_id == S2MPS16_BUCK3)) vthr_val = 0x5 << 5; break; case 0x3: if (reg_id == S2MPS16_LDO8) s2mps16->int_vthr = 900000; else if ((reg_id == S2MPS16_BUCK1) ||(reg_id == S2MPS16_BUCK3)) vthr_val = 0x6 << 5; else if (reg_id == S2MPS16_BUCK2) vthr_val = 0x4 << 5; break; } switch (sram_delta) { case 0x0: if (reg_id == S2MPS16_BUCK2) delta_val = 0x3 << 3; else if (reg_id == S2MPS16_BUCK3) delta_val = 0x1 << 3; else if (reg_id == S2MPS16_BUCK1) delta_val = 0x1 << 3; else if (reg_id == S2MPS16_LDO8) s2mps16->int_delta = 50000; break; case 0x1: if (reg_id == S2MPS16_LDO8) s2mps16->int_delta = 0; else if ((reg_id == S2MPS16_BUCK1) || (reg_id == S2MPS16_BUCK2) || (reg_id == S2MPS16_BUCK3)) delta_val = 0x0 << 3; break; case 0x2: if (reg_id == S2MPS16_LDO8) s2mps16->int_delta = 75000; else if ((reg_id == S2MPS16_BUCK1) || (reg_id == S2MPS16_BUCK2) || (reg_id == S2MPS16_BUCK3)) delta_val = 0x2 << 3; break; case 0x3: if (reg_id == S2MPS16_BUCK2) delta_val = 0x1 << 3; else if ((reg_id == S2MPS16_BUCK3) || (reg_id == S2MPS16_BUCK1)) delta_val = 0x3 << 3; else if (reg_id == S2MPS16_LDO8) s2mps16->int_delta = 100000; break; } if (reg_id == S2MPS16_LDO8) return 0; ctrl_value = vthr_val | delta_val; ret = sec_reg_update(s2mps16->iodev, dvs_reg, ctrl_value, 0xf8); if (ret < 0) goto out; return ret; out: pr_warn("%s: failed to ldo dvs control\n", rdev->desc->name); return ret; }
static int s2m_set_max_int_voltage(struct regulator_dev *rdev, unsigned sel) { struct s2mps16_info *s2mps16 = rdev_get_drvdata(rdev); int ret, ldo_sel; int buck_val, int_max = 0; int reg_id = rdev_get_id(rdev); unsigned int old_sel_buck = 0, old_val_buck, old_val_ldo, buck_delay = 0, target_val; char name[16]; if (reg_id == S2MPS16_BUCK4) { /*INT*/ old_sel_buck = s2mps16->buck4_sel; s2mps16->buck4_sel = sel; } else if (reg_id == S2MPS16_BUCK5) { /*DISP_CAM*/ old_sel_buck = s2mps16->buck5_sel; s2mps16->buck5_sel = sel; } old_val_buck = rdev->desc->min_uV + (rdev->desc->uV_step * old_sel_buck); old_val_ldo = s2mps16->int_max; buck_val = rdev->desc->min_uV + (rdev->desc->uV_step * sel); target_val = buck_val + s2mps16->int_delta; if (target_val > LDO8_MAX) target_val = LDO8_MAX; if (target_val > s2mps16->int_max) { /* UP */ ldo_sel = DIV_ROUND_UP(target_val - regulators[s2mps16->desc_type][S2MPS16_LDO8].min_uV, regulators[s2mps16->desc_type][S2MPS16_LDO8].uV_step); if (ldo_sel < 0) goto out; /* Update int_max */ s2mps16->int_max = target_val; exynos_ss_regulator("LDO8", S2MPS16_REG_L8CTRL, target_val, ESS_FLAG_IN); ret = sec_reg_update(s2mps16->iodev, S2MPS16_REG_L8CTRL, ldo_sel, 0x3f); if (ret < 0) { exynos_ss_regulator("LDO8", S2MPS16_REG_L8CTRL, target_val, ESS_FLAG_ON); goto out; } exynos_ss_regulator("LDO8", S2MPS16_REG_L8CTRL, target_val, ESS_FLAG_OUT); udelay(DIV_ROUND_UP((s2mps16->int_max - old_val_ldo), 12000)); snprintf(name, sizeof(name), "BUCK%d", (reg_id - S2MPS16_BUCK1) + 1); exynos_ss_regulator(name, rdev->desc->vsel_reg, buck_val, ESS_FLAG_IN); s2mps16->vsel_value[reg_id] = sel; ret = sec_reg_write(s2mps16->iodev, rdev->desc->vsel_reg, sel); if (ret < 0) { exynos_ss_regulator(name, rdev->desc->vsel_reg, buck_val, ESS_FLAG_ON); goto out; } exynos_ss_regulator(name, rdev->desc->vsel_reg, buck_val, ESS_FLAG_OUT); } else { if (buck_val < old_val_buck) buck_delay = DIV_ROUND_UP((old_val_buck - buck_val), rdev->constraints->ramp_delay); else buck_delay = DIV_ROUND_UP((buck_val- old_val_buck), rdev->constraints->ramp_delay); snprintf(name, sizeof(name), "BUCK%d", (reg_id - S2MPS16_BUCK1) + 1); exynos_ss_regulator(name, rdev->desc->vsel_reg, buck_val, ESS_FLAG_IN); s2mps16->vsel_value[reg_id] = sel; ret = sec_reg_write(s2mps16->iodev, rdev->desc->vsel_reg, sel); if (ret < 0) { exynos_ss_regulator(name, rdev->desc->vsel_reg, buck_val, ESS_FLAG_ON); goto out; } exynos_ss_regulator(name, rdev->desc->vsel_reg, buck_val, ESS_FLAG_OUT); udelay(buck_delay); int_max = s2m_get_max_int_voltage(s2mps16); if (s2mps16->int_max != int_max) { s2mps16->int_max = int_max; ret = DIV_ROUND_UP(int_max - regulators[s2mps16->desc_type][S2MPS16_LDO8].min_uV, regulators[s2mps16->desc_type][S2MPS16_LDO8].uV_step); if (ret < 0) goto out; exynos_ss_regulator("LDO8", S2MPS16_REG_L8CTRL, int_max, ESS_FLAG_IN); ret = sec_reg_update(s2mps16->iodev, S2MPS16_REG_L8CTRL, ret, 0x3f); exynos_ss_regulator("LDO8", S2MPS16_REG_L8CTRL, int_max, ESS_FLAG_OUT); if (ret < 0) goto out; udelay(DIV_ROUND_UP((old_val_ldo - s2mps16->int_max), 12000)); } } return ret; out: pr_warn("%s: failed to set the max int voltage\n", __func__); return ret; }
static int s2mps16_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = iodev->pdata; struct regulator_config config = { }; struct s2mps16_info *s2mps16; int i, ret, delta_sel; unsigned int temp; unsigned int s2mps16_desc_type; unsigned int buck2_temp = 0; ret = sec_reg_read(iodev, S2MPS16_REG_ID, &SEC_PMIC_REV(iodev)); if (ret < 0) return ret; s2mps16_desc_type = S2MPS16_DESC_TYPE0; if (iodev->dev->of_node) { ret = s2mps16_pmic_dt_parse_pdata(iodev, pdata); if (ret) return ret; } if (!pdata) { dev_err(pdev->dev.parent, "Platform data not supplied\n"); return -ENODEV; } s2mps16 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps16_info), GFP_KERNEL); if (!s2mps16) return -ENOMEM; s2mps16->desc_type = s2mps16_desc_type; s2mps16->iodev = iodev; s2mps16->buck11_en = (const char *)of_find_property(iodev->dev->of_node, "buck11_en", NULL); mutex_init(&s2mps16->lock); static_info = s2mps16; s2mps16->dvs_en = pdata->dvs_en; s2mps16->g3d_en = pdata->g3d_en; s2mps16->cache_data = pdata->cache_data; s2mps16->int_max = 0; s2mps16->buck_dvs_on = pdata->buck_dvs_on; if (s2mps16->buck_dvs_on) dev_info(&pdev->dev, "Buck dvs mode enabled \n"); if (gpio_is_valid(pdata->dvs_pin)) { ret = devm_gpio_request(&pdev->dev, pdata->dvs_pin, "S2MPS16 DVS_PIN"); if (ret < 0) return ret; if (pdata->dvs_en) { /* Set DVS Regulator Voltage 0x20 - 0.5 voltage */ ret = sec_reg_write(iodev, S2MPS16_REG_B6CTRL2, 0x20); if (ret < 0) return ret; s2m_init_dvs(); s2mps16->dvs_pin = pdata->dvs_pin; } else dev_err(&pdev->dev, "g3d dvs is not enabled.\n"); } platform_set_drvdata(pdev, s2mps16); for (i = 0; i < pdata->num_regulators; i++) { int id = pdata->regulators[i].id; config.dev = &pdev->dev; config.regmap = iodev->regmap; config.init_data = pdata->regulators[i].initdata; config.driver_data = s2mps16; config.of_node = pdata->regulators[i].reg_node; s2mps16->opmode[id] = regulators[s2mps16_desc_type][id].enable_mask; s2mps16->rdev[i] = regulator_register( ®ulators[s2mps16_desc_type][id], &config); if (IS_ERR(s2mps16->rdev[i])) { ret = PTR_ERR(s2mps16->rdev[i]); dev_err(&pdev->dev, "regulator init failed for %d\n", i); s2mps16->rdev[i] = NULL; goto err; } if ((id == S2MPS16_BUCK1 || id == S2MPS16_BUCK2 || id == S2MPS16_BUCK3 || id == S2MPS16_LDO8) && s2mps16->buck_dvs_on) { mutex_lock(&s2mps16->lock); ret = s2m_set_ldo_dvs_control(s2mps16->rdev[i]); if (ret < 0) dev_err(&pdev->dev, "failed vth/delta init, id(%d)\n", id); mutex_unlock(&s2mps16->lock); } } s2mps16->num_regulators = pdata->num_regulators; if (s2mps16->buck_dvs_on) { delta_sel = 0; if (s2mps16->buck2_dvs == 0) delta_sel = 100000; else if (s2mps16->buck2_dvs == 1) delta_sel = 0; else if (s2mps16->buck2_dvs == 2) delta_sel = 75000; else if (s2mps16->buck2_dvs == 3) delta_sel = 50000; else delta_sel = 0; delta_sel = delta_sel / S2MPS16_BUCK_STEP1; /* Read BUCK2_OUT value */ ret = sec_reg_read(iodev, S2MPS16_REG_B2CTRL2, &temp); if (ret < 0) goto err; buck2_temp = temp; /* Check tar_volt+delta range (0x98 means 1250000uV) */ s2mps16->buck2_sync = (temp + delta_sel > 0x98) ? false : true; if (!s2mps16->buck2_sync) { /* Set BUCK2 output voltage 1150000uV */ ret = sec_reg_write(s2mps16->iodev, S2MPS16_REG_B2CTRL2, 0x88); if (ret < 0) goto err; /* Disable buck2 dvs mode */ ret = sec_reg_update(s2mps16->iodev, S2MPS16_REG_LDO7_DVS, 0 << 2, 0x1 << 2); if (ret < 0) goto err; /* Set buck previous target voltage */ ret = sec_reg_write(s2mps16->iodev, S2MPS16_REG_B2CTRL2, buck2_temp); if (ret < 0) goto err; } ret = sec_reg_read(iodev, S2MPS16_REG_LDO7_DVS, &temp); if (ret < 0) goto err; ret = sec_reg_read(iodev, S2MPS16_REG_B4CTRL2, &s2mps16->buck4_sel); if (ret < 0) goto err; ret = sec_reg_read(iodev, S2MPS16_REG_B5CTRL2, &s2mps16->buck5_sel); if (ret < 0) goto err; dev_info(&pdev->dev, "S2MPS16_REG_LDO7_DVS : %8.x \n", temp); dev_info(&pdev->dev, "S2MPS16_REG_B4CTRL2 : %8.x \n", s2mps16->buck4_sel); dev_info(&pdev->dev, "S2MPS16_REG_B5CTRL2 : %8.x \n", s2mps16->buck5_sel); s2mps16->int_max = s2m_get_max_int_voltage(s2mps16); } if (pdata->g3d_en) { /* for buck6 gpio control, disable i2c control */ ret = sec_reg_update(iodev, S2MPS16_REG_B6CTRL1, 0x80, 0xC0); if (ret) { dev_err(&pdev->dev, "buck6 gpio control error\n"); goto err; } if (!s2mps16->buck11_en) { ret = sec_reg_update(iodev, S2MPS16_REG_L11CTRL, 0x00, 0xC0); if (ret) { dev_err(&pdev->dev, "regulator sync enable error\n"); goto err; } } else { /* for buck11 gpio control, disable i2c control */ ret = sec_reg_update(iodev, S2MPS16_REG_B11CTRL1, 0x80, 0xC0); if (ret) { dev_err(&pdev->dev, "buck11 gpio control error\n"); goto err; } } } if (pdata->smpl_warn_en) { ret = sec_reg_update(iodev, S2MPS16_REG_CTRL2, pdata->smpl_warn_vth, 0xe0); if (ret) { dev_err(&pdev->dev, "set smpl_warn configuration i2c write error\n"); goto err; } pr_info("%s: smpl_warn vth is 0x%x\n", __func__, pdata->smpl_warn_vth); ret = sec_reg_update(iodev, S2MPS16_REG_CTRL2, pdata->smpl_warn_hys, 0x18); if (ret) { dev_err(&pdev->dev, "set smpl_warn configuration i2c write error\n"); goto err; } pr_info("%s: smpl_warn hysteresis is 0x%x\n", __func__, pdata->smpl_warn_hys); } /* RTC Low jitter mode */ ret = sec_reg_update(iodev, S2MPS16_REG_RTC_BUF, 0x10, 0x10); if (ret) { dev_err(&pdev->dev, "set low jitter mode i2c write error\n"); goto err; } /* SELMIF set LDO2,4,5,6,8,9,12,13 controlled by PWREN_MIF */ ret = sec_reg_write(iodev, S2MPS16_REG_SELMIF, 0xFF); if (ret) { dev_err(&pdev->dev, "set selmif sel error\n"); goto err; } sec_reg_update(iodev, S2MPS16_REG_B4CTRL1, 0x00, 0x10); ret = sec_reg_write(iodev, 0x9B, 0x10); if (ret) { dev_err(&pdev->dev, "BUCK8, BUCK9 DVS setting failed\n"); goto err; } /* On sequence Config for PWREN_MIF */ sec_reg_write(iodev, 0x70, 0xB4); /* seq. Buck2, Buck1 */ sec_reg_write(iodev, 0x71, 0x2C); /* seq. Buck4, Buck3 */ sec_reg_write(iodev, 0x72, 0xD4); /* seq. Buck6, Buck5 */ sec_reg_write(iodev, 0x73, 0x11); /* seq. Buck8, Buck7 */ sec_reg_write(iodev, 0x74, 0xE0); /* seq. Buck10, Buck9 */ if (s2mps16->buck11_en) sec_reg_write(iodev, 0x75, 0x27); /* seq. BB, Buck11 */ else sec_reg_write(iodev, 0x75, 0x20); sec_reg_write(iodev, 0x76, 0x93); /* seq. LDO2, LDO1 */ sec_reg_write(iodev, 0x77, 0x60); /* Seq. LDO4, LDO3 */ sec_reg_write(iodev, 0x78, 0x87); /* seq. LDO6, LDO5 */ sec_reg_write(iodev, 0x79, pdata->ldo8_7_seq); /* Seq. LDO8, LDO7 */ sec_reg_write(iodev, 0x7A, pdata->ldo10_9_seq); /* Seq. LDO10, LDO9 */ if (s2mps16->buck11_en) sec_reg_write(iodev, 0x7B, 0x50); /* Seq. LDO12, LDO11 */ else sec_reg_write(iodev, 0x7B, 0x57); sec_reg_write(iodev, 0x7C, 0x75); /* Seq. LDO14, LDO13 */ sec_reg_write(iodev, 0x7D, 0x98); /* Seq. LDO16, LDO15 */ sec_reg_write(iodev, 0x7E, 0x00); /* Seq. LDO18, LDO17 */ sec_reg_write(iodev, 0x7F, 0x00); /* Seq. LDO20, LDO19 */ sec_reg_write(iodev, 0x80, 0x21); /* Seq. LDO22, LDO21 */ sec_reg_write(iodev, 0x81, 0x3F); /* Seq. LDO24, LDO23 */ sec_reg_write(iodev, 0x82, 0x00); /* Seq. LDO26, LDO25 */ sec_reg_write(iodev, 0x83, 0x40); /* Seq. B1~B8*/ sec_reg_write(iodev, 0x84, 0x40); /* Seq. B9~B11, BB, LDO1~4 */ sec_reg_write(iodev, 0x85, 0x00); /* Seq. LDO5~12 */ sec_reg_write(iodev, 0x86, 0x0E); /* Seq. LDO13~20 */ sec_reg_write(iodev, 0x87, 0x00); /* Seq. LDO26~21 */ return 0; err: for (i = 0; i < S2MPS16_REGULATOR_MAX; i++) regulator_unregister(s2mps16->rdev[i]); return ret; }