Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a320e3c3 authored by Jorge Eduardo Candelaria's avatar Jorge Eduardo Candelaria Committed by Liam Girdwood
Browse files

regulator: tps65911: Add new chip version



The tps65911 chip introduces new features, including changes in
the regulator module.

- VDD1 and VDD2 remain unchanged.
- VDD3 is now named VDDCTRL and has a wider voltage range.
- LDOs are now named LDO1...8 and voltage ranges are sequential,
  making LDOs easier to handle.

Signed-off-by: default avatarJorge Eduardo Candelaria <jedu@slimlogic.co.uk>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent 79557056
Loading
Loading
Loading
Loading
+323 −34
Original line number Diff line number Diff line
@@ -39,8 +39,17 @@
#define TPS65910_REG_VAUX33		11
#define TPS65910_REG_VMMC		12

#define TPS65910_NUM_REGULATOR		13
#define TPS65911_REG_VDDCTRL		4
#define TPS65911_REG_LDO1		5
#define TPS65911_REG_LDO2		6
#define TPS65911_REG_LDO3		7
#define TPS65911_REG_LDO4		8
#define TPS65911_REG_LDO5		9
#define TPS65911_REG_LDO6		10
#define TPS65911_REG_LDO7		11
#define TPS65911_REG_LDO8		12

#define TPS65910_NUM_REGULATOR		13
#define TPS65910_SUPPLY_STATE_ENABLED	0x1

/* supported VIO voltages in milivolts */
@@ -48,7 +57,9 @@ static const u16 VIO_VSEL_table[] = {
	1500, 1800, 2500, 3300,
};

/* supported VIO voltages in milivolts */
/* VSEL tables for TPS65910 specific LDOs and dcdc's */

/* supported VDD3 voltages in milivolts */
static const u16 VDD3_VSEL_table[] = {
	5000,
};
@@ -187,6 +198,71 @@ static struct tps_info tps65910_regs[] = {
	},
};

static struct tps_info tps65911_regs[] = {
	{
		.name = "VIO",
		.min_uV = 1500000,
		.max_uV = 3300000,
		.table_len = ARRAY_SIZE(VIO_VSEL_table),
		.table = VIO_VSEL_table,
	},
	{
		.name = "VDD1",
		.min_uV = 600000,
		.max_uV = 4500000,
	},
	{
		.name = "VDD2",
		.min_uV = 600000,
		.max_uV = 4500000,
	},
	{
		.name = "VDDCTRL",
		.min_uV = 600000,
		.max_uV = 1400000,
	},
	{
		.name = "LDO1",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO2",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO3",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO4",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO5",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO6",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO7",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
	{
		.name = "LDO8",
		.min_uV = 1000000,
		.max_uV = 3300000,
	},
};

struct tps65910_reg {
	struct regulator_desc desc[TPS65910_NUM_REGULATOR];
	struct tps65910 *mfd;
@@ -194,6 +270,7 @@ struct tps65910_reg {
	struct tps_info *info[TPS65910_NUM_REGULATOR];
	struct mutex mutex;
	int mode;
	int  (*get_ctrl_reg)(int);
};

static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
@@ -300,12 +377,46 @@ static int tps65910_get_ctrl_register(int id)
	}
}

static int tps65911_get_ctrl_register(int id)
{
	switch (id) {
	case TPS65910_REG_VRTC:
		return TPS65910_VRTC;
	case TPS65910_REG_VIO:
		return TPS65910_VIO;
	case TPS65910_REG_VDD1:
		return TPS65910_VDD1;
	case TPS65910_REG_VDD2:
		return TPS65910_VDD2;
	case TPS65911_REG_VDDCTRL:
		return TPS65911_VDDCTRL;
	case TPS65911_REG_LDO1:
		return TPS65911_LDO1;
	case TPS65911_REG_LDO2:
		return TPS65911_LDO2;
	case TPS65911_REG_LDO3:
		return TPS65911_LDO3;
	case TPS65911_REG_LDO4:
		return TPS65911_LDO4;
	case TPS65911_REG_LDO5:
		return TPS65911_LDO5;
	case TPS65911_REG_LDO6:
		return TPS65911_LDO6;
	case TPS65911_REG_LDO7:
		return TPS65911_LDO7;
	case TPS65911_REG_LDO8:
		return TPS65911_LDO8;
	default:
		return -EINVAL;
	}
}

