Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+36 -19
-2
sound/soc/meson/axg-fifo.h
··· 21 21 struct snd_soc_pcm_runtime; 22 22 23 23 #define AXG_FIFO_CH_MAX 128 24 - #define AXG_FIFO_RATES (SNDRV_PCM_RATE_5512 | \ 25 - SNDRV_PCM_RATE_8000_384000) 26 24 #define AXG_FIFO_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 27 25 SNDRV_PCM_FMTBIT_S16_LE | \ 28 26 SNDRV_PCM_FMTBIT_S20_LE | \
+6 -2
sound/soc/meson/axg-frddr.c
··· 109 109 .stream_name = "Playback", 110 110 .channels_min = 1, 111 111 .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, 113 115 .formats = AXG_FIFO_FORMATS, 114 116 }, 115 117 .ops = &axg_frddr_ops, ··· 186 184 .stream_name = "Playback", 187 185 .channels_min = 1, 188 186 .channels_max = AXG_FIFO_CH_MAX, 189 - .rates = AXG_FIFO_RATES, 187 + .rates = SNDRV_PCM_RATE_CONTINUOUS, 188 + .rate_min = 5515, 189 + .rate_max = 384000, 190 190 .formats = AXG_FIFO_FORMATS, 191 191 }, 192 192 .ops = &g12a_frddr_ops,
+3 -3
sound/soc/meson/axg-spdifin.c
··· 179 179 SPDIFIN_CTRL1_BASE_TIMER, 180 180 FIELD_PREP(SPDIFIN_CTRL1_BASE_TIMER, rate / 1000)); 181 181 182 - /* Threshold based on the minimum width between two edges */ 182 + /* Threshold based on the maximum width between two edges */ 183 183 regmap_update_bits(priv->map, SPDIFIN_CTRL0, 184 - SPDIFIN_CTRL0_WIDTH_SEL, SPDIFIN_CTRL0_WIDTH_SEL); 184 + SPDIFIN_CTRL0_WIDTH_SEL, 0); 185 185 186 186 /* Calculate the last timer which has no threshold */ 187 187 t_next = axg_spdifin_mode_timer(priv, i, rate); ··· 199 199 axg_spdifin_write_timer(priv->map, i, t); 200 200 201 201 /* 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)); 203 203 204 204 /* Save the current timer for the next threshold calculation */ 205 205 t_next = t;
+21 -10
sound/soc/meson/axg-tdm-interface.c
··· 12 12 13 13 #include "axg-tdm.h" 14 14 15 + /* Maximum bit clock frequency according the datasheets */ 16 + #define MAX_SCLK 100000000 /* Hz */ 17 + 15 18 enum { 16 19 TDM_IFACE_PAD, 17 20 TDM_IFACE_LOOPBACK, ··· 133 130 134 131 case SND_SOC_DAIFMT_BP_FC: 135 132 case SND_SOC_DAIFMT_BC_FP: 136 - dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n"); 133 + dev_err(dai->dev, "only BP_FP and BC_FC are supported\n"); 137 134 fallthrough; 138 135 default: 139 136 return -EINVAL; ··· 156 153 return -EINVAL; 157 154 } 158 155 159 - /* Apply component wide rate symmetry */ 160 156 if (snd_soc_component_active(dai->component)) { 157 + /* Apply component wide rate symmetry */ 161 158 ret = snd_pcm_hw_constraint_single(substream->runtime, 162 159 SNDRV_PCM_HW_PARAM_RATE, 163 160 iface->rate); 164 - if (ret < 0) { 165 - dev_err(dai->dev, 166 - "can't set iface rate constraint\n"); 167 - return ret; 168 - } 161 + 162 + } else { 163 + /* Limit rate according to the slot number and width */ 164 + unsigned int max_rate = 165 + MAX_SCLK / (iface->slots * iface->slot_width); 166 + ret = snd_pcm_hw_constraint_minmax(substream->runtime, 167 + SNDRV_PCM_HW_PARAM_RATE, 168 + 0, max_rate); 169 169 } 170 170 171 - return 0; 171 + if (ret < 0) 172 + dev_err(dai->dev, "can't set iface rate constraint\n"); 173 + else 174 + ret = 0; 175 + 176 + return ret; 172 177 } 173 178 174 179 static int axg_tdm_iface_set_stream(struct snd_pcm_substream *substream, ··· 275 264 srate = iface->slots * iface->slot_width * params_rate(params); 276 265 277 266 if (!iface->mclk_rate) { 278 - /* If no specific mclk is requested, default to bit clock * 4 */ 279 - clk_set_rate(iface->mclk, 4 * srate); 267 + /* If no specific mclk is requested, default to bit clock * 2 */ 268 + clk_set_rate(iface->mclk, 2 * srate); 280 269 } else { 281 270 /* Check if we can actually get the bit clock from mclk */ 282 271 if (iface->mclk_rate % srate) {
+6 -2
sound/soc/meson/axg-toddr.c
··· 131 131 .stream_name = "Capture", 132 132 .channels_min = 1, 133 133 .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, 135 137 .formats = AXG_FIFO_FORMATS, 136 138 }, 137 139 .ops = &axg_toddr_ops, ··· 228 226 .stream_name = "Capture", 229 227 .channels_min = 1, 230 228 .channels_max = AXG_FIFO_CH_MAX, 231 - .rates = AXG_FIFO_RATES, 229 + .rates = SNDRV_PCM_RATE_CONTINUOUS, 230 + .rate_min = 5515, 231 + .rate_max = 384000, 232 232 .formats = AXG_FIFO_FORMATS, 233 233 }, 234 234 .ops = &g12a_toddr_ops,