Lines Matching +full:tdm +full:- +full:sync +full:- +full:src
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
5 #include <dt-bindings/sound/qcom,q6afe.h>
15 #include "q6dsp-lpass-ports.h"
16 #include "q6dsp-common.h"
42 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6slim_hw_params()
43 struct q6afe_slim_cfg *slim = &dai_data->port_config[dai->id].slim; in q6slim_hw_params()
45 slim->sample_rate = params_rate(params); in q6slim_hw_params()
50 slim->bit_width = 16; in q6slim_hw_params()
53 slim->bit_width = 24; in q6slim_hw_params()
56 slim->bit_width = 32; in q6slim_hw_params()
61 return -EINVAL; in q6slim_hw_params()
71 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6hdmi_hw_params()
73 struct q6afe_hdmi_cfg *hdmi = &dai_data->port_config[dai->id].hdmi; in q6hdmi_hw_params()
76 hdmi->sample_rate = params_rate(params); in q6hdmi_hw_params()
79 hdmi->bit_width = 16; in q6hdmi_hw_params()
82 hdmi->bit_width = 24; in q6hdmi_hw_params()
90 hdmi->channel_allocation = (u16) ret; in q6hdmi_hw_params()
99 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_usb_hw_params()
102 struct q6afe_usb_cfg *usb = &dai_data->port_config[dai->id].usb_audio; in q6afe_usb_hw_params()
104 usb->sample_rate = rate; in q6afe_usb_hw_params()
105 usb->num_channels = channels; in q6afe_usb_hw_params()
110 usb->bit_width = 16; in q6afe_usb_hw_params()
114 usb->bit_width = 24; in q6afe_usb_hw_params()
117 usb->bit_width = 32; in q6afe_usb_hw_params()
120 dev_err(dai->dev, "%s: invalid format %d\n", in q6afe_usb_hw_params()
122 return -EINVAL; in q6afe_usb_hw_params()
132 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6i2s_hw_params()
133 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg; in q6i2s_hw_params()
135 i2s->sample_rate = params_rate(params); in q6i2s_hw_params()
136 i2s->bit_width = params_width(params); in q6i2s_hw_params()
137 i2s->num_channels = params_channels(params); in q6i2s_hw_params()
138 i2s->sd_line_mask = dai_data->priv[dai->id].sd_line_mask; in q6i2s_hw_params()
145 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6i2s_set_fmt()
146 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg; in q6i2s_set_fmt()
148 i2s->fmt = fmt; in q6i2s_set_fmt()
159 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6tdm_set_tdm_slot()
160 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; in q6tdm_set_tdm_slot() local
166 dev_err(dai->dev, "%s: invalid slot_width %d\n", in q6tdm_set_tdm_slot()
168 return -EINVAL; in q6tdm_set_tdm_slot()
171 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */ in q6tdm_set_tdm_slot()
186 dev_err(dai->dev, "%s: invalid slots %d\n", in q6tdm_set_tdm_slot()
188 return -EINVAL; in q6tdm_set_tdm_slot()
191 switch (dai->id) { in q6tdm_set_tdm_slot()
193 tdm->nslots_per_frame = slots; in q6tdm_set_tdm_slot()
194 tdm->slot_width = slot_width; in q6tdm_set_tdm_slot()
195 /* TDM RX dais ids are even and tx are odd */ in q6tdm_set_tdm_slot()
196 tdm->slot_mask = ((dai->id & 0x1) ? tx_mask : rx_mask) & cap_mask; in q6tdm_set_tdm_slot()
199 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", in q6tdm_set_tdm_slot()
200 __func__, dai->id); in q6tdm_set_tdm_slot()
201 return -EINVAL; in q6tdm_set_tdm_slot()
212 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6tdm_set_channel_map()
213 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; in q6tdm_set_channel_map() local
217 switch (dai->id) { in q6tdm_set_channel_map()
219 if (dai->id & 0x1) { in q6tdm_set_channel_map()
221 dev_err(dai->dev, "tx slot not found\n"); in q6tdm_set_channel_map()
222 return -EINVAL; in q6tdm_set_channel_map()
225 dev_err(dai->dev, "invalid tx num %d\n", in q6tdm_set_channel_map()
227 return -EINVAL; in q6tdm_set_channel_map()
231 tdm->ch_mapping[i] = tx_slot[i]; in q6tdm_set_channel_map()
234 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID; in q6tdm_set_channel_map()
236 tdm->num_channels = tx_num; in q6tdm_set_channel_map()
240 dev_err(dai->dev, "rx slot not found\n"); in q6tdm_set_channel_map()
241 return -EINVAL; in q6tdm_set_channel_map()
244 dev_err(dai->dev, "invalid rx num %d\n", in q6tdm_set_channel_map()
246 return -EINVAL; in q6tdm_set_channel_map()
250 tdm->ch_mapping[i] = rx_slot[i]; in q6tdm_set_channel_map()
253 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID; in q6tdm_set_channel_map()
255 tdm->num_channels = rx_num; in q6tdm_set_channel_map()
260 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", in q6tdm_set_channel_map()
261 __func__, dai->id); in q6tdm_set_channel_map()
262 return -EINVAL; in q6tdm_set_channel_map()
272 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6tdm_hw_params()
273 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; in q6tdm_hw_params() local
275 tdm->bit_width = params_width(params); in q6tdm_hw_params()
276 tdm->sample_rate = params_rate(params); in q6tdm_hw_params()
277 tdm->num_channels = params_channels(params); in q6tdm_hw_params()
278 tdm->data_align_type = dai_data->priv[dai->id].data_align; in q6tdm_hw_params()
279 tdm->sync_src = dai_data->priv[dai->id].sync_src; in q6tdm_hw_params()
280 tdm->sync_mode = dai_data->priv[dai->id].sync_mode; in q6tdm_hw_params()
292 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6dma_set_channel_map()
293 struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg; in q6dma_set_channel_map()
297 switch (dai->id) { in q6dma_set_channel_map()
311 dev_err(dai->dev, "tx slot not found\n"); in q6dma_set_channel_map()
312 return -EINVAL; in q6dma_set_channel_map()
316 dev_err(dai->dev, "invalid tx num %d\n", in q6dma_set_channel_map()
318 return -EINVAL; in q6dma_set_channel_map()
335 dev_err(dai->dev, "rx slot not found\n"); in q6dma_set_channel_map()
336 return -EINVAL; in q6dma_set_channel_map()
339 dev_err(dai->dev, "invalid rx num %d\n", in q6dma_set_channel_map()
341 return -EINVAL; in q6dma_set_channel_map()
347 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", in q6dma_set_channel_map()
348 __func__, dai->id); in q6dma_set_channel_map()
349 return -EINVAL; in q6dma_set_channel_map()
352 cfg->active_channels_mask = ch_mask; in q6dma_set_channel_map()
361 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6dma_hw_params()
362 struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg; in q6dma_hw_params()
364 cfg->bit_width = params_width(params); in q6dma_hw_params()
365 cfg->sample_rate = params_rate(params); in q6dma_hw_params()
366 cfg->num_channels = params_channels(params); in q6dma_hw_params()
373 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_dai_shutdown()
376 if (!dai_data->is_port_started[dai->id]) in q6afe_dai_shutdown()
379 rc = q6afe_port_stop(dai_data->port[dai->id]); in q6afe_dai_shutdown()
381 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc); in q6afe_dai_shutdown()
383 dai_data->is_port_started[dai->id] = false; in q6afe_dai_shutdown()
390 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_dai_prepare()
393 if (dai_data->is_port_started[dai->id]) { in q6afe_dai_prepare()
395 rc = q6afe_port_stop(dai_data->port[dai->id]); in q6afe_dai_prepare()
397 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc); in q6afe_dai_prepare()
402 switch (dai->id) { in q6afe_dai_prepare()
405 q6afe_hdmi_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
406 &dai_data->port_config[dai->id].hdmi); in q6afe_dai_prepare()
409 q6afe_slim_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
410 &dai_data->port_config[dai->id].slim); in q6afe_dai_prepare()
414 rc = q6afe_i2s_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
415 &dai_data->port_config[dai->id].i2s_cfg); in q6afe_dai_prepare()
417 dev_err(dai->dev, "fail to prepare AFE port %x\n", in q6afe_dai_prepare()
418 dai->id); in q6afe_dai_prepare()
423 q6afe_tdm_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
424 &dai_data->port_config[dai->id].tdm); in q6afe_dai_prepare()
427 q6afe_cdc_dma_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
428 &dai_data->port_config[dai->id].dma_cfg); in q6afe_dai_prepare()
431 q6afe_usb_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
432 &dai_data->port_config[dai->id].usb_audio); in q6afe_dai_prepare()
435 return -EINVAL; in q6afe_dai_prepare()
438 rc = q6afe_port_start(dai_data->port[dai->id]); in q6afe_dai_prepare()
440 dev_err(dai->dev, "fail to start AFE port %x\n", dai->id); in q6afe_dai_prepare()
443 dai_data->is_port_started[dai->id] = true; in q6afe_dai_prepare()
454 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6slim_set_channel_map()
455 struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id]; in q6slim_set_channel_map()
458 if (dai->id & 0x1) { in q6slim_set_channel_map()
462 return -EINVAL; in q6slim_set_channel_map()
466 pcfg->slim.ch_mapping[i] = tx_slot[i]; in q6slim_set_channel_map()
468 pcfg->slim.num_channels = tx_num; in q6slim_set_channel_map()
474 return -EINVAL; in q6slim_set_channel_map()
478 pcfg->slim.ch_mapping[i] = rx_slot[i]; in q6slim_set_channel_map()
480 pcfg->slim.num_channels = rx_num; in q6slim_set_channel_map()
490 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_mi2s_set_sysclk()
491 struct q6afe_port *port = dai_data->port[dai->id]; in q6afe_mi2s_set_sysclk()
669 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in msm_dai_q6_dai_probe()
672 port = q6afe_port_get_from_id(dai->dev, dai->id); in msm_dai_q6_dai_probe()
674 dev_err(dai->dev, "Unable to get afe port\n"); in msm_dai_q6_dai_probe()
675 return -EINVAL; in msm_dai_q6_dai_probe()
677 dai_data->port[dai->id] = port; in msm_dai_q6_dai_probe()
684 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in msm_dai_q6_dai_remove()
686 q6afe_port_put(dai_data->port[dai->id]); in msm_dai_q6_dai_remove()
687 dai_data->port[dai->id] = NULL; in msm_dai_q6_dai_remove()
1012 .name = "q6afe-dai-component",
1027 for_each_child_of_node(dev->of_node, node) { in of_q6afe_parse_dai_data()
1042 priv = &data->priv[id]; in of_q6afe_parse_dai_data()
1044 "qcom,sd-lines", in of_q6afe_parse_dai_data()
1052 priv->sd_line_mask = 0; in of_q6afe_parse_dai_data()
1055 priv->sd_line_mask |= BIT(lines[i]); in of_q6afe_parse_dai_data()
1059 priv = &data->priv[id]; in of_q6afe_parse_dai_data()
1060 ret = of_property_read_u32(node, "qcom,tdm-sync-mode", in of_q6afe_parse_dai_data()
1061 &priv->sync_mode); in of_q6afe_parse_dai_data()
1063 dev_err(dev, "No Sync mode from DT\n"); in of_q6afe_parse_dai_data()
1066 ret = of_property_read_u32(node, "qcom,tdm-sync-src", in of_q6afe_parse_dai_data()
1067 &priv->sync_src); in of_q6afe_parse_dai_data()
1069 dev_err(dev, "No Sync Src from DT\n"); in of_q6afe_parse_dai_data()
1072 ret = of_property_read_u32(node, "qcom,tdm-data-out", in of_q6afe_parse_dai_data()
1073 &priv->data_out_enable); in of_q6afe_parse_dai_data()
1078 ret = of_property_read_u32(node, "qcom,tdm-invert-sync", in of_q6afe_parse_dai_data()
1079 &priv->invert_sync); in of_q6afe_parse_dai_data()
1081 dev_err(dev, "No Invert sync from DT\n"); in of_q6afe_parse_dai_data()
1084 ret = of_property_read_u32(node, "qcom,tdm-data-delay", in of_q6afe_parse_dai_data()
1085 &priv->data_delay); in of_q6afe_parse_dai_data()
1090 ret = of_property_read_u32(node, "qcom,tdm-data-align", in of_q6afe_parse_dai_data()
1091 &priv->data_align); in of_q6afe_parse_dai_data()
1108 struct device *dev = &pdev->dev; in q6afe_dai_dev_probe()
1113 return -ENOMEM; in q6afe_dai_dev_probe()
1131 { .compatible = "qcom,q6afe-dais" },
1139 .name = "q6afe-dai",