static int tps65910_is_enabled(struct regulator_dev *dev)
{
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int reg, value, id = rdev_get_id(dev);

	reg = tps65910_get_ctrl_register(id);
	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -322,7 +433,7 @@ static int tps65910_enable(struct regulator_dev *dev)
	struct tps65910 *mfd = pmic->mfd;
	int reg, id = rdev_get_id(dev);

	reg = tps65910_get_ctrl_register(id);
	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -335,7 +446,7 @@ static int tps65910_disable(struct regulator_dev *dev)
	struct tps65910 *mfd = pmic->mfd;
	int reg, id = rdev_get_id(dev);

	reg = tps65910_get_ctrl_register(id);
	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -348,7 +459,8 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	struct tps65910 *mfd = pmic->mfd;
	int reg, value, id = rdev_get_id(dev);
	reg = tps65910_get_ctrl_register(id);

	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -371,7 +483,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev)
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int reg, value, id = rdev_get_id(dev);

	reg = tps65910_get_ctrl_register(id);
	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -391,7 +503,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
{
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int id = rdev_get_id(dev), voltage = 0;
	int opvsel = 0, srvsel = 0, mult = 0, sr = 0;
	int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;

	switch (id) {
	case TPS65910_REG_VDD1:
@@ -402,6 +514,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
		sr = opvsel & VDD1_OP_CMD_MASK;
		opvsel &= VDD1_OP_SEL_MASK;
		srvsel &= VDD1_SR_SEL_MASK;
		vselmax = 75;
		break;
	case TPS65910_REG_VDD2:
		opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP);
@@ -411,6 +524,15 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
		sr = opvsel & VDD2_OP_CMD_MASK;
		opvsel &= VDD2_OP_SEL_MASK;
		srvsel &= VDD2_SR_SEL_MASK;
		vselmax = 75;
		break;
	case TPS65911_REG_VDDCTRL:
		opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP);
		srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR);
		sr = opvsel & VDDCTRL_OP_CMD_MASK;
		opvsel &= VDDCTRL_OP_SEL_MASK;
		srvsel &= VDDCTRL_SR_SEL_MASK;
		vselmax = 64;
		break;
	}

@@ -419,17 +541,21 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
		mult=1;

	if (sr) {
		/* Valid range is 3-75 so normalise */
		if (srvsel < 3) srvsel = 3;
		if (srvsel > 75) srvsel = 75;
		/* normalise to valid range */
		if (srvsel < 3)
			srvsel = 3;
		if (srvsel > vselmax)
			srvsel = vselmax;
		srvsel -= 3;

		voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
	} else {

		/* Valid range is 3-75 so normalise */
		if (opvsel < 3) opvsel = 3;
		if (opvsel > 75) opvsel = 75;
		/* normalise to valid range*/
		if (opvsel < 3)
			opvsel = 3;
		if (opvsel > vselmax)
			opvsel = vselmax;
		opvsel -= 3;

		voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
@@ -445,7 +571,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev)
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int reg, value, id = rdev_get_id(dev), voltage = 0;

	reg = tps65910_get_ctrl_register(id);
	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -480,29 +606,88 @@ static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
	return 5 * 1000 * 1000;
}

static int tps65911_get_voltage(struct regulator_dev *dev)
{
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int step_mv, id = rdev_get_id(dev);
	u8 value, reg;

	reg = pmic->get_ctrl_reg(id);

	value = tps65910_reg_read(pmic, reg);

	switch (id) {
	case TPS65911_REG_LDO1:
	case TPS65911_REG_LDO2:
	case TPS65911_REG_LDO4:
		value &= LDO1_SEL_MASK;
		value >>= LDO_SEL_SHIFT;
		/* The first 5 values of the selector correspond to 1V */
		if (value < 5)
			value = 0;
		else
			value -= 4;

		step_mv = 50;
		break;
	case TPS65911_REG_LDO3:
	case TPS65911_REG_LDO5:
	case TPS65911_REG_LDO6:
	case TPS65911_REG_LDO7:
	case TPS65911_REG_LDO8:
		value &= LDO3_SEL_MASK;
		value >>= LDO_SEL_SHIFT;
		/* The first 3 values of the selector correspond to 1V */
		if (value < 3)
			value = 0;
		else
			value -= 2;

		step_mv = 100;
		break;
	case TPS65910_REG_VIO:
		return pmic->info[id]->table[value] * 1000;
		break;
	default:
		return -EINVAL;
	}

	return (LDO_MIN_VOLT + value * step_mv) * 1000;
}

