[PATCH 1/4] ASoC: tegra: Fix the I2S enable default value
Jon Hunter <[email protected]>
| Newsgroups | org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
Commit 4b05ccb17f92 ("regcache: Sort the local copy of an unsorted
reg_defaults array") exposed an issue in the Tegra I2S driver where the
register default for the TEGRA210_I2S_ENABLE is specified as 1, but the
hardware default is actually 0. After commit 4b05ccb17f92 was added the
I2S playback/capture is no longer working and so fix this by correcting
the default value for this register and explicitly configuring the
I2S_ENABLE register when runtime resuming the I2S device.
The I2S_ENABLE register offset is different on Tegra264 devices than
other Tegra devices and so add a 'enable_reg' variable to the SoC data
structure to specify the offset for different SoC devices.
Fixes: c0bfa98349d1 ("ASoC: tegra: Add Tegra210 based I2S driver")
Cc: [email protected]
Signed-off-by: Jon Hunter <[email protected]>
---
sound/soc/tegra/tegra210_i2s.c | 19 ++++++++++++++++---
sound/soc/tegra/tegra210_i2s.h | 1 +
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c
index 84506576437d..a1dd99e67a35 100644
--- a/sound/soc/tegra/tegra210_i2s.c
+++ b/sound/soc/tegra/tegra210_i2s.c
@@ -23,7 +23,7 @@ static const struct reg_default tegra210_i2s_reg_defaults[] = {
{ TEGRA210_I2S_RX_CIF_CTRL, 0x00007700 },
{ TEGRA210_I2S_TX_INT_MASK, 0x00000003 },
{ TEGRA210_I2S_TX_CIF_CTRL, 0x00007700 },
- { TEGRA210_I2S_ENABLE, 0x1 },
+ { TEGRA210_I2S_ENABLE, 0x0 },
{ TEGRA210_I2S_CG, 0x1 },
{ TEGRA210_I2S_TIMING, 0x0000001f },
/*
@@ -42,7 +42,7 @@ static const struct reg_default tegra264_i2s_reg_defaults[] = {
{ TEGRA264_I2S_TX_INT_MASK, 0x00000003 },
{ TEGRA264_I2S_TX_CIF_CTRL, 0x00003f00 },
{ TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE, 0x1 },
- { TEGRA264_I2S_ENABLE, 0x1 },
+ { TEGRA264_I2S_ENABLE, 0x0 },
{ TEGRA264_I2S_CG, 0x1 },
{ TEGRA264_I2S_TIMING, 0x0000001f },
};
@@ -201,9 +201,20 @@ static int tegra210_i2s_runtime_resume(struct device *dev)
}
regcache_cache_only(i2s->regmap, false);
- regcache_sync(i2s->regmap);
+ err = regcache_sync(i2s->regmap);
+ if (err)
+ goto disable_clk;
+
+ err = regmap_write(i2s->regmap, i2s->soc_data->enable_reg, I2S_EN);
+ if (err)
+ goto disable_clk;
return 0;
+
+disable_clk:
+ clk_disable_unprepare(i2s->clk_i2s);
+
+ return err;
}
static void tegra210_i2s_set_data_offset(struct tegra210_i2s *i2s,
@@ -1133,6 +1144,7 @@ static const struct tegra_i2s_soc_data soc_data_tegra210 = {
.regmap_conf = &tegra210_regmap_conf,
.i2s_cmpnt = &tegra210_i2s_cmpnt,
.max_ch = TEGRA210_I2S_MAX_CHANNEL,
+ .enable_reg = TEGRA210_I2S_ENABLE,
.tx_offset = TEGRA210_I2S_TX_OFFSET,
.i2s_ctrl_offset = TEGRA210_I2S_CTRL_OFFSET,
.fsync_width_mask = I2S_CTRL_FSYNC_WIDTH_MASK,
@@ -1144,6 +1156,7 @@ static const struct tegra_i2s_soc_data soc_data_tegra264 = {
.regmap_conf = &tegra264_regmap_conf,
.i2s_cmpnt = &tegra264_i2s_cmpnt,
.max_ch = TEGRA264_I2S_MAX_CHANNEL,
+ .enable_reg = TEGRA264_I2S_ENABLE,
.tx_offset = TEGRA264_I2S_TX_OFFSET,
.i2s_ctrl_offset = TEGRA264_I2S_CTRL_OFFSET,
.fsync_width_mask = TEGRA264_I2S_CTRL_FSYNC_WIDTH_MASK,
diff --git a/sound/soc/tegra/tegra210_i2s.h b/sound/soc/tegra/tegra210_i2s.h
index 42be2137342c..82292f96ab36 100644
--- a/sound/soc/tegra/tegra210_i2s.h
+++ b/sound/soc/tegra/tegra210_i2s.h
@@ -150,6 +150,7 @@ struct tegra_i2s_soc_data {
const struct regmap_config *regmap_conf;
const struct snd_soc_component_driver *i2s_cmpnt;
unsigned int max_ch;
+ unsigned int enable_reg;
unsigned int tx_offset;
unsigned int i2s_ctrl_offset;
unsigned int fsync_width_mask;
--
2.43.0