From 9e0538ec5a64009aea7382c10760c8257fc0fac3 Mon Sep 17 00:00:00 2001 From: Xingyu Wu Date: Mon, 29 Aug 2022 11:25:31 +0800 Subject: [PATCH] sound:i2s:wm8960:Support mono 16bit mono:support rate from 16k to 48k. 32bit mono:supoort rate from 22k to 48k. Signed-off-by: Xingyu Wu --- sound/soc/codecs/wm8960.c | 16 ++++++++-------- sound/soc/dwc/dwc-i2s.c | 34 +++++++++++++--------------------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d32ffc8..4368873 100755 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -940,15 +940,15 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream, snd_soc_component_write(component, WM8960_BYPASS1, 0x00); snd_soc_component_write(component, WM8960_BYPASS2, 0x00); snd_soc_component_update_bits(component, WM8960_ADDCTL4, 0x73, 0); - } else { + if (params_channels(params) == 1) - snd_soc_component_write(component, WM8960_LOUT1, 0x100); - else { - if (snd_soc_component_read(component, WM8960_LOUT1) & 0x7f) - snd_soc_component_update_bits(component, WM8960_LOUT1, 0x100, 0x100); - else - snd_soc_component_write(component, WM8960_LOUT1, 0x170); - } + wm8960->lrclk /= 2; + } else { + if (params_channels(params) == 1) { + snd_soc_component_update_bits(component, WM8960_ADDCTL1, 0x10, 0x10); + wm8960->lrclk /= 2; + } else + snd_soc_component_update_bits(component, WM8960_ADDCTL1, 0x10, 0); } } diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index d21ffc6..c6aaeec 100755 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -252,10 +252,11 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, dai_link->stop_dma_first = 1; config->chan_nr = params_channels(params); + config->sample_rate = params_rate(params); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - if (params_rate(params) == 8000) { + if (config->sample_rate == 8000) { dev_err(dev->dev, "I2S: unsupported 8000 rate with S16_LE, Stereo.\n"); return -EINVAL; } @@ -276,25 +277,18 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, break; case SNDRV_PCM_FORMAT_S32_LE: - if (config->chan_nr == 1) { - if (txrx == SNDRV_PCM_STREAM_PLAYBACK) - dev->play_dma_data.dt.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; - else - dev->capture_dma_data.dt.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; - - config->data_width = 16; - dev->ccr = 0x00; - dev->xfer_resolution = 0x02; - } else if (config->chan_nr == 2) { - if (txrx == SNDRV_PCM_STREAM_PLAYBACK) - dev->play_dma_data.dt.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - else - dev->capture_dma_data.dt.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - - config->data_width = 32; - dev->ccr = 0x10; - dev->xfer_resolution = 0x05; + if ((config->sample_rate == 16000) && (config->chan_nr == 1)) { + dev_err(dev->dev, "I2S: unsupported 16000 rate with S32_LE, Mono.\n"); + return -EINVAL; } + if (txrx == SNDRV_PCM_STREAM_PLAYBACK) + dev->play_dma_data.dt.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + else + dev->capture_dma_data.dt.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + + config->data_width = 32; + dev->ccr = 0x10; + dev->xfer_resolution = 0x05; break; default: @@ -369,8 +363,6 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, i2s_write_reg(dev->i2s_base, CCR, dev->ccr); - config->sample_rate = params_rate(params); - if (dev->capability & DW_I2S_MASTER) { if (dev->i2s_clk_cfg) { ret = dev->i2s_clk_cfg(config); -- 2.7.4