static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
				unsigned selector)
{
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int id = rdev_get_id(dev), vsel;
	int dcdc_mult;
	int dcdc_mult = 0;

	/* Split vsel into appropriate registers */
	switch (id) {
	case TPS65910_REG_VDD1:
		dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
	if (dcdc_mult == 1) dcdc_mult--;

		if (dcdc_mult == 1)
			dcdc_mult--;
		vsel = (selector % VDD1_2_NUM_VOLTS) + 3;

	if (id == TPS65910_REG_VDD1) {
		tps65910_modify_bits(pmic, TPS65910_VDD1,
				(dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
						VDD1_VGAIN_SEL_MASK);
		tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
	} else {
		break;
	case TPS65910_REG_VDD2:
		dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
		if (dcdc_mult == 1)
			dcdc_mult--;
		vsel = (selector % VDD1_2_NUM_VOLTS) + 3;

		tps65910_modify_bits(pmic, TPS65910_VDD2,
				(dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
						VDD1_VGAIN_SEL_MASK);
		tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel);
		break;
	case TPS65911_REG_VDDCTRL:
		vsel = selector;
		tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel);
	}

	return 0;
@@ -513,7 +698,7 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector)
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int reg, id = rdev_get_id(dev);

	reg = tps65910_get_ctrl_register(id);
	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

@@ -534,14 +719,49 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector)
	return -EINVAL;
}

static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector)
{
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int reg, id = rdev_get_id(dev);

	reg = pmic->get_ctrl_reg(id);
	if (reg < 0)
		return reg;

	switch (id) {
	case TPS65911_REG_LDO1:
	case TPS65911_REG_LDO2:
	case TPS65911_REG_LDO4:
		return tps65910_modify_bits(pmic, reg,
				(selector << LDO_SEL_SHIFT), LDO1_SEL_MASK);
	case TPS65911_REG_LDO3:
	case TPS65911_REG_LDO5:
	case TPS65911_REG_LDO6:
	case TPS65911_REG_LDO7:
	case TPS65911_REG_LDO8:
	case TPS65910_REG_VIO:
		return tps65910_modify_bits(pmic, reg,
				(selector << LDO_SEL_SHIFT), LDO3_SEL_MASK);
	}

	return -EINVAL;
}


