ASoC: meson: axg fixes and clean-up

Merge series from Jerome Brunet <jbrunet@baylibre.com>:

This are various fixes and clean up gathered while working on Amlogic audio
support. These help better handle higher and unusual clock configuration
for TDM, SPDIF or PDM.
This commit is contained in:
Mark Brown 2024-02-26 18:30:38 +00:00
commit b861437765
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
5 changed files with 36 additions and 19 deletions

View File

@ -21,8 +21,6 @@ struct snd_soc_dai_driver;
struct snd_soc_pcm_runtime;
#define AXG_FIFO_CH_MAX 128
#define AXG_FIFO_RATES (SNDRV_PCM_RATE_5512 | \
SNDRV_PCM_RATE_8000_384000)
#define AXG_FIFO_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_LE | \

View File

@ -109,7 +109,9 @@ static struct snd_soc_dai_driver axg_frddr_dai_drv = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = AXG_FIFO_CH_MAX,
.rates = AXG_FIFO_RATES,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5515,
.rate_max = 384000,
.formats = AXG_FIFO_FORMATS,
},
.ops = &axg_frddr_ops,
@ -184,7 +186,9 @@ static struct snd_soc_dai_driver g12a_frddr_dai_drv = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = AXG_FIFO_CH_MAX,
.rates = AXG_FIFO_RATES,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5515,
.rate_max = 384000,
.formats = AXG_FIFO_FORMATS,
},
.ops = &g12a_frddr_ops,

View File

@ -179,9 +179,9 @@ static int axg_spdifin_sample_mode_config(struct snd_soc_dai *dai,
SPDIFIN_CTRL1_BASE_TIMER,
FIELD_PREP(SPDIFIN_CTRL1_BASE_TIMER, rate / 1000));
/* Threshold based on the minimum width between two edges */
/* Threshold based on the maximum width between two edges */
regmap_update_bits(priv->map, SPDIFIN_CTRL0,
SPDIFIN_CTRL0_WIDTH_SEL, SPDIFIN_CTRL0_WIDTH_SEL);
SPDIFIN_CTRL0_WIDTH_SEL, 0);
/* Calculate the last timer which has no threshold */
t_next = axg_spdifin_mode_timer(priv, i, rate);
@ -199,7 +199,7 @@ static int axg_spdifin_sample_mode_config(struct snd_soc_dai *dai,
axg_spdifin_write_timer(priv->map, i, t);
/* Set the threshold value */
axg_spdifin_write_threshold(priv->map, i, t + t_next);
axg_spdifin_write_threshold(priv->map, i, 3 * (t + t_next));
/* Save the current timer for the next threshold calculation */
t_next = t;

View File

@ -12,6 +12,9 @@
#include "axg-tdm.h"
/* Maximum bit clock frequency according the datasheets */
#define MAX_SCLK 100000000 /* Hz */
enum {
TDM_IFACE_PAD,
TDM_IFACE_LOOPBACK,
@ -130,7 +133,7 @@ static int axg_tdm_iface_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
case SND_SOC_DAIFMT_BP_FC:
case SND_SOC_DAIFMT_BC_FP:
dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n");
dev_err(dai->dev, "only BP_FP and BC_FC are supported\n");
fallthrough;
default:
return -EINVAL;
@ -153,19 +156,27 @@ static int axg_tdm_iface_startup(struct snd_pcm_substream *substream,
return -EINVAL;
}
/* Apply component wide rate symmetry */
if (snd_soc_component_active(dai->component)) {
/* Apply component wide rate symmetry */
ret = snd_pcm_hw_constraint_single(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
iface->rate);
if (ret < 0) {
dev_err(dai->dev,
"can't set iface rate constraint\n");
return ret;
}
} else {
/* Limit rate according to the slot number and width */
unsigned int max_rate =
MAX_SCLK / (iface->slots * iface->slot_width);
ret = snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
0, max_rate);
}
return 0;
if (ret < 0)
dev_err(dai->dev, "can't set iface rate constraint\n");
else
ret = 0;
return ret;
}
static int axg_tdm_iface_set_stream(struct snd_pcm_substream *substream,
@ -264,8 +275,8 @@ static int axg_tdm_iface_set_sclk(struct snd_soc_dai *dai,
srate = iface->slots * iface->slot_width * params_rate(params);
if (!iface->mclk_rate) {
/* If no specific mclk is requested, default to bit clock * 4 */
clk_set_rate(iface->mclk, 4 * srate);
/* If no specific mclk is requested, default to bit clock * 2 */
clk_set_rate(iface->mclk, 2 * srate);
} else {
/* Check if we can actually get the bit clock from mclk */
if (iface->mclk_rate % srate) {

View File

@ -131,7 +131,9 @@ static struct snd_soc_dai_driver axg_toddr_dai_drv = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = AXG_FIFO_CH_MAX,
.rates = AXG_FIFO_RATES,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5515,
.rate_max = 384000,
.formats = AXG_FIFO_FORMATS,
},
.ops = &axg_toddr_ops,
@ -226,7 +228,9 @@ static struct snd_soc_dai_driver g12a_toddr_dai_drv = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = AXG_FIFO_CH_MAX,
.rates = AXG_FIFO_RATES,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5515,
.rate_max = 384000,
.formats = AXG_FIFO_FORMATS,
},
.ops = &g12a_toddr_ops,