Commit b8614377 authored by Mark Brown's avatar Mark Brown

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.
parents 306904db 8b410b3c
......@@ -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 | \
......
......@@ -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,
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment