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/init.h> 6 #include <linux/err.h> 7 #include <linux/module.h> 8 #include <linux/platform_device.h> 9 #include <linux/slab.h> 10 #include <sound/soc.h> 11 #include <sound/soc-dapm.h> 12 #include <sound/pcm.h> 13 #include <linux/spinlock.h> 14 #include <sound/compress_driver.h> 15 #include <asm/dma.h> 16 #include <linux/dma-mapping.h> 17 #include <linux/of_device.h> 18 #include <sound/pcm_params.h> 19 #include "q6asm.h" 20 #include "q6routing.h" 21 #include "q6dsp-errno.h" 22 23 #define DRV_NAME "q6asm-fe-dai" 24 25 #define PLAYBACK_MIN_NUM_PERIODS 2 26 #define PLAYBACK_MAX_NUM_PERIODS 8 27 #define PLAYBACK_MAX_PERIOD_SIZE 65536 28 #define PLAYBACK_MIN_PERIOD_SIZE 128 29 #define CAPTURE_MIN_NUM_PERIODS 2 30 #define CAPTURE_MAX_NUM_PERIODS 8 31 #define CAPTURE_MAX_PERIOD_SIZE 4096 32 #define CAPTURE_MIN_PERIOD_SIZE 320 33 #define SID_MASK_DEFAULT 0xF 34 35 /* Default values used if user space does not set */ 36 #define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024) 37 #define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024) 38 #define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4) 39 #define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4) 40 41 #define ALAC_CH_LAYOUT_MONO ((101 << 16) | 1) 42 #define ALAC_CH_LAYOUT_STEREO ((101 << 16) | 2) 43 44 enum stream_state { 45 Q6ASM_STREAM_IDLE = 0, 46 Q6ASM_STREAM_STOPPED, 47 Q6ASM_STREAM_RUNNING, 48 }; 49 50 struct q6asm_dai_rtd { 51 struct snd_pcm_substream *substream; 52 struct snd_compr_stream *cstream; 53 struct snd_codec codec; 54 struct snd_dma_buffer dma_buffer; 55 spinlock_t lock; 56 phys_addr_t phys; 57 unsigned int pcm_size; 58 unsigned int pcm_count; 59 unsigned int pcm_irq_pos; /* IRQ position */ 60 unsigned int periods; 61 unsigned int bytes_sent; 62 unsigned int bytes_received; 63 unsigned int copied_total; 64 uint16_t bits_per_sample; 65 uint16_t source; /* Encoding source bit mask */ 66 struct audio_client *audio_client; 67 uint32_t next_track_stream_id; 68 bool next_track; 69 uint32_t stream_id; 70 uint16_t session_id; 71 enum stream_state state; 72 uint32_t initial_samples_drop; 73 uint32_t trailing_samples_drop; 74 bool notify_on_drain; 75 }; 76 77 struct q6asm_dai_data { 78 struct snd_soc_dai_driver *dais; 79 int num_dais; 80 long long int sid; 81 }; 82 83 static const struct snd_pcm_hardware q6asm_dai_hardware_capture = { 84 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH | 85 SNDRV_PCM_INFO_BLOCK_TRANSFER | 86 SNDRV_PCM_INFO_MMAP_VALID | 87 SNDRV_PCM_INFO_INTERLEAVED | 88 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 89 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 90 SNDRV_PCM_FMTBIT_S24_LE), 91 .rates = SNDRV_PCM_RATE_8000_48000, 92 .rate_min = 8000, 93 .rate_max = 48000, 94 .channels_min = 1, 95 .channels_max = 4, 96 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * 97 CAPTURE_MAX_PERIOD_SIZE, 98 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, 99 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, 100 .periods_min = CAPTURE_MIN_NUM_PERIODS, 101 .periods_max = CAPTURE_MAX_NUM_PERIODS, 102 .fifo_size = 0, 103 }; 104 105 static struct snd_pcm_hardware q6asm_dai_hardware_playback = { 106 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH | 107 SNDRV_PCM_INFO_BLOCK_TRANSFER | 108 SNDRV_PCM_INFO_MMAP_VALID | 109 SNDRV_PCM_INFO_INTERLEAVED | 110 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 111 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 112 SNDRV_PCM_FMTBIT_S24_LE), 113 .rates = SNDRV_PCM_RATE_8000_192000, 114 .rate_min = 8000, 115 .rate_max = 192000, 116 .channels_min = 1, 117 .channels_max = 8, 118 .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS * 119 PLAYBACK_MAX_PERIOD_SIZE), 120 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, 121 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, 122 .periods_min = PLAYBACK_MIN_NUM_PERIODS, 123 .periods_max = PLAYBACK_MAX_NUM_PERIODS, 124 .fifo_size = 0, 125 }; 126 127 #define Q6ASM_FEDAI_DRIVER(num) { \ 128 .playback = { \ 129 .stream_name = "MultiMedia"#num" Playback", \ 130 .rates = (SNDRV_PCM_RATE_8000_192000| \ 131 SNDRV_PCM_RATE_KNOT), \ 132 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \ 133 SNDRV_PCM_FMTBIT_S24_LE), \ 134 .channels_min = 1, \ 135 .channels_max = 8, \ 136 .rate_min = 8000, \ 137 .rate_max = 192000, \ 138 }, \ 139 .capture = { \ 140 .stream_name = "MultiMedia"#num" Capture", \ 141 .rates = (SNDRV_PCM_RATE_8000_48000| \ 142 SNDRV_PCM_RATE_KNOT), \ 143 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \ 144 SNDRV_PCM_FMTBIT_S24_LE), \ 145 .channels_min = 1, \ 146 .channels_max = 4, \ 147 .rate_min = 8000, \ 148 .rate_max = 48000, \ 149 }, \ 150 .name = "MultiMedia"#num, \ 151 .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \ 152 } 153 154 /* Conventional and unconventional sample rate supported */ 155 static unsigned int supported_sample_rates[] = { 156 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 157 88200, 96000, 176400, 192000 158 }; 159 160 static struct snd_pcm_hw_constraint_list constraints_sample_rates = { 161 .count = ARRAY_SIZE(supported_sample_rates), 162 .list = supported_sample_rates, 163 .mask = 0, 164 }; 165 166 static const struct snd_compr_codec_caps q6asm_compr_caps = { 167 .num_descriptors = 1, 168 .descriptor[0].max_ch = 2, 169 .descriptor[0].sample_rates = { 8000, 11025, 12000, 16000, 22050, 170 24000, 32000, 44100, 48000, 88200, 171 96000, 176400, 192000 }, 172 .descriptor[0].num_sample_rates = 13, 173 .descriptor[0].bit_rate[0] = 320, 174 .descriptor[0].bit_rate[1] = 128, 175 .descriptor[0].num_bitrates = 2, 176 .descriptor[0].profiles = 0, 177 .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, 178 .descriptor[0].formats = 0, 179 }; 180 181 static void event_handler(uint32_t opcode, uint32_t token, 182 void *payload, void *priv) 183 { 184 struct q6asm_dai_rtd *prtd = priv; 185 struct snd_pcm_substream *substream = prtd->substream; 186 187 switch (opcode) { 188 case ASM_CLIENT_EVENT_CMD_RUN_DONE: 189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 190 q6asm_write_async(prtd->audio_client, prtd->stream_id, 191 prtd->pcm_count, 0, 0, 0); 192 break; 193 case ASM_CLIENT_EVENT_CMD_EOS_DONE: 194 prtd->state = Q6ASM_STREAM_STOPPED; 195 break; 196 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: { 197 prtd->pcm_irq_pos += prtd->pcm_count; 198 snd_pcm_period_elapsed(substream); 199 if (prtd->state == Q6ASM_STREAM_RUNNING) 200 q6asm_write_async(prtd->audio_client, prtd->stream_id, 201 prtd->pcm_count, 0, 0, 0); 202 203 break; 204 } 205 case ASM_CLIENT_EVENT_DATA_READ_DONE: 206 prtd->pcm_irq_pos += prtd->pcm_count; 207 snd_pcm_period_elapsed(substream); 208 if (prtd->state == Q6ASM_STREAM_RUNNING) 209 q6asm_read(prtd->audio_client, prtd->stream_id); 210 211 break; 212 default: 213 break; 214 } 215 } 216 217 static int q6asm_dai_prepare(struct snd_soc_component *component, 218 struct snd_pcm_substream *substream) 219 { 220 struct snd_pcm_runtime *runtime = substream->runtime; 221 struct snd_soc_pcm_runtime *soc_prtd = asoc_substream_to_rtd(substream); 222 struct q6asm_dai_rtd *prtd = runtime->private_data; 223 struct q6asm_dai_data *pdata; 224 struct device *dev = component->dev; 225 int ret, i; 226 227 pdata = snd_soc_component_get_drvdata(component); 228 if (!pdata) 229 return -EINVAL; 230 231 if (!prtd || !prtd->audio_client) { 232 dev_err(dev, "%s: private data null or audio client freed\n", 233 __func__); 234 return -EINVAL; 235 } 236 237 prtd->pcm_count = snd_pcm_lib_period_bytes(substream); 238 prtd->pcm_irq_pos = 0; 239 /* rate and channels are sent to audio driver */ 240 if (prtd->state) { 241 /* clear the previous setup if any */ 242 q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE); 243 q6asm_unmap_memory_regions(substream->stream, 244 prtd->audio_client); 245 q6routing_stream_close(soc_prtd->dai_link->id, 246 substream->stream); 247 } 248 249 ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client, 250 prtd->phys, 251 (prtd->pcm_size / prtd->periods), 252 prtd->periods); 253 254 if (ret < 0) { 255 dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", 256 ret); 257 return -ENOMEM; 258 } 259 260 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 261 ret = q6asm_open_write(prtd->audio_client, prtd->stream_id, 262 FORMAT_LINEAR_PCM, 263 0, prtd->bits_per_sample, false); 264 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 265 ret = q6asm_open_read(prtd->audio_client, prtd->stream_id, 266 FORMAT_LINEAR_PCM, 267 prtd->bits_per_sample); 268 } 269 270 if (ret < 0) { 271 dev_err(dev, "%s: q6asm_open_write failed\n", __func__); 272 q6asm_audio_client_free(prtd->audio_client); 273 prtd->audio_client = NULL; 274 return -ENOMEM; 275 } 276 277 prtd->session_id = q6asm_get_session_id(prtd->audio_client); 278 ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE, 279 prtd->session_id, substream->stream); 280 if (ret) { 281 dev_err(dev, "%s: stream reg failed ret:%d\n", __func__, ret); 282 return ret; 283 } 284 285 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 286 ret = q6asm_media_format_block_multi_ch_pcm( 287 prtd->audio_client, prtd->stream_id, 288 runtime->rate, runtime->channels, NULL, 289 prtd->bits_per_sample); 290 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 291 ret = q6asm_enc_cfg_blk_pcm_format_support(prtd->audio_client, 292 prtd->stream_id, 293 runtime->rate, 294 runtime->channels, 295 prtd->bits_per_sample); 296 297 /* Queue the buffers */ 298 for (i = 0; i < runtime->periods; i++) 299 q6asm_read(prtd->audio_client, prtd->stream_id); 300 301 } 302 if (ret < 0) 303 dev_info(dev, "%s: CMD Format block failed\n", __func__); 304 305 prtd->state = Q6ASM_STREAM_RUNNING; 306 307 return 0; 308 } 309 310 static int q6asm_dai_trigger(struct snd_soc_component *component, 311 struct snd_pcm_substream *substream, int cmd) 312 { 313 int ret = 0; 314 struct snd_pcm_runtime *runtime = substream->runtime; 315 struct q6asm_dai_rtd *prtd = runtime->private_data; 316 317 switch (cmd) { 318 case SNDRV_PCM_TRIGGER_START: 319 case SNDRV_PCM_TRIGGER_RESUME: 320 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 321 ret = q6asm_run_nowait(prtd->audio_client, prtd->stream_id, 322 0, 0, 0); 323 break; 324 case SNDRV_PCM_TRIGGER_STOP: 325 prtd->state = Q6ASM_STREAM_STOPPED; 326 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, 327 CMD_EOS); 328 break; 329 case SNDRV_PCM_TRIGGER_SUSPEND: 330 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 331 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, 332 CMD_PAUSE); 333 break; 334 default: 335 ret = -EINVAL; 336 break; 337 } 338 339 return ret; 340 } 341 342 static int q6asm_dai_open(struct snd_soc_component *component, 343 struct snd_pcm_substream *substream) 344 { 345 struct snd_pcm_runtime *runtime = substream->runtime; 346 struct snd_soc_pcm_runtime *soc_prtd = asoc_substream_to_rtd(substream); 347 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_prtd, 0); 348 struct q6asm_dai_rtd *prtd; 349 struct q6asm_dai_data *pdata; 350 struct device *dev = component->dev; 351 int ret = 0; 352 int stream_id; 353 354 stream_id = cpu_dai->driver->id; 355 356 pdata = snd_soc_component_get_drvdata(component); 357 if (!pdata) { 358 dev_err(dev, "Drv data not found ..\n"); 359 return -EINVAL; 360 } 361 362 prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL); 363 if (prtd == NULL) 364 return -ENOMEM; 365 366 prtd->substream = substream; 367 prtd->audio_client = q6asm_audio_client_alloc(dev, 368 (q6asm_cb)event_handler, prtd, stream_id, 369 LEGACY_PCM_MODE); 370 if (IS_ERR(prtd->audio_client)) { 371 dev_info(dev, "%s: Could not allocate memory\n", __func__); 372 ret = PTR_ERR(prtd->audio_client); 373 kfree(prtd); 374 return ret; 375 } 376 377 /* DSP expects stream id from 1 */ 378 prtd->stream_id = 1; 379 380 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 381 runtime->hw = q6asm_dai_hardware_playback; 382 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 383 runtime->hw = q6asm_dai_hardware_capture; 384 385 ret = snd_pcm_hw_constraint_list(runtime, 0, 386 SNDRV_PCM_HW_PARAM_RATE, 387 &constraints_sample_rates); 388 if (ret < 0) 389 dev_info(dev, "snd_pcm_hw_constraint_list failed\n"); 390 /* Ensure that buffer size is a multiple of period size */ 391 ret = snd_pcm_hw_constraint_integer(runtime, 392 SNDRV_PCM_HW_PARAM_PERIODS); 393 if (ret < 0) 394 dev_info(dev, "snd_pcm_hw_constraint_integer failed\n"); 395 396 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 397 ret = snd_pcm_hw_constraint_minmax(runtime, 398 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 399 PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE, 400 PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE); 401 if (ret < 0) { 402 dev_err(dev, "constraint for buffer bytes min max ret = %d\n", 403 ret); 404 } 405 } 406 407 ret = snd_pcm_hw_constraint_step(runtime, 0, 408 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 409 if (ret < 0) { 410 dev_err(dev, "constraint for period bytes step ret = %d\n", 411 ret); 412 } 413 ret = snd_pcm_hw_constraint_step(runtime, 0, 414 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 415 if (ret < 0) { 416 dev_err(dev, "constraint for buffer bytes step ret = %d\n", 417 ret); 418 } 419 420 runtime->private_data = prtd; 421 422 snd_soc_set_runtime_hwparams(substream, &q6asm_dai_hardware_playback); 423 424 runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max; 425 426 427 if (pdata->sid < 0) 428 prtd->phys = substream->dma_buffer.addr; 429 else 430 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); 431 432 return 0; 433 } 434 435 static int q6asm_dai_close(struct snd_soc_component *component, 436 struct snd_pcm_substream *substream) 437 { 438 struct snd_pcm_runtime *runtime = substream->runtime; 439 struct snd_soc_pcm_runtime *soc_prtd = asoc_substream_to_rtd(substream); 440 struct q6asm_dai_rtd *prtd = runtime->private_data; 441 442 if (prtd->audio_client) { 443 if (prtd->state) 444 q6asm_cmd(prtd->audio_client, prtd->stream_id, 445 CMD_CLOSE); 446 447 q6asm_unmap_memory_regions(substream->stream, 448 prtd->audio_client); 449 q6asm_audio_client_free(prtd->audio_client); 450 prtd->audio_client = NULL; 451 } 452 q6routing_stream_close(soc_prtd->dai_link->id, 453 substream->stream); 454 kfree(prtd); 455 return 0; 456 } 457 458 static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_soc_component *component, 459 struct snd_pcm_substream *substream) 460 { 461 462 struct snd_pcm_runtime *runtime = substream->runtime; 463 struct q6asm_dai_rtd *prtd = runtime->private_data; 464 465 if (prtd->pcm_irq_pos >= prtd->pcm_size) 466 prtd->pcm_irq_pos = 0; 467 468 return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); 469 } 470 471 static int q6asm_dai_hw_params(struct snd_soc_component *component, 472 struct snd_pcm_substream *substream, 473 struct snd_pcm_hw_params *params) 474 { 475 struct snd_pcm_runtime *runtime = substream->runtime; 476 struct q6asm_dai_rtd *prtd = runtime->private_data; 477 478 prtd->pcm_size = params_buffer_bytes(params); 479 prtd->periods = params_periods(params); 480 481 switch (params_format(params)) { 482 case SNDRV_PCM_FORMAT_S16_LE: 483 prtd->bits_per_sample = 16; 484 break; 485 case SNDRV_PCM_FORMAT_S24_LE: 486 prtd->bits_per_sample = 24; 487 break; 488 } 489 490 return 0; 491 } 492 493 static void compress_event_handler(uint32_t opcode, uint32_t token, 494 void *payload, void *priv) 495 { 496 struct q6asm_dai_rtd *prtd = priv; 497 struct snd_compr_stream *substream = prtd->cstream; 498 unsigned long flags; 499 u32 wflags = 0; 500 uint64_t avail; 501 uint32_t bytes_written, bytes_to_write; 502 bool is_last_buffer = false; 503 504 switch (opcode) { 505 case ASM_CLIENT_EVENT_CMD_RUN_DONE: 506 spin_lock_irqsave(&prtd->lock, flags); 507 if (!prtd->bytes_sent) { 508 q6asm_stream_remove_initial_silence(prtd->audio_client, 509 prtd->stream_id, 510 prtd->initial_samples_drop); 511 512 q6asm_write_async(prtd->audio_client, prtd->stream_id, 513 prtd->pcm_count, 0, 0, 0); 514 prtd->bytes_sent += prtd->pcm_count; 515 } 516 517 spin_unlock_irqrestore(&prtd->lock, flags); 518 break; 519 520 case ASM_CLIENT_EVENT_CMD_EOS_DONE: 521 spin_lock_irqsave(&prtd->lock, flags); 522 if (prtd->notify_on_drain) { 523 if (substream->partial_drain) { 524 /* 525 * Close old stream and make it stale, switch 526 * the active stream now! 527 */ 528 q6asm_cmd_nowait(prtd->audio_client, 529 prtd->stream_id, 530 CMD_CLOSE); 531 /* 532 * vaild stream ids start from 1, So we are 533 * toggling this between 1 and 2. 534 */ 535 prtd->stream_id = (prtd->stream_id == 1 ? 2 : 1); 536 } 537 538 snd_compr_drain_notify(prtd->cstream); 539 prtd->notify_on_drain = false; 540 541 } else { 542 prtd->state = Q6ASM_STREAM_STOPPED; 543 } 544 spin_unlock_irqrestore(&prtd->lock, flags); 545 break; 546 547 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: 548 spin_lock_irqsave(&prtd->lock, flags); 549 550 bytes_written = token >> ASM_WRITE_TOKEN_LEN_SHIFT; 551 prtd->copied_total += bytes_written; 552 snd_compr_fragment_elapsed(substream); 553 554 if (prtd->state != Q6ASM_STREAM_RUNNING) { 555 spin_unlock_irqrestore(&prtd->lock, flags); 556 break; 557 } 558 559 avail = prtd->bytes_received - prtd->bytes_sent; 560 if (avail > prtd->pcm_count) { 561 bytes_to_write = prtd->pcm_count; 562 } else { 563 if (substream->partial_drain || prtd->notify_on_drain) 564 is_last_buffer = true; 565 bytes_to_write = avail; 566 } 567 568 if (bytes_to_write) { 569 if (substream->partial_drain && is_last_buffer) { 570 wflags |= ASM_LAST_BUFFER_FLAG; 571 q6asm_stream_remove_trailing_silence(prtd->audio_client, 572 prtd->stream_id, 573 prtd->trailing_samples_drop); 574 } 575 576 q6asm_write_async(prtd->audio_client, prtd->stream_id, 577 bytes_to_write, 0, 0, wflags); 578 579 prtd->bytes_sent += bytes_to_write; 580 } 581 582 if (prtd->notify_on_drain && is_last_buffer) 583 q6asm_cmd_nowait(prtd->audio_client, 584 prtd->stream_id, CMD_EOS); 585 586 spin_unlock_irqrestore(&prtd->lock, flags); 587 break; 588 589 default: 590 break; 591 } 592 } 593 594 static int q6asm_dai_compr_open(struct snd_soc_component *component, 595 struct snd_compr_stream *stream) 596 { 597 struct snd_soc_pcm_runtime *rtd = stream->private_data; 598 struct snd_compr_runtime *runtime = stream->runtime; 599 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 600 struct q6asm_dai_data *pdata; 601 struct device *dev = component->dev; 602 struct q6asm_dai_rtd *prtd; 603 int stream_id, size, ret; 604 605 stream_id = cpu_dai->driver->id; 606 pdata = snd_soc_component_get_drvdata(component); 607 if (!pdata) { 608 dev_err(dev, "Drv data not found ..\n"); 609 return -EINVAL; 610 } 611 612 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 613 if (!prtd) 614 return -ENOMEM; 615 616 /* DSP expects stream id from 1 */ 617 prtd->stream_id = 1; 618 619 prtd->cstream = stream; 620 prtd->audio_client = q6asm_audio_client_alloc(dev, 621 (q6asm_cb)compress_event_handler, 622 prtd, stream_id, LEGACY_PCM_MODE); 623 if (IS_ERR(prtd->audio_client)) { 624 dev_err(dev, "Could not allocate memory\n"); 625 ret = PTR_ERR(prtd->audio_client); 626 goto free_prtd; 627 } 628 629 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * 630 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 631 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 632 &prtd->dma_buffer); 633 if (ret) { 634 dev_err(dev, "Cannot allocate buffer(s)\n"); 635 goto free_client; 636 } 637 638 if (pdata->sid < 0) 639 prtd->phys = prtd->dma_buffer.addr; 640 else 641 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); 642 643 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); 644 spin_lock_init(&prtd->lock); 645 runtime->private_data = prtd; 646 647 return 0; 648 649 free_client: 650 q6asm_audio_client_free(prtd->audio_client); 651 free_prtd: 652 kfree(prtd); 653 654 return ret; 655 } 656 657 static int q6asm_dai_compr_free(struct snd_soc_component *component, 658 struct snd_compr_stream *stream) 659 { 660 struct snd_compr_runtime *runtime = stream->runtime; 661 struct q6asm_dai_rtd *prtd = runtime->private_data; 662 struct snd_soc_pcm_runtime *rtd = stream->private_data; 663 664 if (prtd->audio_client) { 665 if (prtd->state) { 666 q6asm_cmd(prtd->audio_client, prtd->stream_id, 667 CMD_CLOSE); 668 if (prtd->next_track_stream_id) { 669 q6asm_cmd(prtd->audio_client, 670 prtd->next_track_stream_id, 671 CMD_CLOSE); 672 } 673 } 674 675 snd_dma_free_pages(&prtd->dma_buffer); 676 q6asm_unmap_memory_regions(stream->direction, 677 prtd->audio_client); 678 q6asm_audio_client_free(prtd->audio_client); 679 prtd->audio_client = NULL; 680 } 681 q6routing_stream_close(rtd->dai_link->id, stream->direction); 682 kfree(prtd); 683 684 return 0; 685 } 686 687 static int __q6asm_dai_compr_set_codec_params(struct snd_soc_component *component, 688 struct snd_compr_stream *stream, 689 struct snd_codec *codec, 690 int stream_id) 691 { 692 struct snd_compr_runtime *runtime = stream->runtime; 693 struct q6asm_dai_rtd *prtd = runtime->private_data; 694 struct q6asm_flac_cfg flac_cfg; 695 struct q6asm_wma_cfg wma_cfg; 696 struct q6asm_alac_cfg alac_cfg; 697 struct q6asm_ape_cfg ape_cfg; 698 unsigned int wma_v9 = 0; 699 struct device *dev = component->dev; 700 int ret; 701 union snd_codec_options *codec_options; 702 struct snd_dec_flac *flac; 703 struct snd_dec_wma *wma; 704 struct snd_dec_alac *alac; 705 struct snd_dec_ape *ape; 706 707 codec_options = &(prtd->codec.options); 708 709 memcpy(&prtd->codec, codec, sizeof(*codec)); 710 711 switch (codec->id) { 712 case SND_AUDIOCODEC_FLAC: 713 714 memset(&flac_cfg, 0x0, sizeof(struct q6asm_flac_cfg)); 715 flac = &codec_options->flac_d; 716 717 flac_cfg.ch_cfg = codec->ch_in; 718 flac_cfg.sample_rate = codec->sample_rate; 719 flac_cfg.stream_info_present = 1; 720 flac_cfg.sample_size = flac->sample_size; 721 flac_cfg.min_blk_size = flac->min_blk_size; 722 flac_cfg.max_blk_size = flac->max_blk_size; 723 flac_cfg.max_frame_size = flac->max_frame_size; 724 flac_cfg.min_frame_size = flac->min_frame_size; 725 726 ret = q6asm_stream_media_format_block_flac(prtd->audio_client, 727 stream_id, 728 &flac_cfg); 729 if (ret < 0) { 730 dev_err(dev, "FLAC CMD Format block failed:%d\n", ret); 731 return -EIO; 732 } 733 break; 734 735 case SND_AUDIOCODEC_WMA: 736 wma = &codec_options->wma_d; 737 738 memset(&wma_cfg, 0x0, sizeof(struct q6asm_wma_cfg)); 739 740 wma_cfg.sample_rate = codec->sample_rate; 741 wma_cfg.num_channels = codec->ch_in; 742 wma_cfg.bytes_per_sec = codec->bit_rate / 8; 743 wma_cfg.block_align = codec->align; 744 wma_cfg.bits_per_sample = prtd->bits_per_sample; 745 wma_cfg.enc_options = wma->encoder_option; 746 wma_cfg.adv_enc_options = wma->adv_encoder_option; 747 wma_cfg.adv_enc_options2 = wma->adv_encoder_option2; 748 749 if (wma_cfg.num_channels == 1) 750 wma_cfg.channel_mask = 4; /* Mono Center */ 751 else if (wma_cfg.num_channels == 2) 752 wma_cfg.channel_mask = 3; /* Stereo FL/FR */ 753 else 754 return -EINVAL; 755 756 /* check the codec profile */ 757 switch (codec->profile) { 758 case SND_AUDIOPROFILE_WMA9: 759 wma_cfg.fmtag = 0x161; 760 wma_v9 = 1; 761 break; 762 763 case SND_AUDIOPROFILE_WMA10: 764 wma_cfg.fmtag = 0x166; 765 break; 766 767 case SND_AUDIOPROFILE_WMA9_PRO: 768 wma_cfg.fmtag = 0x162; 769 break; 770 771 case SND_AUDIOPROFILE_WMA9_LOSSLESS: 772 wma_cfg.fmtag = 0x163; 773 break; 774 775 case SND_AUDIOPROFILE_WMA10_LOSSLESS: 776 wma_cfg.fmtag = 0x167; 777 break; 778 779 default: 780 dev_err(dev, "Unknown WMA profile:%x\n", 781 codec->profile); 782 return -EIO; 783 } 784 785 if (wma_v9) 786 ret = q6asm_stream_media_format_block_wma_v9( 787 prtd->audio_client, stream_id, 788 &wma_cfg); 789 else 790 ret = q6asm_stream_media_format_block_wma_v10( 791 prtd->audio_client, stream_id, 792 &wma_cfg); 793 if (ret < 0) { 794 dev_err(dev, "WMA9 CMD failed:%d\n", ret); 795 return -EIO; 796 } 797 break; 798 799 case SND_AUDIOCODEC_ALAC: 800 memset(&alac_cfg, 0x0, sizeof(alac_cfg)); 801 alac = &codec_options->alac_d; 802 803 alac_cfg.sample_rate = codec->sample_rate; 804 alac_cfg.avg_bit_rate = codec->bit_rate; 805 alac_cfg.bit_depth = prtd->bits_per_sample; 806 alac_cfg.num_channels = codec->ch_in; 807 808 alac_cfg.frame_length = alac->frame_length; 809 alac_cfg.pb = alac->pb; 810 alac_cfg.mb = alac->mb; 811 alac_cfg.kb = alac->kb; 812 alac_cfg.max_run = alac->max_run; 813 alac_cfg.compatible_version = alac->compatible_version; 814 alac_cfg.max_frame_bytes = alac->max_frame_bytes; 815 816 switch (codec->ch_in) { 817 case 1: 818 alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_MONO; 819 break; 820 case 2: 821 alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_STEREO; 822 break; 823 } 824 ret = q6asm_stream_media_format_block_alac(prtd->audio_client, 825 stream_id, 826 &alac_cfg); 827 if (ret < 0) { 828 dev_err(dev, "ALAC CMD Format block failed:%d\n", ret); 829 return -EIO; 830 } 831 break; 832 833 case SND_AUDIOCODEC_APE: 834 memset(&ape_cfg, 0x0, sizeof(ape_cfg)); 835 ape = &codec_options->ape_d; 836 837 ape_cfg.sample_rate = codec->sample_rate; 838 ape_cfg.num_channels = codec->ch_in; 839 ape_cfg.bits_per_sample = prtd->bits_per_sample; 840 841 ape_cfg.compatible_version = ape->compatible_version; 842 ape_cfg.compression_level = ape->compression_level; 843 ape_cfg.format_flags = ape->format_flags; 844 ape_cfg.blocks_per_frame = ape->blocks_per_frame; 845 ape_cfg.final_frame_blocks = ape->final_frame_blocks; 846 ape_cfg.total_frames = ape->total_frames; 847 ape_cfg.seek_table_present = ape->seek_table_present; 848 849 ret = q6asm_stream_media_format_block_ape(prtd->audio_client, 850 stream_id, 851 &ape_cfg); 852 if (ret < 0) { 853 dev_err(dev, "APE CMD Format block failed:%d\n", ret); 854 return -EIO; 855 } 856 break; 857 858 default: 859 break; 860 } 861 862 return 0; 863 } 864 865 static int q6asm_dai_compr_set_params(struct snd_soc_component *component, 866 struct snd_compr_stream *stream, 867 struct snd_compr_params *params) 868 { 869 struct snd_compr_runtime *runtime = stream->runtime; 870 struct q6asm_dai_rtd *prtd = runtime->private_data; 871 struct snd_soc_pcm_runtime *rtd = stream->private_data; 872 int dir = stream->direction; 873 struct q6asm_dai_data *pdata; 874 struct device *dev = component->dev; 875 int ret; 876 877 pdata = snd_soc_component_get_drvdata(component); 878 if (!pdata) 879 return -EINVAL; 880 881 if (!prtd || !prtd->audio_client) { 882 dev_err(dev, "private data null or audio client freed\n"); 883 return -EINVAL; 884 } 885 886 prtd->periods = runtime->fragments; 887 prtd->pcm_count = runtime->fragment_size; 888 prtd->pcm_size = runtime->fragments * runtime->fragment_size; 889 prtd->bits_per_sample = 16; 890 891 if (dir == SND_COMPRESS_PLAYBACK) { 892 ret = q6asm_open_write(prtd->audio_client, prtd->stream_id, params->codec.id, 893 params->codec.profile, prtd->bits_per_sample, 894 true); 895 896 if (ret < 0) { 897 dev_err(dev, "q6asm_open_write failed\n"); 898 q6asm_audio_client_free(prtd->audio_client); 899 prtd->audio_client = NULL; 900 return ret; 901 } 902 } 903 904 prtd->session_id = q6asm_get_session_id(prtd->audio_client); 905 ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE, 906 prtd->session_id, dir); 907 if (ret) { 908 dev_err(dev, "Stream reg failed ret:%d\n", ret); 909 return ret; 910 } 911 912 ret = __q6asm_dai_compr_set_codec_params(component, stream, 913 ¶ms->codec, 914 prtd->stream_id); 915 if (ret) { 916 dev_err(dev, "codec param setup failed ret:%d\n", ret); 917 return ret; 918 } 919 920 ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys, 921 (prtd->pcm_size / prtd->periods), 922 prtd->periods); 923 924 if (ret < 0) { 925 dev_err(dev, "Buffer Mapping failed ret:%d\n", ret); 926 return -ENOMEM; 927 } 928 929 prtd->state = Q6ASM_STREAM_RUNNING; 930 931 return 0; 932 } 933 934 static int q6asm_dai_compr_set_metadata(struct snd_soc_component *component, 935 struct snd_compr_stream *stream, 936 struct snd_compr_metadata *metadata) 937 { 938 struct snd_compr_runtime *runtime = stream->runtime; 939 struct q6asm_dai_rtd *prtd = runtime->private_data; 940 int ret = 0; 941 942 switch (metadata->key) { 943 case SNDRV_COMPRESS_ENCODER_PADDING: 944 prtd->trailing_samples_drop = metadata->value[0]; 945 break; 946 case SNDRV_COMPRESS_ENCODER_DELAY: 947 prtd->initial_samples_drop = metadata->value[0]; 948 if (prtd->next_track_stream_id) { 949 ret = q6asm_open_write(prtd->audio_client, 950 prtd->next_track_stream_id, 951 prtd->codec.id, 952 prtd->codec.profile, 953 prtd->bits_per_sample, 954 true); 955 if (ret < 0) { 956 dev_err(component->dev, "q6asm_open_write failed\n"); 957 return ret; 958 } 959 ret = __q6asm_dai_compr_set_codec_params(component, stream, 960 &prtd->codec, 961 prtd->next_track_stream_id); 962 if (ret < 0) { 963 dev_err(component->dev, "q6asm_open_write failed\n"); 964 return ret; 965 } 966 967 ret = q6asm_stream_remove_initial_silence(prtd->audio_client, 968 prtd->next_track_stream_id, 969 prtd->initial_samples_drop); 970 prtd->next_track_stream_id = 0; 971 972 } 973 974 break; 975 default: 976 ret = -EINVAL; 977 break; 978 } 979 980 return ret; 981 } 982 983 static int q6asm_dai_compr_trigger(struct snd_soc_component *component, 984 struct snd_compr_stream *stream, int cmd) 985 { 986 struct snd_compr_runtime *runtime = stream->runtime; 987 struct q6asm_dai_rtd *prtd = runtime->private_data; 988 int ret = 0; 989 990 switch (cmd) { 991 case SNDRV_PCM_TRIGGER_START: 992 case SNDRV_PCM_TRIGGER_RESUME: 993 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 994 ret = q6asm_run_nowait(prtd->audio_client, prtd->stream_id, 995 0, 0, 0); 996 break; 997 case SNDRV_PCM_TRIGGER_STOP: 998 prtd->state = Q6ASM_STREAM_STOPPED; 999 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, 1000 CMD_EOS); 1001 break; 1002 case SNDRV_PCM_TRIGGER_SUSPEND: 1003 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1004 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, 1005 CMD_PAUSE); 1006 break; 1007 case SND_COMPR_TRIGGER_NEXT_TRACK: 1008 prtd->next_track = true; 1009 prtd->next_track_stream_id = (prtd->stream_id == 1 ? 2 : 1); 1010 break; 1011 case SND_COMPR_TRIGGER_DRAIN: 1012 case SND_COMPR_TRIGGER_PARTIAL_DRAIN: 1013 prtd->notify_on_drain = true; 1014 break; 1015 default: 1016 ret = -EINVAL; 1017 break; 1018 } 1019 1020 return ret; 1021 } 1022 1023 static int q6asm_dai_compr_pointer(struct snd_soc_component *component, 1024 struct snd_compr_stream *stream, 1025 struct snd_compr_tstamp *tstamp) 1026 { 1027 struct snd_compr_runtime *runtime = stream->runtime; 1028 struct q6asm_dai_rtd *prtd = runtime->private_data; 1029 unsigned long flags; 1030 1031 spin_lock_irqsave(&prtd->lock, flags); 1032 1033 tstamp->copied_total = prtd->copied_total; 1034 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; 1035 1036 spin_unlock_irqrestore(&prtd->lock, flags); 1037 1038 return 0; 1039 } 1040 1041 static int q6asm_compr_copy(struct snd_soc_component *component, 1042 struct snd_compr_stream *stream, char __user *buf, 1043 size_t count) 1044 { 1045 struct snd_compr_runtime *runtime = stream->runtime; 1046 struct q6asm_dai_rtd *prtd = runtime->private_data; 1047 unsigned long flags; 1048 u32 wflags = 0; 1049 int avail, bytes_in_flight = 0; 1050 void *dstn; 1051 size_t copy; 1052 u32 app_pointer; 1053 u32 bytes_received; 1054 1055 bytes_received = prtd->bytes_received; 1056 1057 /** 1058 * Make sure that next track data pointer is aligned at 32 bit boundary 1059 * This is a Mandatory requirement from DSP data buffers alignment 1060 */ 1061 if (prtd->next_track) 1062 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count); 1063 1064 app_pointer = bytes_received/prtd->pcm_size; 1065 app_pointer = bytes_received - (app_pointer * prtd->pcm_size); 1066 dstn = prtd->dma_buffer.area + app_pointer; 1067 1068 if (count < prtd->pcm_size - app_pointer) { 1069 if (copy_from_user(dstn, buf, count)) 1070 return -EFAULT; 1071 } else { 1072 copy = prtd->pcm_size - app_pointer; 1073 if (copy_from_user(dstn, buf, copy)) 1074 return -EFAULT; 1075 if (copy_from_user(prtd->dma_buffer.area, buf + copy, 1076 count - copy)) 1077 return -EFAULT; 1078 } 1079 1080 spin_lock_irqsave(&prtd->lock, flags); 1081 1082 bytes_in_flight = prtd->bytes_received - prtd->copied_total; 1083 1084 if (prtd->next_track) { 1085 prtd->next_track = false; 1086 prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count); 1087 prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count); 1088 } 1089 1090 prtd->bytes_received = bytes_received + count; 1091 1092 /* Kick off the data to dsp if its starving!! */ 1093 if (prtd->state == Q6ASM_STREAM_RUNNING && (bytes_in_flight == 0)) { 1094 uint32_t bytes_to_write = prtd->pcm_count; 1095 1096 avail = prtd->bytes_received - prtd->bytes_sent; 1097 1098 if (avail < prtd->pcm_count) 1099 bytes_to_write = avail; 1100 1101 q6asm_write_async(prtd->audio_client, prtd->stream_id, 1102 bytes_to_write, 0, 0, wflags); 1103 prtd->bytes_sent += bytes_to_write; 1104 } 1105 1106 spin_unlock_irqrestore(&prtd->lock, flags); 1107 1108 return count; 1109 } 1110 1111 static int q6asm_dai_compr_mmap(struct snd_soc_component *component, 1112 struct snd_compr_stream *stream, 1113 struct vm_area_struct *vma) 1114 { 1115 struct snd_compr_runtime *runtime = stream->runtime; 1116 struct q6asm_dai_rtd *prtd = runtime->private_data; 1117 struct device *dev = component->dev; 1118 1119 return dma_mmap_coherent(dev, vma, 1120 prtd->dma_buffer.area, prtd->dma_buffer.addr, 1121 prtd->dma_buffer.bytes); 1122 } 1123 1124 static int q6asm_dai_compr_get_caps(struct snd_soc_component *component, 1125 struct snd_compr_stream *stream, 1126 struct snd_compr_caps *caps) 1127 { 1128 caps->direction = SND_COMPRESS_PLAYBACK; 1129 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; 1130 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 1131 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 1132 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 1133 caps->num_codecs = 5; 1134 caps->codecs[0] = SND_AUDIOCODEC_MP3; 1135 caps->codecs[1] = SND_AUDIOCODEC_FLAC; 1136 caps->codecs[2] = SND_AUDIOCODEC_WMA; 1137 caps->codecs[3] = SND_AUDIOCODEC_ALAC; 1138 caps->codecs[4] = SND_AUDIOCODEC_APE; 1139 1140 return 0; 1141 } 1142 1143 static int q6asm_dai_compr_get_codec_caps(struct snd_soc_component *component, 1144 struct snd_compr_stream *stream, 1145 struct snd_compr_codec_caps *codec) 1146 { 1147 switch (codec->codec) { 1148 case SND_AUDIOCODEC_MP3: 1149 *codec = q6asm_compr_caps; 1150 break; 1151 default: 1152 break; 1153 } 1154 1155 return 0; 1156 } 1157 1158 static const struct snd_compress_ops q6asm_dai_compress_ops = { 1159 .open = q6asm_dai_compr_open, 1160 .free = q6asm_dai_compr_free, 1161 .set_params = q6asm_dai_compr_set_params, 1162 .set_metadata = q6asm_dai_compr_set_metadata, 1163 .pointer = q6asm_dai_compr_pointer, 1164 .trigger = q6asm_dai_compr_trigger, 1165 .get_caps = q6asm_dai_compr_get_caps, 1166 .get_codec_caps = q6asm_dai_compr_get_codec_caps, 1167 .mmap = q6asm_dai_compr_mmap, 1168 .copy = q6asm_compr_copy, 1169 }; 1170 1171 static int q6asm_dai_pcm_new(struct snd_soc_component *component, 1172 struct snd_soc_pcm_runtime *rtd) 1173 { 1174 struct snd_pcm *pcm = rtd->pcm; 1175 size_t size = q6asm_dai_hardware_playback.buffer_bytes_max; 1176 1177 return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, 1178 component->dev, size); 1179 } 1180 1181 static const struct snd_soc_dapm_widget q6asm_dapm_widgets[] = { 1182 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, SND_SOC_NOPM, 0, 0), 1183 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, SND_SOC_NOPM, 0, 0), 1184 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, SND_SOC_NOPM, 0, 0), 1185 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, SND_SOC_NOPM, 0, 0), 1186 SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, SND_SOC_NOPM, 0, 0), 1187 SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, SND_SOC_NOPM, 0, 0), 1188 SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, SND_SOC_NOPM, 0, 0), 1189 SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, SND_SOC_NOPM, 0, 0), 1190 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, SND_SOC_NOPM, 0, 0), 1191 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, SND_SOC_NOPM, 0, 0), 1192 SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, SND_SOC_NOPM, 0, 0), 1193 SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, SND_SOC_NOPM, 0, 0), 1194 SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, SND_SOC_NOPM, 0, 0), 1195 SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, SND_SOC_NOPM, 0, 0), 1196 SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, SND_SOC_NOPM, 0, 0), 1197 SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, SND_SOC_NOPM, 0, 0), 1198 }; 1199 1200 static const struct snd_soc_component_driver q6asm_fe_dai_component = { 1201 .name = DRV_NAME, 1202 .open = q6asm_dai_open, 1203 .hw_params = q6asm_dai_hw_params, 1204 .close = q6asm_dai_close, 1205 .prepare = q6asm_dai_prepare, 1206 .trigger = q6asm_dai_trigger, 1207 .pointer = q6asm_dai_pointer, 1208 .pcm_construct = q6asm_dai_pcm_new, 1209 .compress_ops = &q6asm_dai_compress_ops, 1210 .dapm_widgets = q6asm_dapm_widgets, 1211 .num_dapm_widgets = ARRAY_SIZE(q6asm_dapm_widgets), 1212 }; 1213 1214 static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { 1215 Q6ASM_FEDAI_DRIVER(1), 1216 Q6ASM_FEDAI_DRIVER(2), 1217 Q6ASM_FEDAI_DRIVER(3), 1218 Q6ASM_FEDAI_DRIVER(4), 1219 Q6ASM_FEDAI_DRIVER(5), 1220 Q6ASM_FEDAI_DRIVER(6), 1221 Q6ASM_FEDAI_DRIVER(7), 1222 Q6ASM_FEDAI_DRIVER(8), 1223 }; 1224 1225 static int of_q6asm_parse_dai_data(struct device *dev, 1226 struct q6asm_dai_data *pdata) 1227 { 1228 struct snd_soc_dai_driver *dai_drv; 1229 struct snd_soc_pcm_stream empty_stream; 1230 struct device_node *node; 1231 int ret, id, dir, idx = 0; 1232 1233 1234 pdata->num_dais = of_get_child_count(dev->of_node); 1235 if (!pdata->num_dais) { 1236 dev_err(dev, "No dais found in DT\n"); 1237 return -EINVAL; 1238 } 1239 1240 pdata->dais = devm_kcalloc(dev, pdata->num_dais, sizeof(*dai_drv), 1241 GFP_KERNEL); 1242 if (!pdata->dais) 1243 return -ENOMEM; 1244 1245 memset(&empty_stream, 0, sizeof(empty_stream)); 1246 1247 for_each_child_of_node(dev->of_node, node) { 1248 ret = of_property_read_u32(node, "reg", &id); 1249 if (ret || id >= MAX_SESSIONS || id < 0) { 1250 dev_err(dev, "valid dai id not found:%d\n", ret); 1251 continue; 1252 } 1253 1254 dai_drv = &pdata->dais[idx++]; 1255 *dai_drv = q6asm_fe_dais_template[id]; 1256 1257 ret = of_property_read_u32(node, "direction", &dir); 1258 if (ret) 1259 continue; 1260 1261 if (dir == Q6ASM_DAI_RX) 1262 dai_drv->capture = empty_stream; 1263 else if (dir == Q6ASM_DAI_TX) 1264 dai_drv->playback = empty_stream; 1265 1266 if (of_property_read_bool(node, "is-compress-dai")) 1267 dai_drv->compress_new = snd_soc_new_compress; 1268 } 1269 1270 return 0; 1271 } 1272 1273 static int q6asm_dai_probe(struct platform_device *pdev) 1274 { 1275 struct device *dev = &pdev->dev; 1276 struct device_node *node = dev->of_node; 1277 struct of_phandle_args args; 1278 struct q6asm_dai_data *pdata; 1279 int rc; 1280 1281 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 1282 if (!pdata) 1283 return -ENOMEM; 1284 1285 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); 1286 if (rc < 0) 1287 pdata->sid = -1; 1288 else 1289 pdata->sid = args.args[0] & SID_MASK_DEFAULT; 1290 1291 dev_set_drvdata(dev, pdata); 1292 1293 rc = of_q6asm_parse_dai_data(dev, pdata); 1294 if (rc) 1295 return rc; 1296 1297 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, 1298 pdata->dais, pdata->num_dais); 1299 } 1300 1301 #ifdef CONFIG_OF 1302 static const struct of_device_id q6asm_dai_device_id[] = { 1303 { .compatible = "qcom,q6asm-dais" }, 1304 {}, 1305 }; 1306 MODULE_DEVICE_TABLE(of, q6asm_dai_device_id); 1307 #endif 1308 1309 static struct platform_driver q6asm_dai_platform_driver = { 1310 .driver = { 1311 .name = "q6asm-dai", 1312 .of_match_table = of_match_ptr(q6asm_dai_device_id), 1313 }, 1314 .probe = q6asm_dai_probe, 1315 }; 1316 module_platform_driver(q6asm_dai_platform_driver); 1317 1318 MODULE_DESCRIPTION("Q6ASM dai driver"); 1319 MODULE_LICENSE("GPL v2"); 1320