Unverified Commit c5187a24 authored by Adam Ward's avatar Adam Ward Committed by Mark Brown
Browse files

regulator: da9121: Add DA914x support



Add the DA9141 and DA9142 regulators device recognition data and
operational parameters.

Signed-off-by: default avatarAdam Ward <Adam.Ward.opensource@diasemi.com>
Link: https://lore.kernel.org/r/5f5b9b02f07578cd36c6bc266349a56efc9b08d1.1638223185.git.Adam.Ward.opensource@diasemi.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 24f08532
Loading
Loading
Loading
Loading
+105 −3
Original line number Diff line number Diff line
@@ -86,6 +86,22 @@ static struct da9121_range da9121_3A_1phase_current = {
	.reg_max = 6,
};

static struct da9121_range da914x_40A_4phase_current = {
	.val_min = 14000000,
	.val_max = 80000000,
	.val_stp =  2000000,
	.reg_min = 1,
	.reg_max = 14,
};

static struct da9121_range da914x_20A_2phase_current = {
	.val_min =  7000000,
	.val_max = 40000000,
	.val_stp =  2000000,
	.reg_min = 1,
	.reg_max = 14,
};

struct da9121_variant_info {
	int num_bucks;
	int num_phases;
@@ -97,6 +113,8 @@ static const struct da9121_variant_info variant_parameters[] = {
	{ 2, 1, &da9121_3A_1phase_current  },	//DA9121_TYPE_DA9220_DA9132
	{ 2, 1, &da9121_5A_1phase_current  },	//DA9121_TYPE_DA9122_DA9131
	{ 1, 2, &da9121_6A_2phase_current  },	//DA9121_TYPE_DA9217
	{ 1, 4, &da914x_40A_4phase_current },   //DA9121_TYPE_DA9141
	{ 1, 2, &da914x_20A_2phase_current },   //DA9121_TYPE_DA9142
};

struct da9121_field {
@@ -542,11 +560,65 @@ static const struct regulator_desc da9217_reg = {
	.vsel_mask = DA9121_MASK_BUCK_BUCKx_5_CHx_A_VOUT,
};

#define DA914X_MIN_MV		500
#define DA914X_MAX_MV		1000
#define DA914X_STEP_MV		10
#define DA914X_MIN_SEL		(DA914X_MIN_MV / DA914X_STEP_MV)
#define DA914X_N_VOLTAGES	(((DA914X_MAX_MV - DA914X_MIN_MV) / DA914X_STEP_MV) \
				 + 1 + DA914X_MIN_SEL)

static const struct regulator_desc da9141_reg = {
	.id = DA9121_IDX_BUCK1,
	.name = "DA9141",
	.of_match = "buck1",
	.of_parse_cb = da9121_of_parse_cb,
	.owner = THIS_MODULE,
	.regulators_node = of_match_ptr("regulators"),
	.of_map_mode = da9121_map_mode,
	.ops = &da9121_buck_ops,
	.type = REGULATOR_VOLTAGE,
	.n_voltages = DA914X_N_VOLTAGES,
	.min_uV = DA914X_MIN_MV * 1000,
	.uV_step = DA914X_STEP_MV * 1000,
	.linear_min_sel = DA914X_MIN_SEL,
	.vsel_reg = DA9121_REG_BUCK_BUCK1_5,
	.vsel_mask = DA9121_MASK_BUCK_BUCKx_5_CHx_A_VOUT,
	.enable_reg = DA9121_REG_BUCK_BUCK1_0,
	.enable_mask = DA9121_MASK_BUCK_BUCKx_0_CHx_EN,
	/* Default value of BUCK_BUCK1_0.CH1_SRC_DVC_UP */
	.ramp_delay = 20000,
	/* tBUCK_EN */
	.enable_time = 20,
};

static const struct regulator_desc da9142_reg = {
	.id = DA9121_IDX_BUCK1,
	.name = "DA9142 BUCK1",
	.of_match = "buck1",
	.of_parse_cb = da9121_of_parse_cb,
	.owner = THIS_MODULE,
	.regulators_node = of_match_ptr("regulators"),
	.of_map_mode = da9121_map_mode,
	.ops = &da9121_buck_ops,
	.type = REGULATOR_VOLTAGE,
	.n_voltages = DA914X_N_VOLTAGES,
	.min_uV = DA914X_MIN_MV * 1000,
	.uV_step = DA914X_STEP_MV * 1000,
	.linear_min_sel = DA914X_MIN_SEL,
	.enable_reg = DA9121_REG_BUCK_BUCK1_0,
	.enable_mask = DA9121_MASK_BUCK_BUCKx_0_CHx_EN,
	.vsel_reg = DA9121_REG_BUCK_BUCK1_5,
	.vsel_mask = DA9121_MASK_BUCK_BUCKx_5_CHx_A_VOUT,
};


static const struct regulator_desc *local_da9121_regulators[][DA9121_IDX_MAX] = {
	[DA9121_TYPE_DA9121_DA9130] = { &da9121_reg, NULL },
	[DA9121_TYPE_DA9220_DA9132] = { &da9220_reg[0], &da9220_reg[1] },
	[DA9121_TYPE_DA9122_DA9131] = { &da9122_reg[0], &da9122_reg[1] },
	[DA9121_TYPE_DA9217] = { &da9217_reg, NULL },
	[DA9121_TYPE_DA9141] = { &da9141_reg, NULL },
	[DA9121_TYPE_DA9142] = { &da9142_reg, NULL },
};

static void da9121_status_poll_on(struct work_struct *work)
@@ -840,7 +912,7 @@ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
		goto error;
	}

	if (device_id != DA9121_DEVICE_ID) {
	if ((device_id != DA9121_DEVICE_ID) && (device_id != DA914x_DEVICE_ID)) {
		dev_err(chip->dev, "Invalid device ID: 0x%02x\n", device_id);
		ret = -ENODEV;
		goto error;
@@ -882,6 +954,22 @@ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
		break;
	}

	if (device_id == DA914x_DEVICE_ID) {
		switch (chip->subvariant_id) {
		case DA9121_SUBTYPE_DA9141:
			type = "DA9141";
			config_match = (variant_vrc == DA9141_VARIANT_VRC);
			break;
		case DA9121_SUBTYPE_DA9142:
			type = "DA9142";
			config_match = (variant_vrc == DA9142_VARIANT_VRC);
			break;
		default:
			type = "Unknown";
			break;
		}
	}

	dev_info(chip->dev,
		 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
		 device_id, variant_id, type);
@@ -895,8 +983,10 @@ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
	variant_mrc = (variant_id & DA9121_MASK_OTP_VARIANT_ID_MRC)
			>> DA9121_SHIFT_OTP_VARIANT_ID_MRC;

	if ((device_id == DA9121_DEVICE_ID) &&
	    (variant_mrc < DA9121_VARIANT_MRC_BASE)) {
	if (((device_id == DA9121_DEVICE_ID) &&
	     (variant_mrc < DA9121_VARIANT_MRC_BASE)) ||
	    ((device_id == DA914x_DEVICE_ID) &&
	     (variant_mrc != DA914x_VARIANT_MRC_BASE))) {
		dev_err(chip->dev,
			"Cannot support variant MRC: 0x%02X\n", variant_mrc);
		ret = -EINVAL;
@@ -936,6 +1026,14 @@ static int da9121_assign_chip_model(struct i2c_client *i2c,
		chip->variant_id = DA9121_TYPE_DA9220_DA9132;
		regmap = &da9121_2ch_regmap_config;
		break;
	case DA9121_SUBTYPE_DA9141:
		chip->variant_id = DA9121_TYPE_DA9141;
		regmap = &da9121_1ch_regmap_config;
		break;
	case DA9121_SUBTYPE_DA9142:
		chip->variant_id = DA9121_TYPE_DA9142;
		regmap = &da9121_2ch_regmap_config;
		break;
	}

	/* Set these up for of_regulator_match call which may want .of_map_modes */
@@ -1015,6 +1113,8 @@ static const struct of_device_id da9121_dt_ids[] = {
	{ .compatible = "dlg,da9131", .data = (void *) DA9121_SUBTYPE_DA9131 },
	{ .compatible = "dlg,da9220", .data = (void *) DA9121_SUBTYPE_DA9220 },
	{ .compatible = "dlg,da9132", .data = (void *) DA9121_SUBTYPE_DA9132 },
	{ .compatible = "dlg,da9141", .data = (void *) DA9121_SUBTYPE_DA9141 },
	{ .compatible = "dlg,da9142", .data = (void *) DA9121_SUBTYPE_DA9142 },
	{ }
};
MODULE_DEVICE_TABLE(of, da9121_dt_ids);
@@ -1089,6 +1189,8 @@ static const struct i2c_device_id da9121_i2c_id[] = {
	{"da9131", DA9121_TYPE_DA9122_DA9131},
	{"da9220", DA9121_TYPE_DA9220_DA9132},
	{"da9132", DA9121_TYPE_DA9220_DA9132},
	{"da9141", DA9121_TYPE_DA9141},
	{"da9142", DA9121_TYPE_DA9142},
	{},
};
MODULE_DEVICE_TABLE(i2c, da9121_i2c_id);
+19 −2
Original line number Diff line number Diff line
@@ -26,7 +26,9 @@ enum da9121_variant {
	DA9121_TYPE_DA9121_DA9130,
	DA9121_TYPE_DA9220_DA9132,
	DA9121_TYPE_DA9122_DA9131,
	DA9121_TYPE_DA9217
	DA9121_TYPE_DA9217,
	DA9121_TYPE_DA9141,
	DA9121_TYPE_DA9142
};

enum da9121_subvariant {
@@ -36,7 +38,9 @@ enum da9121_subvariant {
	DA9121_SUBTYPE_DA9132,
	DA9121_SUBTYPE_DA9122,
	DA9121_SUBTYPE_DA9131,
	DA9121_SUBTYPE_DA9217
	DA9121_SUBTYPE_DA9217,
	DA9121_SUBTYPE_DA9141,
	DA9121_SUBTYPE_DA9142
};

/* Minimum, maximum and default polling millisecond periods are provided
@@ -70,6 +74,14 @@ enum da9121_subvariant {
#define DA9121_REG_SYS_GPIO1_1		0x13
#define DA9121_REG_SYS_GPIO2_0		0x14
#define DA9121_REG_SYS_GPIO2_1		0x15
#define DA914x_REG_SYS_GPIO3_0		0x16
#define DA914x_REG_SYS_GPIO3_1		0x17
#define DA914x_REG_SYS_GPIO4_0		0x18
#define DA914x_REG_SYS_GPIO4_1		0x19
#define DA914x_REG_SYS_ADMUX1_0		0x1A
#define DA914x_REG_SYS_ADMUX1_1		0x1B
#define DA914x_REG_SYS_ADMUX2_0		0x1C
#define DA914x_REG_SYS_ADMUX2_1		0x1D
#define DA9121_REG_BUCK_BUCK1_0		0x20
#define DA9121_REG_BUCK_BUCK1_1		0x21
#define DA9121_REG_BUCK_BUCK1_2		0x22
@@ -276,6 +288,7 @@ enum da9121_subvariant {
#define DA9121_MASK_OTP_DEVICE_ID_DEV_ID		0xFF

#define DA9121_DEVICE_ID	0x05
#define DA914x_DEVICE_ID	0x26

/* DA9121_REG_OTP_VARIANT_ID */

@@ -293,6 +306,10 @@ enum da9121_subvariant {
#define DA9131_VARIANT_VRC	0x1
#define DA9132_VARIANT_VRC	0x2

#define DA914x_VARIANT_MRC_BASE	0x0
#define DA9141_VARIANT_VRC	0x1
#define DA9142_VARIANT_VRC	0x2

/* DA9121_REG_OTP_CUSTOMER_ID */

#define DA9121_MASK_OTP_CUSTOMER_ID_CUST_ID		0xFF