diff options
author | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2019-09-09 15:04:37 +0300 |
---|---|---|
committer | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2019-09-09 15:04:37 +0300 |
commit | babaf479582f7697fbfd4c001945fbfb766d914d (patch) | |
tree | 076e1b1edfa8c2497e67dcc9c0ebc2764dae5aef | |
parent | d26e03d1e61da1ba12f0fb84d5ee13a8810c0d59 (diff) |
apalis/colibri t30: fix record/playback for sgtl5000 codec
Backported commit f997df18c0e4c988de49e984329cefdf6e13ed86
According to the manual [1], SYS_MCLK should base on SYS_FS, not on sample rate.
Calculating SYS_MCLK using sample rate only prevents playing/recording
samples with rate < 16 kHz:
---------------------------------------------------------------
root@apalis-t30:~# aplay test-8k-sample.wav
Playing WAVE 'test-8k-sample.wav' : Signed 16 bit
[...] tegra-snd-apalis-tk1-sgtl5000 tegra-snd-apalis-tk1-sgtl5000.0: ASoC: machine hw_params failed: -22
Little Endian, Rate 8000 Hz, Stereo
aplay: set_params:1403: Unable to install hw params:
...
---------------------------------------------------------------
Using the helper from sgtl5000.h fixes this issue.
To keep determination of sys_fs solid, use a helper in device driver.
[1] https://www.nxp.com/docs/en/data-sheet/SGTL5000.pdf
Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
-rw-r--r-- | sound/soc/codecs/sgtl5000.c | 22 | ||||
-rw-r--r-- | sound/soc/tegra/apalis_t30.c | 16 |
2 files changed, 7 insertions, 31 deletions
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index b2228e0f5472..22f76d4895dc 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -732,27 +732,13 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate) int clk_ctl = 0; int sys_fs; /* sample freq */ - /* - * sample freq should be divided by frame clock, - * if frame clock lower than 44.1khz, sample feq should set to - * 32khz or 44.1khz. - */ - switch (frame_rate) { - case 8000: - case 16000: - sys_fs = 32000; - break; - case 11025: - case 22050: - sys_fs = 44100; - break; - default: - sys_fs = frame_rate; - break; - } + sys_fs = sgtl5000_srate_to_sys_fs(frame_rate); /* set divided factor of frame clock */ switch (sys_fs / frame_rate) { + case 6: + clk_ctl |= SGTL5000_RATE_MODE_DIV_6 << SGTL5000_RATE_MODE_SHIFT; + break; case 4: clk_ctl |= SGTL5000_RATE_MODE_DIV_4 << SGTL5000_RATE_MODE_SHIFT; break; diff --git a/sound/soc/tegra/apalis_t30.c b/sound/soc/tegra/apalis_t30.c index e824f65df5a4..c1907a4f6c3e 100644 --- a/sound/soc/tegra/apalis_t30.c +++ b/sound/soc/tegra/apalis_t30.c @@ -65,20 +65,10 @@ static int apalis_t30_sgtl5000_hw_params(struct snd_pcm_substream *substream, int err; int rate; - /* sgtl5000 does not support 512*rate when in 96000 fs */ srate = params_rate(params); - switch (srate) { - case 96000: - mclk = 256 * srate; - break; - default: - mclk = 512 * srate; - break; - } - - /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */ - if (mclk < 8000000 || mclk > 27000000) - return -EINVAL; + mclk = sgtl5000_srate_to_mclk(srate); + if (IS_ERR_VALUE(mclk)) + return mclk; if(pdata->i2s_param[HIFI_CODEC].is_i2s_master) { i2s_daifmt = SND_SOC_DAIFMT_NB_NF | |