예제 #1
0
static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev)
{
	struct lp872x *lp = rdev_get_drvdata(rdev);
	enum lp872x_regulator_id buck = rdev_get_id(rdev);
	u8 addr, mask, val;
	int ret;

	switch (buck) {
	case LP8720_ID_BUCK:
		addr = LP8720_BUCK_VOUT2;
		mask = LP8720_BUCK_FPWM_M;
		break;
	case LP8725_ID_BUCK1:
		addr = LP8725_BUCK_CTRL;
		mask = LP8725_BUCK1_FPWM_M;
		break;
	case LP8725_ID_BUCK2:
		addr = LP8725_BUCK_CTRL;
		mask = LP8725_BUCK2_FPWM_M;
		break;
	default:
		return -EINVAL;
	}

	ret = lp872x_read_byte(lp, addr, &val);
	if (ret)
		return ret;

	return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}
예제 #2
0
static int lp8725_buck_get_current_limit(struct regulator_dev *rdev)
{
	struct lp872x *lp = rdev_get_drvdata(rdev);
	enum lp872x_regulator_id buck = rdev_get_id(rdev);
	u8 addr, val;
	int ret;

	switch (buck) {
	case LP8725_ID_BUCK1:
		addr = LP8725_BUCK1_VOUT2;
		break;
	case LP8725_ID_BUCK2:
		addr = LP8725_BUCK2_VOUT2;
		break;
	default:
		return -EINVAL;
	}

	ret = lp872x_read_byte(lp, addr, &val);
	if (ret)
		return ret;

	val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S;

	return (val < ARRAY_SIZE(lp8725_buck_uA)) ?
			lp8725_buck_uA[val] : -EINVAL;
}
예제 #3
0
static int lp872x_get_timestep_usec(struct lp872x *lp)
{
	enum lp872x_id chip = lp->chipid;
	u8 val, mask, shift;
	int *time_usec, size, ret;
	int lp8720_time_usec[] = { 25, 50 };
	int lp8725_time_usec[] = { 32, 64, 128, 256 };

	switch (chip) {
	case LP8720:
		mask = LP8720_TIMESTEP_M;
		shift = LP8720_TIMESTEP_S;
		time_usec = &lp8720_time_usec[0];
		size = ARRAY_SIZE(lp8720_time_usec);
		break;
	case LP8725:
		mask = LP8725_TIMESTEP_M;
		shift = LP8725_TIMESTEP_S;
		time_usec = &lp8725_time_usec[0];
		size = ARRAY_SIZE(lp8725_time_usec);
		break;
	default:
		return -EINVAL;
	}

	ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val);
	if (ret)
		return -EINVAL;

	val = (val & mask) >> shift;
	if (val >= size)
		return -EINVAL;

	return *(time_usec + val);
}
예제 #4
0
static int lp872x_regulator_enable_time(struct regulator_dev *rdev)
{
	struct lp872x *lp = rdev_get_drvdata(rdev);
	enum lp872x_regulator_id rid = rdev_get_id(rdev);
	int time_step_us = lp872x_get_timestep_usec(lp);
	int ret;
	u8 addr, val;

	if (time_step_us < 0)
		return time_step_us;

	switch (rid) {
	case LP8720_ID_LDO1 ... LP8720_ID_BUCK:
		addr = LP872X_LDO1_VOUT + rid;
		break;
	case LP8725_ID_LDO1 ... LP8725_ID_BUCK1:
		addr = LP872X_LDO1_VOUT + rid - LP8725_ID_BASE;
		break;
	case LP8725_ID_BUCK2:
		addr = LP8725_BUCK2_VOUT1;
		break;
	default:
		return -EINVAL;
	}

	ret = lp872x_read_byte(lp, addr, &val);
	if (ret)
		return ret;

	val = (val & LP872X_START_DELAY_M) >> LP872X_START_DELAY_S;

	return val > MAX_DELAY ? 0 : val * time_step_us;
}
예제 #5
0
static u8 lp872x_select_buck_vout_addr(struct lp872x *lp,
				enum lp872x_regulator_id buck)
{
	u8 val, addr;

	if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val))
		return 0;

	switch (buck) {
	case LP8720_ID_BUCK:
		if (val & LP8720_EXT_DVS_M) {
			addr = (lp->dvs_pin == DVS_HIGH) ?
				LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2;
		} else {
			if (lp872x_read_byte(lp, LP8720_ENABLE, &val))
				return 0;

			addr = val & LP8720_DVS_SEL_M ?
				LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2;
		}
		break;
	case LP8725_ID_BUCK1:
		if (val & LP8725_DVS1_M)
			addr = LP8725_BUCK1_VOUT1;
		else
			addr = (lp->dvs_pin == DVS_HIGH) ?
				LP8725_BUCK1_VOUT1 : LP8725_BUCK1_VOUT2;
		break;
	case LP8725_ID_BUCK2:
		addr =  val & LP8725_DVS2_M ?
			LP8725_BUCK2_VOUT1 : LP8725_BUCK2_VOUT2;
		break;
	default:
		return 0;
	}

	return addr;
}
예제 #6
0
static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev)
{
	struct lp872x *lp = rdev_get_drvdata(rdev);
	enum lp872x_regulator_id buck = rdev_get_id(rdev);
	u8 addr, val;
	int ret;

	addr = lp872x_select_buck_vout_addr(lp, buck);
	if (!lp872x_is_valid_buck_addr(addr))
		return -EINVAL;

	ret = lp872x_read_byte(lp, addr, &val);
	if (ret)
		return ret;

	return val & LP872X_VOUT_M;
}
예제 #7
0
static int lp872x_check_dvs_validity(struct lp872x *lp)
{
	struct lp872x_dvs *dvs = lp->pdata->dvs;
	u8 val = 0;
	int ret;

	ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val);
	if (ret)
		return ret;

	ret = 0;
	if (lp->chipid == LP8720) {
		if (val & LP8720_EXT_DVS_M)
			ret = dvs ? 0 : -EINVAL;
	} else {
		if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED)
			ret = dvs ? 0 : -EINVAL;
	}

	return ret;
}