@@ -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 */
@@ -658,6 +658,60 @@ 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_DSP1_CCM_CORE_CTRL, 0x00000000 },
+ { 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_DSP1_CCM_CORE_CTRL, 0x00000000 },
+ { 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_DSP1_CCM_CORE_CTRL, 0x00000000 },
+ { CS35L41_PWR_CTRL2, 0x00000000 },
+ { CS35L41_AMP_GAIN_CTRL, 0x00000000 },
+};
+
static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = {
{
.id = 0x01,
@@ -844,6 +898,40 @@ 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)
+{
+ int ret = 0;
+ char *rev;
+
+ 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);
+
+ 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>");
@@ -1271,60 +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_DSP1_CCM_CORE_CTRL, 0x00000000 },
- { 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_DSP1_CCM_CORE_CTRL, 0x00000000 },
- { 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_DSP1_CCM_CORE_CTRL, 0x00000000 },
- { 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 },
@@ -1504,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);
- goto err;
- }
- break;
- }
+ ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid);
+ if (ret)
+ goto err;
irq_pol = cs35l41_irq_gpio_config(cs35l41);
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 Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> --- include/sound/cs35l41.h | 1 + sound/soc/codecs/cs35l41-lib.c | 88 +++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41.c | 89 ++-------------------------------- 3 files changed, 92 insertions(+), 86 deletions(-)