Lines Matching +full:playback +full:- +full:sd +full:- +full:lines
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 q6i2s_hw_params()
100 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg; in q6i2s_hw_params()
102 i2s->sample_rate = params_rate(params); in q6i2s_hw_params()
103 i2s->bit_width = params_width(params); in q6i2s_hw_params()
104 i2s->num_channels = params_channels(params); in q6i2s_hw_params()
105 i2s->sd_line_mask = dai_data->priv[dai->id].sd_line_mask; in q6i2s_hw_params()
112 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6i2s_set_fmt()
113 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg; in q6i2s_set_fmt()
115 i2s->fmt = fmt; in q6i2s_set_fmt()
126 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6tdm_set_tdm_slot()
127 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; in q6tdm_set_tdm_slot()
133 dev_err(dai->dev, "%s: invalid slot_width %d\n", in q6tdm_set_tdm_slot()
135 return -EINVAL; in q6tdm_set_tdm_slot()
138 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */ in q6tdm_set_tdm_slot()
153 dev_err(dai->dev, "%s: invalid slots %d\n", in q6tdm_set_tdm_slot()
155 return -EINVAL; in q6tdm_set_tdm_slot()
158 switch (dai->id) { in q6tdm_set_tdm_slot()
160 tdm->nslots_per_frame = slots; in q6tdm_set_tdm_slot()
161 tdm->slot_width = slot_width; in q6tdm_set_tdm_slot()
163 tdm->slot_mask = ((dai->id & 0x1) ? tx_mask : rx_mask) & cap_mask; in q6tdm_set_tdm_slot()
166 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", in q6tdm_set_tdm_slot()
167 __func__, dai->id); in q6tdm_set_tdm_slot()
168 return -EINVAL; in q6tdm_set_tdm_slot()
179 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6tdm_set_channel_map()
180 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; in q6tdm_set_channel_map()
184 switch (dai->id) { in q6tdm_set_channel_map()
186 if (dai->id & 0x1) { in q6tdm_set_channel_map()
188 dev_err(dai->dev, "tx slot not found\n"); in q6tdm_set_channel_map()
189 return -EINVAL; in q6tdm_set_channel_map()
192 dev_err(dai->dev, "invalid tx num %d\n", in q6tdm_set_channel_map()
194 return -EINVAL; in q6tdm_set_channel_map()
198 tdm->ch_mapping[i] = tx_slot[i]; in q6tdm_set_channel_map()
201 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID; in q6tdm_set_channel_map()
203 tdm->num_channels = tx_num; in q6tdm_set_channel_map()
207 dev_err(dai->dev, "rx slot not found\n"); in q6tdm_set_channel_map()
208 return -EINVAL; in q6tdm_set_channel_map()
211 dev_err(dai->dev, "invalid rx num %d\n", in q6tdm_set_channel_map()
213 return -EINVAL; in q6tdm_set_channel_map()
217 tdm->ch_mapping[i] = rx_slot[i]; in q6tdm_set_channel_map()
220 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID; in q6tdm_set_channel_map()
222 tdm->num_channels = rx_num; in q6tdm_set_channel_map()
227 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", in q6tdm_set_channel_map()
228 __func__, dai->id); in q6tdm_set_channel_map()
229 return -EINVAL; in q6tdm_set_channel_map()
239 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6tdm_hw_params()
240 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; in q6tdm_hw_params()
242 tdm->bit_width = params_width(params); in q6tdm_hw_params()
243 tdm->sample_rate = params_rate(params); in q6tdm_hw_params()
244 tdm->num_channels = params_channels(params); in q6tdm_hw_params()
245 tdm->data_align_type = dai_data->priv[dai->id].data_align; in q6tdm_hw_params()
246 tdm->sync_src = dai_data->priv[dai->id].sync_src; in q6tdm_hw_params()
247 tdm->sync_mode = dai_data->priv[dai->id].sync_mode; in q6tdm_hw_params()
257 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6dma_set_channel_map()
258 struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg; in q6dma_set_channel_map()
262 switch (dai->id) { in q6dma_set_channel_map()
276 dev_err(dai->dev, "tx slot not found\n"); in q6dma_set_channel_map()
277 return -EINVAL; in q6dma_set_channel_map()
281 dev_err(dai->dev, "invalid tx num %d\n", in q6dma_set_channel_map()
283 return -EINVAL; in q6dma_set_channel_map()
300 dev_err(dai->dev, "rx slot not found\n"); in q6dma_set_channel_map()
301 return -EINVAL; in q6dma_set_channel_map()
304 dev_err(dai->dev, "invalid rx num %d\n", in q6dma_set_channel_map()
306 return -EINVAL; in q6dma_set_channel_map()
312 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", in q6dma_set_channel_map()
313 __func__, dai->id); in q6dma_set_channel_map()
314 return -EINVAL; in q6dma_set_channel_map()
317 cfg->active_channels_mask = ch_mask; in q6dma_set_channel_map()
326 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6dma_hw_params()
327 struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg; in q6dma_hw_params()
329 cfg->bit_width = params_width(params); in q6dma_hw_params()
330 cfg->sample_rate = params_rate(params); in q6dma_hw_params()
331 cfg->num_channels = params_channels(params); in q6dma_hw_params()
338 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_dai_shutdown()
341 if (!dai_data->is_port_started[dai->id]) in q6afe_dai_shutdown()
344 rc = q6afe_port_stop(dai_data->port[dai->id]); in q6afe_dai_shutdown()
346 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc); in q6afe_dai_shutdown()
348 dai_data->is_port_started[dai->id] = false; in q6afe_dai_shutdown()
355 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_dai_prepare()
358 if (dai_data->is_port_started[dai->id]) { in q6afe_dai_prepare()
360 rc = q6afe_port_stop(dai_data->port[dai->id]); in q6afe_dai_prepare()
362 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc); in q6afe_dai_prepare()
367 switch (dai->id) { in q6afe_dai_prepare()
370 q6afe_hdmi_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
371 &dai_data->port_config[dai->id].hdmi); in q6afe_dai_prepare()
374 q6afe_slim_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
375 &dai_data->port_config[dai->id].slim); in q6afe_dai_prepare()
379 rc = q6afe_i2s_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
380 &dai_data->port_config[dai->id].i2s_cfg); in q6afe_dai_prepare()
382 dev_err(dai->dev, "fail to prepare AFE port %x\n", in q6afe_dai_prepare()
383 dai->id); in q6afe_dai_prepare()
388 q6afe_tdm_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
389 &dai_data->port_config[dai->id].tdm); in q6afe_dai_prepare()
392 q6afe_cdc_dma_port_prepare(dai_data->port[dai->id], in q6afe_dai_prepare()
393 &dai_data->port_config[dai->id].dma_cfg); in q6afe_dai_prepare()
396 return -EINVAL; in q6afe_dai_prepare()
399 rc = q6afe_port_start(dai_data->port[dai->id]); in q6afe_dai_prepare()
401 dev_err(dai->dev, "fail to start AFE port %x\n", dai->id); in q6afe_dai_prepare()
404 dai_data->is_port_started[dai->id] = true; in q6afe_dai_prepare()
413 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6slim_set_channel_map()
414 struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id]; in q6slim_set_channel_map()
417 if (dai->id & 0x1) { in q6slim_set_channel_map()
421 return -EINVAL; in q6slim_set_channel_map()
425 pcfg->slim.ch_mapping[i] = tx_slot[i]; in q6slim_set_channel_map()
427 pcfg->slim.num_channels = tx_num; in q6slim_set_channel_map()
433 return -EINVAL; in q6slim_set_channel_map()
437 pcfg->slim.ch_mapping[i] = rx_slot[i]; in q6slim_set_channel_map()
439 pcfg->slim.num_channels = rx_num; in q6slim_set_channel_map()
449 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in q6afe_mi2s_set_sysclk()
450 struct q6afe_port *port = dai_data->port[dai->id]; in q6afe_mi2s_set_sysclk()
479 {"HDMI Playback", NULL, "HDMI_RX"},
480 {"DISPLAY_PORT_RX_0 Playback", NULL, "DISPLAY_PORT_RX"},
481 {"Slimbus Playback", NULL, "SLIMBUS_0_RX"},
482 {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"},
483 {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"},
484 {"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"},
485 {"Slimbus4 Playback", NULL, "SLIMBUS_4_RX"},
486 {"Slimbus5 Playback", NULL, "SLIMBUS_5_RX"},
487 {"Slimbus6 Playback", NULL, "SLIMBUS_6_RX"},
497 {"Primary MI2S Playback", NULL, "PRI_MI2S_RX"},
498 {"Secondary MI2S Playback", NULL, "SEC_MI2S_RX"},
499 {"Tertiary MI2S Playback", NULL, "TERT_MI2S_RX"},
500 {"Quaternary MI2S Playback", NULL, "QUAT_MI2S_RX"},
501 {"Quinary MI2S Playback", NULL, "QUIN_MI2S_RX"},
503 {"Primary TDM0 Playback", NULL, "PRIMARY_TDM_RX_0"},
504 {"Primary TDM1 Playback", NULL, "PRIMARY_TDM_RX_1"},
505 {"Primary TDM2 Playback", NULL, "PRIMARY_TDM_RX_2"},
506 {"Primary TDM3 Playback", NULL, "PRIMARY_TDM_RX_3"},
507 {"Primary TDM4 Playback", NULL, "PRIMARY_TDM_RX_4"},
508 {"Primary TDM5 Playback", NULL, "PRIMARY_TDM_RX_5"},
509 {"Primary TDM6 Playback", NULL, "PRIMARY_TDM_RX_6"},
510 {"Primary TDM7 Playback", NULL, "PRIMARY_TDM_RX_7"},
512 {"Secondary TDM0 Playback", NULL, "SEC_TDM_RX_0"},
513 {"Secondary TDM1 Playback", NULL, "SEC_TDM_RX_1"},
514 {"Secondary TDM2 Playback", NULL, "SEC_TDM_RX_2"},
515 {"Secondary TDM3 Playback", NULL, "SEC_TDM_RX_3"},
516 {"Secondary TDM4 Playback", NULL, "SEC_TDM_RX_4"},
517 {"Secondary TDM5 Playback", NULL, "SEC_TDM_RX_5"},
518 {"Secondary TDM6 Playback", NULL, "SEC_TDM_RX_6"},
519 {"Secondary TDM7 Playback", NULL, "SEC_TDM_RX_7"},
521 {"Tertiary TDM0 Playback", NULL, "TERT_TDM_RX_0"},
522 {"Tertiary TDM1 Playback", NULL, "TERT_TDM_RX_1"},
523 {"Tertiary TDM2 Playback", NULL, "TERT_TDM_RX_2"},
524 {"Tertiary TDM3 Playback", NULL, "TERT_TDM_RX_3"},
525 {"Tertiary TDM4 Playback", NULL, "TERT_TDM_RX_4"},
526 {"Tertiary TDM5 Playback", NULL, "TERT_TDM_RX_5"},
527 {"Tertiary TDM6 Playback", NULL, "TERT_TDM_RX_6"},
528 {"Tertiary TDM7 Playback", NULL, "TERT_TDM_RX_7"},
530 {"Quaternary TDM0 Playback", NULL, "QUAT_TDM_RX_0"},
531 {"Quaternary TDM1 Playback", NULL, "QUAT_TDM_RX_1"},
532 {"Quaternary TDM2 Playback", NULL, "QUAT_TDM_RX_2"},
533 {"Quaternary TDM3 Playback", NULL, "QUAT_TDM_RX_3"},
534 {"Quaternary TDM4 Playback", NULL, "QUAT_TDM_RX_4"},
535 {"Quaternary TDM5 Playback", NULL, "QUAT_TDM_RX_5"},
536 {"Quaternary TDM6 Playback", NULL, "QUAT_TDM_RX_6"},
537 {"Quaternary TDM7 Playback", NULL, "QUAT_TDM_RX_7"},
539 {"Quinary TDM0 Playback", NULL, "QUIN_TDM_RX_0"},
540 {"Quinary TDM1 Playback", NULL, "QUIN_TDM_RX_1"},
541 {"Quinary TDM2 Playback", NULL, "QUIN_TDM_RX_2"},
542 {"Quinary TDM3 Playback", NULL, "QUIN_TDM_RX_3"},
543 {"Quinary TDM4 Playback", NULL, "QUIN_TDM_RX_4"},
544 {"Quinary TDM5 Playback", NULL, "QUIN_TDM_RX_5"},
545 {"Quinary TDM6 Playback", NULL, "QUIN_TDM_RX_6"},
546 {"Quinary TDM7 Playback", NULL, "QUIN_TDM_RX_7"},
599 {"WSA_CODEC_DMA_RX_0 Playback", NULL, "WSA_CODEC_DMA_RX_0"},
601 {"WSA_CODEC_DMA_RX_1 Playback", NULL, "WSA_CODEC_DMA_RX_1"},
607 {"RX_CODEC_DMA_RX_0 Playback", NULL, "RX_CODEC_DMA_RX_0"},
609 {"RX_CODEC_DMA_RX_1 Playback", NULL, "RX_CODEC_DMA_RX_1"},
611 {"RX_CODEC_DMA_RX_2 Playback", NULL, "RX_CODEC_DMA_RX_2"},
613 {"RX_CODEC_DMA_RX_3 Playback", NULL, "RX_CODEC_DMA_RX_3"},
615 {"RX_CODEC_DMA_RX_4 Playback", NULL, "RX_CODEC_DMA_RX_4"},
617 {"RX_CODEC_DMA_RX_5 Playback", NULL, "RX_CODEC_DMA_RX_5"},
619 {"RX_CODEC_DMA_RX_6 Playback", NULL, "RX_CODEC_DMA_RX_6"},
620 {"RX_CODEC_DMA_RX_7 Playback", NULL, "RX_CODEC_DMA_RX_7"},
625 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in msm_dai_q6_dai_probe()
628 port = q6afe_port_get_from_id(dai->dev, dai->id); in msm_dai_q6_dai_probe()
630 dev_err(dai->dev, "Unable to get afe port\n"); in msm_dai_q6_dai_probe()
631 return -EINVAL; in msm_dai_q6_dai_probe()
633 dai_data->port[dai->id] = port; in msm_dai_q6_dai_probe()
640 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); in msm_dai_q6_dai_remove()
642 q6afe_port_put(dai_data->port[dai->id]); in msm_dai_q6_dai_remove()
643 dai_data->port[dai->id] = NULL; in msm_dai_q6_dai_remove()
729 "Secondary MI2S Playback SD1",
949 .name = "q6afe-dai-component",
964 for_each_child_of_node(dev->of_node, node) { in of_q6afe_parse_dai_data()
965 unsigned int lines[Q6AFE_MAX_MI2S_LINES]; in of_q6afe_parse_dai_data() local
979 priv = &data->priv[id]; in of_q6afe_parse_dai_data()
981 "qcom,sd-lines", in of_q6afe_parse_dai_data()
982 lines, 0, in of_q6afe_parse_dai_data()
989 priv->sd_line_mask = 0; in of_q6afe_parse_dai_data()
992 priv->sd_line_mask |= BIT(lines[i]); in of_q6afe_parse_dai_data()
996 priv = &data->priv[id]; in of_q6afe_parse_dai_data()
997 ret = of_property_read_u32(node, "qcom,tdm-sync-mode", in of_q6afe_parse_dai_data()
998 &priv->sync_mode); in of_q6afe_parse_dai_data()
1003 ret = of_property_read_u32(node, "qcom,tdm-sync-src", in of_q6afe_parse_dai_data()
1004 &priv->sync_src); in of_q6afe_parse_dai_data()
1009 ret = of_property_read_u32(node, "qcom,tdm-data-out", in of_q6afe_parse_dai_data()
1010 &priv->data_out_enable); in of_q6afe_parse_dai_data()
1015 ret = of_property_read_u32(node, "qcom,tdm-invert-sync", in of_q6afe_parse_dai_data()
1016 &priv->invert_sync); in of_q6afe_parse_dai_data()
1021 ret = of_property_read_u32(node, "qcom,tdm-data-delay", in of_q6afe_parse_dai_data()
1022 &priv->data_delay); in of_q6afe_parse_dai_data()
1027 ret = of_property_read_u32(node, "qcom,tdm-data-align", in of_q6afe_parse_dai_data()
1028 &priv->data_align); in of_q6afe_parse_dai_data()
1045 struct device *dev = &pdev->dev; in q6afe_dai_dev_probe()
1050 return -ENOMEM; in q6afe_dai_dev_probe()
1067 { .compatible = "qcom,q6afe-dais" },
1075 .name = "q6afe-dai",