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 PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX: 479 rc = q6afe_i2s_port_prepare(dai_data->port[dai->id], 480 &dai_data->port_config[dai->id].i2s_cfg); 481 if (rc < 0) { 482 dev_err(dai->dev, "fail to prepare AFE port %x\n", 483 dai->id); 484 return rc; 485 } 486 break; 487 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 488 q6afe_tdm_port_prepare(dai_data->port[dai->id], 489 &dai_data->port_config[dai->id].tdm); 490 break; 491 case WSA_CODEC_DMA_RX_0 ... RX_CODEC_DMA_RX_7: 492 q6afe_cdc_dma_port_prepare(dai_data->port[dai->id], 493 &dai_data->port_config[dai->id].dma_cfg); 494 break; 495 default: 496 return -EINVAL; 497 } 498 499 rc = q6afe_port_start(dai_data->port[dai->id]); 500 if (rc < 0) { 501 dev_err(dai->dev, "fail to start AFE port %x\n", dai->id); 502 return rc; 503 } 504 dai_data->is_port_started[dai->id] = true; 505 506 return 0; 507 } 508 509 static int q6slim_set_channel_map(struct snd_soc_dai *dai, 510 unsigned int tx_num, unsigned int *tx_slot, 511 unsigned int rx_num, unsigned int *rx_slot) 512 { 513 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 514 struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id]; 515 int i; 516 517 if (dai->id & 0x1) { 518 /* TX */ 519 if (!tx_slot) { 520 pr_err("%s: tx slot not found\n", __func__); 521 return -EINVAL; 522 } 523 524 for (i = 0; i < tx_num; i++) 525 pcfg->slim.ch_mapping[i] = tx_slot[i]; 526 527 pcfg->slim.num_channels = tx_num; 528 529 530 } else { 531 if (!rx_slot) { 532 pr_err("%s: rx slot not found\n", __func__); 533 return -EINVAL; 534 } 535 536 for (i = 0; i < rx_num; i++) 537 pcfg->slim.ch_mapping[i] = rx_slot[i]; 538 539 pcfg->slim.num_channels = rx_num; 540 541 } 542 543 return 0; 544 } 545 546 static int q6afe_mi2s_set_sysclk(struct snd_soc_dai *dai, 547 int clk_id, unsigned int freq, int dir) 548 { 549 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 550 struct q6afe_port *port = dai_data->port[dai->id]; 551 552 switch (clk_id) { 553 case LPAIF_DIG_CLK: 554 return q6afe_port_set_sysclk(port, clk_id, 0, 5, freq, dir); 555 case LPAIF_BIT_CLK: 556 case LPAIF_OSR_CLK: 557 return q6afe_port_set_sysclk(port, clk_id, 558 Q6AFE_LPASS_CLK_SRC_INTERNAL, 559 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 560 freq, dir); 561 case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR: 562 case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1: 563 case Q6AFE_LPASS_CLK_ID_WSA_CORE_MCLK ... Q6AFE_LPASS_CLK_ID_VA_CORE_2X_MCLK: 564 return q6afe_port_set_sysclk(port, clk_id, 565 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, 566 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 567 freq, dir); 568 case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT: 569 return q6afe_port_set_sysclk(port, clk_id, 570 Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO, 571 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 572 freq, dir); 573 } 574 575 return 0; 576 } 577 578 static const struct snd_soc_dapm_route q6afe_dapm_routes[] = { 579 {"HDMI Playback", NULL, "HDMI_RX"}, 580 {"Display Port Playback", NULL, "DISPLAY_PORT_RX"}, 581 {"Slimbus Playback", NULL, "SLIMBUS_0_RX"}, 582 {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"}, 583 {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"}, 584 {"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"}, 585 {"Slimbus4 Playback", NULL, "SLIMBUS_4_RX"}, 586 {"Slimbus5 Playback", NULL, "SLIMBUS_5_RX"}, 587 {"Slimbus6 Playback", NULL, "SLIMBUS_6_RX"}, 588 589 {"SLIMBUS_0_TX", NULL, "Slimbus Capture"}, 590 {"SLIMBUS_1_TX", NULL, "Slimbus1 Capture"}, 591 {"SLIMBUS_2_TX", NULL, "Slimbus2 Capture"}, 592 {"SLIMBUS_3_TX", NULL, "Slimbus3 Capture"}, 593 {"SLIMBUS_4_TX", NULL, "Slimbus4 Capture"}, 594 {"SLIMBUS_5_TX", NULL, "Slimbus5 Capture"}, 595 {"SLIMBUS_6_TX", NULL, "Slimbus6 Capture"}, 596 597 {"Primary MI2S Playback", NULL, "PRI_MI2S_RX"}, 598 {"Secondary MI2S Playback", NULL, "SEC_MI2S_RX"}, 599 {"Tertiary MI2S Playback", NULL, "TERT_MI2S_RX"}, 600 {"Quaternary MI2S Playback", NULL, "QUAT_MI2S_RX"}, 601 602 {"Primary TDM0 Playback", NULL, "PRIMARY_TDM_RX_0"}, 603 {"Primary TDM1 Playback", NULL, "PRIMARY_TDM_RX_1"}, 604 {"Primary TDM2 Playback", NULL, "PRIMARY_TDM_RX_2"}, 605 {"Primary TDM3 Playback", NULL, "PRIMARY_TDM_RX_3"}, 606 {"Primary TDM4 Playback", NULL, "PRIMARY_TDM_RX_4"}, 607 {"Primary TDM5 Playback", NULL, "PRIMARY_TDM_RX_5"}, 608 {"Primary TDM6 Playback", NULL, "PRIMARY_TDM_RX_6"}, 609 {"Primary TDM7 Playback", NULL, "PRIMARY_TDM_RX_7"}, 610 611 {"Secondary TDM0 Playback", NULL, "SEC_TDM_RX_0"}, 612 {"Secondary TDM1 Playback", NULL, "SEC_TDM_RX_1"}, 613 {"Secondary TDM2 Playback", NULL, "SEC_TDM_RX_2"}, 614 {"Secondary TDM3 Playback", NULL, "SEC_TDM_RX_3"}, 615 {"Secondary TDM4 Playback", NULL, "SEC_TDM_RX_4"}, 616 {"Secondary TDM5 Playback", NULL, "SEC_TDM_RX_5"}, 617 {"Secondary TDM6 Playback", NULL, "SEC_TDM_RX_6"}, 618 {"Secondary TDM7 Playback", NULL, "SEC_TDM_RX_7"}, 619 620 {"Tertiary TDM0 Playback", NULL, "TERT_TDM_RX_0"}, 621 {"Tertiary TDM1 Playback", NULL, "TERT_TDM_RX_1"}, 622 {"Tertiary TDM2 Playback", NULL, "TERT_TDM_RX_2"}, 623 {"Tertiary TDM3 Playback", NULL, "TERT_TDM_RX_3"}, 624 {"Tertiary TDM4 Playback", NULL, "TERT_TDM_RX_4"}, 625 {"Tertiary TDM5 Playback", NULL, "TERT_TDM_RX_5"}, 626 {"Tertiary TDM6 Playback", NULL, "TERT_TDM_RX_6"}, 627 {"Tertiary TDM7 Playback", NULL, "TERT_TDM_RX_7"}, 628 629 {"Quaternary TDM0 Playback", NULL, "QUAT_TDM_RX_0"}, 630 {"Quaternary TDM1 Playback", NULL, "QUAT_TDM_RX_1"}, 631 {"Quaternary TDM2 Playback", NULL, "QUAT_TDM_RX_2"}, 632 {"Quaternary TDM3 Playback", NULL, "QUAT_TDM_RX_3"}, 633 {"Quaternary TDM4 Playback", NULL, "QUAT_TDM_RX_4"}, 634 {"Quaternary TDM5 Playback", NULL, "QUAT_TDM_RX_5"}, 635 {"Quaternary TDM6 Playback", NULL, "QUAT_TDM_RX_6"}, 636 {"Quaternary TDM7 Playback", NULL, "QUAT_TDM_RX_7"}, 637 638 {"Quinary TDM0 Playback", NULL, "QUIN_TDM_RX_0"}, 639 {"Quinary TDM1 Playback", NULL, "QUIN_TDM_RX_1"}, 640 {"Quinary TDM2 Playback", NULL, "QUIN_TDM_RX_2"}, 641 {"Quinary TDM3 Playback", NULL, "QUIN_TDM_RX_3"}, 642 {"Quinary TDM4 Playback", NULL, "QUIN_TDM_RX_4"}, 643 {"Quinary TDM5 Playback", NULL, "QUIN_TDM_RX_5"}, 644 {"Quinary TDM6 Playback", NULL, "QUIN_TDM_RX_6"}, 645 {"Quinary TDM7 Playback", NULL, "QUIN_TDM_RX_7"}, 646 647 {"PRIMARY_TDM_TX_0", NULL, "Primary TDM0 Capture"}, 648 {"PRIMARY_TDM_TX_1", NULL, "Primary TDM1 Capture"}, 649 {"PRIMARY_TDM_TX_2", NULL, "Primary TDM2 Capture"}, 650 {"PRIMARY_TDM_TX_3", NULL, "Primary TDM3 Capture"}, 651 {"PRIMARY_TDM_TX_4", NULL, "Primary TDM4 Capture"}, 652 {"PRIMARY_TDM_TX_5", NULL, "Primary TDM5 Capture"}, 653 {"PRIMARY_TDM_TX_6", NULL, "Primary TDM6 Capture"}, 654 {"PRIMARY_TDM_TX_7", NULL, "Primary TDM7 Capture"}, 655 656 {"SEC_TDM_TX_0", NULL, "Secondary TDM0 Capture"}, 657 {"SEC_TDM_TX_1", NULL, "Secondary TDM1 Capture"}, 658 {"SEC_TDM_TX_2", NULL, "Secondary TDM2 Capture"}, 659 {"SEC_TDM_TX_3", NULL, "Secondary TDM3 Capture"}, 660 {"SEC_TDM_TX_4", NULL, "Secondary TDM4 Capture"}, 661 {"SEC_TDM_TX_5", NULL, "Secondary TDM5 Capture"}, 662 {"SEC_TDM_TX_6", NULL, "Secondary TDM6 Capture"}, 663 {"SEC_TDM_TX_7", NULL, "Secondary TDM7 Capture"}, 664 665 {"TERT_TDM_TX_0", NULL, "Tertiary TDM0 Capture"}, 666 {"TERT_TDM_TX_1", NULL, "Tertiary TDM1 Capture"}, 667 {"TERT_TDM_TX_2", NULL, "Tertiary TDM2 Capture"}, 668 {"TERT_TDM_TX_3", NULL, "Tertiary TDM3 Capture"}, 669 {"TERT_TDM_TX_4", NULL, "Tertiary TDM4 Capture"}, 670 {"TERT_TDM_TX_5", NULL, "Tertiary TDM5 Capture"}, 671 {"TERT_TDM_TX_6", NULL, "Tertiary TDM6 Capture"}, 672 {"TERT_TDM_TX_7", NULL, "Tertiary TDM7 Capture"}, 673 674 {"QUAT_TDM_TX_0", NULL, "Quaternary TDM0 Capture"}, 675 {"QUAT_TDM_TX_1", NULL, "Quaternary TDM1 Capture"}, 676 {"QUAT_TDM_TX_2", NULL, "Quaternary TDM2 Capture"}, 677 {"QUAT_TDM_TX_3", NULL, "Quaternary TDM3 Capture"}, 678 {"QUAT_TDM_TX_4", NULL, "Quaternary TDM4 Capture"}, 679 {"QUAT_TDM_TX_5", NULL, "Quaternary TDM5 Capture"}, 680 {"QUAT_TDM_TX_6", NULL, "Quaternary TDM6 Capture"}, 681 {"QUAT_TDM_TX_7", NULL, "Quaternary TDM7 Capture"}, 682 683 {"QUIN_TDM_TX_0", NULL, "Quinary TDM0 Capture"}, 684 {"QUIN_TDM_TX_1", NULL, "Quinary TDM1 Capture"}, 685 {"QUIN_TDM_TX_2", NULL, "Quinary TDM2 Capture"}, 686 {"QUIN_TDM_TX_3", NULL, "Quinary TDM3 Capture"}, 687 {"QUIN_TDM_TX_4", NULL, "Quinary TDM4 Capture"}, 688 {"QUIN_TDM_TX_5", NULL, "Quinary TDM5 Capture"}, 689 {"QUIN_TDM_TX_6", NULL, "Quinary TDM6 Capture"}, 690 {"QUIN_TDM_TX_7", NULL, "Quinary TDM7 Capture"}, 691 692 {"TERT_MI2S_TX", NULL, "Tertiary MI2S Capture"}, 693 {"PRI_MI2S_TX", NULL, "Primary MI2S Capture"}, 694 {"SEC_MI2S_TX", NULL, "Secondary MI2S Capture"}, 695 {"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"}, 696 697 {"WSA_CODEC_DMA_RX_0 Playback", NULL, "WSA_CODEC_DMA_RX_0"}, 698 {"WSA_CODEC_DMA_TX_0", NULL, "WSA_CODEC_DMA_TX_0 Capture"}, 699 {"WSA_CODEC_DMA_RX_1 Playback", NULL, "WSA_CODEC_DMA_RX_1"}, 700 {"WSA_CODEC_DMA_TX_1", NULL, "WSA_CODEC_DMA_TX_1 Capture"}, 701 {"WSA_CODEC_DMA_TX_2", NULL, "WSA_CODEC_DMA_TX_2 Capture"}, 702 {"VA_CODEC_DMA_TX_0", NULL, "VA_CODEC_DMA_TX_0 Capture"}, 703 {"VA_CODEC_DMA_TX_1", NULL, "VA_CODEC_DMA_TX_1 Capture"}, 704 {"VA_CODEC_DMA_TX_2", NULL, "VA_CODEC_DMA_TX_2 Capture"}, 705 {"RX_CODEC_DMA_RX_0 Playback", NULL, "RX_CODEC_DMA_RX_0"}, 706 {"TX_CODEC_DMA_TX_0", NULL, "TX_CODEC_DMA_TX_0 Capture"}, 707 {"RX_CODEC_DMA_RX_1 Playback", NULL, "RX_CODEC_DMA_RX_1"}, 708 {"TX_CODEC_DMA_TX_1", NULL, "TX_CODEC_DMA_TX_1 Capture"}, 709 {"RX_CODEC_DMA_RX_2 Playback", NULL, "RX_CODEC_DMA_RX_2"}, 710 {"TX_CODEC_DMA_TX_2", NULL, "TX_CODEC_DMA_TX_2 Capture"}, 711 {"RX_CODEC_DMA_RX_3 Playback", NULL, "RX_CODEC_DMA_RX_3"}, 712 {"TX_CODEC_DMA_TX_3", NULL, "TX_CODEC_DMA_TX_3 Capture"}, 713 {"RX_CODEC_DMA_RX_4 Playback", NULL, "RX_CODEC_DMA_RX_4"}, 714 {"TX_CODEC_DMA_TX_4", NULL, "TX_CODEC_DMA_TX_4 Capture"}, 715 {"RX_CODEC_DMA_RX_5 Playback", NULL, "RX_CODEC_DMA_RX_5"}, 716 {"TX_CODEC_DMA_TX_5", NULL, "TX_CODEC_DMA_TX_5 Capture"}, 717 {"RX_CODEC_DMA_RX_6 Playback", NULL, "RX_CODEC_DMA_RX_6"}, 718 {"RX_CODEC_DMA_RX_7 Playback", NULL, "RX_CODEC_DMA_RX_7"}, 719 }; 720 721 static const struct snd_soc_dai_ops q6hdmi_ops = { 722 .prepare = q6afe_dai_prepare, 723 .hw_params = q6hdmi_hw_params, 724 .shutdown = q6afe_dai_shutdown, 725 }; 726 727 static const struct snd_soc_dai_ops q6i2s_ops = { 728 .prepare = q6afe_dai_prepare, 729 .hw_params = q6i2s_hw_params, 730 .set_fmt = q6i2s_set_fmt, 731 .shutdown = q6afe_dai_shutdown, 732 .set_sysclk = q6afe_mi2s_set_sysclk, 733 }; 734 735 static const struct snd_soc_dai_ops q6slim_ops = { 736 .prepare = q6afe_dai_prepare, 737 .hw_params = q6slim_hw_params, 738 .shutdown = q6afe_dai_shutdown, 739 .set_channel_map = q6slim_set_channel_map, 740 }; 741 742 static const struct snd_soc_dai_ops q6tdm_ops = { 743 .prepare = q6afe_dai_prepare, 744 .shutdown = q6afe_dai_shutdown, 745 .set_sysclk = q6afe_mi2s_set_sysclk, 746 .set_tdm_slot = q6tdm_set_tdm_slot, 747 .set_channel_map = q6tdm_set_channel_map, 748 .hw_params = q6tdm_hw_params, 749 }; 750 751 static const struct snd_soc_dai_ops q6dma_ops = { 752 .prepare = q6afe_dai_prepare, 753 .shutdown = q6afe_dai_shutdown, 754 .set_sysclk = q6afe_mi2s_set_sysclk, 755 .set_channel_map = q6dma_set_channel_map, 756 .hw_params = q6dma_hw_params, 757 }; 758 759 static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) 760 { 761 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 762 struct q6afe_port *port; 763 764 port = q6afe_port_get_from_id(dai->dev, dai->id); 765 if (IS_ERR(port)) { 766 dev_err(dai->dev, "Unable to get afe port\n"); 767 return -EINVAL; 768 } 769 dai_data->port[dai->id] = port; 770 771 return 0; 772 } 773 774 static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai) 775 { 776 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev); 777 778 q6afe_port_put(dai_data->port[dai->id]); 779 dai_data->port[dai->id] = NULL; 780 781 return 0; 782 } 783 784 static struct snd_soc_dai_driver q6afe_dais[] = { 785 { 786 .playback = { 787 .stream_name = "HDMI Playback", 788 .rates = SNDRV_PCM_RATE_48000 | 789 SNDRV_PCM_RATE_96000 | 790 SNDRV_PCM_RATE_192000, 791 .formats = SNDRV_PCM_FMTBIT_S16_LE | 792 SNDRV_PCM_FMTBIT_S24_LE, 793 .channels_min = 2, 794 .channels_max = 8, 795 .rate_max = 192000, 796 .rate_min = 48000, 797 }, 798 .ops = &q6hdmi_ops, 799 .id = HDMI_RX, 800 .name = "HDMI", 801 .probe = msm_dai_q6_dai_probe, 802 .remove = msm_dai_q6_dai_remove, 803 }, { 804 .name = "SLIMBUS_0_RX", 805 .ops = &q6slim_ops, 806 .id = SLIMBUS_0_RX, 807 .probe = msm_dai_q6_dai_probe, 808 .remove = msm_dai_q6_dai_remove, 809 .playback = { 810 .stream_name = "Slimbus Playback", 811 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 812 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 813 SNDRV_PCM_RATE_192000, 814 .formats = SNDRV_PCM_FMTBIT_S16_LE | 815 SNDRV_PCM_FMTBIT_S24_LE, 816 .channels_min = 1, 817 .channels_max = 8, 818 .rate_min = 8000, 819 .rate_max = 192000, 820 }, 821 }, { 822 .name = "SLIMBUS_0_TX", 823 .ops = &q6slim_ops, 824 .id = SLIMBUS_0_TX, 825 .probe = msm_dai_q6_dai_probe, 826 .remove = msm_dai_q6_dai_remove, 827 .capture = { 828 .stream_name = "Slimbus Capture", 829 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 830 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 831 SNDRV_PCM_RATE_192000, 832 .formats = SNDRV_PCM_FMTBIT_S16_LE | 833 SNDRV_PCM_FMTBIT_S24_LE, 834 .channels_min = 1, 835 .channels_max = 8, 836 .rate_min = 8000, 837 .rate_max = 192000, 838 }, 839 }, { 840 .playback = { 841 .stream_name = "Slimbus1 Playback", 842 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 843 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 844 SNDRV_PCM_RATE_192000, 845 .formats = SNDRV_PCM_FMTBIT_S16_LE | 846 SNDRV_PCM_FMTBIT_S24_LE, 847 .channels_min = 1, 848 .channels_max = 2, 849 .rate_min = 8000, 850 .rate_max = 192000, 851 }, 852 .name = "SLIMBUS_1_RX", 853 .ops = &q6slim_ops, 854 .id = SLIMBUS_1_RX, 855 .probe = msm_dai_q6_dai_probe, 856 .remove = msm_dai_q6_dai_remove, 857 }, { 858 .name = "SLIMBUS_1_TX", 859 .ops = &q6slim_ops, 860 .id = SLIMBUS_1_TX, 861 .probe = msm_dai_q6_dai_probe, 862 .remove = msm_dai_q6_dai_remove, 863 .capture = { 864 .stream_name = "Slimbus1 Capture", 865 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 866 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 867 SNDRV_PCM_RATE_192000, 868 .formats = SNDRV_PCM_FMTBIT_S16_LE | 869 SNDRV_PCM_FMTBIT_S24_LE, 870 .channels_min = 1, 871 .channels_max = 8, 872 .rate_min = 8000, 873 .rate_max = 192000, 874 }, 875 }, { 876 .playback = { 877 .stream_name = "Slimbus2 Playback", 878 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 879 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 880 SNDRV_PCM_RATE_192000, 881 .formats = SNDRV_PCM_FMTBIT_S16_LE | 882 SNDRV_PCM_FMTBIT_S24_LE, 883 .channels_min = 1, 884 .channels_max = 8, 885 .rate_min = 8000, 886 .rate_max = 192000, 887 }, 888 .name = "SLIMBUS_2_RX", 889 .ops = &q6slim_ops, 890 .id = SLIMBUS_2_RX, 891 .probe = msm_dai_q6_dai_probe, 892 .remove = msm_dai_q6_dai_remove, 893 894 }, { 895 .name = "SLIMBUS_2_TX", 896 .ops = &q6slim_ops, 897 .id = SLIMBUS_2_TX, 898 .probe = msm_dai_q6_dai_probe, 899 .remove = msm_dai_q6_dai_remove, 900 .capture = { 901 .stream_name = "Slimbus2 Capture", 902 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 903 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 904 SNDRV_PCM_RATE_192000, 905 .formats = SNDRV_PCM_FMTBIT_S16_LE | 906 SNDRV_PCM_FMTBIT_S24_LE, 907 .channels_min = 1, 908 .channels_max = 8, 909 .rate_min = 8000, 910 .rate_max = 192000, 911 }, 912 }, { 913 .playback = { 914 .stream_name = "Slimbus3 Playback", 915 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 916 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 917 SNDRV_PCM_RATE_192000, 918 .formats = SNDRV_PCM_FMTBIT_S16_LE | 919 SNDRV_PCM_FMTBIT_S24_LE, 920 .channels_min = 1, 921 .channels_max = 2, 922 .rate_min = 8000, 923 .rate_max = 192000, 924 }, 925 .name = "SLIMBUS_3_RX", 926 .ops = &q6slim_ops, 927 .id = SLIMBUS_3_RX, 928 .probe = msm_dai_q6_dai_probe, 929 .remove = msm_dai_q6_dai_remove, 930 931 }, { 932 .name = "SLIMBUS_3_TX", 933 .ops = &q6slim_ops, 934 .id = SLIMBUS_3_TX, 935 .probe = msm_dai_q6_dai_probe, 936 .remove = msm_dai_q6_dai_remove, 937 .capture = { 938 .stream_name = "Slimbus3 Capture", 939 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 940 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 941 SNDRV_PCM_RATE_192000, 942 .formats = SNDRV_PCM_FMTBIT_S16_LE | 943 SNDRV_PCM_FMTBIT_S24_LE, 944 .channels_min = 1, 945 .channels_max = 8, 946 .rate_min = 8000, 947 .rate_max = 192000, 948 }, 949 }, { 950 .playback = { 951 .stream_name = "Slimbus4 Playback", 952 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 953 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 954 SNDRV_PCM_RATE_192000, 955 .formats = SNDRV_PCM_FMTBIT_S16_LE | 956 SNDRV_PCM_FMTBIT_S24_LE, 957 .channels_min = 1, 958 .channels_max = 2, 959 .rate_min = 8000, 960 .rate_max = 192000, 961 }, 962 .name = "SLIMBUS_4_RX", 963 .ops = &q6slim_ops, 964 .id = SLIMBUS_4_RX, 965 .probe = msm_dai_q6_dai_probe, 966 .remove = msm_dai_q6_dai_remove, 967 968 }, { 969 .name = "SLIMBUS_4_TX", 970 .ops = &q6slim_ops, 971 .id = SLIMBUS_4_TX, 972 .probe = msm_dai_q6_dai_probe, 973 .remove = msm_dai_q6_dai_remove, 974 .capture = { 975 .stream_name = "Slimbus4 Capture", 976 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 977 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 978 SNDRV_PCM_RATE_192000, 979 .formats = SNDRV_PCM_FMTBIT_S16_LE | 980 SNDRV_PCM_FMTBIT_S24_LE, 981 .channels_min = 1, 982 .channels_max = 8, 983 .rate_min = 8000, 984 .rate_max = 192000, 985 }, 986 }, { 987 .playback = { 988 .stream_name = "Slimbus5 Playback", 989 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 990 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 991 SNDRV_PCM_RATE_192000, 992 .formats = SNDRV_PCM_FMTBIT_S16_LE | 993 SNDRV_PCM_FMTBIT_S24_LE, 994 .channels_min = 1, 995 .channels_max = 2, 996 .rate_min = 8000, 997 .rate_max = 192000, 998 }, 999 .name = "SLIMBUS_5_RX", 1000 .ops = &q6slim_ops, 1001 .id = SLIMBUS_5_RX, 1002 .probe = msm_dai_q6_dai_probe, 1003 .remove = msm_dai_q6_dai_remove, 1004 1005 }, { 1006 .name = "SLIMBUS_5_TX", 1007 .ops = &q6slim_ops, 1008 .id = SLIMBUS_5_TX, 1009 .probe = msm_dai_q6_dai_probe, 1010 .remove = msm_dai_q6_dai_remove, 1011 .capture = { 1012 .stream_name = "Slimbus5 Capture", 1013 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1014 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 1015 SNDRV_PCM_RATE_192000, 1016 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1017 SNDRV_PCM_FMTBIT_S24_LE, 1018 .channels_min = 1, 1019 .channels_max = 8, 1020 .rate_min = 8000, 1021 .rate_max = 192000, 1022 }, 1023 }, { 1024 .playback = { 1025 .stream_name = "Slimbus6 Playback", 1026 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 1027 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | 1028 SNDRV_PCM_RATE_192000, 1029 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1030 SNDRV_PCM_FMTBIT_S24_LE, 1031 .channels_min = 1, 1032 .channels_max = 2, 1033 .rate_min = 8000, 1034 .rate_max = 192000, 1035 }, 1036 .ops = &q6slim_ops, 1037 .name = "SLIMBUS_6_RX", 1038 .id = SLIMBUS_6_RX, 1039 .probe = msm_dai_q6_dai_probe, 1040 .remove = msm_dai_q6_dai_remove, 1041 1042 }, { 1043 .name = "SLIMBUS_6_TX", 1044 .ops = &q6slim_ops, 1045 .id = SLIMBUS_6_TX, 1046 .probe = msm_dai_q6_dai_probe, 1047 .remove = msm_dai_q6_dai_remove, 1048 .capture = { 1049 .stream_name = "Slimbus6 Capture", 1050 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1051 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | 1052 SNDRV_PCM_RATE_192000, 1053 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1054 SNDRV_PCM_FMTBIT_S24_LE, 1055 .channels_min = 1, 1056 .channels_max = 8, 1057 .rate_min = 8000, 1058 .rate_max = 192000, 1059 }, 1060 }, { 1061 .playback = { 1062 .stream_name = "Primary MI2S Playback", 1063 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1064 SNDRV_PCM_RATE_16000, 1065 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1066 SNDRV_PCM_FMTBIT_S24_LE, 1067 .channels_min = 1, 1068 .channels_max = 8, 1069 .rate_min = 8000, 1070 .rate_max = 48000, 1071 }, 1072 .id = PRIMARY_MI2S_RX, 1073 .name = "PRI_MI2S_RX", 1074 .ops = &q6i2s_ops, 1075 .probe = msm_dai_q6_dai_probe, 1076 .remove = msm_dai_q6_dai_remove, 1077 }, { 1078 .capture = { 1079 .stream_name = "Primary MI2S Capture", 1080 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1081 SNDRV_PCM_RATE_16000, 1082 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1083 SNDRV_PCM_FMTBIT_S24_LE, 1084 .channels_min = 1, 1085 .channels_max = 8, 1086 .rate_min = 8000, 1087 .rate_max = 48000, 1088 }, 1089 .id = PRIMARY_MI2S_TX, 1090 .name = "PRI_MI2S_TX", 1091 .ops = &q6i2s_ops, 1092 .probe = msm_dai_q6_dai_probe, 1093 .remove = msm_dai_q6_dai_remove, 1094 }, { 1095 .playback = { 1096 .stream_name = "Secondary MI2S Playback", 1097 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1098 SNDRV_PCM_RATE_16000, 1099 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1100 .channels_min = 1, 1101 .channels_max = 8, 1102 .rate_min = 8000, 1103 .rate_max = 48000, 1104 }, 1105 .name = "SEC_MI2S_RX", 1106 .id = SECONDARY_MI2S_RX, 1107 .ops = &q6i2s_ops, 1108 .probe = msm_dai_q6_dai_probe, 1109 .remove = msm_dai_q6_dai_remove, 1110 }, { 1111 .capture = { 1112 .stream_name = "Secondary MI2S Capture", 1113 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1114 SNDRV_PCM_RATE_16000, 1115 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1116 SNDRV_PCM_FMTBIT_S24_LE, 1117 .channels_min = 1, 1118 .channels_max = 8, 1119 .rate_min = 8000, 1120 .rate_max = 48000, 1121 }, 1122 .id = SECONDARY_MI2S_TX, 1123 .name = "SEC_MI2S_TX", 1124 .ops = &q6i2s_ops, 1125 .probe = msm_dai_q6_dai_probe, 1126 .remove = msm_dai_q6_dai_remove, 1127 }, { 1128 .playback = { 1129 .stream_name = "Tertiary MI2S Playback", 1130 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1131 SNDRV_PCM_RATE_16000, 1132 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1133 .channels_min = 1, 1134 .channels_max = 8, 1135 .rate_min = 8000, 1136 .rate_max = 48000, 1137 }, 1138 .name = "TERT_MI2S_RX", 1139 .id = TERTIARY_MI2S_RX, 1140 .ops = &q6i2s_ops, 1141 .probe = msm_dai_q6_dai_probe, 1142 .remove = msm_dai_q6_dai_remove, 1143 }, { 1144 .capture = { 1145 .stream_name = "Tertiary MI2S Capture", 1146 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1147 SNDRV_PCM_RATE_16000, 1148 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1149 SNDRV_PCM_FMTBIT_S24_LE, 1150 .channels_min = 1, 1151 .channels_max = 8, 1152 .rate_min = 8000, 1153 .rate_max = 48000, 1154 }, 1155 .id = TERTIARY_MI2S_TX, 1156 .name = "TERT_MI2S_TX", 1157 .ops = &q6i2s_ops, 1158 .probe = msm_dai_q6_dai_probe, 1159 .remove = msm_dai_q6_dai_remove, 1160 }, { 1161 .playback = { 1162 .stream_name = "Quaternary MI2S Playback", 1163 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1164 SNDRV_PCM_RATE_16000, 1165 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1166 .channels_min = 1, 1167 .channels_max = 8, 1168 .rate_min = 8000, 1169 .rate_max = 48000, 1170 }, 1171 .name = "QUAT_MI2S_RX", 1172 .id = QUATERNARY_MI2S_RX, 1173 .ops = &q6i2s_ops, 1174 .probe = msm_dai_q6_dai_probe, 1175 .remove = msm_dai_q6_dai_remove, 1176 }, { 1177 .capture = { 1178 .stream_name = "Quaternary MI2S Capture", 1179 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | 1180 SNDRV_PCM_RATE_16000, 1181 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1182 SNDRV_PCM_FMTBIT_S24_LE, 1183 .channels_min = 1, 1184 .channels_max = 8, 1185 .rate_min = 8000, 1186 .rate_max = 48000, 1187 }, 1188 .id = QUATERNARY_MI2S_TX, 1189 .name = "QUAT_MI2S_TX", 1190 .ops = &q6i2s_ops, 1191 .probe = msm_dai_q6_dai_probe, 1192 .remove = msm_dai_q6_dai_remove, 1193 }, 1194 Q6AFE_TDM_PB_DAI("Primary", 0, PRIMARY_TDM_RX_0), 1195 Q6AFE_TDM_PB_DAI("Primary", 1, PRIMARY_TDM_RX_1), 1196 Q6AFE_TDM_PB_DAI("Primary", 2, PRIMARY_TDM_RX_2), 1197 Q6AFE_TDM_PB_DAI("Primary", 3, PRIMARY_TDM_RX_3), 1198 Q6AFE_TDM_PB_DAI("Primary", 4, PRIMARY_TDM_RX_4), 1199 Q6AFE_TDM_PB_DAI("Primary", 5, PRIMARY_TDM_RX_5), 1200 Q6AFE_TDM_PB_DAI("Primary", 6, PRIMARY_TDM_RX_6), 1201 Q6AFE_TDM_PB_DAI("Primary", 7, PRIMARY_TDM_RX_7), 1202 Q6AFE_TDM_CAP_DAI("Primary", 0, PRIMARY_TDM_TX_0), 1203 Q6AFE_TDM_CAP_DAI("Primary", 1, PRIMARY_TDM_TX_1), 1204 Q6AFE_TDM_CAP_DAI("Primary", 2, PRIMARY_TDM_TX_2), 1205 Q6AFE_TDM_CAP_DAI("Primary", 3, PRIMARY_TDM_TX_3), 1206 Q6AFE_TDM_CAP_DAI("Primary", 4, PRIMARY_TDM_TX_4), 1207 Q6AFE_TDM_CAP_DAI("Primary", 5, PRIMARY_TDM_TX_5), 1208 Q6AFE_TDM_CAP_DAI("Primary", 6, PRIMARY_TDM_TX_6), 1209 Q6AFE_TDM_CAP_DAI("Primary", 7, PRIMARY_TDM_TX_7), 1210 Q6AFE_TDM_PB_DAI("Secondary", 0, SECONDARY_TDM_RX_0), 1211 Q6AFE_TDM_PB_DAI("Secondary", 1, SECONDARY_TDM_RX_1), 1212 Q6AFE_TDM_PB_DAI("Secondary", 2, SECONDARY_TDM_RX_2), 1213 Q6AFE_TDM_PB_DAI("Secondary", 3, SECONDARY_TDM_RX_3), 1214 Q6AFE_TDM_PB_DAI("Secondary", 4, SECONDARY_TDM_RX_4), 1215 Q6AFE_TDM_PB_DAI("Secondary", 5, SECONDARY_TDM_RX_5), 1216 Q6AFE_TDM_PB_DAI("Secondary", 6, SECONDARY_TDM_RX_6), 1217 Q6AFE_TDM_PB_DAI("Secondary", 7, SECONDARY_TDM_RX_7), 1218 Q6AFE_TDM_CAP_DAI("Secondary", 0, SECONDARY_TDM_TX_0), 1219 Q6AFE_TDM_CAP_DAI("Secondary", 1, SECONDARY_TDM_TX_1), 1220 Q6AFE_TDM_CAP_DAI("Secondary", 2, SECONDARY_TDM_TX_2), 1221 Q6AFE_TDM_CAP_DAI("Secondary", 3, SECONDARY_TDM_TX_3), 1222 Q6AFE_TDM_CAP_DAI("Secondary", 4, SECONDARY_TDM_TX_4), 1223 Q6AFE_TDM_CAP_DAI("Secondary", 5, SECONDARY_TDM_TX_5), 1224 Q6AFE_TDM_CAP_DAI("Secondary", 6, SECONDARY_TDM_TX_6), 1225 Q6AFE_TDM_CAP_DAI("Secondary", 7, SECONDARY_TDM_TX_7), 1226 Q6AFE_TDM_PB_DAI("Tertiary", 0, TERTIARY_TDM_RX_0), 1227 Q6AFE_TDM_PB_DAI("Tertiary", 1, TERTIARY_TDM_RX_1), 1228 Q6AFE_TDM_PB_DAI("Tertiary", 2, TERTIARY_TDM_RX_2), 1229 Q6AFE_TDM_PB_DAI("Tertiary", 3, TERTIARY_TDM_RX_3), 1230 Q6AFE_TDM_PB_DAI("Tertiary", 4, TERTIARY_TDM_RX_4), 1231 Q6AFE_TDM_PB_DAI("Tertiary", 5, TERTIARY_TDM_RX_5), 1232 Q6AFE_TDM_PB_DAI("Tertiary", 6, TERTIARY_TDM_RX_6), 1233 Q6AFE_TDM_PB_DAI("Tertiary", 7, TERTIARY_TDM_RX_7), 1234 Q6AFE_TDM_CAP_DAI("Tertiary", 0, TERTIARY_TDM_TX_0), 1235 Q6AFE_TDM_CAP_DAI("Tertiary", 1, TERTIARY_TDM_TX_1), 1236 Q6AFE_TDM_CAP_DAI("Tertiary", 2, TERTIARY_TDM_TX_2), 1237 Q6AFE_TDM_CAP_DAI("Tertiary", 3, TERTIARY_TDM_TX_3), 1238 Q6AFE_TDM_CAP_DAI("Tertiary", 4, TERTIARY_TDM_TX_4), 1239 Q6AFE_TDM_CAP_DAI("Tertiary", 5, TERTIARY_TDM_TX_5), 1240 Q6AFE_TDM_CAP_DAI("Tertiary", 6, TERTIARY_TDM_TX_6), 1241 Q6AFE_TDM_CAP_DAI("Tertiary", 7, TERTIARY_TDM_TX_7), 1242 Q6AFE_TDM_PB_DAI("Quaternary", 0, QUATERNARY_TDM_RX_0), 1243 Q6AFE_TDM_PB_DAI("Quaternary", 1, QUATERNARY_TDM_RX_1), 1244 Q6AFE_TDM_PB_DAI("Quaternary", 2, QUATERNARY_TDM_RX_2), 1245 Q6AFE_TDM_PB_DAI("Quaternary", 3, QUATERNARY_TDM_RX_3), 1246 Q6AFE_TDM_PB_DAI("Quaternary", 4, QUATERNARY_TDM_RX_4), 1247 Q6AFE_TDM_PB_DAI("Quaternary", 5, QUATERNARY_TDM_RX_5), 1248 Q6AFE_TDM_PB_DAI("Quaternary", 6, QUATERNARY_TDM_RX_6), 1249 Q6AFE_TDM_PB_DAI("Quaternary", 7, QUATERNARY_TDM_RX_7), 1250 Q6AFE_TDM_CAP_DAI("Quaternary", 0, QUATERNARY_TDM_TX_0), 1251 Q6AFE_TDM_CAP_DAI("Quaternary", 1, QUATERNARY_TDM_TX_1), 1252 Q6AFE_TDM_CAP_DAI("Quaternary", 2, QUATERNARY_TDM_TX_2), 1253 Q6AFE_TDM_CAP_DAI("Quaternary", 3, QUATERNARY_TDM_TX_3), 1254 Q6AFE_TDM_CAP_DAI("Quaternary", 4, QUATERNARY_TDM_TX_4), 1255 Q6AFE_TDM_CAP_DAI("Quaternary", 5, QUATERNARY_TDM_TX_5), 1256 Q6AFE_TDM_CAP_DAI("Quaternary", 6, QUATERNARY_TDM_TX_6), 1257 Q6AFE_TDM_CAP_DAI("Quaternary", 7, QUATERNARY_TDM_TX_7), 1258 Q6AFE_TDM_PB_DAI("Quinary", 0, QUINARY_TDM_RX_0), 1259 Q6AFE_TDM_PB_DAI("Quinary", 1, QUINARY_TDM_RX_1), 1260 Q6AFE_TDM_PB_DAI("Quinary", 2, QUINARY_TDM_RX_2), 1261 Q6AFE_TDM_PB_DAI("Quinary", 3, QUINARY_TDM_RX_3), 1262 Q6AFE_TDM_PB_DAI("Quinary", 4, QUINARY_TDM_RX_4), 1263 Q6AFE_TDM_PB_DAI("Quinary", 5, QUINARY_TDM_RX_5), 1264 Q6AFE_TDM_PB_DAI("Quinary", 6, QUINARY_TDM_RX_6), 1265 Q6AFE_TDM_PB_DAI("Quinary", 7, QUINARY_TDM_RX_7), 1266 Q6AFE_TDM_CAP_DAI("Quinary", 0, QUINARY_TDM_TX_0), 1267 Q6AFE_TDM_CAP_DAI("Quinary", 1, QUINARY_TDM_TX_1), 1268 Q6AFE_TDM_CAP_DAI("Quinary", 2, QUINARY_TDM_TX_2), 1269 Q6AFE_TDM_CAP_DAI("Quinary", 3, QUINARY_TDM_TX_3), 1270 Q6AFE_TDM_CAP_DAI("Quinary", 4, QUINARY_TDM_TX_4), 1271 Q6AFE_TDM_CAP_DAI("Quinary", 5, QUINARY_TDM_TX_5), 1272 Q6AFE_TDM_CAP_DAI("Quinary", 6, QUINARY_TDM_TX_6), 1273 Q6AFE_TDM_CAP_DAI("Quinary", 7, QUINARY_TDM_TX_7), 1274 { 1275 .playback = { 1276 .stream_name = "Display Port Playback", 1277 .rates = SNDRV_PCM_RATE_48000 | 1278 SNDRV_PCM_RATE_96000 | 1279 SNDRV_PCM_RATE_192000, 1280 .formats = SNDRV_PCM_FMTBIT_S16_LE | 1281 SNDRV_PCM_FMTBIT_S24_LE, 1282 .channels_min = 2, 1283 .channels_max = 8, 1284 .rate_max = 192000, 1285 .rate_min = 48000, 1286 }, 1287 .ops = &q6hdmi_ops, 1288 .id = DISPLAY_PORT_RX, 1289 .name = "DISPLAY_PORT", 1290 .probe = msm_dai_q6_dai_probe, 1291 .remove = msm_dai_q6_dai_remove, 1292 }, 1293 Q6AFE_CDC_DMA_RX_DAI(WSA_CODEC_DMA_RX_0), 1294 Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_0), 1295 Q6AFE_CDC_DMA_RX_DAI(WSA_CODEC_DMA_RX_1), 1296 Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_1), 1297 Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_2), 1298 Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_0), 1299 Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_1), 1300 Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_2), 1301 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_0), 1302 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_0), 1303 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_1), 1304 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_1), 1305 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_2), 1306 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_2), 1307 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_3), 1308 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_3), 1309 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_4), 1310 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_4), 1311 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_5), 1312 Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_5), 1313 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_6), 1314 Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_7), 1315 }; 1316 1317 static int q6afe_of_xlate_dai_name(struct snd_soc_component *component, 1318 const struct of_phandle_args *args, 1319 const char **dai_name) 1320 { 1321 int id = args->args[0]; 1322 int ret = -EINVAL; 1323 int i; 1324 1325 for (i = 0; i < ARRAY_SIZE(q6afe_dais); i++) { 1326 if (q6afe_dais[i].id == id) { 1327 *dai_name = q6afe_dais[i].name; 1328 ret = 0; 1329 break; 1330 } 1331 } 1332 1333 return ret; 1334 } 1335 1336 static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = { 1337 SND_SOC_DAPM_AIF_IN("HDMI_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1338 SND_SOC_DAPM_AIF_IN("SLIMBUS_0_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1339 SND_SOC_DAPM_AIF_IN("SLIMBUS_1_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1340 SND_SOC_DAPM_AIF_IN("SLIMBUS_2_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1341 SND_SOC_DAPM_AIF_IN("SLIMBUS_3_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1342 SND_SOC_DAPM_AIF_IN("SLIMBUS_4_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1343 SND_SOC_DAPM_AIF_IN("SLIMBUS_5_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1344 SND_SOC_DAPM_AIF_IN("SLIMBUS_6_RX", NULL, 0, SND_SOC_NOPM, 0, 0), 1345 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1346 SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1347 SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1348 SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1349 SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1350 SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1351 SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, SND_SOC_NOPM, 0, 0), 1352 SND_SOC_DAPM_AIF_IN("QUAT_MI2S_RX", NULL, 1353 0, SND_SOC_NOPM, 0, 0), 1354 SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_TX", NULL, 1355 0, SND_SOC_NOPM, 0, 0), 1356 SND_SOC_DAPM_AIF_IN("TERT_MI2S_RX", NULL, 1357 0, SND_SOC_NOPM, 0, 0), 1358 SND_SOC_DAPM_AIF_OUT("TERT_MI2S_TX", NULL, 1359 0, SND_SOC_NOPM, 0, 0), 1360 SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX", NULL, 1361 0, SND_SOC_NOPM, 0, 0), 1362 SND_SOC_DAPM_AIF_OUT("SEC_MI2S_TX", NULL, 1363 0, SND_SOC_NOPM, 0, 0), 1364 SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX_SD1", 1365 "Secondary MI2S Playback SD1", 1366 0, SND_SOC_NOPM, 0, 0), 1367 SND_SOC_DAPM_AIF_IN("PRI_MI2S_RX", NULL, 1368 0, SND_SOC_NOPM, 0, 0), 1369 SND_SOC_DAPM_AIF_OUT("PRI_MI2S_TX", NULL, 1370 0, SND_SOC_NOPM, 0, 0), 1371 1372 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_0", NULL, 1373 0, SND_SOC_NOPM, 0, 0), 1374 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_1", NULL, 1375 0, SND_SOC_NOPM, 0, 0), 1376 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_2", NULL, 1377 0, SND_SOC_NOPM, 0, 0), 1378 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_3", NULL, 1379 0, SND_SOC_NOPM, 0, 0), 1380 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_4", NULL, 1381 0, SND_SOC_NOPM, 0, 0), 1382 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_5", NULL, 1383 0, SND_SOC_NOPM, 0, 0), 1384 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_6", NULL, 1385 0, SND_SOC_NOPM, 0, 0), 1386 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_7", NULL, 1387 0, SND_SOC_NOPM, 0, 0), 1388 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_0", NULL, 1389 0, SND_SOC_NOPM, 0, 0), 1390 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_1", NULL, 1391 0, SND_SOC_NOPM, 0, 0), 1392 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_2", NULL, 1393 0, SND_SOC_NOPM, 0, 0), 1394 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_3", NULL, 1395 0, SND_SOC_NOPM, 0, 0), 1396 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_4", NULL, 1397 0, SND_SOC_NOPM, 0, 0), 1398 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_5", NULL, 1399 0, SND_SOC_NOPM, 0, 0), 1400 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_6", NULL, 1401 0, SND_SOC_NOPM, 0, 0), 1402 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_7", NULL, 1403 0, SND_SOC_NOPM, 0, 0), 1404 1405 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0", NULL, 1406 0, SND_SOC_NOPM, 0, 0), 1407 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1", NULL, 1408 0, SND_SOC_NOPM, 0, 0), 1409 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2", NULL, 1410 0, SND_SOC_NOPM, 0, 0), 1411 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3", NULL, 1412 0, SND_SOC_NOPM, 0, 0), 1413 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4", NULL, 1414 0, SND_SOC_NOPM, 0, 0), 1415 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5", NULL, 1416 0, SND_SOC_NOPM, 0, 0), 1417 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6", NULL, 1418 0, SND_SOC_NOPM, 0, 0), 1419 SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7", NULL, 1420 0, SND_SOC_NOPM, 0, 0), 1421 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0", NULL, 1422 0, SND_SOC_NOPM, 0, 0), 1423 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1", NULL, 1424 0, SND_SOC_NOPM, 0, 0), 1425 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2", NULL, 1426 0, SND_SOC_NOPM, 0, 0), 1427 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3", NULL, 1428 0, SND_SOC_NOPM, 0, 0), 1429 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4", NULL, 1430 0, SND_SOC_NOPM, 0, 0), 1431 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5", NULL, 1432 0, SND_SOC_NOPM, 0, 0), 1433 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6", NULL, 1434 0, SND_SOC_NOPM, 0, 0), 1435 SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7", NULL, 1436 0, SND_SOC_NOPM, 0, 0), 1437 1438 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0", NULL, 1439 0, SND_SOC_NOPM, 0, 0), 1440 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1", NULL, 1441 0, SND_SOC_NOPM, 0, 0), 1442 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2", NULL, 1443 0, SND_SOC_NOPM, 0, 0), 1444 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3", NULL, 1445 0, SND_SOC_NOPM, 0, 0), 1446 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4", NULL, 1447 0, SND_SOC_NOPM, 0, 0), 1448 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5", NULL, 1449 0, SND_SOC_NOPM, 0, 0), 1450 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6", NULL, 1451 0, SND_SOC_NOPM, 0, 0), 1452 SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7", NULL, 1453 0, SND_SOC_NOPM, 0, 0), 1454 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0", NULL, 1455 0, SND_SOC_NOPM, 0, 0), 1456 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1", NULL, 1457 0, SND_SOC_NOPM, 0, 0), 1458 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2", NULL, 1459 0, SND_SOC_NOPM, 0, 0), 1460 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3", NULL, 1461 0, SND_SOC_NOPM, 0, 0), 1462 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4", NULL, 1463 0, SND_SOC_NOPM, 0, 0), 1464 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5", NULL, 1465 0, SND_SOC_NOPM, 0, 0), 1466 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6", NULL, 1467 0, SND_SOC_NOPM, 0, 0), 1468 SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7", NULL, 1469 0, SND_SOC_NOPM, 0, 0), 1470 1471 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0", NULL, 1472 0, SND_SOC_NOPM, 0, 0), 1473 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1", NULL, 1474 0, SND_SOC_NOPM, 0, 0), 1475 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2", NULL, 1476 0, SND_SOC_NOPM, 0, 0), 1477 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3", NULL, 1478 0, SND_SOC_NOPM, 0, 0), 1479 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4", NULL, 1480 0, SND_SOC_NOPM, 0, 0), 1481 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5", NULL, 1482 0, SND_SOC_NOPM, 0, 0), 1483 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6", NULL, 1484 0, SND_SOC_NOPM, 0, 0), 1485 SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7", NULL, 1486 0, SND_SOC_NOPM, 0, 0), 1487 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0", NULL, 1488 0, SND_SOC_NOPM, 0, 0), 1489 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1", NULL, 1490 0, SND_SOC_NOPM, 0, 0), 1491 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2", NULL, 1492 0, SND_SOC_NOPM, 0, 0), 1493 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3", NULL, 1494 0, SND_SOC_NOPM, 0, 0), 1495 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4", NULL, 1496 0, SND_SOC_NOPM, 0, 0), 1497 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5", NULL, 1498 0, SND_SOC_NOPM, 0, 0), 1499 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6", NULL, 1500 0, SND_SOC_NOPM, 0, 0), 1501 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7", NULL, 1502 0, SND_SOC_NOPM, 0, 0), 1503 1504 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0", NULL, 1505 0, SND_SOC_NOPM, 0, 0), 1506 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1", NULL, 1507 0, SND_SOC_NOPM, 0, 0), 1508 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2", NULL, 1509 0, SND_SOC_NOPM, 0, 0), 1510 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3", NULL, 1511 0, SND_SOC_NOPM, 0, 0), 1512 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4", NULL, 1513 0, SND_SOC_NOPM, 0, 0), 1514 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5", NULL, 1515 0, SND_SOC_NOPM, 0, 0), 1516 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6", NULL, 1517 0, SND_SOC_NOPM, 0, 0), 1518 SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7", NULL, 1519 0, SND_SOC_NOPM, 0, 0), 1520 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0", NULL, 1521 0, SND_SOC_NOPM, 0, 0), 1522 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1", NULL, 1523 0, SND_SOC_NOPM, 0, 0), 1524 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2", NULL, 1525 0, SND_SOC_NOPM, 0, 0), 1526 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3", NULL, 1527 0, SND_SOC_NOPM, 0, 0), 1528 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4", NULL, 1529 0, SND_SOC_NOPM, 0, 0), 1530 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5", NULL, 1531 0, SND_SOC_NOPM, 0, 0), 1532 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6", NULL, 1533 0, SND_SOC_NOPM, 0, 0), 1534 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL, 1535 0, SND_SOC_NOPM, 0, 0), 1536 SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT_RX", "NULL", 0, SND_SOC_NOPM, 0, 0), 1537 1538 SND_SOC_DAPM_AIF_IN("WSA_CODEC_DMA_RX_0", "NULL", 1539 0, SND_SOC_NOPM, 0, 0), 1540 SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_0", "NULL", 1541 0, SND_SOC_NOPM, 0, 0), 1542 SND_SOC_DAPM_AIF_IN("WSA_CODEC_DMA_RX_1", "NULL", 1543 0, SND_SOC_NOPM, 0, 0), 1544 SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_1", "NULL", 1545 0, SND_SOC_NOPM, 0, 0), 1546 SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_2", "NULL", 1547 0, SND_SOC_NOPM, 0, 0), 1548 SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_0", "NULL", 1549 0, SND_SOC_NOPM, 0, 0), 1550 SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_1", "NULL", 1551 0, SND_SOC_NOPM, 0, 0), 1552 SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_2", "NULL", 1553 0, SND_SOC_NOPM, 0, 0), 1554 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_0", "NULL", 1555 0, SND_SOC_NOPM, 0, 0), 1556 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_0", "NULL", 1557 0, SND_SOC_NOPM, 0, 0), 1558 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_1", "NULL", 1559 0, SND_SOC_NOPM, 0, 0), 1560 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_1", "NULL", 1561 0, SND_SOC_NOPM, 0, 0), 1562 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_2", "NULL", 1563 0, SND_SOC_NOPM, 0, 0), 1564 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_2", "NULL", 1565 0, SND_SOC_NOPM, 0, 0), 1566 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_3", "NULL", 1567 0, SND_SOC_NOPM, 0, 0), 1568 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_3", "NULL", 1569 0, SND_SOC_NOPM, 0, 0), 1570 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_4", "NULL", 1571 0, SND_SOC_NOPM, 0, 0), 1572 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_4", "NULL", 1573 0, SND_SOC_NOPM, 0, 0), 1574 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_5", "NULL", 1575 0, SND_SOC_NOPM, 0, 0), 1576 SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_5", "NULL", 1577 0, SND_SOC_NOPM, 0, 0), 1578 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_6", "NULL", 1579 0, SND_SOC_NOPM, 0, 0), 1580 SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_7", "NULL", 1581 0, SND_SOC_NOPM, 0, 0), 1582 }; 1583 1584 static const struct snd_soc_component_driver q6afe_dai_component = { 1585 .name = "q6afe-dai-component", 1586 .dapm_widgets = q6afe_dai_widgets, 1587 .num_dapm_widgets = ARRAY_SIZE(q6afe_dai_widgets), 1588 .dapm_routes = q6afe_dapm_routes, 1589 .num_dapm_routes = ARRAY_SIZE(q6afe_dapm_routes), 1590 .of_xlate_dai_name = q6afe_of_xlate_dai_name, 1591 1592 }; 1593 1594 static void of_q6afe_parse_dai_data(struct device *dev, 1595 struct q6afe_dai_data *data) 1596 { 1597 struct device_node *node; 1598 int ret; 1599 1600 for_each_child_of_node(dev->of_node, node) { 1601 unsigned int lines[Q6AFE_MAX_MI2S_LINES]; 1602 struct q6afe_dai_priv_data *priv; 1603 int id, i, num_lines; 1604 1605 ret = of_property_read_u32(node, "reg", &id); 1606 if (ret || id < 0 || id >= AFE_PORT_MAX) { 1607 dev_err(dev, "valid dai id not found:%d\n", ret); 1608 continue; 1609 } 1610 1611 switch (id) { 1612 /* MI2S specific properties */ 1613 case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX: 1614 priv = &data->priv[id]; 1615 ret = of_property_read_variable_u32_array(node, 1616 "qcom,sd-lines", 1617 lines, 0, 1618 Q6AFE_MAX_MI2S_LINES); 1619 if (ret < 0) 1620 num_lines = 0; 1621 else 1622 num_lines = ret; 1623 1624 priv->sd_line_mask = 0; 1625 1626 for (i = 0; i < num_lines; i++) 1627 priv->sd_line_mask |= BIT(lines[i]); 1628 1629 break; 1630 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 1631 priv = &data->priv[id]; 1632 ret = of_property_read_u32(node, "qcom,tdm-sync-mode", 1633 &priv->sync_mode); 1634 if (ret) { 1635 dev_err(dev, "No Sync mode from DT\n"); 1636 break; 1637 } 1638 ret = of_property_read_u32(node, "qcom,tdm-sync-src", 1639 &priv->sync_src); 1640 if (ret) { 1641 dev_err(dev, "No Sync Src from DT\n"); 1642 break; 1643 } 1644 ret = of_property_read_u32(node, "qcom,tdm-data-out", 1645 &priv->data_out_enable); 1646 if (ret) { 1647 dev_err(dev, "No Data out enable from DT\n"); 1648 break; 1649 } 1650 ret = of_property_read_u32(node, "qcom,tdm-invert-sync", 1651 &priv->invert_sync); 1652 if (ret) { 1653 dev_err(dev, "No Invert sync from DT\n"); 1654 break; 1655 } 1656 ret = of_property_read_u32(node, "qcom,tdm-data-delay", 1657 &priv->data_delay); 1658 if (ret) { 1659 dev_err(dev, "No Data Delay from DT\n"); 1660 break; 1661 } 1662 ret = of_property_read_u32(node, "qcom,tdm-data-align", 1663 &priv->data_align); 1664 if (ret) { 1665 dev_err(dev, "No Data align from DT\n"); 1666 break; 1667 } 1668 break; 1669 default: 1670 break; 1671 } 1672 } 1673 } 1674 1675 static int q6afe_dai_dev_probe(struct platform_device *pdev) 1676 { 1677 struct q6afe_dai_data *dai_data; 1678 struct device *dev = &pdev->dev; 1679 1680 dai_data = devm_kzalloc(dev, sizeof(*dai_data), GFP_KERNEL); 1681 if (!dai_data) 1682 return -ENOMEM; 1683 1684 dev_set_drvdata(dev, dai_data); 1685 1686 of_q6afe_parse_dai_data(dev, dai_data); 1687 1688 return devm_snd_soc_register_component(dev, &q6afe_dai_component, 1689 q6afe_dais, ARRAY_SIZE(q6afe_dais)); 1690 } 1691 1692 #ifdef CONFIG_OF 1693 static const struct of_device_id q6afe_dai_device_id[] = { 1694 { .compatible = "qcom,q6afe-dais" }, 1695 {}, 1696 }; 1697 MODULE_DEVICE_TABLE(of, q6afe_dai_device_id); 1698 #endif 1699 1700 static struct platform_driver q6afe_dai_platform_driver = { 1701 .driver = { 1702 .name = "q6afe-dai", 1703 .of_match_table = of_match_ptr(q6afe_dai_device_id), 1704 }, 1705 .probe = q6afe_dai_dev_probe, 1706 }; 1707 module_platform_driver(q6afe_dai_platform_driver); 1708 1709 MODULE_DESCRIPTION("Q6 Audio Fronend dai driver"); 1710 MODULE_LICENSE("GPL v2"); 1711