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 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 433 434 return 0; 435 } 436 437 static int q6asm_dai_close(struct snd_soc_component *component, 438 struct snd_pcm_substream *substream) 439 { 440 struct snd_pcm_runtime *runtime = substream->runtime; 441 struct snd_soc_pcm_runtime *soc_prtd = asoc_substream_to_rtd(substream); 442 struct q6asm_dai_rtd *prtd = runtime->private_data; 443 444 if (prtd->audio_client) { 445 if (prtd->state) 446 q6asm_cmd(prtd->audio_client, prtd->stream_id, 447 CMD_CLOSE); 448 449 q6asm_unmap_memory_regions(substream->stream, 450 prtd->audio_client); 451 q6asm_audio_client_free(prtd->audio_client); 452 prtd->audio_client = NULL; 453 } 454 q6routing_stream_close(soc_prtd->dai_link->id, 455 substream->stream); 456 kfree(prtd); 457 return 0; 458 } 459 460 static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_soc_component *component, 461 struct snd_pcm_substream *substream) 462 { 463 464 struct snd_pcm_runtime *runtime = substream->runtime; 465 struct q6asm_dai_rtd *prtd = runtime->private_data; 466 467 if (prtd->pcm_irq_pos >= prtd->pcm_size) 468 prtd->pcm_irq_pos = 0; 469 470 return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); 471 } 472 473 static int q6asm_dai_mmap(struct snd_soc_component *component, 474 struct snd_pcm_substream *substream, 475 struct vm_area_struct *vma) 476 { 477 struct snd_pcm_runtime *runtime = substream->runtime; 478 struct device *dev = component->dev; 479 480 return dma_mmap_coherent(dev, vma, 481 runtime->dma_area, runtime->dma_addr, 482 runtime->dma_bytes); 483 } 484 485 static int q6asm_dai_hw_params(struct snd_soc_component *component, 486 struct snd_pcm_substream *substream, 487 struct snd_pcm_hw_params *params) 488 { 489 struct snd_pcm_runtime *runtime = substream->runtime; 490 struct q6asm_dai_rtd *prtd = runtime->private_data; 491 492 prtd->pcm_size = params_buffer_bytes(params); 493 prtd->periods = params_periods(params); 494 495 switch (params_format(params)) { 496 case SNDRV_PCM_FORMAT_S16_LE: 497 prtd->bits_per_sample = 16; 498 break; 499 case SNDRV_PCM_FORMAT_S24_LE: 500 prtd->bits_per_sample = 24; 501 break; 502 } 503 504 return 0; 505 } 506 507 static void compress_event_handler(uint32_t opcode, uint32_t token, 508 void *payload, void *priv) 509 { 510 struct q6asm_dai_rtd *prtd = priv; 511 struct snd_compr_stream *substream = prtd->cstream; 512 unsigned long flags; 513 u32 wflags = 0; 514 uint64_t avail; 515 uint32_t bytes_written, bytes_to_write; 516 bool is_last_buffer = false; 517 518 switch (opcode) { 519 case ASM_CLIENT_EVENT_CMD_RUN_DONE: 520 spin_lock_irqsave(&prtd->lock, flags); 521 if (!prtd->bytes_sent) { 522 q6asm_stream_remove_initial_silence(prtd->audio_client, 523 prtd->stream_id, 524 prtd->initial_samples_drop); 525 526 q6asm_write_async(prtd->audio_client, prtd->stream_id, 527 prtd->pcm_count, 0, 0, 0); 528 prtd->bytes_sent += prtd->pcm_count; 529 } 530 531 spin_unlock_irqrestore(&prtd->lock, flags); 532 break; 533 534 case ASM_CLIENT_EVENT_CMD_EOS_DONE: 535 spin_lock_irqsave(&prtd->lock, flags); 536 if (prtd->notify_on_drain) { 537 if (substream->partial_drain) { 538 /* 539 * Close old stream and make it stale, switch 540 * the active stream now! 541 */ 542 q6asm_cmd_nowait(prtd->audio_client, 543 prtd->stream_id, 544 CMD_CLOSE); 545 /* 546 * vaild stream ids start from 1, So we are 547 * toggling this between 1 and 2. 548 */ 549 prtd->stream_id = (prtd->stream_id == 1 ? 2 : 1); 550 } 551 552 snd_compr_drain_notify(prtd->cstream); 553 prtd->notify_on_drain = false; 554 555 } else { 556 prtd->state = Q6ASM_STREAM_STOPPED; 557 } 558 spin_unlock_irqrestore(&prtd->lock, flags); 559 break; 560 561 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: 562 spin_lock_irqsave(&prtd->lock, flags); 563 564 bytes_written = token >> ASM_WRITE_TOKEN_LEN_SHIFT; 565 prtd->copied_total += bytes_written; 566 snd_compr_fragment_elapsed(substream); 567 568 if (prtd->state != Q6ASM_STREAM_RUNNING) { 569 spin_unlock_irqrestore(&prtd->lock, flags); 570 break; 571 } 572 573 avail = prtd->bytes_received - prtd->bytes_sent; 574 if (avail > prtd->pcm_count) { 575 bytes_to_write = prtd->pcm_count; 576 } else { 577 if (substream->partial_drain || prtd->notify_on_drain) 578 is_last_buffer = true; 579 bytes_to_write = avail; 580 } 581 582 if (bytes_to_write) { 583 if (substream->partial_drain && is_last_buffer) { 584 wflags |= ASM_LAST_BUFFER_FLAG; 585 q6asm_stream_remove_trailing_silence(prtd->audio_client, 586 prtd->stream_id, 587 prtd->trailing_samples_drop); 588 } 589 590 q6asm_write_async(prtd->audio_client, prtd->stream_id, 591 bytes_to_write, 0, 0, wflags); 592 593 prtd->bytes_sent += bytes_to_write; 594 } 595 596 if (prtd->notify_on_drain && is_last_buffer) 597 q6asm_cmd_nowait(prtd->audio_client, 598 prtd->stream_id, CMD_EOS); 599 600 spin_unlock_irqrestore(&prtd->lock, flags); 601 break; 602 603 default: 604 break; 605 } 606 } 607 608 static int q6asm_dai_compr_open(struct snd_soc_component *component, 609 struct snd_compr_stream *stream) 610 { 611 struct snd_soc_pcm_runtime *rtd = stream->private_data; 612 struct snd_compr_runtime *runtime = stream->runtime; 613 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 614 struct q6asm_dai_data *pdata; 615 struct device *dev = component->dev; 616 struct q6asm_dai_rtd *prtd; 617 int stream_id, size, ret; 618 619 stream_id = cpu_dai->driver->id; 620 pdata = snd_soc_component_get_drvdata(component); 621 if (!pdata) { 622 dev_err(dev, "Drv data not found ..\n"); 623 return -EINVAL; 624 } 625 626 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 627 if (!prtd) 628 return -ENOMEM; 629 630 /* DSP expects stream id from 1 */ 631 prtd->stream_id = 1; 632 633 prtd->cstream = stream; 634 prtd->audio_client = q6asm_audio_client_alloc(dev, 635 (q6asm_cb)compress_event_handler, 636 prtd, stream_id, LEGACY_PCM_MODE); 637 if (IS_ERR(prtd->audio_client)) { 638 dev_err(dev, "Could not allocate memory\n"); 639 ret = PTR_ERR(prtd->audio_client); 640 goto free_prtd; 641 } 642 643 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * 644 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 645 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 646 &prtd->dma_buffer); 647 if (ret) { 648 dev_err(dev, "Cannot allocate buffer(s)\n"); 649 goto free_client; 650 } 651 652 if (pdata->sid < 0) 653 prtd->phys = prtd->dma_buffer.addr; 654 else 655 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); 656 657 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); 658 spin_lock_init(&prtd->lock); 659 runtime->private_data = prtd; 660 661 return 0; 662 663 free_client: 664 q6asm_audio_client_free(prtd->audio_client); 665 free_prtd: 666 kfree(prtd); 667 668 return ret; 669 } 670 671 static int q6asm_dai_compr_free(struct snd_soc_component *component, 672 struct snd_compr_stream *stream) 673 { 674 struct snd_compr_runtime *runtime = stream->runtime; 675 struct q6asm_dai_rtd *prtd = runtime->private_data; 676 struct snd_soc_pcm_runtime *rtd = stream->private_data; 677 678 if (prtd->audio_client) { 679 if (prtd->state) { 680 q6asm_cmd(prtd->audio_client, prtd->stream_id, 681 CMD_CLOSE); 682 if (prtd->next_track_stream_id) { 683 q6asm_cmd(prtd->audio_client, 684 prtd->next_track_stream_id, 685 CMD_CLOSE); 686 } 687 } 688 689 snd_dma_free_pages(&prtd->dma_buffer); 690 q6asm_unmap_memory_regions(stream->direction, 691 prtd->audio_client); 692 q6asm_audio_client_free(prtd->audio_client); 693 prtd->audio_client = NULL; 694 } 695 q6routing_stream_close(rtd->dai_link->id, stream->direction); 696 kfree(prtd); 697 698 return 0; 699 } 700 701 static int __q6asm_dai_compr_set_codec_params(struct snd_soc_component *component, 702 struct snd_compr_stream *stream, 703 struct snd_codec *codec, 704 int stream_id) 705 { 706 struct snd_compr_runtime *runtime = stream->runtime; 707 struct q6asm_dai_rtd *prtd = runtime->private_data; 708 struct q6asm_flac_cfg flac_cfg; 709 struct q6asm_wma_cfg wma_cfg; 710 struct q6asm_alac_cfg alac_cfg; 711 struct q6asm_ape_cfg ape_cfg; 712 unsigned int wma_v9 = 0; 713 struct device *dev = component->dev; 714 int ret; 715 union snd_codec_options *codec_options; 716 struct snd_dec_flac *flac; 717 struct snd_dec_wma *wma; 718 struct snd_dec_alac *alac; 719 struct snd_dec_ape *ape; 720 721 codec_options = &(prtd->codec.options); 722 723 memcpy(&prtd->codec, codec, sizeof(*codec)); 724 725 switch (codec->id) { 726 case SND_AUDIOCODEC_FLAC: 727 728 memset(&flac_cfg, 0x0, sizeof(struct q6asm_flac_cfg)); 729 flac = &codec_options->flac_d; 730 731 flac_cfg.ch_cfg = codec->ch_in; 732 flac_cfg.sample_rate = codec->sample_rate; 733 flac_cfg.stream_info_present = 1; 734 flac_cfg.sample_size = flac->sample_size; 735 flac_cfg.min_blk_size = flac->min_blk_size; 736 flac_cfg.max_blk_size = flac->max_blk_size; 737 flac_cfg.max_frame_size = flac->max_frame_size; 738 flac_cfg.min_frame_size = flac->min_frame_size; 739 740 ret = q6asm_stream_media_format_block_flac(prtd->audio_client, 741 stream_id, 742 &flac_cfg); 743 if (ret < 0) { 744 dev_err(dev, "FLAC CMD Format block failed:%d\n", ret); 745 return -EIO; 746 } 747 break; 748 749 case SND_AUDIOCODEC_WMA: 750 wma = &codec_options->wma_d; 751 752 memset(&wma_cfg, 0x0, sizeof(struct q6asm_wma_cfg)); 753 754 wma_cfg.sample_rate = codec->sample_rate; 755 wma_cfg.num_channels = codec->ch_in; 756 wma_cfg.bytes_per_sec = codec->bit_rate / 8; 757 wma_cfg.block_align = codec->align; 758 wma_cfg.bits_per_sample = prtd->bits_per_sample; 759 wma_cfg.enc_options = wma->encoder_option; 760 wma_cfg.adv_enc_options = wma->adv_encoder_option; 761 wma_cfg.adv_enc_options2 = wma->adv_encoder_option2; 762 763 if (wma_cfg.num_channels == 1) 764 wma_cfg.channel_mask = 4; /* Mono Center */ 765 else if (wma_cfg.num_channels == 2) 766 wma_cfg.channel_mask = 3; /* Stereo FL/FR */ 767 else 768 return -EINVAL; 769 770 /* check the codec profile */ 771 switch (codec->profile) { 772 case SND_AUDIOPROFILE_WMA9: 773 wma_cfg.fmtag = 0x161; 774 wma_v9 = 1; 775 break; 776 777 case SND_AUDIOPROFILE_WMA10: 778 wma_cfg.fmtag = 0x166; 779 break; 780 781 case SND_AUDIOPROFILE_WMA9_PRO: 782 wma_cfg.fmtag = 0x162; 783 break; 784 785 case SND_AUDIOPROFILE_WMA9_LOSSLESS: 786 wma_cfg.fmtag = 0x163; 787 break; 788 789 case SND_AUDIOPROFILE_WMA10_LOSSLESS: 790 wma_cfg.fmtag = 0x167; 791 break; 792 793 default: 794 dev_err(dev, "Unknown WMA profile:%x\n", 795 codec->profile); 796 return -EIO; 797 } 798 799 if (wma_v9) 800 ret = q6asm_stream_media_format_block_wma_v9( 801 prtd->audio_client, stream_id, 802 &wma_cfg); 803 else 804 ret = q6asm_stream_media_format_block_wma_v10( 805 prtd->audio_client, stream_id, 806 &wma_cfg); 807 if (ret < 0) { 808 dev_err(dev, "WMA9 CMD failed:%d\n", ret); 809 return -EIO; 810 } 811 break; 812 813 case SND_AUDIOCODEC_ALAC: 814 memset(&alac_cfg, 0x0, sizeof(alac_cfg)); 815 alac = &codec_options->alac_d; 816 817 alac_cfg.sample_rate = codec->sample_rate; 818 alac_cfg.avg_bit_rate = codec->bit_rate; 819 alac_cfg.bit_depth = prtd->bits_per_sample; 820 alac_cfg.num_channels = codec->ch_in; 821 822 alac_cfg.frame_length = alac->frame_length; 823 alac_cfg.pb = alac->pb; 824 alac_cfg.mb = alac->mb; 825 alac_cfg.kb = alac->kb; 826 alac_cfg.max_run = alac->max_run; 827 alac_cfg.compatible_version = alac->compatible_version; 828 alac_cfg.max_frame_bytes = alac->max_frame_bytes; 829 830 switch (codec->ch_in) { 831 case 1: 832 alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_MONO; 833 break; 834 case 2: 835 alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_STEREO; 836 break; 837 } 838 ret = q6asm_stream_media_format_block_alac(prtd->audio_client, 839 stream_id, 840 &alac_cfg); 841 if (ret < 0) { 842 dev_err(dev, "ALAC CMD Format block failed:%d\n", ret); 843 return -EIO; 844 } 845 break; 846 847 case SND_AUDIOCODEC_APE: 848 memset(&ape_cfg, 0x0, sizeof(ape_cfg)); 849 ape = &codec_options->ape_d; 850 851 ape_cfg.sample_rate = codec->sample_rate; 852 ape_cfg.num_channels = codec->ch_in; 853 ape_cfg.bits_per_sample = prtd->bits_per_sample; 854 855 ape_cfg.compatible_version = ape->compatible_version; 856 ape_cfg.compression_level = ape->compression_level; 857 ape_cfg.format_flags = ape->format_flags; 858 ape_cfg.blocks_per_frame = ape->blocks_per_frame; 859 ape_cfg.final_frame_blocks = ape->final_frame_blocks; 860 ape_cfg.total_frames = ape->total_frames; 861 ape_cfg.seek_table_present = ape->seek_table_present; 862 863 ret = q6asm_stream_media_format_block_ape(prtd->audio_client, 864 stream_id, 865 &ape_cfg); 866 if (ret < 0) { 867 dev_err(dev, "APE CMD Format block failed:%d\n", ret); 868 return -EIO; 869 } 870 break; 871 872 default: 873 break; 874 } 875 876 return 0; 877 } 878 879 static int q6asm_dai_compr_set_params(struct snd_soc_component *component, 880 struct snd_compr_stream *stream, 881 struct snd_compr_params *params) 882 { 883 struct snd_compr_runtime *runtime = stream->runtime; 884 struct q6asm_dai_rtd *prtd = runtime->private_data; 885 struct snd_soc_pcm_runtime *rtd = stream->private_data; 886 int dir = stream->direction; 887 struct q6asm_dai_data *pdata; 888 struct device *dev = component->dev; 889 int ret; 890 891 pdata = snd_soc_component_get_drvdata(component); 892 if (!pdata) 893 return -EINVAL; 894 895 if (!prtd || !prtd->audio_client) { 896 dev_err(dev, "private data null or audio client freed\n"); 897 return -EINVAL; 898 } 899 900 prtd->periods = runtime->fragments; 901 prtd->pcm_count = runtime->fragment_size; 902 prtd->pcm_size = runtime->fragments * runtime->fragment_size; 903 prtd->bits_per_sample = 16; 904 905 if (dir == SND_COMPRESS_PLAYBACK) { 906 ret = q6asm_open_write(prtd->audio_client, prtd->stream_id, params->codec.id, 907 params->codec.profile, prtd->bits_per_sample, 908 true); 909 910 if (ret < 0) { 911 dev_err(dev, "q6asm_open_write failed\n"); 912 q6asm_audio_client_free(prtd->audio_client); 913 prtd->audio_client = NULL; 914 return ret; 915 } 916 } 917 918 prtd->session_id = q6asm_get_session_id(prtd->audio_client); 919 ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE, 920 prtd->session_id, dir); 921 if (ret) { 922 dev_err(dev, "Stream reg failed ret:%d\n", ret); 923 return ret; 924 } 925 926 ret = __q6asm_dai_compr_set_codec_params(component, stream, 927 ¶ms->codec, 928 prtd->stream_id); 929 if (ret) { 930 dev_err(dev, "codec param setup failed ret:%d\n", ret); 931 return ret; 932 } 933 934 ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys, 935 (prtd->pcm_size / prtd->periods), 936 prtd->periods); 937 938 if (ret < 0) { 939 dev_err(dev, "Buffer Mapping failed ret:%d\n", ret); 940 return -ENOMEM; 941 } 942 943 prtd->state = Q6ASM_STREAM_RUNNING; 944 945 return 0; 946 } 947 948 static int q6asm_dai_compr_set_metadata(struct snd_soc_component *component, 949 struct snd_compr_stream *stream, 950 struct snd_compr_metadata *metadata) 951 { 952 struct snd_compr_runtime *runtime = stream->runtime; 953 struct q6asm_dai_rtd *prtd = runtime->private_data; 954 int ret = 0; 955 956 switch (metadata->key) { 957 case SNDRV_COMPRESS_ENCODER_PADDING: 958 prtd->trailing_samples_drop = metadata->value[0]; 959 break; 960 case SNDRV_COMPRESS_ENCODER_DELAY: 961 prtd->initial_samples_drop = metadata->value[0]; 962 if (prtd->next_track_stream_id) { 963 ret = q6asm_open_write(prtd->audio_client, 964 prtd->next_track_stream_id, 965 prtd->codec.id, 966 prtd->codec.profile, 967 prtd->bits_per_sample, 968 true); 969 if (ret < 0) { 970 dev_err(component->dev, "q6asm_open_write failed\n"); 971 return ret; 972 } 973 ret = __q6asm_dai_compr_set_codec_params(component, stream, 974 &prtd->codec, 975 prtd->next_track_stream_id); 976 if (ret < 0) { 977 dev_err(component->dev, "q6asm_open_write failed\n"); 978 return ret; 979 } 980 981 ret = q6asm_stream_remove_initial_silence(prtd->audio_client, 982 prtd->next_track_stream_id, 983 prtd->initial_samples_drop); 984 prtd->next_track_stream_id = 0; 985 986 } 987 988 break; 989 default: 990 ret = -EINVAL; 991 break; 992 } 993 994 return ret; 995 } 996 997 static int q6asm_dai_compr_trigger(struct snd_soc_component *component, 998 struct snd_compr_stream *stream, int cmd) 999 { 1000 struct snd_compr_runtime *runtime = stream->runtime; 1001 struct q6asm_dai_rtd *prtd = runtime->private_data; 1002 int ret = 0; 1003 1004 switch (cmd) { 1005 case SNDRV_PCM_TRIGGER_START: 1006 case SNDRV_PCM_TRIGGER_RESUME: 1007 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1008 ret = q6asm_run_nowait(prtd->audio_client, prtd->stream_id, 1009 0, 0, 0); 1010 break; 1011 case SNDRV_PCM_TRIGGER_STOP: 1012 prtd->state = Q6ASM_STREAM_STOPPED; 1013 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, 1014 CMD_EOS); 1015 break; 1016 case SNDRV_PCM_TRIGGER_SUSPEND: 1017 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1018 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, 1019 CMD_PAUSE); 1020 break; 1021 case SND_COMPR_TRIGGER_NEXT_TRACK: 1022 prtd->next_track = true; 1023 prtd->next_track_stream_id = (prtd->stream_id == 1 ? 2 : 1); 1024 break; 1025 case SND_COMPR_TRIGGER_DRAIN: 1026 case SND_COMPR_TRIGGER_PARTIAL_DRAIN: 1027 prtd->notify_on_drain = true; 1028 break; 1029 default: 1030 ret = -EINVAL; 1031 break; 1032 } 1033 1034 return ret; 1035 } 1036 1037 static int q6asm_dai_compr_pointer(struct snd_soc_component *component, 1038 struct snd_compr_stream *stream, 1039 struct snd_compr_tstamp *tstamp) 1040 { 1041 struct snd_compr_runtime *runtime = stream->runtime; 1042 struct q6asm_dai_rtd *prtd = runtime->private_data; 1043 unsigned long flags; 1044 1045 spin_lock_irqsave(&prtd->lock, flags); 1046 1047 tstamp->copied_total = prtd->copied_total; 1048 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; 1049 1050 spin_unlock_irqrestore(&prtd->lock, flags); 1051 1052 return 0; 1053 } 1054 1055 static int q6asm_compr_copy(struct snd_soc_component *component, 1056 struct snd_compr_stream *stream, char __user *buf, 1057 size_t count) 1058 { 1059 struct snd_compr_runtime *runtime = stream->runtime; 1060 struct q6asm_dai_rtd *prtd = runtime->private_data; 1061 unsigned long flags; 1062 u32 wflags = 0; 1063 int avail, bytes_in_flight = 0; 1064 void *dstn; 1065 size_t copy; 1066 u32 app_pointer; 1067 u32 bytes_received; 1068 1069 bytes_received = prtd->bytes_received; 1070 1071 /** 1072 * Make sure that next track data pointer is aligned at 32 bit boundary 1073 * This is a Mandatory requirement from DSP data buffers alignment 1074 */ 1075 if (prtd->next_track) 1076 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count); 1077 1078 app_pointer = bytes_received/prtd->pcm_size; 1079 app_pointer = bytes_received - (app_pointer * prtd->pcm_size); 1080 dstn = prtd->dma_buffer.area + app_pointer; 1081 1082 if (count < prtd->pcm_size - app_pointer) { 1083 if (copy_from_user(dstn, buf, count)) 1084 return -EFAULT; 1085 } else { 1086 copy = prtd->pcm_size - app_pointer; 1087 if (copy_from_user(dstn, buf, copy)) 1088 return -EFAULT; 1089 if (copy_from_user(prtd->dma_buffer.area, buf + copy, 1090 count - copy)) 1091 return -EFAULT; 1092 } 1093 1094 spin_lock_irqsave(&prtd->lock, flags); 1095 1096 bytes_in_flight = prtd->bytes_received - prtd->copied_total; 1097 1098 if (prtd->next_track) { 1099 prtd->next_track = false; 1100 prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count); 1101 prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count); 1102 } 1103 1104 prtd->bytes_received = bytes_received + count; 1105 1106 /* Kick off the data to dsp if its starving!! */ 1107 if (prtd->state == Q6ASM_STREAM_RUNNING && (bytes_in_flight == 0)) { 1108 uint32_t bytes_to_write = prtd->pcm_count; 1109 1110 avail = prtd->bytes_received - prtd->bytes_sent; 1111 1112 if (avail < prtd->pcm_count) 1113 bytes_to_write = avail; 1114 1115 q6asm_write_async(prtd->audio_client, prtd->stream_id, 1116 bytes_to_write, 0, 0, wflags); 1117 prtd->bytes_sent += bytes_to_write; 1118 } 1119 1120 spin_unlock_irqrestore(&prtd->lock, flags); 1121 1122 return count; 1123 } 1124 1125 static int q6asm_dai_compr_mmap(struct snd_soc_component *component, 1126 struct snd_compr_stream *stream, 1127 struct vm_area_struct *vma) 1128 { 1129 struct snd_compr_runtime *runtime = stream->runtime; 1130 struct q6asm_dai_rtd *prtd = runtime->private_data; 1131 struct device *dev = component->dev; 1132 1133 return dma_mmap_coherent(dev, vma, 1134 prtd->dma_buffer.area, prtd->dma_buffer.addr, 1135 prtd->dma_buffer.bytes); 1136 } 1137 1138 static int q6asm_dai_compr_get_caps(struct snd_soc_component *component, 1139 struct snd_compr_stream *stream, 1140 struct snd_compr_caps *caps) 1141 { 1142 caps->direction = SND_COMPRESS_PLAYBACK; 1143 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; 1144 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 1145 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 1146 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 1147 caps->num_codecs = 5; 1148 caps->codecs[0] = SND_AUDIOCODEC_MP3; 1149 caps->codecs[1] = SND_AUDIOCODEC_FLAC; 1150 caps->codecs[2] = SND_AUDIOCODEC_WMA; 1151 caps->codecs[3] = SND_AUDIOCODEC_ALAC; 1152 caps->codecs[4] = SND_AUDIOCODEC_APE; 1153 1154 return 0; 1155 } 1156 1157 static int q6asm_dai_compr_get_codec_caps(struct snd_soc_component *component, 1158 struct snd_compr_stream *stream, 1159 struct snd_compr_codec_caps *codec) 1160 { 1161 switch (codec->codec) { 1162 case SND_AUDIOCODEC_MP3: 1163 *codec = q6asm_compr_caps; 1164 break; 1165 default: 1166 break; 1167 } 1168 1169 return 0; 1170 } 1171 1172 static const struct snd_compress_ops q6asm_dai_compress_ops = { 1173 .open = q6asm_dai_compr_open, 1174 .free = q6asm_dai_compr_free, 1175 .set_params = q6asm_dai_compr_set_params, 1176 .set_metadata = q6asm_dai_compr_set_metadata, 1177 .pointer = q6asm_dai_compr_pointer, 1178 .trigger = q6asm_dai_compr_trigger, 1179 .get_caps = q6asm_dai_compr_get_caps, 1180 .get_codec_caps = q6asm_dai_compr_get_codec_caps, 1181 .mmap = q6asm_dai_compr_mmap, 1182 .copy = q6asm_compr_copy, 1183 }; 1184 1185 static int q6asm_dai_pcm_new(struct snd_soc_component *component, 1186 struct snd_soc_pcm_runtime *rtd) 1187 { 1188 struct snd_pcm_substream *psubstream, *csubstream; 1189 struct snd_pcm *pcm = rtd->pcm; 1190 struct device *dev; 1191 int size, ret; 1192 1193 dev = component->dev; 1194 size = q6asm_dai_hardware_playback.buffer_bytes_max; 1195 psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 1196 if (psubstream) { 1197 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 1198 &psubstream->dma_buffer); 1199 if (ret) { 1200 dev_err(dev, "Cannot allocate buffer(s)\n"); 1201 return ret; 1202 } 1203 } 1204 1205 csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 1206 if (csubstream) { 1207 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 1208 &csubstream->dma_buffer); 1209 if (ret) { 1210 dev_err(dev, "Cannot allocate buffer(s)\n"); 1211 if (psubstream) 1212 snd_dma_free_pages(&psubstream->dma_buffer); 1213 return ret; 1214 } 1215 } 1216 1217 return 0; 1218 } 1219 1220 static void q6asm_dai_pcm_free(struct snd_soc_component *component, 1221 struct snd_pcm *pcm) 1222 { 1223 struct snd_pcm_substream *substream; 1224 int i; 1225 1226 for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) { 1227 substream = pcm->streams[i].substream; 1228 if (substream) { 1229 snd_dma_free_pages(&substream->dma_buffer); 1230 substream->dma_buffer.area = NULL; 1231 substream->dma_buffer.addr = 0; 1232 } 1233 } 1234 } 1235 1236 static const struct snd_soc_dapm_widget q6asm_dapm_widgets[] = { 1237 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, SND_SOC_NOPM, 0, 0), 1238 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, SND_SOC_NOPM, 0, 0), 1239 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, SND_SOC_NOPM, 0, 0), 1240 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, SND_SOC_NOPM, 0, 0), 1241 SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, SND_SOC_NOPM, 0, 0), 1242 SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, SND_SOC_NOPM, 0, 0), 1243 SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, SND_SOC_NOPM, 0, 0), 1244 SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, SND_SOC_NOPM, 0, 0), 1245 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, SND_SOC_NOPM, 0, 0), 1246 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, SND_SOC_NOPM, 0, 0), 1247 SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, SND_SOC_NOPM, 0, 0), 1248 SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, SND_SOC_NOPM, 0, 0), 1249 SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, SND_SOC_NOPM, 0, 0), 1250 SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, SND_SOC_NOPM, 0, 0), 1251 SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, SND_SOC_NOPM, 0, 0), 1252 SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, SND_SOC_NOPM, 0, 0), 1253 }; 1254 1255 static const struct snd_soc_component_driver q6asm_fe_dai_component = { 1256 .name = DRV_NAME, 1257 .open = q6asm_dai_open, 1258 .hw_params = q6asm_dai_hw_params, 1259 .close = q6asm_dai_close, 1260 .prepare = q6asm_dai_prepare, 1261 .trigger = q6asm_dai_trigger, 1262 .pointer = q6asm_dai_pointer, 1263 .mmap = q6asm_dai_mmap, 1264 .pcm_construct = q6asm_dai_pcm_new, 1265 .pcm_destruct = q6asm_dai_pcm_free, 1266 .compress_ops = &q6asm_dai_compress_ops, 1267 .dapm_widgets = q6asm_dapm_widgets, 1268 .num_dapm_widgets = ARRAY_SIZE(q6asm_dapm_widgets), 1269 }; 1270 1271 static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { 1272 Q6ASM_FEDAI_DRIVER(1), 1273 Q6ASM_FEDAI_DRIVER(2), 1274 Q6ASM_FEDAI_DRIVER(3), 1275 Q6ASM_FEDAI_DRIVER(4), 1276 Q6ASM_FEDAI_DRIVER(5), 1277 Q6ASM_FEDAI_DRIVER(6), 1278 Q6ASM_FEDAI_DRIVER(7), 1279 Q6ASM_FEDAI_DRIVER(8), 1280 }; 1281 1282 static int of_q6asm_parse_dai_data(struct device *dev, 1283 struct q6asm_dai_data *pdata) 1284 { 1285 struct snd_soc_dai_driver *dai_drv; 1286 struct snd_soc_pcm_stream empty_stream; 1287 struct device_node *node; 1288 int ret, id, dir, idx = 0; 1289 1290 1291 pdata->num_dais = of_get_child_count(dev->of_node); 1292 if (!pdata->num_dais) { 1293 dev_err(dev, "No dais found in DT\n"); 1294 return -EINVAL; 1295 } 1296 1297 pdata->dais = devm_kcalloc(dev, pdata->num_dais, sizeof(*dai_drv), 1298 GFP_KERNEL); 1299 if (!pdata->dais) 1300 return -ENOMEM; 1301 1302 memset(&empty_stream, 0, sizeof(empty_stream)); 1303 1304 for_each_child_of_node(dev->of_node, node) { 1305 ret = of_property_read_u32(node, "reg", &id); 1306 if (ret || id >= MAX_SESSIONS || id < 0) { 1307 dev_err(dev, "valid dai id not found:%d\n", ret); 1308 continue; 1309 } 1310 1311 dai_drv = &pdata->dais[idx++]; 1312 *dai_drv = q6asm_fe_dais_template[id]; 1313 1314 ret = of_property_read_u32(node, "direction", &dir); 1315 if (ret) 1316 continue; 1317 1318 if (dir == Q6ASM_DAI_RX) 1319 dai_drv->capture = empty_stream; 1320 else if (dir == Q6ASM_DAI_TX) 1321 dai_drv->playback = empty_stream; 1322 1323 if (of_property_read_bool(node, "is-compress-dai")) 1324 dai_drv->compress_new = snd_soc_new_compress; 1325 } 1326 1327 return 0; 1328 } 1329 1330 static int q6asm_dai_probe(struct platform_device *pdev) 1331 { 1332 struct device *dev = &pdev->dev; 1333 struct device_node *node = dev->of_node; 1334 struct of_phandle_args args; 1335 struct q6asm_dai_data *pdata; 1336 int rc; 1337 1338 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 1339 if (!pdata) 1340 return -ENOMEM; 1341 1342 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); 1343 if (rc < 0) 1344 pdata->sid = -1; 1345 else 1346 pdata->sid = args.args[0] & SID_MASK_DEFAULT; 1347 1348 dev_set_drvdata(dev, pdata); 1349 1350 rc = of_q6asm_parse_dai_data(dev, pdata); 1351 if (rc) 1352 return rc; 1353 1354 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, 1355 pdata->dais, pdata->num_dais); 1356 } 1357 1358 #ifdef CONFIG_OF 1359 static const struct of_device_id q6asm_dai_device_id[] = { 1360 { .compatible = "qcom,q6asm-dais" }, 1361 {}, 1362 }; 1363 MODULE_DEVICE_TABLE(of, q6asm_dai_device_id); 1364 #endif 1365 1366 static struct platform_driver q6asm_dai_platform_driver = { 1367 .driver = { 1368 .name = "q6asm-dai", 1369 .of_match_table = of_match_ptr(q6asm_dai_device_id), 1370 }, 1371 .probe = q6asm_dai_probe, 1372 }; 1373 module_platform_driver(q6asm_dai_platform_driver); 1374 1375 MODULE_DESCRIPTION("Q6ASM dai driver"); 1376 MODULE_LICENSE("GPL v2"); 1377