Lines Matching +full:default +full:- +full:sample +full:- +full:phase
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()
51 dev_err(dai->dev, "interface has no slot\n"); in axg_tdm_set_tdm_slots()
52 return -EINVAL; in axg_tdm_set_tdm_slots()
60 tx->mask = tx_mask; in axg_tdm_set_tdm_slots()
61 dai->driver->playback.channels_max = tx_slots; in axg_tdm_set_tdm_slots()
65 rx->mask = rx_mask; in axg_tdm_set_tdm_slots()
66 dai->driver->capture.channels_max = rx_slots; in axg_tdm_set_tdm_slots()
69 iface->slots = slots; in axg_tdm_set_tdm_slots()
74 iface->slot_width = 32; in axg_tdm_set_tdm_slots()
80 iface->slot_width = slot_width; in axg_tdm_set_tdm_slots()
82 default: in axg_tdm_set_tdm_slots()
83 dev_err(dai->dev, "unsupported slot width: %d\n", slot_width); in axg_tdm_set_tdm_slots()
84 return -EINVAL; in axg_tdm_set_tdm_slots()
95 int ret = -ENOTSUPP; in axg_tdm_iface_set_sysclk()
98 if (!iface->mclk) { in axg_tdm_iface_set_sysclk()
99 dev_warn(dai->dev, "master clock not provided\n"); in axg_tdm_iface_set_sysclk()
101 ret = clk_set_rate(iface->mclk, freq); in axg_tdm_iface_set_sysclk()
103 iface->mclk_rate = freq; in axg_tdm_iface_set_sysclk()
116 if (!iface->mclk) { in axg_tdm_iface_set_fmt()
117 dev_err(dai->dev, "cpu clock master: mclk missing\n"); in axg_tdm_iface_set_fmt()
118 return -ENODEV; in axg_tdm_iface_set_fmt()
127 dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n"); in axg_tdm_iface_set_fmt()
128 /* Fall-through */ in axg_tdm_iface_set_fmt()
129 default: in axg_tdm_iface_set_fmt()
130 return -EINVAL; in axg_tdm_iface_set_fmt()
133 iface->fmt = fmt; in axg_tdm_iface_set_fmt()
145 if (!axg_tdm_slots_total(ts->mask)) { in axg_tdm_iface_startup()
146 dev_err(dai->dev, "interface has not slots\n"); in axg_tdm_iface_startup()
147 return -EINVAL; in axg_tdm_iface_startup()
151 if (dai->component->active) { in axg_tdm_iface_startup()
152 ret = snd_pcm_hw_constraint_single(substream->runtime, in axg_tdm_iface_startup()
154 iface->rate); in axg_tdm_iface_startup()
156 dev_err(dai->dev, in axg_tdm_iface_startup()
175 iface->rate = params_rate(params); in axg_tdm_iface_set_stream()
178 if (axg_tdm_slots_total(ts->mask) < channels) { in axg_tdm_iface_set_stream()
179 dev_err(dai->dev, "not enough slots for channels\n"); in axg_tdm_iface_set_stream()
180 return -EINVAL; in axg_tdm_iface_set_stream()
183 if (iface->slot_width < width) { in axg_tdm_iface_set_stream()
184 dev_err(dai->dev, "incompatible slots width for stream\n"); in axg_tdm_iface_set_stream()
185 return -EINVAL; in axg_tdm_iface_set_stream()
189 ts->physical_width = params_physical_width(params); in axg_tdm_iface_set_stream()
190 ts->width = params_width(params); in axg_tdm_iface_set_stream()
191 ts->channels = params_channels(params); in axg_tdm_iface_set_stream()
203 ret = clk_set_rate(iface->lrclk, params_rate(params)); in axg_tdm_iface_set_lrclk()
205 dev_err(dai->dev, "setting sample clock failed: %d\n", ret); in axg_tdm_iface_set_lrclk()
209 switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in axg_tdm_iface_set_lrclk()
228 default: in axg_tdm_iface_set_lrclk()
229 return -EINVAL; in axg_tdm_iface_set_lrclk()
232 ret = clk_set_duty_cycle(iface->lrclk, ratio_num, 2); in axg_tdm_iface_set_lrclk()
234 dev_err(dai->dev, in axg_tdm_iface_set_lrclk()
235 "setting sample clock duty cycle failed: %d\n", ret); in axg_tdm_iface_set_lrclk()
239 /* Set sample clock inversion */ in axg_tdm_iface_set_lrclk()
240 ret = clk_set_phase(iface->lrclk, in axg_tdm_iface_set_lrclk()
241 axg_tdm_lrclk_invert(iface->fmt) ? 180 : 0); in axg_tdm_iface_set_lrclk()
243 dev_err(dai->dev, in axg_tdm_iface_set_lrclk()
244 "setting sample clock phase failed: %d\n", ret); in axg_tdm_iface_set_lrclk()
258 srate = iface->slots * iface->slot_width * params_rate(params); in axg_tdm_iface_set_sclk()
260 if (!iface->mclk_rate) { in axg_tdm_iface_set_sclk()
261 /* If no specific mclk is requested, default to bit clock * 4 */ in axg_tdm_iface_set_sclk()
262 clk_set_rate(iface->mclk, 4 * srate); in axg_tdm_iface_set_sclk()
265 if (iface->mclk_rate % srate) { in axg_tdm_iface_set_sclk()
266 dev_err(dai->dev, in axg_tdm_iface_set_sclk()
268 srate, iface->mclk_rate); in axg_tdm_iface_set_sclk()
269 return -EINVAL; in axg_tdm_iface_set_sclk()
273 ret = clk_set_rate(iface->sclk, srate); in axg_tdm_iface_set_sclk()
275 dev_err(dai->dev, "setting bit clock failed: %d\n", ret); in axg_tdm_iface_set_sclk()
280 ret = clk_set_phase(iface->sclk, in axg_tdm_iface_set_sclk()
281 axg_tdm_sclk_invert(iface->fmt) ? 0 : 180); in axg_tdm_iface_set_sclk()
283 dev_err(dai->dev, "setting bit clock phase failed: %d\n", ret); in axg_tdm_iface_set_sclk()
297 switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in axg_tdm_iface_hw_params()
301 if (iface->slots > 2) { in axg_tdm_iface_hw_params()
302 dev_err(dai->dev, "bad slot number for format: %d\n", in axg_tdm_iface_hw_params()
303 iface->slots); in axg_tdm_iface_hw_params()
304 return -EINVAL; in axg_tdm_iface_hw_params()
312 default: in axg_tdm_iface_hw_params()
313 dev_err(dai->dev, "unsupported dai format\n"); in axg_tdm_iface_hw_params()
314 return -EINVAL; in axg_tdm_iface_hw_params()
321 if ((iface->fmt & SND_SOC_DAIFMT_MASTER_MASK) == in axg_tdm_iface_hw_params()
357 if (dai->capture_dma_data) in axg_tdm_iface_remove_dai()
358 axg_tdm_stream_free(dai->capture_dma_data); in axg_tdm_iface_remove_dai()
360 if (dai->playback_dma_data) in axg_tdm_iface_remove_dai()
361 axg_tdm_stream_free(dai->playback_dma_data); in axg_tdm_iface_remove_dai()
370 if (dai->capture_widget) { in axg_tdm_iface_probe_dai()
371 dai->capture_dma_data = axg_tdm_stream_alloc(iface); in axg_tdm_iface_probe_dai()
372 if (!dai->capture_dma_data) in axg_tdm_iface_probe_dai()
373 return -ENOMEM; in axg_tdm_iface_probe_dai()
376 if (dai->playback_widget) { in axg_tdm_iface_probe_dai()
377 dai->playback_dma_data = axg_tdm_stream_alloc(iface); in axg_tdm_iface_probe_dai()
378 if (!dai->playback_dma_data) { in axg_tdm_iface_probe_dai()
380 return -ENOMEM; in axg_tdm_iface_probe_dai()
446 ret = clk_prepare_enable(iface->mclk); in axg_tdm_iface_set_bias_level()
451 clk_disable_unprepare(iface->mclk); in axg_tdm_iface_set_bias_level()
467 { .compatible = "amlogic,axg-tdm-iface", },
474 struct device *dev = &pdev->dev; in axg_tdm_iface_probe()
481 return -ENOMEM; in axg_tdm_iface_probe()
492 return -ENOMEM; in axg_tdm_iface_probe()
499 iface->sclk = devm_clk_get(dev, "sclk"); in axg_tdm_iface_probe()
500 if (IS_ERR(iface->sclk)) { in axg_tdm_iface_probe()
501 ret = PTR_ERR(iface->sclk); in axg_tdm_iface_probe()
502 if (ret != -EPROBE_DEFER) in axg_tdm_iface_probe()
507 /* Sample clock provided on the pad */ in axg_tdm_iface_probe()
508 iface->lrclk = devm_clk_get(dev, "lrclk"); in axg_tdm_iface_probe()
509 if (IS_ERR(iface->lrclk)) { in axg_tdm_iface_probe()
510 ret = PTR_ERR(iface->lrclk); in axg_tdm_iface_probe()
511 if (ret != -EPROBE_DEFER) in axg_tdm_iface_probe()
522 iface->mclk = devm_clk_get(dev, "mclk"); in axg_tdm_iface_probe()
523 if (IS_ERR(iface->mclk)) { in axg_tdm_iface_probe()
524 ret = PTR_ERR(iface->mclk); in axg_tdm_iface_probe()
525 if (ret == -ENOENT) { in axg_tdm_iface_probe()
526 iface->mclk = NULL; in axg_tdm_iface_probe()
528 if (ret != -EPROBE_DEFER) in axg_tdm_iface_probe()
542 .name = "axg-tdm-iface",