1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. 3 // Copyright (c) 2018, Linaro Limited 4 5 #include <linux/err.h> 6 #include <linux/init.h> 7 #include <linux/module.h> 8 #include <linux/device.h> 9 #include <linux/platform_device.h> 10 #include <linux/slab.h> 11 #include <sound/pcm.h> 12 #include <sound/soc.h> 13 #include <sound/pcm_params.h> 14 #include "q6afe.h" 15 16 #define Q6AFE_TDM_PB_DAI(pre, num, did) { \ 17 .playback = { \ 18 .stream_name = pre" TDM"#num" Playback", \ 19 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 20 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 21 SNDRV_PCM_RATE_176400, \ 22 .formats = SNDRV_PCM_FMTBIT_S16_LE | \ 23 SNDRV_PCM_FMTBIT_S24_LE | \ 24 SNDRV_PCM_FMTBIT_S32_LE, \ 25 .channels_min = 1, \ 26 .channels_max = 8, \ 27 .rate_min = 8000, \ 28 .rate_max = 176400, \ 29 }, \ 30 .name = #did, \ 31 .ops = &q6tdm_ops, \ 32 .id = did, \ 33 .probe = msm_dai_q6_dai_probe, \ 34 .remove = msm_dai_q6_dai_remove, \ 35 } 36 37 #define Q6AFE_TDM_CAP_DAI(pre, num, did) { \ 38 .capture = { \ 39 .stream_name = pre" TDM"#num" Capture", \ 40 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 41 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 42 SNDRV_PCM_RATE_176400, \ 43 .formats = SNDRV_PCM_FMTBIT_S16_LE | \ 44 SNDRV_PCM_FMTBIT_S24_LE | \ 45 SNDRV_PCM_FMTBIT_S32_LE, \ 46 .channels_min = 1, \ 47 .channels_max = 8, \ 48 .rate_min = 8000, \ 49 .rate_max = 176400, \ 50 }, \ 51 .name = #did, \ 52 .ops = &q6tdm_ops, \ 53 .id = did, \ 54 .probe = msm_dai_q6_dai_probe, \ 55 .remove = msm_dai_q6_dai_remove, \ 56 } 57 58 #define Q6AFE_CDC_DMA_RX_DAI(did) { \ 59 .playback = { \ 60 .stream_name = #did" Playback", \ 61 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 62 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 63 SNDRV_PCM_RATE_176400, \ 64 .formats = SNDRV_PCM_FMTBIT_S16_LE | \ 65 SNDRV_PCM_FMTBIT_S24_LE | \ 66 SNDRV_PCM_FMTBIT_S32_LE, \ 67 .channels_min = 1, \ 68 .channels_max = 8, \ 69 .rate_min = 8000, \ 70 .rate_max = 176400, \ 71 }, \ 72 .name = #did, \ 73 .ops = &q6dma_ops, \ 74 .id = did, \ 75 .probe = msm_dai_q6_dai_probe, \ 76 .remove = msm_dai_q6_dai_remove, \ 77 } 78 79 #define Q6AFE_CDC_DMA_TX_DAI(did) { \ 80 .capture = { \ 81 .stream_name = #did" Capture", \ 82 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 83 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 84 SNDRV_PCM_RATE_176400, \ 85 .formats = SNDRV_PCM_FMTBIT_S16_LE | \ 86 SNDRV_PCM_FMTBIT_S24_LE | \ 87 SNDRV_PCM_FMTBIT_S32_LE, \ 88 .channels_min = 1, \ 89 .channels_max = 8, \ 90 .rate_min = 8000, \ 91 .rate_max = 176400, \ 92 }, \ 93 .name = #did, \ 94 .ops = &q6dma_ops, \ 95 .id = did, \ 96 .probe = msm_dai_q6_dai_probe, \ 97 .remove = msm_dai_q6_dai_remove, \ 98 } 99 100 struct q6afe_dai_priv_data { 101 uint32_t sd_line_mask; 102 uint32_t sync_mode; 103 uint32_t sync_src; 104 uint32_t data_out_enable; 105 uint32_t invert_sync; 106 uint32_t data_delay; 107 uint32_t data_align; 108 }; 109 110 struct q6afe_dai_data { 111 struct q6afe_port *port[AFE_PORT_MAX]; 112 struct q6afe_port_config port_config[AFE_PORT_MAX]; 113 bool is_port_started[AFE_PORT_MAX]; 114 struct q6afe_dai_priv_data priv[AFE_PORT_MAX]; 115 }; 116 117 static int q6slim_hw_params(struct snd_pcm_substream *substream, 118 struct snd_pcm_hw_params *params, 119 struct snd_soc_dai *dai) 120 { 121 122 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 123 struct q6afe_slim_cfg *slim = &dai_data->port_config[dai->id].slim; 124 125 slim->sample_rate = params_rate(params); 126 127 switch (params_format(params)) { 128 case SNDRV_PCM_FORMAT_S16_LE: 129 case SNDRV_PCM_FORMAT_SPECIAL: 130 slim->bit_width = 16; 131 break; 132 case SNDRV_PCM_FORMAT_S24_LE: 133 slim->bit_width = 24; 134 break; 135 case SNDRV_PCM_FORMAT_S32_LE: 136 slim->bit_width = 32; 137 break; 138 default: 139 pr_err("%s: format %d\n", 140 __func__, params_format(params)); 141 return -EINVAL; 142 } 143 144 return 0; 145 } 146 147 static int q6hdmi_hw_params(struct snd_pcm_substream *substream, 148 struct snd_pcm_hw_params *params, 149 struct snd_soc_dai *dai) 150 { 151 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 152 int channels = params_channels(params); 153 struct q6afe_hdmi_cfg *hdmi = &dai_data->port_config[dai->id].hdmi; 154 155 hdmi->sample_rate = params_rate(params); 156 switch (params_format(params)) { 157 case SNDRV_PCM_FORMAT_S16_LE: 158 hdmi->bit_width = 16; 159 break; 160 case SNDRV_PCM_FORMAT_S24_LE: 161 hdmi->bit_width = 24; 162 break; 163 } 164 165 /* HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4 */ 166 switch (channels) { 167 case 2: 168 hdmi->channel_allocation = 0; 169 break; 170 case 3: 171 hdmi->channel_allocation = 0x02; 172 break; 173 case 4: 174 hdmi->channel_allocation = 0x06; 175 break; 176 case 5: 177 hdmi->channel_allocation = 0x0A; 178 break; 179 case 6: 180 hdmi->channel_allocation = 0x0B; 181 break; 182 case 7: 183 hdmi->channel_allocation = 0x12; 184 break; 185 case 8: 186 hdmi->channel_allocation = 0x13; 187 break; 188 default: 189 dev_err(dai->dev, "invalid Channels = %u\n", channels); 190 return -EINVAL; 191 } 192 193 return 0; 194 } 195 196 static int q6i2s_hw_params(struct snd_pcm_substream *substream, 197 struct snd_pcm_hw_params *params, 198 struct snd_soc_dai *dai) 199 { 200 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 201 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg; 202 203 i2s->sample_rate = params_rate(params); 204 i2s->bit_width = params_width(params); 205 i2s->num_channels = params_channels(params); 206 i2s->sd_line_mask = dai_data->priv[dai->id].sd_line_mask; 207 208 return 0; 209 } 210 211 static int q6i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 212 { 213 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 214 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg; 215 216 i2s->fmt = fmt; 217 218 return 0; 219 } 220 221 static int q6tdm_set_tdm_slot(struct snd_soc_dai *dai, 222 unsigned int tx_mask, 223 unsigned int rx_mask, 224 int slots, int slot_width) 225 { 226 227 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 228 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; 229 unsigned int cap_mask; 230 int rc = 0; 231 232 /* HW only supports 16 and 32 bit slot width configuration */ 233 if ((slot_width != 16) && (slot_width != 32)) { 234 dev_err(dai->dev, "%s: invalid slot_width %d\n", 235 __func__, slot_width); 236 return -EINVAL; 237 } 238 239 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */ 240 switch (slots) { 241 case 2: 242 cap_mask = 0x03; 243 break; 244 case 4: 245 cap_mask = 0x0F; 246 break; 247 case 8: 248 cap_mask = 0xFF; 249 break; 250 case 16: 251 cap_mask = 0xFFFF; 252 break; 253 default: 254 dev_err(dai->dev, "%s: invalid slots %d\n", 255 __func__, slots); 256 return -EINVAL; 257 } 258 259 switch (dai->id) { 260 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 261 tdm->nslots_per_frame = slots; 262 tdm->slot_width = slot_width; 263 /* TDM RX dais ids are even and tx are odd */ 264 tdm->slot_mask = ((dai->id & 0x1) ? tx_mask : rx_mask) & cap_mask; 265 break; 266 default: 267 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", 268 __func__, dai->id); 269 return -EINVAL; 270 } 271 272 return rc; 273 } 274 275 static int q6tdm_set_channel_map(struct snd_soc_dai *dai, 276 unsigned int tx_num, unsigned int *tx_slot, 277 unsigned int rx_num, unsigned int *rx_slot) 278 { 279 280 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 281 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; 282 int rc = 0; 283 int i = 0; 284 285 switch (dai->id) { 286 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 287 if (dai->id & 0x1) { 288 if (!tx_slot) { 289 dev_err(dai->dev, "tx slot not found\n"); 290 return -EINVAL; 291 } 292 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { 293 dev_err(dai->dev, "invalid tx num %d\n", 294 tx_num); 295 return -EINVAL; 296 } 297 298 for (i = 0; i < tx_num; i++) 299 tdm->ch_mapping[i] = tx_slot[i]; 300 301 for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) 302 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID; 303 304 tdm->num_channels = tx_num; 305 } else { 306 /* rx */ 307 if (!rx_slot) { 308 dev_err(dai->dev, "rx slot not found\n"); 309 return -EINVAL; 310 } 311 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { 312 dev_err(dai->dev, "invalid rx num %d\n", 313 rx_num); 314 return -EINVAL; 315 } 316 317 for (i = 0; i < rx_num; i++) 318 tdm->ch_mapping[i] = rx_slot[i]; 319 320 for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) 321 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID; 322 323 tdm->num_channels = rx_num; 324 } 325 326 break; 327 default: 328 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", 329 __func__, dai->id); 330 return -EINVAL; 331 } 332 333 return rc; 334 } 335 336 static int q6tdm_hw_params(struct snd_pcm_substream *substream, 337 struct snd_pcm_hw_params *params, 338 struct snd_soc_dai *dai) 339 { 340 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 341 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm; 342 343 tdm->bit_width = params_width(params); 344 tdm->sample_rate = params_rate(params); 345 tdm->num_channels = params_channels(params); 346 tdm->data_align_type = dai_data->priv[dai->id].data_align; 347 tdm->sync_src = dai_data->priv[dai->id].sync_src; 348 tdm->sync_mode = dai_data->priv[dai->id].sync_mode; 349 350 return 0; 351 } 352 353 static int q6dma_set_channel_map(struct snd_soc_dai *dai, 354 unsigned int tx_num, unsigned int *tx_ch_mask, 355 unsigned int rx_num, unsigned int *rx_ch_mask) 356 { 357 358 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 359 struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg; 360 int ch_mask; 361 int rc = 0; 362 363 switch (dai->id) { 364 case WSA_CODEC_DMA_TX_0: 365 case WSA_CODEC_DMA_TX_1: 366 case WSA_CODEC_DMA_TX_2: 367 case VA_CODEC_DMA_TX_0: 368 case VA_CODEC_DMA_TX_1: 369 case VA_CODEC_DMA_TX_2: 370 case TX_CODEC_DMA_TX_0: 371 case TX_CODEC_DMA_TX_1: 372 case TX_CODEC_DMA_TX_2: 373 case TX_CODEC_DMA_TX_3: 374 case TX_CODEC_DMA_TX_4: 375 case TX_CODEC_DMA_TX_5: 376 if (!tx_ch_mask) { 377 dev_err(dai->dev, "tx slot not found\n"); 378 return -EINVAL; 379 } 380 381 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { 382 dev_err(dai->dev, "invalid tx num %d\n", 383 tx_num); 384 return -EINVAL; 385 } 386 ch_mask = *tx_ch_mask; 387 388 break; 389 case WSA_CODEC_DMA_RX_0: 390 case WSA_CODEC_DMA_RX_1: 391 case RX_CODEC_DMA_RX_0: 392 case RX_CODEC_DMA_RX_1: 393 case RX_CODEC_DMA_RX_2: 394 case RX_CODEC_DMA_RX_3: 395 case RX_CODEC_DMA_RX_4: 396 case RX_CODEC_DMA_RX_5: 397 case RX_CODEC_DMA_RX_6: 398 case RX_CODEC_DMA_RX_7: 399 /* rx */ 400 if (!rx_ch_mask) { 401 dev_err(dai->dev, "rx slot not found\n"); 402 return -EINVAL; 403 } 404 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { 405 dev_err(dai->dev, "invalid rx num %d\n", 406 rx_num); 407 return -EINVAL; 408 } 409 ch_mask = *rx_ch_mask; 410 411 break; 412 default: 413 dev_err(dai->dev, "%s: invalid dai id 0x%x\n", 414 __func__, dai->id); 415 return -EINVAL; 416 } 417 418 cfg->active_channels_mask = ch_mask; 419 420 return rc; 421 } 422 423 static int q6dma_hw_params(struct snd_pcm_substream *substream, 424 struct snd_pcm_hw_params *params, 425 struct snd_soc_dai *dai) 426 { 427 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 428 struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg; 429 430 cfg->bit_width = params_width(params); 431 cfg->sample_rate = params_rate(params); 432 cfg->num_channels = params_channels(params); 433 434 return 0; 435 } 436 static void q6afe_dai_shutdown(struct snd_pcm_substream *substream, 437 struct snd_soc_dai *dai) 438 { 439 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 440 int rc; 441 442 if (!dai_data->is_port_started[dai->id]) 443 return; 444 445 rc = q6afe_port_stop(dai_data->port[dai->id]); 446 if (rc < 0) 447 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc); 448 449 dai_data->is_port_started[dai->id] = false; 450 451 } 452 453 static int q6afe_dai_prepare(struct snd_pcm_substream *substream, 454 struct snd_soc_dai *dai) 455 { 456 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 457 int rc; 458 459 if (dai_data->is_port_started[dai->id]) { 460 /* stop the port and restart with new port config */ 461 rc = q6afe_port_stop(dai_data->port[dai->id]); 462 if (rc < 0) { 463 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc); 464 return rc; 465 } 466 } 467 468 switch (dai->id) { 469 case HDMI_RX: 470 case DISPLAY_PORT_RX: 471 q6afe_hdmi_port_prepare(dai_data->port[dai->id], 472 &dai_data->port_config[dai->id].hdmi); 473 break; 474 case SLIMBUS_0_RX ... SLIMBUS_6_TX: 475 q6afe_slim_port_prepare(dai_data->port[dai->id], 476 &dai_data->port_config[dai->id].slim); 477 break; 478 case QUINARY_MI2S_RX ... QUINARY_MI2S_TX: 479 case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX: 480 rc = q6afe_i2s_port_prepare(dai_data->port[dai->id], 481 &dai_data->port_config[dai->id].i2s_cfg); 482 if (rc < 0) { 483 dev_err(dai->dev, "fail to prepare AFE port %x\n", 484 dai->id); 485 return rc; 486 } 487 break; 488 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 489 q6afe_tdm_port_prepare(dai_data->port[dai->id], 490 &dai_data->port_config[dai->id].tdm); 491 break; 492 case WSA_CODEC_DMA_RX_0 ... RX_CODEC_DMA_RX_7: 493 q6afe_cdc_dma_port_prepare(dai_data->port[dai->id], 494 &dai_data->port_config[dai->id].dma_cfg); 495 break; 496 default: 497 return -EINVAL; 498 } 499 500 rc = q6afe_port_start(dai_data->port[dai->id]); 501 if (rc < 0) { 502 dev_err(dai->dev, "fail to start AFE port %x\n", dai->id); 503 return rc; 504 } 505 dai_data->is_port_started[dai->id] = true; 506 507 return 0; 508 } 509 510 static int q6slim_set_channel_map(struct snd_soc_dai *dai, 511 unsigned int tx_num, unsigned int *tx_slot, 512 unsigned int rx_num, unsigned int *rx_slot) 513 { 514 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 515 struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id]; 516 int i; 517 518 if (dai->id & 0x1) { 519 /* TX */ 520 if (!tx_slot) { 521 pr_err("%s: tx slot not found\n", __func__); 522 return -EINVAL; 523 } 524 525 for (i = 0; i < tx_num; i++) 526 pcfg->slim.ch_mapping[i] = tx_slot[i]; 527 528 pcfg->slim.num_channels = tx_num; 529 530 531 } else { 532 if (!rx_slot) { 533 pr_err("%s: rx slot not found\n", __func__); 534 return -EINVAL; 535 } 536 537 for (i = 0; i < rx_num; i++) 538 pcfg->slim.ch_mapping[i] = rx_slot[i]; 539 540 pcfg->slim.num_channels = rx_num; 541 542 } 543 544 return 0; 545 } 546 547 static int q6afe_mi2s_set_sysclk(struct snd_soc_dai *dai, 548 int clk_id, unsigned int freq, int dir) 549 { 550 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 551 struct q6afe_port *port = dai_data->port[dai->id]; 552 553 switch (clk_id) { 554 case LPAIF_DIG_CLK: 555 return q6afe_port_set_sysclk(port, clk_id, 0, 5, freq, dir); 556 case LPAIF_BIT_CLK: 557 case LPAIF_OSR_CLK: 558 return q6afe_port_set_sysclk(port, clk_id, 559 Q6AFE_LPASS_CLK_SRC_INTERNAL, 560 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 561 freq, dir); 562 case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR: 563 case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1: 564 case Q6AFE_LPASS_CLK_ID_WSA_CORE_MCLK ... Q6AFE_LPASS_CLK_ID_VA_CORE_2X_MCLK: 565 return q6afe_port_set_sysclk(port, clk_id, 566 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, 567 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 568 freq, dir); 569 case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT: 570 return q6afe_port_set_sysclk(port, clk_id, 571 Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO, 572 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 573 freq, dir); 574 } 575 576 return 0; 577 } 578 579 static const struct snd_soc_dapm_route q6afe_dapm_routes[] = { 580 {"HDMI Playback", NULL, "HDMI_RX"}, 581 {"Display Port Playback", NULL, "DISPLAY_PORT_RX"}, 582 {"Slimbus Playback", NULL, "SLIMBUS_0_RX"}, 583 {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"}, 584 {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"}, 585 {"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"}, 586 {"Slimbus4 Playback", NULL, "SLIMBUS_4_RX"}, 587 {"Slimbus5 Playback", NULL, "SLIMBUS_5_RX"}, 588 {"Slimbus6 Playback", NULL, "SLIMBUS_6_RX"}, 589 590 {"SLIMBUS_0_TX", NULL, "Slimbus Capture"}, 591 {"SLIMBUS_1_TX", NULL, "Slimbus1 Capture"}, 592 {"SLIMBUS_2_TX", NULL, "Slimbus2 Capture"}, 593 {"SLIMBUS_3_TX", NULL, "Slimbus3 Capture"}, 594 {"SLIMBUS_4_TX", NULL, "Slimbus4 Capture"}, 595 {"SLIMBUS_5_TX", NULL, "Slimbus5 Capture"}, 596 {"SLIMBUS_6_TX", NULL, "Slimbus6 Capture"}, 597 598 {"Primary MI2S Playback", NULL, "PRI_MI2S_RX"}, 599 {"Secondary MI2S Playback", NULL, "SEC_MI2S_RX"}, 600 {"Tertiary MI2S Playback", NULL, "TERT_MI2S_RX"}, 601 {"Quaternary MI2S Playback", NULL, "QUAT_MI2S_RX"}, 602 {"Quinary MI2S Playback", NULL, "QUIN_MI2S_RX"}, 603 604 {"Primary TDM0 Playback", NULL, "PRIMARY_TDM_RX_0"}, 605 {"Primary TDM1 Playback", NULL, "PRIMARY_TDM_RX_1"}, 606 {"Primary TDM2 Playback", NULL, "PRIMARY_TDM_RX_2"}, 607 {"Primary TDM3 Playback", NULL, "PRIMARY_TDM_RX_3"}, 608 {"Primary TDM4 Playback", NULL, "PRIMARY_TDM_RX_4"}, 609 {"Primary TDM5 Playback", NULL, "PRIMARY_TDM_RX_5"}, 610 {"Primary TDM6 Playback", NULL, "PRIMARY_TDM_RX_6"}, 611 {"Primary TDM7 Playback", NULL, "PRIMARY_TDM_RX_7"}, 612 613 {"Secondary TDM0 Playback", NULL, "SEC_TDM_RX_0"}, 614 {"Secondary TDM1 Playback", NULL, "SEC_TDM_RX_1"}, 615 {"Secondary TDM2 Playback", NULL, "SEC_TDM_RX_2"}, 616 {"Secondary TDM3 Playback", NULL, "SEC_TDM_RX_3"}, 617 {"Secondary TDM4 Playback", NULL, "SEC_TDM_RX_4"}, 618 {"Secondary TDM5 Playback", NULL, "SEC_TDM_RX_5"}, 619 {"Secondary TDM6 Playback", NULL, "SEC_TDM_RX_6"}, 620 {"Secondary TDM7 Playback", NULL, "SEC_TDM_RX_7"}, 621 622 {"Tertiary TDM0 Playback", NULL, "TERT_TDM_RX_0"}, 623 {"Tertiary TDM1 Playback", NULL, "TERT_TDM_RX_1"}, 624 {"Tertiary TDM2 Playback", NULL, "TERT_TDM_RX_2"}, 625 {"Tertiary TDM3 Playback", NULL, "TERT_TDM_RX_3"}, 626 {"Tertiary TDM4 Playback", NULL, "TERT_TDM_RX_4"}, 627 {"Tertiary TDM5 Playback", NULL, "TERT_TDM_RX_5"}, 628 {"Tertiary TDM6 Playback", NULL, "TERT_TDM_RX_6"}, 629 {"Tertiary TDM7 Playback", NULL, "TERT_TDM_RX_7"}, 630 631 {"Quaternary TDM0 Playback", NULL, "QUAT_TDM_RX_0"}, 632 {"Quaternary TDM1 Playback", NULL, "QUAT_TDM_RX_1"}, 633 {"Quaternary TDM2 Playback", NULL, "QUAT_TDM_RX_2"}, 634 {"Quaternary TDM3 Playback", NULL, "QUAT_TDM_RX_3"}, 635 {"Quaternary TDM4 Playback", NULL, "QUAT_TDM_RX_4"}, 636 {"Quaternary TDM5 Playback", NULL, "QUAT_TDM_RX_5"}, 637 {"Quaternary TDM6 Playback", NULL, "QUAT_TDM_RX_6"}, 638 {"Quaternary TDM7 Playback", NULL, "QUAT_TDM_RX_7"}, 639 640 {"Quinary TDM0 Playback", NULL, "QUIN_TDM_RX_0"}, 641 {"Quinary TDM1 Playback", NULL, "QUIN_TDM_RX_1"}, 642 {"Quinary TDM2 Playback", NULL, "QUIN_TDM_RX_2"}, 643 {"Quinary TDM3 Playback", NULL, "QUIN_TDM_RX_3"}, 644 {"Quinary TDM4 Playback", NULL, "QUIN_TDM_RX_4"}, 645 {"Quinary TDM5 Playback", NULL, "QUIN_TDM_RX_5"}, 646 {"Quinary TDM6 Playback", NULL, "QUIN_TDM_RX_6"}, 647 {"Quinary TDM7 Playback", NULL, "QUIN_TDM_RX_7"}, 648 649 {"PRIMARY_TDM_TX_0", NULL, "Primary TDM0 Capture"}, 650 {"PRIMARY_TDM_TX_1", NULL, "Primary TDM1 Capture"}, 651 {"PRIMARY_TDM_TX_2", NULL, "Primary TDM2 Capture"}, 652 {"PRIMARY_TDM_TX_3", NULL, "Primary TDM3 Capture"}, 653 {"PRIMARY_TDM_TX_4", NULL, "Primary TDM4 Capture"}, 654 {"PRIMARY_TDM_TX_5", NULL, "Primary TDM5 Capture"}, 655 {"PRIMARY_TDM_TX_6", NULL, "Primary TDM6 Capture"}, 656 {"PRIMARY_TDM_TX_7", NULL, "Primary TDM7 Capture"}, 657 658 {"SEC_TDM_TX_0", NULL, "Secondary TDM0 Capture"}, 659 {"SEC_TDM_TX_1", NULL, "Secondary TDM1 Capture"}, 660 {"SEC_TDM_TX_2", NULL, "Secondary TDM2 Capture"}, 661 {"SEC_TDM_TX_3", NULL, "Secondary TDM3 Capture"}, 662 {"SEC_TDM_TX_4", NULL, "Secondary TDM4 Capture"}, 663 {"SEC_TDM_TX_5", NULL, "Secondary TDM5 Capture"}, 664 {"SEC_TDM_TX_6", NULL, "Secondary TDM6 Capture"}, 665 {"SEC_TDM_TX_7", NULL, "Secondary TDM7 Capture"}, 666 667 {"TERT_TDM_TX_0", NULL, "Tertiary TDM0 Capture"}, 668 {"TERT_TDM_TX_1", NULL, "Tertiary TDM1 Capture"}, 669 {"TERT_TDM_TX_2", NULL, "Tertiary TDM2 Capture"}, 670 {"TERT_TDM_TX_3", NULL, "Tertiary TDM3 Capture"}, 671 {"TERT_TDM_TX_4", NULL, "Tertiary TDM4 Capture"}, 672 {"TERT_TDM_TX_5", NULL, "Tertiary TDM5 Capture"}, 673 {"TERT_TDM_TX_6", NULL, "Tertiary TDM6 Capture"}, 674 {"TERT_TDM_TX_7", NULL, "Tertiary TDM7 Capture"}, 675 676 {"QUAT_TDM_TX_0", NULL, "Quaternary TDM0 Capture"}, 677 {"QUAT_TDM_TX_1", NULL, "Quaternary TDM1 Capture"}, 678 {"QUAT_TDM_TX_2", NULL, "Quaternary TDM2 Capture"}, 679 {"QUAT_TDM_TX_3", NULL, "Quaternary TDM3 Capture"}, 680 {"QUAT_TDM_TX_4", NULL, "Quaternary TDM4 Capture"}, 681 {"QUAT_TDM_TX_5", NULL, "Quaternary TDM5 Capture"}, 682 {"QUAT_TDM_TX_6", NULL, "Quaternary TDM6 Capture"}, 683 {"QUAT_TDM_TX_7", NULL, "Quaternary TDM7 Capture"}, 684 685 {"QUIN_TDM_TX_0", NULL, "Quinary TDM0 Capture"}, 686 {"QUIN_TDM_TX_1", NULL, "Quinary TDM1 Capture"}, 687 {"QUIN_TDM_TX_2", NULL, "Quinary TDM2 Capture"}, 688 {"QUIN_TDM_TX_3", NULL, "Quinary TDM3 Capture"}, 689 {"QUIN_TDM_TX_4", NULL, "Quinary TDM4 Capture"}, 690 {"QUIN_TDM_TX_5", NULL, "Quinary TDM5 Capture"}, 691 {"QUIN_TDM_TX_6", NULL, "Quinary TDM6 Capture"}, 692 {"QUIN_TDM_TX_7", NULL, "Quinary TDM7 Capture"}, 693 694 {"TERT_MI2S_TX", NULL, "Tertiary MI2S Capture"}, 695 {"PRI_MI2S_TX", NULL, "Primary MI2S Capture"}, 696 {"SEC_MI2S_TX", NULL, "Secondary MI2S Capture"}, 697 {"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"}, 698 {"QUIN_MI2S_TX", NULL, "Quinary MI2S Capture"}, 699 700 {"WSA_CODEC_DMA_RX_0 Playback", NULL, "WSA_CODEC_DMA_RX_0"}, 701 {"WSA_CODEC_DMA_TX_0", NULL, "WSA_CODEC_DMA_TX_0 Capture"}, 702 {"WSA_CODEC_DMA_RX_1 Playback", NULL, "WSA_CODEC_DMA_RX_1"}, 703 {"WSA_CODEC_DMA_TX_1", NULL, "WSA_CODEC_DMA_TX_1 Capture"}, 704 {"WSA_CODEC_DMA_TX_2", NULL, "WSA_CODEC_DMA_TX_2 Capture"}, 705 {"VA_CODEC_DMA_TX_0", NULL, "VA_CODEC_DMA_TX_0 Capture"}, 706 {"VA_CODEC_DMA_TX_1", NULL, "VA_CODEC_DMA_TX_1 Capture"}, 707 {"VA_CODEC_DMA_TX_2", NULL, "VA_CODEC_DMA_TX_2 Capture"}, 708 {"RX_CODEC_DMA_RX_0 Playback", NULL, "RX_CODEC_DMA_RX_0"}, 709 {"TX_CODEC_DMA_TX_0", NULL, "TX_CODEC_DMA_TX_0 Capture"}, 710 {"RX_CODEC_DMA_RX_1 Playback", NULL, "RX_CODEC_DMA_RX_1"}, 711 {"TX_CODEC_DMA_TX_1", NULL, "TX_CODEC_DMA_TX_1 Capture"}, 712 {"RX_CODEC_DMA_RX_2 Playback", NULL, "RX_CODEC_DMA_RX_2"}, 713 {"TX_CODEC_DMA_TX_2", NULL, "TX_CODEC_DMA_TX_2 Capture"}, 714 {"RX_CODEC_DMA_RX_3 Playback", NULL, "RX_CODEC_DMA_RX_3"}, 715 {"TX_CODEC_DMA_TX_3", NULL, "TX_CODEC_DMA_TX_3 Capture"}, 716 {"RX_CODEC_DMA_RX_4 Playback", NULL, "RX_CODEC_DMA_RX_4"}, 717 {"TX_CODEC_DMA_TX_4", NULL, "TX_CODEC_DMA_TX_4 Capture"}, 718 {"RX_CODEC_DMA_RX_5 Playback", NULL, "RX_CODEC_DMA_RX_5"}, 719 {"TX_CODEC_DMA_TX_5", NULL, "TX_CODEC_DMA_TX_5 Capture"}, 720 {"RX_CODEC_DMA_RX_6 Playback", NULL, "RX_CODEC_DMA_RX_6"}, 721 {"RX_CODEC_DMA_RX_7 Playback", NULL, "RX_CODEC_DMA_RX_7"}, 722 }; 723 724 static const struct snd_soc_dai_ops q6hdmi_ops = { 725 .prepare = q6afe_dai_prepare, 726 .hw_params = q6hdmi_hw_params, 727 .shutdown = q6afe_dai_shutdown, 728 }; 729 730 static const struct snd_soc_dai_ops q6i2s_ops = { 731 .prepare = q6afe_dai_prepare, 732 .hw_params = q6i2s_hw_params, 733 .set_fmt = q6i2s_set_fmt, 734 .shutdown = q6afe_dai_shutdown, 735 .set_sysclk = q6afe_mi2s_set_sysclk, 736 }; 737 738 static const struct snd_soc_dai_ops q6slim_ops = { 739 .prepare = q6afe_dai_prepare, 740 .hw_params = q6slim_hw_params, 741 .shutdown = q6afe_dai_shutdown, 742 .set_channel_map = q6slim_set_channel_map, 743 }; 744 745 static const struct snd_soc_dai_ops q6tdm_ops = { 746 .prepare = q6afe_dai_prepare, 747 .shutdown = q6afe_dai_shutdown, 748 .set_sysclk = q6afe_mi2s_set_sysclk, 749 .set_tdm_slot = q6tdm_set_tdm_slot, 750 .set_channel_map = q6tdm_set_channel_map, 751 .hw_params = q6tdm_hw_params, 752 }; 753 754 static const struct snd_soc_dai_ops q6dma_ops = { 755 .prepare = q6afe_dai_prepare, 756 .shutdown = q6afe_dai_shutdown, 757 .set_sysclk = q6afe_mi2s_set_sysclk, 758 .set_channel_map = q6dma_set_channel_map, 759 .hw_params = q6dma_hw_params, 760 }; 761 762 static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) 763 { 764 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 765 struct q6afe_port *port; 766 767 port = q6afe_port_get_from_id(dai->dev, dai->id); 768 if (IS_ERR(port)) { 769 dev_err(dai->dev, "Unable to get afe port\n"); 770 return -EINVAL; 771 } 772 dai_data->port[dai->id] = port; 773 774 return 0; 775 } 776 777 static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai) 778 { 779 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 780 781 q6afe_port_put(dai_data->port[dai->id]); 782 dai_data->port[dai->id] = NULL; 783 784 return 0; 785 } 786 787 static struct snd_soc_dai_driver q6afe_dais[] = { 788 { 789 .playback = { 790 .stream_name = "HDMI Playback", 791 .rates = SNDRV_PCM_RATE_48000 | 792 SNDRV_PCM_RATE_96000 | 793 SNDRV_PCM_RATE_192000, 794 .formats = SNDRV_PCM_FMTBIT_S16_LE | 795 SNDRV_PCM_FMTBIT_S24_LE, 796 .channels_min = 2, 797 .channels_max = 8, 798 .rate_max = 192000, 799 .rate_min = 48000, 800 }, 801 .ops = &q6hdmi_ops, 802 .id = HDMI_RX, 803 .name = "HDMI", 804 .probe = msm_dai_q6_dai_probe, 805 .remove = msm_dai_q6_dai_remove, 806 }, { 807 .name = "SLIMBUS_0_RX", 808 .ops = &q6slim_ops, 809 .id = SLIMBUS_0_RX, 810 .probe = msm_dai_q6_dai_probe, 811 .remove = msm_dai_q6_dai_remove, 812 .playback = { 813 .stream_name = "Slimbus Playback", 814 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 815 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 816 SNDRV_PCM_RATE_192000, 817 .formats = SNDRV_PCM_FMTBIT_S16_LE | 818 SNDRV_PCM_FMTBIT_S24_LE, 819 .channels_min = 1, 820 .channels_max = 8, 821 .rate_min = 8000, 822 .rate_max = 192000, 823 }, 824 }, { 825 .name = "SLIMBUS_0_TX", 826 .ops = &q6slim_ops, 827 .id = SLIMBUS_0_TX, 828 .probe = msm_dai_q6_dai_probe, 829 .remove = msm_dai_q6_dai_remove, 830 .capture = { 831 .stream_name = "Slimbus Capture", 832 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 833 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 834 SNDRV_PCM_RATE_192000, 835 .formats = SNDRV_PCM_FMTBIT_S16_LE | 836 SNDRV_PCM_FMTBIT_S24_LE, 837 .channels_min = 1, 838 .channels_max = 8, 839 .rate_min = 8000, 840 .rate_max = 192000, 841 }, 842 }, { 843 .playback = { 844 .stream_name = "Slimbus1 Playback", 845 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 846 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 847 SNDRV_PCM_RATE_192000, 848 .formats = SNDRV_PCM_FMTBIT_S16_LE | 849 SNDRV_PCM_FMTBIT_S24_LE, 850 .channels_min = 1, 851 .channels_max = 2, 852 .rate_min = 8000, 853 .rate_max = 192000, 854 }, 855 .name = "SLIMBUS_1_RX", 856 .ops = &q6slim_ops, 857 .id = SLIMBUS_1_RX, 858 .probe = msm_dai_q6_dai_probe, 859 .remove = msm_dai_q6_dai_remove, 860 }, { 861 .name = "SLIMBUS_1_TX", 862 .ops = &q6slim_ops, 863 .id = SLIMBUS_1_TX, 864 .probe = msm_dai_q6_dai_probe, 865 .remove = msm_dai_q6_dai_remove, 866 .capture = { 867 .stream_name = "Slimbus1 Capture", 868 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 869 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 870 SNDRV_PCM_RATE_192000, 871 .formats = SNDRV_PCM_FMTBIT_S16_LE | 872 SNDRV_PCM_FMTBIT_S24_LE, 873 .channels_min = 1, 874 .channels_max = 8, 875 .rate_min = 8000, 876 .rate_max = 192000, 877 }, 878 }, { 879 .playback = { 880 .stream_name = "Slimbus2 Playback", 881 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 882 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 883 SNDRV_PCM_RATE_192000, 884 .formats = SNDRV_PCM_FMTBIT_S16_LE | 885 SNDRV_PCM_FMTBIT_S24_LE, 886 .channels_min = 1, 887 .channels_max = 8, 888 .rate_min = 8000, 889 .rate_max = 192000, 890 }, 891 .name = "SLIMBUS_2_RX", 892 .ops = &q6slim_ops, 893 .id = SLIMBUS_2_RX, 894 .probe = msm_dai_q6_dai_probe, 895 .remove = msm_dai_q6_dai_remove, 896 897 }, { 898 .name = "SLIMBUS_2_TX", 899 .ops = &q6slim_ops, 900 .id = SLIMBUS_2_TX, 901 .probe = msm_dai_q6_dai_probe, 902 .remove = msm_dai_q6_dai_remove, 903 .capture = { 904 .stream_name = "Slimbus2 Capture", 905 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 906 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 907 SNDRV_PCM_RATE_192000, 908 .formats = SNDRV_PCM_FMTBIT_S16_LE | 909 SNDRV_PCM_FMTBIT_S24_LE, 910 .channels_min = 1, 911 .channels_max = 8, 912 .rate_min = 8000, 913 .rate_max = 192000, 914 }, 915 }, { 916 .playback = { 917 .stream_name = "Slimbus3 Playback", 918 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 919 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 920 SNDRV_PCM_RATE_192000, 921 .formats = SNDRV_PCM_FMTBIT_S16_LE | 922 SNDRV_PCM_FMTBIT_S24_LE, 923 .channels_min = 1, 924 .channels_max = 2, 925 .rate_min = 8000, 926 .rate_max = 192000, 927 }, 928 .name = "SLIMBUS_3_RX", 929 .ops = &q6slim_ops, 930 .id = SLIMBUS_3_RX, 931 .probe = msm_dai_q6_dai_probe, 932 .remove = msm_dai_q6_dai_remove, 933 934 }, { 935 .name = "SLIMBUS_3_TX", 936 .ops = &q6slim_ops, 937 .id = SLIMBUS_3_TX, 938 .probe = msm_dai_q6_dai_probe, 939 .remove = msm_dai_q6_dai_remove, 940 .capture = { 941 .stream_name = "Slimbus3 Capture", 942 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 943 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 944 SNDRV_PCM_RATE_192000, 945 .formats = SNDRV_PCM_FMTBIT_S16_LE | 946 SNDRV_PCM_FMTBIT_S24_LE, 947 .channels_min = 1, 948 .channels_max = 8, 949 .rate_min = 8000, 950 .rate_max = 192000, 951 }, 952 }, { 953 .playback = { 954 .stream_name = "Slimbus4 Playback", 955 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 956 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 957 SNDRV_PCM_RATE_192000, 958 .formats = SNDRV_PCM_FMTBIT_S16_LE | 959 SNDRV_PCM_FMTBIT_S24_LE, 960 .channels_min = 1, 961 .channels_max = 2, 962 .rate_min = 8000, 963 .rate_max = 192000, 964 }, 965 .name = "SLIMBUS_4_RX", 966 .ops = &q6slim_ops, 967 .id = SLIMBUS_4_RX, 968 .probe = msm_dai_q6_dai_probe, 969 .remove = msm_dai_q6_dai_remove, 970 971 }, { 972 .name = "SLIMBUS_4_TX", 973 .ops = &q6slim_ops, 974 .id = SLIMBUS_4_TX, 975 .probe = msm_dai_q6_dai_probe, 976 .remove = msm_dai_q6_dai_remove, 977 .capture = { 978 .stream_name = "Slimbus4 Capture", 979 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 980 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 981 SNDRV_PCM_RATE_192000, 982 .formats = SNDRV_PCM_FMTBIT_S16_LE | 983 SNDRV_PCM_FMTBIT_S24_LE, 984 .channels_min = 1, 985 .channels_max = 8, 986 .rate_min = 8000, 987 .rate_max = 192000, 988 }, 989 }, { 990 .playback = { 991 .stream_name = "Slimbus5 Playback", 992 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 993 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 994 SNDRV_PCM_RATE_192000, 995 .formats = SNDRV_PCM_FMTBIT_S16_LE | 996 SNDRV_PCM_FMTBIT_S24_LE, 997 .channels_min = 1, 998 .channels_max = 2, 999 .rate_min = 8000, 1000 .rate_max = 192000, 1001 }, 1002 .name = "SLIMBUS_5_RX", 1003 .ops = &q6slim_ops, 1004 .id = SLIMBUS_5_RX, 1005 .probe = msm_dai_q6_dai_probe, 1006 .remove = msm_dai_q6_dai_remove, 1007 1008 }, { 1009 .name = "SLIMBUS_5_TX", 1010 .ops = &q6slim_ops, 1011 .id = SLIMBUS_5_TX, 1012 .probe = msm_dai_q6_dai_probe, 1013 .remove = msm_dai_q6_dai_remove, 1014 .capture = { 1015 .stream_name = "Slimbus5 Capture", 1016 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1017 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 1018 SNDRV_PCM_RATE_192000, 1019 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1020 SNDRV_PCM_FMTBIT_S24_LE, 1021 .channels_min = 1, 1022 .channels_max = 8, 1023 .rate_min = 8000, 1024 .rate_max = 192000, 1025 }, 1026 }, { 1027 .playback = { 1028 .stream_name = "Slimbus6 Playback", 1029 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 1030 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 1031 SNDRV_PCM_RATE_192000, 1032 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1033 SNDRV_PCM_FMTBIT_S24_LE, 1034 .channels_min = 1, 1035 .channels_max = 2, 1036 .rate_min = 8000, 1037 .rate_max = 192000, 1038 }, 1039 .ops = &q6slim_ops, 1040 .name = "SLIMBUS_6_RX", 1041 .id = SLIMBUS_6_RX, 1042 .probe = msm_dai_q6_dai_probe, 1043 .remove = msm_dai_q6_dai_remove, 1044 1045 }, { 1046 .name = "SLIMBUS_6_TX", 1047 .ops = &q6slim_ops, 1048 .id = SLIMBUS_6_TX, 1049 .probe = msm_dai_q6_dai_probe, 1050 .remove = msm_dai_q6_dai_remove, 1051 .capture = { 1052 .stream_name = "Slimbus6 Capture", 1053 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1054 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 1055 SNDRV_PCM_RATE_192000, 1056 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1057 SNDRV_PCM_FMTBIT_S24_LE, 1058 .channels_min = 1, 1059 .channels_max = 8, 1060 .rate_min = 8000, 1061 .rate_max = 192000, 1062 }, 1063 }, { 1064 .playback = { 1065 .stream_name = "Primary MI2S Playback", 1066 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1067 SNDRV_PCM_RATE_16000, 1068 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1069 SNDRV_PCM_FMTBIT_S24_LE, 1070 .channels_min = 1, 1071 .channels_max = 8, 1072 .rate_min = 8000, 1073 .rate_max = 48000, 1074 }, 1075 .id = PRIMARY_MI2S_RX, 1076 .name = "PRI_MI2S_RX", 1077 .ops = &q6i2s_ops, 1078 .probe = msm_dai_q6_dai_probe, 1079 .remove = msm_dai_q6_dai_remove, 1080 }, { 1081 .capture = { 1082 .stream_name = "Primary MI2S Capture", 1083 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1084 SNDRV_PCM_RATE_16000, 1085 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1086 SNDRV_PCM_FMTBIT_S24_LE, 1087 .channels_min = 1, 1088 .channels_max = 8, 1089 .rate_min = 8000, 1090 .rate_max = 48000, 1091 }, 1092 .id = PRIMARY_MI2S_TX, 1093 .name = "PRI_MI2S_TX", 1094 .ops = &q6i2s_ops, 1095 .probe = msm_dai_q6_dai_probe, 1096 .remove = msm_dai_q6_dai_remove, 1097 }, { 1098 .playback = { 1099 .stream_name = "Secondary MI2S Playback", 1100 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1101 SNDRV_PCM_RATE_16000, 1102 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1103 .channels_min = 1, 1104 .channels_max = 8, 1105 .rate_min = 8000, 1106 .rate_max = 48000, 1107 }, 1108 .name = "SEC_MI2S_RX", 1109 .id = SECONDARY_MI2S_RX, 1110 .ops = &q6i2s_ops, 1111 .probe = msm_dai_q6_dai_probe, 1112 .remove = msm_dai_q6_dai_remove, 1113 }, { 1114 .capture = { 1115 .stream_name = "Secondary MI2S Capture", 1116 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1117 SNDRV_PCM_RATE_16000, 1118 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1119 SNDRV_PCM_FMTBIT_S24_LE, 1120 .channels_min = 1, 1121 .channels_max = 8, 1122 .rate_min = 8000, 1123 .rate_max = 48000, 1124 }, 1125 .id = SECONDARY_MI2S_TX, 1126 .name = "SEC_MI2S_TX", 1127 .ops = &q6i2s_ops, 1128 .probe = msm_dai_q6_dai_probe, 1129 .remove = msm_dai_q6_dai_remove, 1130 }, { 1131 .playback = { 1132 .stream_name = "Tertiary MI2S Playback", 1133 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1134 SNDRV_PCM_RATE_16000, 1135 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1136 .channels_min = 1, 1137 .channels_max = 8, 1138 .rate_min = 8000, 1139 .rate_max = 48000, 1140 }, 1141 .name = "TERT_MI2S_RX", 1142 .id = TERTIARY_MI2S_RX, 1143 .ops = &q6i2s_ops, 1144 .probe = msm_dai_q6_dai_probe, 1145 .remove = msm_dai_q6_dai_remove, 1146 }, { 1147 .capture = { 1148 .stream_name = "Tertiary MI2S Capture", 1149 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1150 SNDRV_PCM_RATE_16000, 1151 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1152 SNDRV_PCM_FMTBIT_S24_LE, 1153 .channels_min = 1, 1154 .channels_max = 8, 1155 .rate_min = 8000, 1156 .rate_max = 48000, 1157 }, 1158 .id = TERTIARY_MI2S_TX, 1159 .name = "TERT_MI2S_TX", 1160 .ops = &q6i2s_ops, 1161 .probe = msm_dai_q6_dai_probe, 1162 .remove = msm_dai_q6_dai_remove, 1163 }, { 1164 .playback = { 1165 .stream_name = "Quaternary MI2S Playback", 1166 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1167 SNDRV_PCM_RATE_16000, 1168 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1169 .channels_min = 1, 1170 .channels_max = 8, 1171 .rate_min = 8000, 1172 .rate_max = 48000, 1173 }, 1174 .name = "QUAT_MI2S_RX", 1175 .id = QUATERNARY_MI2S_RX, 1176 .ops = &q6i2s_ops, 1177 .probe = msm_dai_q6_dai_probe, 1178 .remove = msm_dai_q6_dai_remove, 1179 }, { 1180 .capture = { 1181 .stream_name = "Quaternary MI2S Capture", 1182 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1183 SNDRV_PCM_RATE_16000, 1184 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1185 SNDRV_PCM_FMTBIT_S24_LE, 1186 .channels_min = 1, 1187 .channels_max = 8, 1188 .rate_min = 8000, 1189 .rate_max = 48000, 1190 }, 1191 .id = QUATERNARY_MI2S_TX, 1192 .name = "QUAT_MI2S_TX", 1193 .ops = &q6i2s_ops, 1194 .probe = msm_dai_q6_dai_probe, 1195 .remove = msm_dai_q6_dai_remove, 1196 }, { 1197 .playback = { 1198 .stream_name = "Quinary MI2S Playback", 1199 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1200 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 1201 SNDRV_PCM_RATE_192000, 1202 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1203 .channels_min = 1, 1204 .channels_max = 8, 1205 .rate_min = 8000, 1206 .rate_max = 192000, 1207 }, 1208 .id = QUINARY_MI2S_RX, 1209 .name = "QUIN_MI2S_RX", 1210 .ops = &q6i2s_ops, 1211 .probe = msm_dai_q6_dai_probe, 1212 .remove = msm_dai_q6_dai_remove, 1213 }, { 1214 .capture = { 1215 .stream_name = "Quinary MI2S Capture", 1216 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1217 SNDRV_PCM_RATE_16000, 1218 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1219 .channels_min = 1, 1220 .channels_max = 8, 1221 .rate_min = 8000, 1222 .rate_max = 48000, 1223 }, 1224 .id = QUINARY_MI2S_TX, 1225 .name = "QUIN_MI2S_TX", 1226 .ops = &q6i2s_ops, 1227 .probe = msm_dai_q6_dai_probe, 1228 .remove = msm_dai_q6_dai_remove, 1229 }, 1230 Q6AFE_TDM_PB_DAI("Primary", 0, PRIMARY_TDM_RX_0), 1231 Q6AFE_TDM_PB_DAI("Primary", 1, PRIMARY_TDM_RX_1), 1232 Q6AFE_TDM_PB_DAI("Primary", 2, PRIMARY_TDM_RX_2), 1233 Q6AFE_TDM_PB_DAI("Primary", 3, PRIMARY_TDM_RX_3), 1234 Q6AFE_TDM_PB_DAI("Primary", 4, PRIMARY_TDM_RX_4), 1235 Q6AFE_TDM_PB_DAI("Primary", 5, PRIMARY_TDM_RX_5), 1236 Q6AFE_TDM_PB_DAI("Primary", 6, PRIMARY_TDM_RX_6), 1237 Q6AFE_TDM_PB_DAI("Primary", 7, PRIMARY_TDM_RX_7), 1238 Q6AFE_TDM_CAP_DAI("Primary", 0, PRIMARY_TDM_TX_0), 1239 Q6AFE_TDM_CAP_DAI("Primary", 1, PRIMARY_TDM_TX_1), 1240 Q6AFE_TDM_CAP_DAI("Primary", 2, PRIMARY_TDM_TX_2), 1241 Q6AFE_TDM_CAP_DAI("Primary", 3, PRIMARY_TDM_TX_3), 1242 Q6AFE_TDM_CAP_DAI("Primary", 4, PRIMARY_TDM_TX_4), 1243 Q6AFE_TDM_CAP_DAI("Primary", 5, PRIMARY_TDM_TX_5), 1244 Q6AFE_TDM_CAP_DAI("Primary", 6, PRIMARY_TDM_TX_6), 1245 Q6AFE_TDM_CAP_DAI("Primary", 7, PRIMARY_TDM_TX_7), 1246 Q6AFE_TDM_PB_DAI("Secondary", 0, SECONDARY_TDM_RX_0), 1247 Q6AFE_TDM_PB_DAI("Secondary", 1, SECONDARY_TDM_RX_1), 1248 Q6AFE_TDM_PB_DAI("Secondary", 2, SECONDARY_TDM_RX_2), 1249 Q6AFE_TDM_PB_DAI("Secondary", 3, SECONDARY_TDM_RX_3), 1250 Q6AFE_TDM_PB_DAI("Secondary", 4, SECONDARY_TDM_RX_4), 1251 Q6AFE_TDM_PB_DAI("Secondary", 5, SECONDARY_TDM_RX_5), 1252 Q6AFE_TDM_PB_DAI("Secondary", 6, SECONDARY_TDM_RX_6), 1253 Q6AFE_TDM_PB_DAI("Secondary", 7, SECONDARY_TDM_RX_7), 1254 Q6AFE_TDM_CAP_DAI("Secondary", 0, SECONDARY_TDM_TX_0), 1255 Q6AFE_TDM_CAP_DAI("Secondary", 1, SECONDARY_TDM_TX_1), 1256 Q6AFE_TDM_CAP_DAI("Secondary", 2, SECONDARY_TDM_TX_2), 1257 Q6AFE_TDM_CAP_DAI("Secondary", 3, SECONDARY_TDM_TX_3), 1258 Q6AFE_TDM_CAP_DAI("Secondary", 4, SECONDARY_TDM_TX_4), 1259 Q6AFE_TDM_CAP_DAI("Secondary", 5, SECONDARY_TDM_TX_5), 1260 Q6AFE_TDM_CAP_DAI("Secondary", 6, SECONDARY_TDM_TX_6), 1261 Q6AFE_TDM_CAP_DAI("Secondary", 7, SECONDARY_TDM_TX_7), 1262 Q6AFE_TDM_PB_DAI("Tertiary", 0, TERTIARY_TDM_RX_0), 1263 Q6AFE_TDM_PB_DAI("Tertiary", 1, TERTIARY_TDM_RX_1), 1264 Q6AFE_TDM_PB_DAI("Tertiary", 2, TERTIARY_TDM_RX_2), 1265 Q6AFE_TDM_PB_DAI("Tertiary", 3, TERTIARY_TDM_RX_3), 1266 Q6AFE_TDM_PB_DAI("Tertiary", 4, TERTIARY_TDM_RX_4), 1267 Q6AFE_TDM_PB_DAI("Tertiary", 5, TERTIARY_TDM_RX_5), 1268 Q6AFE_TDM_PB_DAI("Tertiary", 6, TERTIARY_TDM_RX_6), 1269 Q6AFE_TDM_PB_DAI("Tertiary", 7, TERTIARY_TDM_RX_7), 1270 Q6AFE_TDM_CAP_DAI("Tertiary", 0, TERTIARY_TDM_TX_0), 1271 Q6AFE_TDM_CAP_DAI("Tertiary", 1, TERTIARY_TDM_TX_1), 1272 Q6AFE_TDM_CAP_DAI("Tertiary", 2, TERTIARY_TDM_TX_2), 1273 Q6AFE_TDM_CAP_DAI("Tertiary", 3, TERTIARY_TDM_TX_3), 1274 Q6AFE_TDM_CAP_DAI("Tertiary", 4, TERTIARY_TDM_TX_4), 1275 Q6AFE_TDM_CAP_DAI("Tertiary", 5, TERTIARY_TDM_TX_5), 1276 Q6AFE_TDM_CAP_DAI("Tertiary", 6, TERTIARY_TDM_TX_6), 1277 Q6AFE_TDM_CAP_DAI("Tertiary", 7, TERTIARY_TDM_TX_7), 1278 Q6AFE_TDM_PB_DAI("Quaternary", 0, QUATERNARY_TDM_RX_0), 1279 Q6AFE_TDM_PB_DAI("Quaternary", 1, QUATERNARY_TDM_RX_1), 1280 Q6AFE_TDM_PB_DAI("Quaternary", 2, QUATERNARY_TDM_RX_2), 1281 Q6AFE_TDM_PB_DAI("Quaternary", 3, QUATERNARY_TDM_RX_3), 1282 Q6AFE_TDM_PB_DAI("Quaternary", 4, QUATERNARY_TDM_RX_4), 1283 Q6AFE_TDM_PB_DAI("Quaternary", 5, QUATERNARY_TDM_RX_5), 1284 Q6AFE_TDM_PB_DAI("Quaternary", 6, QUATERNARY_TDM_RX_6), 1285 Q6AFE_TDM_PB_DAI("Quaternary", 7, QUATERNARY_TDM_RX_7), 1286 Q6AFE_TDM_CAP_DAI("Quaternary", 0, QUATERNARY_TDM_TX_0), 1287 Q6AFE_TDM_CAP_DAI("Quaternary", 1, QUATERNARY_TDM_TX_1), 1288 Q6AFE_TDM_CAP_DAI("Quaternary", 2, QUATERNARY_TDM_TX_2), 1289 Q6AFE_TDM_CAP_DAI("Quaternary", 3, QUATERNARY_TDM_TX_3), 1290 Q6AFE_TDM_CAP_DAI("Quaternary", 4, QUATERNARY_TDM_TX_4), 1291 Q6AFE_TDM_CAP_DAI("Quaternary", 5, QUATERNARY_TDM_TX_5), 1292 Q6AFE_TDM_CAP_DAI("Quaternary", 6, QUATERNARY_TDM_TX_6), 1293 Q6AFE_TDM_CAP_DAI("Quaternary", 7, QUATERNARY_TDM_TX_7), 1294 Q6AFE_TDM_PB_DAI("Quinary", 0, QUINARY_TDM_RX_0), 1295 Q6AFE_TDM_PB_DAI("Quinary", 1, QUINARY_TDM_RX_1), 1296 Q6AFE_TDM_PB_DAI("Quinary", 2, QUINARY_TDM_RX_2), 1297 Q6AFE_TDM_PB_DAI("Quinary", 3, QUINARY_TDM_RX_3), 1298 Q6AFE_TDM_PB_DAI("Quinary", 4, QUINARY_TDM_RX_4), 1299 Q6AFE_TDM_PB_DAI("Quinary", 5, QUINARY_TDM_RX_5), 1300 Q6AFE_TDM_PB_DAI("Quinary", 6, QUINARY_TDM_RX_6), 1301 Q6AFE_TDM_PB_DAI("Quinary", 7, QUINARY_TDM_RX_7), 1302 Q6AFE_TDM_CAP_DAI("Quinary", 0, QUINARY_TDM_TX_0), 1303 Q6AFE_TDM_CAP_DAI("Quinary", 1, QUINARY_TDM_TX_1), 1304 Q6AFE_TDM_CAP_DAI("Quinary", 2, QUINARY_TDM_TX_2), 1305 Q6AFE_TDM_CAP_DAI("Quinary", 3, QUINARY_TDM_TX_3), 1306 Q6AFE_TDM_CAP_DAI("Quinary", 4, QUINARY_TDM_TX_4), 1307 Q6AFE_TDM_CAP_DAI("Quinary", 5, QUINARY_TDM_TX_5), 1308 Q6AFE_TDM_CAP_DAI("Quinary", 6, QUINARY_TDM_TX_6), 1309 Q6AFE_TDM_CAP_DAI("Quinary", 7, QUINARY_TDM_TX_7), 1310 { 1311 .playback = { 1312 .stream_name = "Display Port Playback", 1313 .rates = SNDRV_PCM_RATE_48000 | 1314 SNDRV_PCM_RATE_96000 | 1315 SNDRV_PCM_RATE_192000, 1316 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1317 SNDRV_PCM_FMTBIT_S24_LE, 1318 .channels_min = 2, 1319 .channels_max = 8, 1320 .rate_max = 192000, 1321 .rate_min = 48000, 1322 }, 1323 .ops = &q6hdmi_ops, 1324 .id = DISPLAY_PORT_RX, 1325 .name = "DISPLAY_PORT", 1326 .probe = msm_dai_q6_dai_probe, 1327 .remove = msm_dai_q6_dai_remove, 1328 }, 1329 Q6AFE_CDC_DMA_RX_DAI(WSA_CODEC_DMA_RX_0), 1330 Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_0), 1331 Q6AFE_CDC_DMA_RX_DAI(WSA_CODEC_DMA_RX_1), 1332 Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_1), 1333 Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_2), 1334 Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_0), 1335 Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_1), 1336 Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_2), 1337 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_0), 1338 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_0), 1339 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_1), 1340 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_1), 1341 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_2), 1342 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_2), 1343 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_3), 1344 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_3), 1345 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_4), 1346 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_4), 1347 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_5), 1348 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_5), 1349 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_6), 1350 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_7), 1351 }; 1352 1353 static int q6afe_of_xlate_dai_name(struct snd_soc_component *component, 1354 const struct of_phandle_args *args, 1355 const char **dai_name) 1356 { 1357 int id = args->args[0]; 1358 int ret = -EINVAL; 1359 int i; 1360 1361 for (i = 0; i < ARRAY_SIZE(q6afe_dais); i++) { 1362 if (q6afe_dais[i].id == id) { 1363 *dai_name = q6afe_dais[i].name; 1364 ret = 0; 1365 break; 1366 } 1367 } 1368 1369 return ret; 1370 } 1371 1372 static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = { 1373 SND_SOC_DAPM_AIF_IN("HDMI_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1374 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1375 SND_SOC_DAPM_AIF_IN("SLIMBUS_1_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1376 SND_SOC_DAPM_AIF_IN("SLIMBUS_2_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1377 SND_SOC_DAPM_AIF_IN("SLIMBUS_3_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1378 SND_SOC_DAPM_AIF_IN("SLIMBUS_4_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1379 SND_SOC_DAPM_AIF_IN("SLIMBUS_5_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1380 SND_SOC_DAPM_AIF_IN("SLIMBUS_6_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1381 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1382 SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1383 SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1384 SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1385 SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1386 SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1387 SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1388 SND_SOC_DAPM_AIF_IN("QUIN_MI2S_RX", NULL, 1389 0, SND_SOC_NOPM, 0, 0), 1390 SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_TX", NULL, 1391 0, SND_SOC_NOPM, 0, 0), 1392 SND_SOC_DAPM_AIF_IN("QUAT_MI2S_RX", NULL, 1393 0, SND_SOC_NOPM, 0, 0), 1394 SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_TX", NULL, 1395 0, SND_SOC_NOPM, 0, 0), 1396 SND_SOC_DAPM_AIF_IN("TERT_MI2S_RX", NULL, 1397 0, SND_SOC_NOPM, 0, 0), 1398 SND_SOC_DAPM_AIF_OUT("TERT_MI2S_TX", NULL, 1399 0, SND_SOC_NOPM, 0, 0), 1400 SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX", NULL, 1401 0, SND_SOC_NOPM, 0, 0), 1402 SND_SOC_DAPM_AIF_OUT("SEC_MI2S_TX", NULL, 1403 0, SND_SOC_NOPM, 0, 0), 1404 SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX_SD1", 1405 "Secondary MI2S Playback SD1", 1406 0, SND_SOC_NOPM, 0, 0), 1407 SND_SOC_DAPM_AIF_IN("PRI_MI2S_RX", NULL, 1408 0, SND_SOC_NOPM, 0, 0), 1409 SND_SOC_DAPM_AIF_OUT("PRI_MI2S_TX", NULL, 1410 0, SND_SOC_NOPM, 0, 0), 1411 1412 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_0", NULL, 1413 0, SND_SOC_NOPM, 0, 0), 1414 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_1", NULL, 1415 0, SND_SOC_NOPM, 0, 0), 1416 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_2", NULL, 1417 0, SND_SOC_NOPM, 0, 0), 1418 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_3", NULL, 1419 0, SND_SOC_NOPM, 0, 0), 1420 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_4", NULL, 1421 0, SND_SOC_NOPM, 0, 0), 1422 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_5", NULL, 1423 0, SND_SOC_NOPM, 0, 0), 1424 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_6", NULL, 1425 0, SND_SOC_NOPM, 0, 0), 1426 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_7", NULL, 1427 0, SND_SOC_NOPM, 0, 0), 1428 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_0", NULL, 1429 0, SND_SOC_NOPM, 0, 0), 1430 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_1", NULL, 1431 0, SND_SOC_NOPM, 0, 0), 1432 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_2", NULL, 1433 0, SND_SOC_NOPM, 0, 0), 1434 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_3", NULL, 1435 0, SND_SOC_NOPM, 0, 0), 1436 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_4", NULL, 1437 0, SND_SOC_NOPM, 0, 0), 1438 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_5", NULL, 1439 0, SND_SOC_NOPM, 0, 0), 1440 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_6", NULL, 1441 0, SND_SOC_NOPM, 0, 0), 1442 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_7", NULL, 1443 0, SND_SOC_NOPM, 0, 0), 1444 1445 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0", NULL, 1446 0, SND_SOC_NOPM, 0, 0), 1447 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1", NULL, 1448 0, SND_SOC_NOPM, 0, 0), 1449 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2", NULL, 1450 0, SND_SOC_NOPM, 0, 0), 1451 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3", NULL, 1452 0, SND_SOC_NOPM, 0, 0), 1453 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4", NULL, 1454 0, SND_SOC_NOPM, 0, 0), 1455 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5", NULL, 1456 0, SND_SOC_NOPM, 0, 0), 1457 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6", NULL, 1458 0, SND_SOC_NOPM, 0, 0), 1459 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7", NULL, 1460 0, SND_SOC_NOPM, 0, 0), 1461 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0", NULL, 1462 0, SND_SOC_NOPM, 0, 0), 1463 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1", NULL, 1464 0, SND_SOC_NOPM, 0, 0), 1465 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2", NULL, 1466 0, SND_SOC_NOPM, 0, 0), 1467 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3", NULL, 1468 0, SND_SOC_NOPM, 0, 0), 1469 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4", NULL, 1470 0, SND_SOC_NOPM, 0, 0), 1471 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5", NULL, 1472 0, SND_SOC_NOPM, 0, 0), 1473 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6", NULL, 1474 0, SND_SOC_NOPM, 0, 0), 1475 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7", NULL, 1476 0, SND_SOC_NOPM, 0, 0), 1477 1478 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0", NULL, 1479 0, SND_SOC_NOPM, 0, 0), 1480 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1", NULL, 1481 0, SND_SOC_NOPM, 0, 0), 1482 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2", NULL, 1483 0, SND_SOC_NOPM, 0, 0), 1484 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3", NULL, 1485 0, SND_SOC_NOPM, 0, 0), 1486 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4", NULL, 1487 0, SND_SOC_NOPM, 0, 0), 1488 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5", NULL, 1489 0, SND_SOC_NOPM, 0, 0), 1490 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6", NULL, 1491 0, SND_SOC_NOPM, 0, 0), 1492 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7", NULL, 1493 0, SND_SOC_NOPM, 0, 0), 1494 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0", NULL, 1495 0, SND_SOC_NOPM, 0, 0), 1496 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1", NULL, 1497 0, SND_SOC_NOPM, 0, 0), 1498 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2", NULL, 1499 0, SND_SOC_NOPM, 0, 0), 1500 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3", NULL, 1501 0, SND_SOC_NOPM, 0, 0), 1502 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4", NULL, 1503 0, SND_SOC_NOPM, 0, 0), 1504 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5", NULL, 1505 0, SND_SOC_NOPM, 0, 0), 1506 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6", NULL, 1507 0, SND_SOC_NOPM, 0, 0), 1508 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7", NULL, 1509 0, SND_SOC_NOPM, 0, 0), 1510 1511 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0", NULL, 1512 0, SND_SOC_NOPM, 0, 0), 1513 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1", NULL, 1514 0, SND_SOC_NOPM, 0, 0), 1515 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2", NULL, 1516 0, SND_SOC_NOPM, 0, 0), 1517 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3", NULL, 1518 0, SND_SOC_NOPM, 0, 0), 1519 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4", NULL, 1520 0, SND_SOC_NOPM, 0, 0), 1521 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5", NULL, 1522 0, SND_SOC_NOPM, 0, 0), 1523 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6", NULL, 1524 0, SND_SOC_NOPM, 0, 0), 1525 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7", NULL, 1526 0, SND_SOC_NOPM, 0, 0), 1527 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0", NULL, 1528 0, SND_SOC_NOPM, 0, 0), 1529 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1", NULL, 1530 0, SND_SOC_NOPM, 0, 0), 1531 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2", NULL, 1532 0, SND_SOC_NOPM, 0, 0), 1533 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3", NULL, 1534 0, SND_SOC_NOPM, 0, 0), 1535 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4", NULL, 1536 0, SND_SOC_NOPM, 0, 0), 1537 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5", NULL, 1538 0, SND_SOC_NOPM, 0, 0), 1539 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6", NULL, 1540 0, SND_SOC_NOPM, 0, 0), 1541 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7", NULL, 1542 0, SND_SOC_NOPM, 0, 0), 1543 1544 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0", NULL, 1545 0, SND_SOC_NOPM, 0, 0), 1546 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1", NULL, 1547 0, SND_SOC_NOPM, 0, 0), 1548 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2", NULL, 1549 0, SND_SOC_NOPM, 0, 0), 1550 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3", NULL, 1551 0, SND_SOC_NOPM, 0, 0), 1552 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4", NULL, 1553 0, SND_SOC_NOPM, 0, 0), 1554 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5", NULL, 1555 0, SND_SOC_NOPM, 0, 0), 1556 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6", NULL, 1557 0, SND_SOC_NOPM, 0, 0), 1558 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7", NULL, 1559 0, SND_SOC_NOPM, 0, 0), 1560 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0", NULL, 1561 0, SND_SOC_NOPM, 0, 0), 1562 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1", NULL, 1563 0, SND_SOC_NOPM, 0, 0), 1564 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2", NULL, 1565 0, SND_SOC_NOPM, 0, 0), 1566 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3", NULL, 1567 0, SND_SOC_NOPM, 0, 0), 1568 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4", NULL, 1569 0, SND_SOC_NOPM, 0, 0), 1570 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5", NULL, 1571 0, SND_SOC_NOPM, 0, 0), 1572 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6", NULL, 1573 0, SND_SOC_NOPM, 0, 0), 1574 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL, 1575 0, SND_SOC_NOPM, 0, 0), 1576 SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT_RX", "NULL", 0, SND_SOC_NOPM, 0, 0), 1577 1578 SND_SOC_DAPM_AIF_IN("WSA_CODEC_DMA_RX_0", "NULL", 1579 0, SND_SOC_NOPM, 0, 0), 1580 SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_0", "NULL", 1581 0, SND_SOC_NOPM, 0, 0), 1582 SND_SOC_DAPM_AIF_IN("WSA_CODEC_DMA_RX_1", "NULL", 1583 0, SND_SOC_NOPM, 0, 0), 1584 SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_1", "NULL", 1585 0, SND_SOC_NOPM, 0, 0), 1586 SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_2", "NULL", 1587 0, SND_SOC_NOPM, 0, 0), 1588 SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_0", "NULL", 1589 0, SND_SOC_NOPM, 0, 0), 1590 SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_1", "NULL", 1591 0, SND_SOC_NOPM, 0, 0), 1592 SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_2", "NULL", 1593 0, SND_SOC_NOPM, 0, 0), 1594 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_0", "NULL", 1595 0, SND_SOC_NOPM, 0, 0), 1596 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_0", "NULL", 1597 0, SND_SOC_NOPM, 0, 0), 1598 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_1", "NULL", 1599 0, SND_SOC_NOPM, 0, 0), 1600 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_1", "NULL", 1601 0, SND_SOC_NOPM, 0, 0), 1602 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_2", "NULL", 1603 0, SND_SOC_NOPM, 0, 0), 1604 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_2", "NULL", 1605 0, SND_SOC_NOPM, 0, 0), 1606 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_3", "NULL", 1607 0, SND_SOC_NOPM, 0, 0), 1608 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_3", "NULL", 1609 0, SND_SOC_NOPM, 0, 0), 1610 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_4", "NULL", 1611 0, SND_SOC_NOPM, 0, 0), 1612 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_4", "NULL", 1613 0, SND_SOC_NOPM, 0, 0), 1614 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_5", "NULL", 1615 0, SND_SOC_NOPM, 0, 0), 1616 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_5", "NULL", 1617 0, SND_SOC_NOPM, 0, 0), 1618 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_6", "NULL", 1619 0, SND_SOC_NOPM, 0, 0), 1620 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_7", "NULL", 1621 0, SND_SOC_NOPM, 0, 0), 1622 }; 1623 1624 static const struct snd_soc_component_driver q6afe_dai_component = { 1625 .name = "q6afe-dai-component", 1626 .dapm_widgets = q6afe_dai_widgets, 1627 .num_dapm_widgets = ARRAY_SIZE(q6afe_dai_widgets), 1628 .dapm_routes = q6afe_dapm_routes, 1629 .num_dapm_routes = ARRAY_SIZE(q6afe_dapm_routes), 1630 .of_xlate_dai_name = q6afe_of_xlate_dai_name, 1631 1632 }; 1633 1634 static void of_q6afe_parse_dai_data(struct device *dev, 1635 struct q6afe_dai_data *data) 1636 { 1637 struct device_node *node; 1638 int ret; 1639 1640 for_each_child_of_node(dev->of_node, node) { 1641 unsigned int lines[Q6AFE_MAX_MI2S_LINES]; 1642 struct q6afe_dai_priv_data *priv; 1643 int id, i, num_lines; 1644 1645 ret = of_property_read_u32(node, "reg", &id); 1646 if (ret || id < 0 || id >= AFE_PORT_MAX) { 1647 dev_err(dev, "valid dai id not found:%d\n", ret); 1648 continue; 1649 } 1650 1651 switch (id) { 1652 /* MI2S specific properties */ 1653 case QUINARY_MI2S_RX ... QUINARY_MI2S_TX: 1654 case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX: 1655 priv = &data->priv[id]; 1656 ret = of_property_read_variable_u32_array(node, 1657 "qcom,sd-lines", 1658 lines, 0, 1659 Q6AFE_MAX_MI2S_LINES); 1660 if (ret < 0) 1661 num_lines = 0; 1662 else 1663 num_lines = ret; 1664 1665 priv->sd_line_mask = 0; 1666 1667 for (i = 0; i < num_lines; i++) 1668 priv->sd_line_mask |= BIT(lines[i]); 1669 1670 break; 1671 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 1672 priv = &data->priv[id]; 1673 ret = of_property_read_u32(node, "qcom,tdm-sync-mode", 1674 &priv->sync_mode); 1675 if (ret) { 1676 dev_err(dev, "No Sync mode from DT\n"); 1677 break; 1678 } 1679 ret = of_property_read_u32(node, "qcom,tdm-sync-src", 1680 &priv->sync_src); 1681 if (ret) { 1682 dev_err(dev, "No Sync Src from DT\n"); 1683 break; 1684 } 1685 ret = of_property_read_u32(node, "qcom,tdm-data-out", 1686 &priv->data_out_enable); 1687 if (ret) { 1688 dev_err(dev, "No Data out enable from DT\n"); 1689 break; 1690 } 1691 ret = of_property_read_u32(node, "qcom,tdm-invert-sync", 1692 &priv->invert_sync); 1693 if (ret) { 1694 dev_err(dev, "No Invert sync from DT\n"); 1695 break; 1696 } 1697 ret = of_property_read_u32(node, "qcom,tdm-data-delay", 1698 &priv->data_delay); 1699 if (ret) { 1700 dev_err(dev, "No Data Delay from DT\n"); 1701 break; 1702 } 1703 ret = of_property_read_u32(node, "qcom,tdm-data-align", 1704 &priv->data_align); 1705 if (ret) { 1706 dev_err(dev, "No Data align from DT\n"); 1707 break; 1708 } 1709 break; 1710 default: 1711 break; 1712 } 1713 } 1714 } 1715 1716 static int q6afe_dai_dev_probe(struct platform_device *pdev) 1717 { 1718 struct q6afe_dai_data *dai_data; 1719 struct device *dev = &pdev->dev; 1720 1721 dai_data = devm_kzalloc(dev, sizeof(*dai_data), GFP_KERNEL); 1722 if (!dai_data) 1723 return -ENOMEM; 1724 1725 dev_set_drvdata(dev, dai_data); 1726 1727 of_q6afe_parse_dai_data(dev, dai_data); 1728 1729 return devm_snd_soc_register_component(dev, &q6afe_dai_component, 1730 q6afe_dais, ARRAY_SIZE(q6afe_dais)); 1731 } 1732 1733 #ifdef CONFIG_OF 1734 static const struct of_device_id q6afe_dai_device_id[] = { 1735 { .compatible = "qcom,q6afe-dais" }, 1736 {}, 1737 }; 1738 MODULE_DEVICE_TABLE(of, q6afe_dai_device_id); 1739 #endif 1740 1741 static struct platform_driver q6afe_dai_platform_driver = { 1742 .driver = { 1743 .name = "q6afe-dai", 1744 .of_match_table = of_match_ptr(q6afe_dai_device_id), 1745 }, 1746 .probe = q6afe_dai_dev_probe, 1747 }; 1748 module_platform_driver(q6afe_dai_platform_driver); 1749 1750 MODULE_DESCRIPTION("Q6 Audio Fronend dai driver"); 1751 MODULE_LICENSE("GPL v2"); 1752