Unverified Commit 8b227860 authored by Lucas Tanure's avatar Lucas Tanure Committed by Mark Brown
Browse files

ASoC: cs35l41: Create shared function for errata patches



ASoC and HDA systems require the same errata patches, so
move it to the shared code using a function the correctly
applies the patches by revision

Also, move CS35L41_DSP1_CCM_CORE_CTRL write to errata
patch function as is required to be written at boot,
but not in regmap_register_patch sequence as will affect
waking up from hibernation

Signed-off-by: default avatarLucas Tanure <tanureal@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211217115708.882525-5-tanureal@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 062ce059
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -763,5 +763,6 @@ extern struct regmap_config cs35l41_regmap_i2c;
extern struct regmap_config cs35l41_regmap_spi;

int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap);
int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid);

#endif /* __CS35L41_H */
+89 −0
Original line number Diff line number Diff line
@@ -659,6 +659,57 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM]
	{ 0x00017044,	0,	24 }, /*LOT_NUMBER*/
};

static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
	{ 0x00000040,			 0x00005555 },
	{ 0x00000040,			 0x0000AAAA },
	{ 0x00003854,			 0x05180240 },
	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
	{ 0x00004310,			 0x00000000 },
	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
	{ CS35L41_OTP_TRIM_30,		 0x9091A1C8 },
	{ 0x00003014,			 0x0200EE0E },
	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
	{ 0x00000054,			 0x00000004 },
	{ CS35L41_IRQ1_DB3,		 0x00000000 },
	{ CS35L41_IRQ2_DB3,		 0x00000000 },
	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
	{ 0x00000040,			 0x0000CCCC },
	{ 0x00000040,			 0x00003333 },
	{ CS35L41_PWR_CTRL2,		 0x00000000 },
	{ CS35L41_AMP_GAIN_CTRL,	 0x00000000 },
};

static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
	{ 0x00000040,			 0x00005555 },
	{ 0x00000040,			 0x0000AAAA },
	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
	{ 0x00004310,			 0x00000000 },
	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
	{ 0x00000040,			 0x0000CCCC },
	{ 0x00000040,			 0x00003333 },
	{ CS35L41_PWR_CTRL2,		 0x00000000 },
	{ CS35L41_AMP_GAIN_CTRL,	 0x00000000 },
};

static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
	{ 0x00000040,			 0x00005555 },
	{ 0x00000040,			 0x0000AAAA },
	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
	{ 0x00004310,			 0x00000000 },
	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
	{ 0x00000040,			 0x0000CCCC },
	{ 0x00000040,			 0x00003333 },
	{ CS35L41_PWR_CTRL2,		 0x00000000 },
	{ CS35L41_AMP_GAIN_CTRL,	 0x00000000 },
};

static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = {
	{
		.id = 0x01,
@@ -845,6 +896,44 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap)
}
EXPORT_SYMBOL_GPL(cs35l41_otp_unpack);

int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid)
{
	char *rev;
	int ret;

	switch (reg_revid) {
	case CS35L41_REVID_A0:
		ret = regmap_register_patch(reg, cs35l41_reva0_errata_patch,
					    ARRAY_SIZE(cs35l41_reva0_errata_patch));
		rev = "A0";
		break;
	case CS35L41_REVID_B0:
		ret = regmap_register_patch(reg, cs35l41_revb0_errata_patch,
					    ARRAY_SIZE(cs35l41_revb0_errata_patch));
		rev = "B0";
		break;
	case CS35L41_REVID_B2:
		ret = regmap_register_patch(reg, cs35l41_revb2_errata_patch,
					    ARRAY_SIZE(cs35l41_revb2_errata_patch));
		rev = "B2";
		break;
	default:
		ret = -EINVAL;
		rev = "XX";
		break;
	}

	if (ret)
		dev_err(dev, "Failed to apply %s errata patch: %d\n", rev, ret);

	ret = regmap_write(reg, CS35L41_DSP1_CCM_CORE_CTRL, 0);
	if (ret < 0)
		dev_err(dev, "Write CCM_CORE_CTRL failed: %d\n", ret);

	return ret;
}
EXPORT_SYMBOL_GPL(cs35l41_register_errata_patch);

