Lines Matching +full:ts +full:- +full:attached
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
11 #include <sound/soc-dai.h>
13 #include "axg-tdm.h"
41 dai->playback_dma_data; in axg_tdm_set_tdm_slots()
43 dai->capture_dma_data; in axg_tdm_set_tdm_slots()
52 dev_err(dai->dev, "interface has no slot\n"); in axg_tdm_set_tdm_slots()
53 return -EINVAL; in axg_tdm_set_tdm_slots()
56 iface->slots = slots; in axg_tdm_set_tdm_slots()
76 dev_err(dai->dev, "unsupported slot width: %d\n", slot_width); in axg_tdm_set_tdm_slots()
77 return -EINVAL; in axg_tdm_set_tdm_slots()
80 iface->slot_width = slot_width; in axg_tdm_set_tdm_slots()
84 tx->mask = tx_mask; in axg_tdm_set_tdm_slots()
85 dai->driver->playback.channels_max = tx_slots; in axg_tdm_set_tdm_slots()
86 dai->driver->playback.formats = fmt; in axg_tdm_set_tdm_slots()
90 rx->mask = rx_mask; in axg_tdm_set_tdm_slots()
91 dai->driver->capture.channels_max = rx_slots; in axg_tdm_set_tdm_slots()
92 dai->driver->capture.formats = fmt; in axg_tdm_set_tdm_slots()
103 int ret = -ENOTSUPP; in axg_tdm_iface_set_sysclk()
106 if (!iface->mclk) { in axg_tdm_iface_set_sysclk()
107 dev_warn(dai->dev, "master clock not provided\n"); in axg_tdm_iface_set_sysclk()
109 ret = clk_set_rate(iface->mclk, freq); in axg_tdm_iface_set_sysclk()
111 iface->mclk_rate = freq; in axg_tdm_iface_set_sysclk()
124 if (!iface->mclk) { in axg_tdm_iface_set_fmt()
125 dev_err(dai->dev, "cpu clock master: mclk missing\n"); in axg_tdm_iface_set_fmt()
126 return -ENODEV; in axg_tdm_iface_set_fmt()
135 dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n"); in axg_tdm_iface_set_fmt()
138 return -EINVAL; in axg_tdm_iface_set_fmt()
141 iface->fmt = fmt; in axg_tdm_iface_set_fmt()
149 struct axg_tdm_stream *ts = in axg_tdm_iface_startup() local
153 if (!axg_tdm_slots_total(ts->mask)) { in axg_tdm_iface_startup()
154 dev_err(dai->dev, "interface has not slots\n"); in axg_tdm_iface_startup()
155 return -EINVAL; in axg_tdm_iface_startup()
159 if (snd_soc_component_active(dai->component)) { in axg_tdm_iface_startup()
160 ret = snd_pcm_hw_constraint_single(substream->runtime, in axg_tdm_iface_startup()
162 iface->rate); in axg_tdm_iface_startup()
164 dev_err(dai->dev, in axg_tdm_iface_startup()
178 struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); in axg_tdm_iface_set_stream() local
183 iface->rate = params_rate(params); in axg_tdm_iface_set_stream()
186 if (axg_tdm_slots_total(ts->mask) < channels) { in axg_tdm_iface_set_stream()
187 dev_err(dai->dev, "not enough slots for channels\n"); in axg_tdm_iface_set_stream()
188 return -EINVAL; in axg_tdm_iface_set_stream()
191 if (iface->slot_width < width) { in axg_tdm_iface_set_stream()
192 dev_err(dai->dev, "incompatible slots width for stream\n"); in axg_tdm_iface_set_stream()
193 return -EINVAL; in axg_tdm_iface_set_stream()
197 ts->physical_width = params_physical_width(params); in axg_tdm_iface_set_stream()
198 ts->width = params_width(params); in axg_tdm_iface_set_stream()
199 ts->channels = params_channels(params); in axg_tdm_iface_set_stream()
211 ret = clk_set_rate(iface->lrclk, params_rate(params)); in axg_tdm_iface_set_lrclk()
213 dev_err(dai->dev, "setting sample clock failed: %d\n", ret); in axg_tdm_iface_set_lrclk()
217 switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in axg_tdm_iface_set_lrclk()
237 return -EINVAL; in axg_tdm_iface_set_lrclk()
240 ret = clk_set_duty_cycle(iface->lrclk, ratio_num, 2); in axg_tdm_iface_set_lrclk()
242 dev_err(dai->dev, in axg_tdm_iface_set_lrclk()
248 ret = clk_set_phase(iface->lrclk, in axg_tdm_iface_set_lrclk()
249 axg_tdm_lrclk_invert(iface->fmt) ? 180 : 0); in axg_tdm_iface_set_lrclk()
251 dev_err(dai->dev, in axg_tdm_iface_set_lrclk()
266 srate = iface->slots * iface->slot_width * params_rate(params); in axg_tdm_iface_set_sclk()
268 if (!iface->mclk_rate) { in axg_tdm_iface_set_sclk()
270 clk_set_rate(iface->mclk, 4 * srate); in axg_tdm_iface_set_sclk()
273 if (iface->mclk_rate % srate) { in axg_tdm_iface_set_sclk()
274 dev_err(dai->dev, in axg_tdm_iface_set_sclk()
276 srate, iface->mclk_rate); in axg_tdm_iface_set_sclk()
277 return -EINVAL; in axg_tdm_iface_set_sclk()
281 ret = clk_set_rate(iface->sclk, srate); in axg_tdm_iface_set_sclk()
283 dev_err(dai->dev, "setting bit clock failed: %d\n", ret); in axg_tdm_iface_set_sclk()
288 ret = clk_set_phase(iface->sclk, in axg_tdm_iface_set_sclk()
289 axg_tdm_sclk_invert(iface->fmt) ? 0 : 180); in axg_tdm_iface_set_sclk()
291 dev_err(dai->dev, "setting bit clock phase failed: %d\n", ret); in axg_tdm_iface_set_sclk()
305 switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in axg_tdm_iface_hw_params()
309 if (iface->slots > 2) { in axg_tdm_iface_hw_params()
310 dev_err(dai->dev, "bad slot number for format: %d\n", in axg_tdm_iface_hw_params()
311 iface->slots); in axg_tdm_iface_hw_params()
312 return -EINVAL; in axg_tdm_iface_hw_params()
321 dev_err(dai->dev, "unsupported dai format\n"); in axg_tdm_iface_hw_params()
322 return -EINVAL; in axg_tdm_iface_hw_params()
329 if ((iface->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == in axg_tdm_iface_hw_params()
346 struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); in axg_tdm_iface_hw_free() local
348 /* Stop all attached formatters */ in axg_tdm_iface_hw_free()
349 axg_tdm_stream_stop(ts); in axg_tdm_iface_hw_free()
357 struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); in axg_tdm_iface_prepare() local
359 /* Force all attached formatters to update */ in axg_tdm_iface_prepare()
360 return axg_tdm_stream_reset(ts); in axg_tdm_iface_prepare()
365 if (dai->capture_dma_data) in axg_tdm_iface_remove_dai()
366 axg_tdm_stream_free(dai->capture_dma_data); in axg_tdm_iface_remove_dai()
368 if (dai->playback_dma_data) in axg_tdm_iface_remove_dai()
369 axg_tdm_stream_free(dai->playback_dma_data); in axg_tdm_iface_remove_dai()
378 if (dai->capture_widget) { in axg_tdm_iface_probe_dai()
379 dai->capture_dma_data = axg_tdm_stream_alloc(iface); in axg_tdm_iface_probe_dai()
380 if (!dai->capture_dma_data) in axg_tdm_iface_probe_dai()
381 return -ENOMEM; in axg_tdm_iface_probe_dai()
384 if (dai->playback_widget) { in axg_tdm_iface_probe_dai()
385 dai->playback_dma_data = axg_tdm_stream_alloc(iface); in axg_tdm_iface_probe_dai()
386 if (!dai->playback_dma_data) { in axg_tdm_iface_probe_dai()
388 return -ENOMEM; in axg_tdm_iface_probe_dai()
454 ret = clk_prepare_enable(iface->mclk); in axg_tdm_iface_set_bias_level()
459 clk_disable_unprepare(iface->mclk); in axg_tdm_iface_set_bias_level()
487 { .compatible = "amlogic,axg-tdm-iface", },
494 struct device *dev = &pdev->dev; in axg_tdm_iface_probe()
501 return -ENOMEM; in axg_tdm_iface_probe()
512 return -ENOMEM; in axg_tdm_iface_probe()
519 iface->sclk = devm_clk_get(dev, "sclk"); in axg_tdm_iface_probe()
520 if (IS_ERR(iface->sclk)) in axg_tdm_iface_probe()
521 return dev_err_probe(dev, PTR_ERR(iface->sclk), "failed to get sclk\n"); in axg_tdm_iface_probe()
524 iface->lrclk = devm_clk_get(dev, "lrclk"); in axg_tdm_iface_probe()
525 if (IS_ERR(iface->lrclk)) in axg_tdm_iface_probe()
526 return dev_err_probe(dev, PTR_ERR(iface->lrclk), "failed to get lrclk\n"); in axg_tdm_iface_probe()
534 iface->mclk = devm_clk_get(dev, "mclk"); in axg_tdm_iface_probe()
535 if (IS_ERR(iface->mclk)) { in axg_tdm_iface_probe()
536 ret = PTR_ERR(iface->mclk); in axg_tdm_iface_probe()
537 if (ret == -ENOENT) in axg_tdm_iface_probe()
538 iface->mclk = NULL; in axg_tdm_iface_probe()
551 .name = "axg-tdm-iface",