summaryrefslogtreecommitdiff
path: root/sound/soc/rockchip/rockchip_i2s_tdm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/rockchip/rockchip_i2s_tdm.c')
-rw-r--r--sound/soc/rockchip/rockchip_i2s_tdm.c94
1 files changed, 50 insertions, 44 deletions
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
index 9fa020ef7eab..d9a1fab7f403 100644
--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -22,7 +22,6 @@
#define DRV_NAME "rockchip-i2s-tdm"
-#define DEFAULT_MCLK_FS 256
#define CH_GRP_MAX 4 /* The max channel 8 / 2 */
#define MULTIPLEX_CH_MAX 10
@@ -70,6 +69,8 @@ struct rk_i2s_tdm_dev {
bool has_playback;
bool has_capture;
struct snd_soc_dai_driver *dai;
+ unsigned int mclk_rx_freq;
+ unsigned int mclk_tx_freq;
};
static int to_ch_num(unsigned int val)
@@ -121,7 +122,7 @@ err_mclk_tx:
return ret;
}
-static int __maybe_unused i2s_tdm_runtime_suspend(struct device *dev)
+static int i2s_tdm_runtime_suspend(struct device *dev)
{
struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
@@ -133,7 +134,7 @@ static int __maybe_unused i2s_tdm_runtime_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused i2s_tdm_runtime_resume(struct device *dev)
+static int i2s_tdm_runtime_resume(struct device *dev)
{
struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
int ret;
@@ -450,11 +451,11 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
break;
case SND_SOC_DAIFMT_DSP_A:
val = I2S_TXCR_TFS_TDM_PCM;
- tdm_val = TDM_SHIFT_CTRL(0);
+ tdm_val = TDM_SHIFT_CTRL(2);
break;
case SND_SOC_DAIFMT_DSP_B:
val = I2S_TXCR_TFS_TDM_PCM;
- tdm_val = TDM_SHIFT_CTRL(2);
+ tdm_val = TDM_SHIFT_CTRL(4);
break;
default:
ret = -EINVAL;
@@ -514,33 +515,6 @@ static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream,
I2S_XFER_RXS_START);
}
-static int rockchip_i2s_ch_to_io(unsigned int ch, bool substream_capture)
-{
- if (substream_capture) {
- switch (ch) {
- case I2S_CHN_4:
- return I2S_IO_6CH_OUT_4CH_IN;
- case I2S_CHN_6:
- return I2S_IO_4CH_OUT_6CH_IN;
- case I2S_CHN_8:
- return I2S_IO_2CH_OUT_8CH_IN;
- default:
- return I2S_IO_8CH_OUT_2CH_IN;
- }
- } else {
- switch (ch) {
- case I2S_CHN_4:
- return I2S_IO_4CH_OUT_6CH_IN;
- case I2S_CHN_6:
- return I2S_IO_6CH_OUT_4CH_IN;
- case I2S_CHN_8:
- return I2S_IO_8CH_OUT_2CH_IN;
- default:
- return I2S_IO_2CH_OUT_8CH_IN;
- }
- }
-}
-
static int rockchip_i2s_io_multiplex(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -577,7 +551,6 @@ static int rockchip_i2s_io_multiplex(struct snd_pcm_substream *substream,
return -EINVAL;
}
- rockchip_i2s_ch_to_io(val, true);
} else {
struct snd_pcm_str *capture_str =
&substream->pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -645,6 +618,27 @@ static int rockchip_i2s_trcm_mode(struct snd_pcm_substream *substream,
return 0;
}
+static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
+ unsigned int freq, int dir)
+{
+ struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+
+ if (i2s_tdm->clk_trcm) {
+ i2s_tdm->mclk_tx_freq = freq;
+ i2s_tdm->mclk_rx_freq = freq;
+ } else {
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ i2s_tdm->mclk_tx_freq = freq;
+ else
+ i2s_tdm->mclk_rx_freq = freq;
+ }
+
+ dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n",
+ stream ? "rx" : "tx", freq);
+
+ return 0;
+}
+
static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -655,10 +649,23 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
int err;
if (i2s_tdm->is_master_mode) {
- struct clk *mclk = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- i2s_tdm->mclk_tx : i2s_tdm->mclk_rx;
+ struct clk *mclk;
+
+ if (i2s_tdm->clk_trcm == TRCM_TX) {
+ mclk = i2s_tdm->mclk_tx;
+ mclk_rate = i2s_tdm->mclk_tx_freq;
+ } else if (i2s_tdm->clk_trcm == TRCM_RX) {
+ mclk = i2s_tdm->mclk_rx;
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ mclk = i2s_tdm->mclk_tx;
+ mclk_rate = i2s_tdm->mclk_tx_freq;
+ } else {
+ mclk = i2s_tdm->mclk_rx;
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ }
- err = clk_set_rate(mclk, DEFAULT_MCLK_FS * params_rate(params));
+ err = clk_set_rate(mclk, mclk_rate);
if (err)
return err;
@@ -818,6 +825,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = {
.hw_params = rockchip_i2s_tdm_hw_params,
.set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio,
.set_fmt = rockchip_i2s_tdm_set_fmt,
+ .set_sysclk = rockchip_i2s_tdm_set_sysclk,
.set_tdm_slot = rockchip_dai_tdm_slot,
.trigger = rockchip_i2s_tdm_trigger,
};
@@ -1382,7 +1390,7 @@ static void rockchip_i2s_tdm_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
}
-static int __maybe_unused rockchip_i2s_tdm_suspend(struct device *dev)
+static int rockchip_i2s_tdm_suspend(struct device *dev)
{
struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
@@ -1391,7 +1399,7 @@ static int __maybe_unused rockchip_i2s_tdm_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused rockchip_i2s_tdm_resume(struct device *dev)
+static int rockchip_i2s_tdm_resume(struct device *dev)
{
struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
int ret;
@@ -1406,19 +1414,17 @@ static int __maybe_unused rockchip_i2s_tdm_resume(struct device *dev)
}
static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops = {
- SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume,
- NULL)
- SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend,
- rockchip_i2s_tdm_resume)
+ RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend, rockchip_i2s_tdm_resume)
};
static struct platform_driver rockchip_i2s_tdm_driver = {
.probe = rockchip_i2s_tdm_probe,
- .remove_new = rockchip_i2s_tdm_remove,
+ .remove = rockchip_i2s_tdm_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = rockchip_i2s_tdm_match,
- .pm = &rockchip_i2s_tdm_pm_ops,
+ .pm = pm_ptr(&rockchip_i2s_tdm_pm_ops),
},
};
module_platform_driver(rockchip_i2s_tdm_driver);