MODULE_DESCRIPTION("CS35L41 library");
MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>");
+3 −89
Original line number Diff line number Diff line
@@ -1271,57 +1271,6 @@ static int cs35l41_handle_pdata(struct device *dev,
	return 0;
}

static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
	{ 0x00000040,			 0x00005555 },
	{ 0x00000040,			 0x0000AAAA },
	{ 0x00003854,			 0x05180240 },
	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
	{ 0x00004310,			 0x00000000 },
	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
	{ CS35L41_OTP_TRIM_30,		 0x9091A1C8 },
	{ 0x00003014,			 0x0200EE0E },
	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
	{ 0x00000054,			 0x00000004 },
	{ CS35L41_IRQ1_DB3,		 0x00000000 },
	{ CS35L41_IRQ2_DB3,		 0x00000000 },
	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
	{ 0x00000040,			 0x0000CCCC },
	{ 0x00000040,			 0x00003333 },
	{ CS35L41_PWR_CTRL2,		 0x00000000 },
	{ CS35L41_AMP_GAIN_CTRL,	 0x00000000 },
};

static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
	{ 0x00000040,			 0x00005555 },
	{ 0x00000040,			 0x0000AAAA },
	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
	{ 0x00004310,			 0x00000000 },
	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
	{ 0x00000040,			 0x0000CCCC },
	{ 0x00000040,			 0x00003333 },
	{ CS35L41_PWR_CTRL2,		 0x00000000 },
	{ CS35L41_AMP_GAIN_CTRL,	 0x00000000 },
};

static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
	{ 0x00000040,			 0x00005555 },
	{ 0x00000040,			 0x0000AAAA },
	{ CS35L41_VIMON_SPKMON_RESYNC,	 0x00000000 },
	{ 0x00004310,			 0x00000000 },
	{ CS35L41_VPVBST_FS_SEL,	 0x00000000 },
	{ CS35L41_BSTCVRT_DCM_CTRL,	 0x00000051 },
	{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
	{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
	{ 0x00000040,			 0x0000CCCC },
	{ 0x00000040,			 0x00003333 },
	{ CS35L41_PWR_CTRL2,		 0x00000000 },
	{ CS35L41_AMP_GAIN_CTRL,	 0x00000000 },
};

static const struct reg_sequence cs35l41_fs_errata_patch[] = {
	{ CS35L41_DSP1_RX1_RATE,	0x00000001 },
	{ CS35L41_DSP1_RX2_RATE,	0x00000001 },
@@ -1501,38 +1450,9 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
		goto err;
	}

	switch (reg_revid) {
	case CS35L41_REVID_A0:
		ret = regmap_register_patch(cs35l41->regmap,
					    cs35l41_reva0_errata_patch,
					    ARRAY_SIZE(cs35l41_reva0_errata_patch));
		if (ret < 0) {
			dev_err(cs35l41->dev,
				"Failed to apply A0 errata patch: %d\n", ret);
			goto err;
		}
		break;
	case CS35L41_REVID_B0:
		ret = regmap_register_patch(cs35l41->regmap,
					    cs35l41_revb0_errata_patch,
					    ARRAY_SIZE(cs35l41_revb0_errata_patch));
		if (ret < 0) {
			dev_err(cs35l41->dev,
				"Failed to apply B0 errata patch: %d\n", ret);
			goto err;
		}
		break;
	case CS35L41_REVID_B2:
		ret = regmap_register_patch(cs35l41->regmap,
					    cs35l41_revb2_errata_patch,
					    ARRAY_SIZE(cs35l41_revb2_errata_patch));
		if (ret < 0) {
			dev_err(cs35l41->dev,
				"Failed to apply B2 errata patch: %d\n", ret);
	ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid);
	if (ret)
		goto err;
		}
		break;
	}

	irq_pol = cs35l41_irq_gpio_config(cs35l41);

@@ -1556,12 +1476,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
		goto err;
	}

	ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0);
	if (ret < 0) {
		dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret);
		goto err;
	}

	ret = cs35l41_set_pdata(cs35l41);
	if (ret < 0) {
		dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);