static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
					unsigned selector)
{
	int mult, volt;
	int volt, mult = 1, id = rdev_get_id(dev);

	switch (id) {
	case TPS65910_REG_VDD1:
	case TPS65910_REG_VDD2:
		mult = (selector / VDD1_2_NUM_VOLTS) + 1;

	volt = VDD1_2_MIN_VOLT + (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
		volt = VDD1_2_MIN_VOLT +
				(selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
	case TPS65911_REG_VDDCTRL:
		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
	}

	return  volt * 100 * mult;
}
@@ -563,6 +783,45 @@ static int tps65910_list_voltage(struct regulator_dev *dev,
	return voltage;
}

static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
{
	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
	int step_mv = 0, id = rdev_get_id(dev);

	switch(id) {
	case TPS65911_REG_LDO1:
	case TPS65911_REG_LDO2:
	case TPS65911_REG_LDO4:
		/* The first 5 values of the selector correspond to 1V */
		if (selector < 5)
			selector = 0;
		else
			selector -= 4;

		step_mv = 50;
		break;
	case TPS65911_REG_LDO3:
	case TPS65911_REG_LDO5:
	case TPS65911_REG_LDO6:
	case TPS65911_REG_LDO7:
	case TPS65911_REG_LDO8:
		/* The first 3 values of the selector correspond to 1V */
		if (selector < 3)
			selector = 0;
		else
			selector -= 2;

		step_mv = 100;
		break;
	case TPS65910_REG_VIO:
		return pmic->info[id]->table[selector] * 1000;
	default:
		return -EINVAL;
	}

	return (LDO_MIN_VOLT + selector * step_mv) * 1000;
}

/* Regulator ops (except VRTC) */
static struct regulator_ops tps65910_ops_dcdc = {
	.is_enabled		= tps65910_is_enabled,
@@ -596,10 +855,21 @@ static struct regulator_ops tps65910_ops = {
	.list_voltage		= tps65910_list_voltage,
};

static struct regulator_ops tps65911_ops = {
	.is_enabled		= tps65910_is_enabled,
	.enable			= tps65910_enable,
	.disable		= tps65910_disable,
	.set_mode		= tps65910_set_mode,
	.get_mode		= tps65910_get_mode,
	.get_voltage		= tps65911_get_voltage,
	.set_voltage_sel	= tps65911_set_voltage,
	.list_voltage		= tps65911_list_voltage,
};

static __devinit int tps65910_probe(struct platform_device *pdev)
{
	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
	struct tps_info *info = tps65910_regs;
	struct tps_info *info;
	struct regulator_init_data *reg_data;
	struct regulator_dev *rdev;
	struct tps65910_reg *pmic;
@@ -624,6 +894,18 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
	tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL,
				DEVCTRL_SR_CTL_I2C_SEL_MASK);

	switch(tps65910_chip_id(tps65910)) {
	case TPS65910:
		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
		info = tps65910_regs;
	case TPS65911:
		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
		info = tps65911_regs;
	default:
		pr_err("Invalid tps chip version\n");
		return -ENODEV;
	}

	for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) {
		/* Register the regulators */
		pmic->info[i] = info;
@@ -632,12 +914,19 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
		pmic->desc[i].id = i;
		pmic->desc[i].n_voltages = info->table_len;

		if ((i == TPS65910_REG_VDD1) || (i == TPS65910_REG_VDD2))
		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
			pmic->desc[i].ops = &tps65910_ops_dcdc;
		else if (i == TPS65910_REG_VDD3)
		} else if (i == TPS65910_REG_VDD3) {
			if (tps65910_chip_id(tps65910) == TPS65910)
				pmic->desc[i].ops = &tps65910_ops_vdd3;
			else
				pmic->desc[i].ops = &tps65910_ops_dcdc;
		} else {
			if (tps65910_chip_id(tps65910) == TPS65910)
				pmic->desc[i].ops = &tps65910_ops;
			else
				pmic->desc[i].ops = &tps65911_ops;
		}

		pmic->desc[i].type = REGULATOR_VOLTAGE;
		pmic->desc[i].owner = THIS_MODULE;
+9 −1
Original line number Diff line number Diff line
@@ -232,7 +232,6 @@
#define VDD2_OP_SEL_MASK				0x7F
#define VDD2_OP_SEL_SHIFT				0


/*Register VDD2_SR  (0x80) register.RegisterDescription */
#define VDD2_SR_SEL_MASK				0x7F
#define VDD2_SR_SEL_SHIFT				0
@@ -249,6 +248,8 @@
#define VDD3_CKINEN_SHIFT				2
#define VDD3_ST_MASK					0x03
#define VDD3_ST_SHIFT					0
#define VDDCTRL_MIN_VOLT				6000
#define VDDCTRL_OFFSET					125

/*Registers VDIG (0x80) to VDAC register.RegisterDescription */
#define LDO_SEL_MASK					0x0C
@@ -259,6 +260,13 @@
#define LDO_ST_MODE_BIT					0x02	


/* Registers LDO1 to LDO8 in tps65910 */
#define LDO1_SEL_MASK					0xFC
#define LDO3_SEL_MASK					0x7C
#define LDO_MIN_VOLT					1000
#define LDO_MAX_VOLT					3300;


/*Register VDIG1  (0x80) register.RegisterDescription */
#define VDIG1_SEL_MASK					0x0C
#define VDIG1_SEL_SHIFT					2