Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
/* 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__);
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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(
					&regulators[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;
}
Exemple #10
0
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;
}
Exemple #11
0
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;

}
Exemple #12
0
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;
}
Exemple #13
0
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(
				&regulators[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;
}