Skip to content

Commit b861437

Browse files
committed
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.
2 parents 306904d + 8b410b3 commit b861437

File tree

5 files changed

+36
-19
lines changed

5 files changed

+36
-19
lines changed

sound/soc/meson/axg-fifo.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ struct snd_soc_dai_driver;
2121
struct snd_soc_pcm_runtime;
2222

2323
#define AXG_FIFO_CH_MAX 128
24-
#define AXG_FIFO_RATES (SNDRV_PCM_RATE_5512 | \
25-
SNDRV_PCM_RATE_8000_384000)
2624
#define AXG_FIFO_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
2725
SNDRV_PCM_FMTBIT_S16_LE | \
2826
SNDRV_PCM_FMTBIT_S20_LE | \

sound/soc/meson/axg-frddr.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ static struct snd_soc_dai_driver axg_frddr_dai_drv = {
109109
.stream_name = "Playback",
110110
.channels_min = 1,
111111
.channels_max = AXG_FIFO_CH_MAX,
112-
.rates = AXG_FIFO_RATES,
112+
.rates = SNDRV_PCM_RATE_CONTINUOUS,
113+
.rate_min = 5515,
114+
.rate_max = 384000,
113115
.formats = AXG_FIFO_FORMATS,
114116
},
115117
.ops = &axg_frddr_ops,
@@ -184,7 +186,9 @@ static struct snd_soc_dai_driver g12a_frddr_dai_drv = {
184186
.stream_name = "Playback",
185187
.channels_min = 1,
186188
.channels_max = AXG_FIFO_CH_MAX,
187-
.rates = AXG_FIFO_RATES,
189+
.rates = SNDRV_PCM_RATE_CONTINUOUS,
190+
.rate_min = 5515,
191+
.rate_max = 384000,
188192
.formats = AXG_FIFO_FORMATS,
189193
},
190194
.ops = &g12a_frddr_ops,

sound/soc/meson/axg-spdifin.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ static int axg_spdifin_sample_mode_config(struct snd_soc_dai *dai,
179179
SPDIFIN_CTRL1_BASE_TIMER,
180180
FIELD_PREP(SPDIFIN_CTRL1_BASE_TIMER, rate / 1000));
181181

182-
/* Threshold based on the minimum width between two edges */
182+
/* Threshold based on the maximum width between two edges */
183183
regmap_update_bits(priv->map, SPDIFIN_CTRL0,
184-
SPDIFIN_CTRL0_WIDTH_SEL, SPDIFIN_CTRL0_WIDTH_SEL);
184+
SPDIFIN_CTRL0_WIDTH_SEL, 0);
185185

186186
/* Calculate the last timer which has no threshold */
187187
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,
199199
axg_spdifin_write_timer(priv->map, i, t);
200200

201201
/* Set the threshold value */
202-
axg_spdifin_write_threshold(priv->map, i, t + t_next);
202+
axg_spdifin_write_threshold(priv->map, i, 3 * (t + t_next));
203203

204204
/* Save the current timer for the next threshold calculation */
205205
t_next = t;

sound/soc/meson/axg-tdm-interface.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
#include "axg-tdm.h"
1414

15+
/* Maximum bit clock frequency according the datasheets */
16+
#define MAX_SCLK 100000000 /* Hz */
17+
1518
enum {
1619
TDM_IFACE_PAD,
1720
TDM_IFACE_LOOPBACK,
@@ -130,7 +133,7 @@ static int axg_tdm_iface_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
130133

131134
case SND_SOC_DAIFMT_BP_FC:
132135
case SND_SOC_DAIFMT_BC_FP:
133-
dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n");
136+
dev_err(dai->dev, "only BP_FP and BC_FC are supported\n");
134137
fallthrough;
135138
default:
136139
return -EINVAL;
@@ -153,19 +156,27 @@ static int axg_tdm_iface_startup(struct snd_pcm_substream *substream,
153156
return -EINVAL;
154157
}
155158

156-
/* Apply component wide rate symmetry */
157159
if (snd_soc_component_active(dai->component)) {
160+
/* Apply component wide rate symmetry */
158161
ret = snd_pcm_hw_constraint_single(substream->runtime,
159162
SNDRV_PCM_HW_PARAM_RATE,
160163
iface->rate);
161-
if (ret < 0) {
162-
dev_err(dai->dev,
163-
"can't set iface rate constraint\n");
164-
return ret;
165-
}
164+
165+
} else {
166+
/* Limit rate according to the slot number and width */
167+
unsigned int max_rate =
168+
MAX_SCLK / (iface->slots * iface->slot_width);
169+
ret = snd_pcm_hw_constraint_minmax(substream->runtime,
170+
SNDRV_PCM_HW_PARAM_RATE,
171+
0, max_rate);
166172
}
167173

168-
return 0;
174+
if (ret < 0)
175+
dev_err(dai->dev, "can't set iface rate constraint\n");
176+
else
177+
ret = 0;
178+
179+
return ret;
169180
}
170181

171182
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,
264275
srate = iface->slots * iface->slot_width * params_rate(params);
265276

266277
if (!iface->mclk_rate) {
267-
/* If no specific mclk is requested, default to bit clock * 4 */
268-
clk_set_rate(iface->mclk, 4 * srate);
278+
/* If no specific mclk is requested, default to bit clock * 2 */
279+
clk_set_rate(iface->mclk, 2 * srate);
269280
} else {
270281
/* Check if we can actually get the bit clock from mclk */
271282
if (iface->mclk_rate % srate) {

sound/soc/meson/axg-toddr.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ static struct snd_soc_dai_driver axg_toddr_dai_drv = {
131131
.stream_name = "Capture",
132132
.channels_min = 1,
133133
.channels_max = AXG_FIFO_CH_MAX,
134-
.rates = AXG_FIFO_RATES,
134+
.rates = SNDRV_PCM_RATE_CONTINUOUS,
135+
.rate_min = 5515,
136+
.rate_max = 384000,
135137
.formats = AXG_FIFO_FORMATS,
136138
},
137139
.ops = &axg_toddr_ops,
@@ -226,7 +228,9 @@ static struct snd_soc_dai_driver g12a_toddr_dai_drv = {
226228
.stream_name = "Capture",
227229
.channels_min = 1,
228230
.channels_max = AXG_FIFO_CH_MAX,
229-
.rates = AXG_FIFO_RATES,
231+
.rates = SNDRV_PCM_RATE_CONTINUOUS,
232+
.rate_min = 5515,
233+
.rate_max = 384000,
230234
.formats = AXG_FIFO_FORMATS,
231235
},
232236
.ops = &g12a_toddr_ops,

0 commit comments

Comments
 (0)