ASoC: rt9120: Fix clock auto sync issue when fs is the multiple of 48
If fs is divided by 48, to make audio clock sync rate correct, internal
sync function have be disabled.
Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
Link: https://lore.kernel.org/r/1636515921-31694-3-git-send-email-u0084500@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
diff --git a/sound/soc/codecs/rt9120.c b/sound/soc/codecs/rt9120.c
index 032c520..981aead 100644
--- a/sound/soc/codecs/rt9120.c
+++ b/sound/soc/codecs/rt9120.c
@@ -26,6 +26,7 @@
#define RT9120_REG_INTERNAL0 0x65
#define RT9120_REG_INTERNAL1 0x69
#define RT9120_REG_UVPOPT 0x6C
+#define RT9120_REG_DIGCFG 0xF8
#define RT9120_VID_MASK GENMASK(15, 8)
#define RT9120_SWRST_MASK BIT(7)
@@ -46,6 +47,7 @@
#define RT9120_CFG_WORDLEN_24 24
#define RT9120_CFG_WORDLEN_32 32
#define RT9120_DVDD_UVSEL_MASK GENMASK(5, 4)
+#define RT9120_AUTOSYNC_MASK BIT(6)
#define RT9120_VENDOR_ID 0x4200
#define RT9120_RESET_WAITMS 20
@@ -200,8 +202,8 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *comp = dai->component;
- unsigned int param_width, param_slot_width;
- int width;
+ unsigned int param_width, param_slot_width, auto_sync;
+ int width, fs;
switch (width = params_width(param)) {
case 16:
@@ -239,6 +241,16 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream,
snd_soc_component_update_bits(comp, RT9120_REG_I2SWL,
RT9120_AUDWL_MASK, param_slot_width);
+
+ fs = width * params_channels(param);
+ /* If fs is divided by 48, disable auto sync */
+ if (fs % 48 == 0)
+ auto_sync = 0;
+ else
+ auto_sync = RT9120_AUTOSYNC_MASK;
+
+ snd_soc_component_update_bits(comp, RT9120_REG_DIGCFG,
+ RT9120_AUTOSYNC_MASK, auto_sync);
return 0;
}
@@ -280,7 +292,8 @@ static const struct regmap_range rt9120_rd_yes_ranges[] = {
regmap_reg_range(0x3A, 0x40),
regmap_reg_range(0x65, 0x65),
regmap_reg_range(0x69, 0x69),
- regmap_reg_range(0x6C, 0x6C)
+ regmap_reg_range(0x6C, 0x6C),
+ regmap_reg_range(0xF8, 0xF8)
};
static const struct regmap_access_table rt9120_rd_table = {
@@ -298,7 +311,8 @@ static const struct regmap_range rt9120_wr_yes_ranges[] = {
regmap_reg_range(0x40, 0x40),
regmap_reg_range(0x65, 0x65),
regmap_reg_range(0x69, 0x69),
- regmap_reg_range(0x6C, 0x6C)
+ regmap_reg_range(0x6C, 0x6C),
+ regmap_reg_range(0xF8, 0xF8)
};
static const struct regmap_access_table rt9120_wr_table = {
@@ -369,7 +383,7 @@ static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val)
static const struct regmap_config rt9120_regmap_config = {
.reg_bits = 8,
.val_bits = 32,
- .max_register = RT9120_REG_UVPOPT,
+ .max_register = RT9120_REG_DIGCFG,
.reg_read = rt9120_reg_read,
.reg_write = rt9120_reg_write,