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 #define Q6ASM_DAI_TX_RX 0 41 #define Q6ASM_DAI_TX 1 42 #define Q6ASM_DAI_RX 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_compr_params codec_param; 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 uint16_t session_id; 68 enum stream_state state; 69 }; 70 71 struct q6asm_dai_data { 72 long long int sid; 73 }; 74 75 static struct snd_pcm_hardware q6asm_dai_hardware_capture = { 76 .info = (SNDRV_PCM_INFO_MMAP | 77 SNDRV_PCM_INFO_BLOCK_TRANSFER | 78 SNDRV_PCM_INFO_MMAP_VALID | 79 SNDRV_PCM_INFO_INTERLEAVED | 80 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 81 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 82 SNDRV_PCM_FMTBIT_S24_LE), 83 .rates = SNDRV_PCM_RATE_8000_48000, 84 .rate_min = 8000, 85 .rate_max = 48000, 86 .channels_min = 1, 87 .channels_max = 4, 88 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * 89 CAPTURE_MAX_PERIOD_SIZE, 90 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, 91 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, 92 .periods_min = CAPTURE_MIN_NUM_PERIODS, 93 .periods_max = CAPTURE_MAX_NUM_PERIODS, 94 .fifo_size = 0, 95 }; 96 97 static struct snd_pcm_hardware q6asm_dai_hardware_playback = { 98 .info = (SNDRV_PCM_INFO_MMAP | 99 SNDRV_PCM_INFO_BLOCK_TRANSFER | 100 SNDRV_PCM_INFO_MMAP_VALID | 101 SNDRV_PCM_INFO_INTERLEAVED | 102 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 103 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 104 SNDRV_PCM_FMTBIT_S24_LE), 105 .rates = SNDRV_PCM_RATE_8000_192000, 106 .rate_min = 8000, 107 .rate_max = 192000, 108 .channels_min = 1, 109 .channels_max = 8, 110 .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS * 111 PLAYBACK_MAX_PERIOD_SIZE), 112 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, 113 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, 114 .periods_min = PLAYBACK_MIN_NUM_PERIODS, 115 .periods_max = PLAYBACK_MAX_NUM_PERIODS, 116 .fifo_size = 0, 117 }; 118 119 #define Q6ASM_FEDAI_DRIVER(num) { \ 120 .playback = { \ 121 .stream_name = "MultiMedia"#num" Playback", \ 122 .rates = (SNDRV_PCM_RATE_8000_192000| \ 123 SNDRV_PCM_RATE_KNOT), \ 124 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \ 125 SNDRV_PCM_FMTBIT_S24_LE), \ 126 .channels_min = 1, \ 127 .channels_max = 8, \ 128 .rate_min = 8000, \ 129 .rate_max = 192000, \ 130 }, \ 131 .capture = { \ 132 .stream_name = "MultiMedia"#num" Capture", \ 133 .rates = (SNDRV_PCM_RATE_8000_48000| \ 134 SNDRV_PCM_RATE_KNOT), \ 135 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \ 136 SNDRV_PCM_FMTBIT_S24_LE), \ 137 .channels_min = 1, \ 138 .channels_max = 4, \ 139 .rate_min = 8000, \ 140 .rate_max = 48000, \ 141 }, \ 142 .name = "MultiMedia"#num, \ 143 .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \ 144 } 145 146 /* Conventional and unconventional sample rate supported */ 147 static unsigned int supported_sample_rates[] = { 148 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 149 88200, 96000, 176400, 192000 150 }; 151 152 static struct snd_pcm_hw_constraint_list constraints_sample_rates = { 153 .count = ARRAY_SIZE(supported_sample_rates), 154 .list = supported_sample_rates, 155 .mask = 0, 156 }; 157 158 static const struct snd_compr_codec_caps q6asm_compr_caps = { 159 .num_descriptors = 1, 160 .descriptor[0].max_ch = 2, 161 .descriptor[0].sample_rates = { 8000, 11025, 12000, 16000, 22050, 162 24000, 32000, 44100, 48000, 88200, 163 96000, 176400, 192000 }, 164 .descriptor[0].num_sample_rates = 13, 165 .descriptor[0].bit_rate[0] = 320, 166 .descriptor[0].bit_rate[1] = 128, 167 .descriptor[0].num_bitrates = 2, 168 .descriptor[0].profiles = 0, 169 .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, 170 .descriptor[0].formats = 0, 171 }; 172 173 static void event_handler(uint32_t opcode, uint32_t token, 174 uint32_t *payload, void *priv) 175 { 176 struct q6asm_dai_rtd *prtd = priv; 177 struct snd_pcm_substream *substream = prtd->substream; 178 179 switch (opcode) { 180 case ASM_CLIENT_EVENT_CMD_RUN_DONE: 181 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 182 q6asm_write_async(prtd->audio_client, 183 prtd->pcm_count, 0, 0, NO_TIMESTAMP); 184 break; 185 case ASM_CLIENT_EVENT_CMD_EOS_DONE: 186 prtd->state = Q6ASM_STREAM_STOPPED; 187 break; 188 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: { 189 prtd->pcm_irq_pos += prtd->pcm_count; 190 snd_pcm_period_elapsed(substream); 191 if (prtd->state == Q6ASM_STREAM_RUNNING) 192 q6asm_write_async(prtd->audio_client, 193 prtd->pcm_count, 0, 0, NO_TIMESTAMP); 194 195 break; 196 } 197 case ASM_CLIENT_EVENT_DATA_READ_DONE: 198 prtd->pcm_irq_pos += prtd->pcm_count; 199 snd_pcm_period_elapsed(substream); 200 if (prtd->state == Q6ASM_STREAM_RUNNING) 201 q6asm_read(prtd->audio_client); 202 203 break; 204 default: 205 break; 206 } 207 } 208 209 static int q6asm_dai_prepare(struct snd_soc_component *component, 210 struct snd_pcm_substream *substream) 211 { 212 struct snd_pcm_runtime *runtime = substream->runtime; 213 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 214 struct q6asm_dai_rtd *prtd = runtime->private_data; 215 struct q6asm_dai_data *pdata; 216 int ret, i; 217 218 pdata = snd_soc_component_get_drvdata(component); 219 if (!pdata) 220 return -EINVAL; 221 222 if (!prtd || !prtd->audio_client) { 223 pr_err("%s: private data null or audio client freed\n", 224 __func__); 225 return -EINVAL; 226 } 227 228 prtd->pcm_count = snd_pcm_lib_period_bytes(substream); 229 prtd->pcm_irq_pos = 0; 230 /* rate and channels are sent to audio driver */ 231 if (prtd->state) { 232 /* clear the previous setup if any */ 233 q6asm_cmd(prtd->audio_client, CMD_CLOSE); 234 q6asm_unmap_memory_regions(substream->stream, 235 prtd->audio_client); 236 q6routing_stream_close(soc_prtd->dai_link->id, 237 substream->stream); 238 } 239 240 ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client, 241 prtd->phys, 242 (prtd->pcm_size / prtd->periods), 243 prtd->periods); 244 245 if (ret < 0) { 246 pr_err("Audio Start: Buffer Allocation failed rc = %d\n", 247 ret); 248 return -ENOMEM; 249 } 250 251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 252 ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM, 253 prtd->bits_per_sample); 254 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 255 ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM, 256 prtd->bits_per_sample); 257 } 258 259 if (ret < 0) { 260 pr_err("%s: q6asm_open_write failed\n", __func__); 261 q6asm_audio_client_free(prtd->audio_client); 262 prtd->audio_client = NULL; 263 return -ENOMEM; 264 } 265 266 prtd->session_id = q6asm_get_session_id(prtd->audio_client); 267 ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE, 268 prtd->session_id, substream->stream); 269 if (ret) { 270 pr_err("%s: stream reg failed ret:%d\n", __func__, ret); 271 return ret; 272 } 273 274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 275 ret = q6asm_media_format_block_multi_ch_pcm( 276 prtd->audio_client, runtime->rate, 277 runtime->channels, NULL, 278 prtd->bits_per_sample); 279 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 280 ret = q6asm_enc_cfg_blk_pcm_format_support(prtd->audio_client, 281 runtime->rate, runtime->channels, 282 prtd->bits_per_sample); 283 284 /* Queue the buffers */ 285 for (i = 0; i < runtime->periods; i++) 286 q6asm_read(prtd->audio_client); 287 288 } 289 if (ret < 0) 290 pr_info("%s: CMD Format block failed\n", __func__); 291 292 prtd->state = Q6ASM_STREAM_RUNNING; 293 294 return 0; 295 } 296 297 static int q6asm_dai_trigger(struct snd_soc_component *component, 298 struct snd_pcm_substream *substream, int cmd) 299 { 300 int ret = 0; 301 struct snd_pcm_runtime *runtime = substream->runtime; 302 struct q6asm_dai_rtd *prtd = runtime->private_data; 303 304 switch (cmd) { 305 case SNDRV_PCM_TRIGGER_START: 306 case SNDRV_PCM_TRIGGER_RESUME: 307 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 308 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); 309 break; 310 case SNDRV_PCM_TRIGGER_STOP: 311 prtd->state = Q6ASM_STREAM_STOPPED; 312 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); 313 break; 314 case SNDRV_PCM_TRIGGER_SUSPEND: 315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 316 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); 317 break; 318 default: 319 ret = -EINVAL; 320 break; 321 } 322 323 return ret; 324 } 325 326 static int q6asm_dai_open(struct snd_soc_component *component, 327 struct snd_pcm_substream *substream) 328 { 329 struct snd_pcm_runtime *runtime = substream->runtime; 330 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 331 struct snd_soc_dai *cpu_dai = soc_prtd->cpu_dai; 332 struct q6asm_dai_rtd *prtd; 333 struct q6asm_dai_data *pdata; 334 struct device *dev = component->dev; 335 int ret = 0; 336 int stream_id; 337 338 stream_id = cpu_dai->driver->id; 339 340 pdata = snd_soc_component_get_drvdata(component); 341 if (!pdata) { 342 pr_err("Drv data not found ..\n"); 343 return -EINVAL; 344 } 345 346 prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL); 347 if (prtd == NULL) 348 return -ENOMEM; 349 350 prtd->substream = substream; 351 prtd->audio_client = q6asm_audio_client_alloc(dev, 352 (q6asm_cb)event_handler, prtd, stream_id, 353 LEGACY_PCM_MODE); 354 if (IS_ERR(prtd->audio_client)) { 355 pr_info("%s: Could not allocate memory\n", __func__); 356 ret = PTR_ERR(prtd->audio_client); 357 kfree(prtd); 358 return ret; 359 } 360 361 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 362 runtime->hw = q6asm_dai_hardware_playback; 363 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 364 runtime->hw = q6asm_dai_hardware_capture; 365 366 ret = snd_pcm_hw_constraint_list(runtime, 0, 367 SNDRV_PCM_HW_PARAM_RATE, 368 &constraints_sample_rates); 369 if (ret < 0) 370 pr_info("snd_pcm_hw_constraint_list failed\n"); 371 /* Ensure that buffer size is a multiple of period size */ 372 ret = snd_pcm_hw_constraint_integer(runtime, 373 SNDRV_PCM_HW_PARAM_PERIODS); 374 if (ret < 0) 375 pr_info("snd_pcm_hw_constraint_integer failed\n"); 376 377 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 378 ret = snd_pcm_hw_constraint_minmax(runtime, 379 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 380 PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE, 381 PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE); 382 if (ret < 0) { 383 pr_err("constraint for buffer bytes min max ret = %d\n", 384 ret); 385 } 386 } 387 388 ret = snd_pcm_hw_constraint_step(runtime, 0, 389 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 390 if (ret < 0) { 391 pr_err("constraint for period bytes step ret = %d\n", 392 ret); 393 } 394 ret = snd_pcm_hw_constraint_step(runtime, 0, 395 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 396 if (ret < 0) { 397 pr_err("constraint for buffer bytes step ret = %d\n", 398 ret); 399 } 400 401 runtime->private_data = prtd; 402 403 snd_soc_set_runtime_hwparams(substream, &q6asm_dai_hardware_playback); 404 405 runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max; 406 407 408 if (pdata->sid < 0) 409 prtd->phys = substream->dma_buffer.addr; 410 else 411 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); 412 413 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 414 415 return 0; 416 } 417 418 static int q6asm_dai_close(struct snd_soc_component *component, 419 struct snd_pcm_substream *substream) 420 { 421 struct snd_pcm_runtime *runtime = substream->runtime; 422 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 423 struct q6asm_dai_rtd *prtd = runtime->private_data; 424 425 if (prtd->audio_client) { 426 if (prtd->state) 427 q6asm_cmd(prtd->audio_client, CMD_CLOSE); 428 429 q6asm_unmap_memory_regions(substream->stream, 430 prtd->audio_client); 431 q6asm_audio_client_free(prtd->audio_client); 432 prtd->audio_client = NULL; 433 } 434 q6routing_stream_close(soc_prtd->dai_link->id, 435 substream->stream); 436 kfree(prtd); 437 return 0; 438 } 439 440 static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_soc_component *component, 441 struct snd_pcm_substream *substream) 442 { 443 444 struct snd_pcm_runtime *runtime = substream->runtime; 445 struct q6asm_dai_rtd *prtd = runtime->private_data; 446 447 if (prtd->pcm_irq_pos >= prtd->pcm_size) 448 prtd->pcm_irq_pos = 0; 449 450 return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); 451 } 452 453 static int q6asm_dai_mmap(struct snd_soc_component *component, 454 struct snd_pcm_substream *substream, 455 struct vm_area_struct *vma) 456 { 457 struct snd_pcm_runtime *runtime = substream->runtime; 458 struct device *dev = component->dev; 459 460 return dma_mmap_coherent(dev, vma, 461 runtime->dma_area, runtime->dma_addr, 462 runtime->dma_bytes); 463 } 464 465 static int q6asm_dai_hw_params(struct snd_soc_component *component, 466 struct snd_pcm_substream *substream, 467 struct snd_pcm_hw_params *params) 468 { 469 struct snd_pcm_runtime *runtime = substream->runtime; 470 struct q6asm_dai_rtd *prtd = runtime->private_data; 471 472 prtd->pcm_size = params_buffer_bytes(params); 473 prtd->periods = params_periods(params); 474 475 switch (params_format(params)) { 476 case SNDRV_PCM_FORMAT_S16_LE: 477 prtd->bits_per_sample = 16; 478 break; 479 case SNDRV_PCM_FORMAT_S24_LE: 480 prtd->bits_per_sample = 24; 481 break; 482 } 483 484 return 0; 485 } 486 487 static void compress_event_handler(uint32_t opcode, uint32_t token, 488 uint32_t *payload, void *priv) 489 { 490 struct q6asm_dai_rtd *prtd = priv; 491 struct snd_compr_stream *substream = prtd->cstream; 492 unsigned long flags; 493 uint64_t avail; 494 495 switch (opcode) { 496 case ASM_CLIENT_EVENT_CMD_RUN_DONE: 497 spin_lock_irqsave(&prtd->lock, flags); 498 if (!prtd->bytes_sent) { 499 q6asm_write_async(prtd->audio_client, prtd->pcm_count, 500 0, 0, NO_TIMESTAMP); 501 prtd->bytes_sent += prtd->pcm_count; 502 } 503 504 spin_unlock_irqrestore(&prtd->lock, flags); 505 break; 506 507 case ASM_CLIENT_EVENT_CMD_EOS_DONE: 508 prtd->state = Q6ASM_STREAM_STOPPED; 509 break; 510 511 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: 512 spin_lock_irqsave(&prtd->lock, flags); 513 514 prtd->copied_total += prtd->pcm_count; 515 snd_compr_fragment_elapsed(substream); 516 517 if (prtd->state != Q6ASM_STREAM_RUNNING) { 518 spin_unlock_irqrestore(&prtd->lock, flags); 519 break; 520 } 521 522 avail = prtd->bytes_received - prtd->bytes_sent; 523 524 if (avail >= prtd->pcm_count) { 525 q6asm_write_async(prtd->audio_client, 526 prtd->pcm_count, 0, 0, NO_TIMESTAMP); 527 prtd->bytes_sent += prtd->pcm_count; 528 } 529 530 spin_unlock_irqrestore(&prtd->lock, flags); 531 break; 532 533 default: 534 break; 535 } 536 } 537 538 static int q6asm_dai_compr_open(struct snd_compr_stream *stream) 539 { 540 struct snd_soc_pcm_runtime *rtd = stream->private_data; 541 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 542 struct snd_compr_runtime *runtime = stream->runtime; 543 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 544 struct q6asm_dai_data *pdata; 545 struct device *dev = c->dev; 546 struct q6asm_dai_rtd *prtd; 547 int stream_id, size, ret; 548 549 stream_id = cpu_dai->driver->id; 550 pdata = snd_soc_component_get_drvdata(c); 551 if (!pdata) { 552 dev_err(dev, "Drv data not found ..\n"); 553 return -EINVAL; 554 } 555 556 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 557 if (!prtd) 558 return -ENOMEM; 559 560 prtd->cstream = stream; 561 prtd->audio_client = q6asm_audio_client_alloc(dev, 562 (q6asm_cb)compress_event_handler, 563 prtd, stream_id, LEGACY_PCM_MODE); 564 if (IS_ERR(prtd->audio_client)) { 565 dev_err(dev, "Could not allocate memory\n"); 566 ret = PTR_ERR(prtd->audio_client); 567 goto free_prtd; 568 } 569 570 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * 571 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 572 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 573 &prtd->dma_buffer); 574 if (ret) { 575 dev_err(dev, "Cannot allocate buffer(s)\n"); 576 goto free_client; 577 } 578 579 if (pdata->sid < 0) 580 prtd->phys = prtd->dma_buffer.addr; 581 else 582 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); 583 584 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); 585 spin_lock_init(&prtd->lock); 586 runtime->private_data = prtd; 587 588 return 0; 589 590 free_client: 591 q6asm_audio_client_free(prtd->audio_client); 592 free_prtd: 593 kfree(prtd); 594 595 return ret; 596 } 597 598 static int q6asm_dai_compr_free(struct snd_compr_stream *stream) 599 { 600 struct snd_compr_runtime *runtime = stream->runtime; 601 struct q6asm_dai_rtd *prtd = runtime->private_data; 602 struct snd_soc_pcm_runtime *rtd = stream->private_data; 603 604 if (prtd->audio_client) { 605 if (prtd->state) 606 q6asm_cmd(prtd->audio_client, CMD_CLOSE); 607 608 snd_dma_free_pages(&prtd->dma_buffer); 609 q6asm_unmap_memory_regions(stream->direction, 610 prtd->audio_client); 611 q6asm_audio_client_free(prtd->audio_client); 612 prtd->audio_client = NULL; 613 } 614 q6routing_stream_close(rtd->dai_link->id, stream->direction); 615 kfree(prtd); 616 617 return 0; 618 } 619 620 static int q6asm_dai_compr_set_params(struct snd_compr_stream *stream, 621 struct snd_compr_params *params) 622 { 623 struct snd_compr_runtime *runtime = stream->runtime; 624 struct q6asm_dai_rtd *prtd = runtime->private_data; 625 struct snd_soc_pcm_runtime *rtd = stream->private_data; 626 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 627 int dir = stream->direction; 628 struct q6asm_dai_data *pdata; 629 struct q6asm_flac_cfg flac_cfg; 630 struct device *dev = c->dev; 631 int ret; 632 union snd_codec_options *codec_options; 633 struct snd_dec_flac *flac; 634 635 codec_options = &(prtd->codec_param.codec.options); 636 637 638 memcpy(&prtd->codec_param, params, sizeof(*params)); 639 640 pdata = snd_soc_component_get_drvdata(c); 641 if (!pdata) 642 return -EINVAL; 643 644 if (!prtd || !prtd->audio_client) { 645 dev_err(dev, "private data null or audio client freed\n"); 646 return -EINVAL; 647 } 648 649 prtd->periods = runtime->fragments; 650 prtd->pcm_count = runtime->fragment_size; 651 prtd->pcm_size = runtime->fragments * runtime->fragment_size; 652 prtd->bits_per_sample = 16; 653 if (dir == SND_COMPRESS_PLAYBACK) { 654 ret = q6asm_open_write(prtd->audio_client, params->codec.id, 655 prtd->bits_per_sample); 656 657 if (ret < 0) { 658 dev_err(dev, "q6asm_open_write failed\n"); 659 q6asm_audio_client_free(prtd->audio_client); 660 prtd->audio_client = NULL; 661 return ret; 662 } 663 } 664 665 prtd->session_id = q6asm_get_session_id(prtd->audio_client); 666 ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE, 667 prtd->session_id, dir); 668 if (ret) { 669 dev_err(dev, "Stream reg failed ret:%d\n", ret); 670 return ret; 671 } 672 673 switch (params->codec.id) { 674 case SND_AUDIOCODEC_FLAC: 675 676 memset(&flac_cfg, 0x0, sizeof(struct q6asm_flac_cfg)); 677 flac = &codec_options->flac_d; 678 679 flac_cfg.ch_cfg = params->codec.ch_in; 680 flac_cfg.sample_rate = params->codec.sample_rate; 681 flac_cfg.stream_info_present = 1; 682 flac_cfg.sample_size = flac->sample_size; 683 flac_cfg.min_blk_size = flac->min_blk_size; 684 flac_cfg.max_blk_size = flac->max_blk_size; 685 flac_cfg.max_frame_size = flac->max_frame_size; 686 flac_cfg.min_frame_size = flac->min_frame_size; 687 688 ret = q6asm_stream_media_format_block_flac(prtd->audio_client, 689 &flac_cfg); 690 if (ret < 0) { 691 dev_err(dev, "FLAC CMD Format block failed:%d\n", ret); 692 return -EIO; 693 } 694 break; 695 default: 696 break; 697 } 698 699 ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys, 700 (prtd->pcm_size / prtd->periods), 701 prtd->periods); 702 703 if (ret < 0) { 704 dev_err(dev, "Buffer Mapping failed ret:%d\n", ret); 705 return -ENOMEM; 706 } 707 708 prtd->state = Q6ASM_STREAM_RUNNING; 709 710 return 0; 711 } 712 713 static int q6asm_dai_compr_trigger(struct snd_compr_stream *stream, int cmd) 714 { 715 struct snd_compr_runtime *runtime = stream->runtime; 716 struct q6asm_dai_rtd *prtd = runtime->private_data; 717 int ret = 0; 718 719 switch (cmd) { 720 case SNDRV_PCM_TRIGGER_START: 721 case SNDRV_PCM_TRIGGER_RESUME: 722 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 723 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); 724 break; 725 case SNDRV_PCM_TRIGGER_STOP: 726 prtd->state = Q6ASM_STREAM_STOPPED; 727 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); 728 break; 729 case SNDRV_PCM_TRIGGER_SUSPEND: 730 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 731 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); 732 break; 733 default: 734 ret = -EINVAL; 735 break; 736 } 737 738 return ret; 739 } 740 741 static int q6asm_dai_compr_pointer(struct snd_compr_stream *stream, 742 struct snd_compr_tstamp *tstamp) 743 { 744 struct snd_compr_runtime *runtime = stream->runtime; 745 struct q6asm_dai_rtd *prtd = runtime->private_data; 746 unsigned long flags; 747 748 spin_lock_irqsave(&prtd->lock, flags); 749 750 tstamp->copied_total = prtd->copied_total; 751 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; 752 753 spin_unlock_irqrestore(&prtd->lock, flags); 754 755 return 0; 756 } 757 758 static int q6asm_dai_compr_ack(struct snd_compr_stream *stream, 759 size_t count) 760 { 761 struct snd_compr_runtime *runtime = stream->runtime; 762 struct q6asm_dai_rtd *prtd = runtime->private_data; 763 unsigned long flags; 764 765 spin_lock_irqsave(&prtd->lock, flags); 766 prtd->bytes_received += count; 767 spin_unlock_irqrestore(&prtd->lock, flags); 768 769 return count; 770 } 771 772 static int q6asm_dai_compr_mmap(struct snd_compr_stream *stream, 773 struct vm_area_struct *vma) 774 { 775 struct snd_compr_runtime *runtime = stream->runtime; 776 struct q6asm_dai_rtd *prtd = runtime->private_data; 777 struct snd_soc_pcm_runtime *rtd = stream->private_data; 778 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 779 struct device *dev = c->dev; 780 781 return dma_mmap_coherent(dev, vma, 782 prtd->dma_buffer.area, prtd->dma_buffer.addr, 783 prtd->dma_buffer.bytes); 784 } 785 786 static int q6asm_dai_compr_get_caps(struct snd_compr_stream *stream, 787 struct snd_compr_caps *caps) 788 { 789 caps->direction = SND_COMPRESS_PLAYBACK; 790 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; 791 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 792 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 793 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 794 caps->num_codecs = 2; 795 caps->codecs[0] = SND_AUDIOCODEC_MP3; 796 caps->codecs[1] = SND_AUDIOCODEC_FLAC; 797 798 return 0; 799 } 800 801 static int q6asm_dai_compr_get_codec_caps(struct snd_compr_stream *stream, 802 struct snd_compr_codec_caps *codec) 803 { 804 switch (codec->codec) { 805 case SND_AUDIOCODEC_MP3: 806 *codec = q6asm_compr_caps; 807 break; 808 default: 809 break; 810 } 811 812 return 0; 813 } 814 815 static struct snd_compr_ops q6asm_dai_compr_ops = { 816 .open = q6asm_dai_compr_open, 817 .free = q6asm_dai_compr_free, 818 .set_params = q6asm_dai_compr_set_params, 819 .pointer = q6asm_dai_compr_pointer, 820 .trigger = q6asm_dai_compr_trigger, 821 .get_caps = q6asm_dai_compr_get_caps, 822 .get_codec_caps = q6asm_dai_compr_get_codec_caps, 823 .mmap = q6asm_dai_compr_mmap, 824 .ack = q6asm_dai_compr_ack, 825 }; 826 827 static int q6asm_dai_pcm_new(struct snd_soc_component *component, 828 struct snd_soc_pcm_runtime *rtd) 829 { 830 struct snd_pcm_substream *psubstream, *csubstream; 831 struct snd_pcm *pcm = rtd->pcm; 832 struct device *dev; 833 int size, ret; 834 835 dev = component->dev; 836 size = q6asm_dai_hardware_playback.buffer_bytes_max; 837 psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 838 if (psubstream) { 839 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 840 &psubstream->dma_buffer); 841 if (ret) { 842 dev_err(dev, "Cannot allocate buffer(s)\n"); 843 return ret; 844 } 845 } 846 847 csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 848 if (csubstream) { 849 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 850 &csubstream->dma_buffer); 851 if (ret) { 852 dev_err(dev, "Cannot allocate buffer(s)\n"); 853 if (psubstream) 854 snd_dma_free_pages(&psubstream->dma_buffer); 855 return ret; 856 } 857 } 858 859 return 0; 860 } 861 862 static void q6asm_dai_pcm_free(struct snd_soc_component *component, 863 struct snd_pcm *pcm) 864 { 865 struct snd_pcm_substream *substream; 866 int i; 867 868 for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) { 869 substream = pcm->streams[i].substream; 870 if (substream) { 871 snd_dma_free_pages(&substream->dma_buffer); 872 substream->dma_buffer.area = NULL; 873 substream->dma_buffer.addr = 0; 874 } 875 } 876 } 877 878 static const struct snd_soc_component_driver q6asm_fe_dai_component = { 879 .name = DRV_NAME, 880 .open = q6asm_dai_open, 881 .hw_params = q6asm_dai_hw_params, 882 .close = q6asm_dai_close, 883 .ioctl = snd_soc_pcm_lib_ioctl, 884 .prepare = q6asm_dai_prepare, 885 .trigger = q6asm_dai_trigger, 886 .pointer = q6asm_dai_pointer, 887 .mmap = q6asm_dai_mmap, 888 .pcm_construct = q6asm_dai_pcm_new, 889 .pcm_destruct = q6asm_dai_pcm_free, 890 .compr_ops = &q6asm_dai_compr_ops, 891 }; 892 893 static struct snd_soc_dai_driver q6asm_fe_dais[] = { 894 Q6ASM_FEDAI_DRIVER(1), 895 Q6ASM_FEDAI_DRIVER(2), 896 Q6ASM_FEDAI_DRIVER(3), 897 Q6ASM_FEDAI_DRIVER(4), 898 Q6ASM_FEDAI_DRIVER(5), 899 Q6ASM_FEDAI_DRIVER(6), 900 Q6ASM_FEDAI_DRIVER(7), 901 Q6ASM_FEDAI_DRIVER(8), 902 }; 903 904 static int of_q6asm_parse_dai_data(struct device *dev, 905 struct q6asm_dai_data *pdata) 906 { 907 static struct snd_soc_dai_driver *dai_drv; 908 struct snd_soc_pcm_stream empty_stream; 909 struct device_node *node; 910 int ret, id, dir; 911 912 memset(&empty_stream, 0, sizeof(empty_stream)); 913 914 for_each_child_of_node(dev->of_node, node) { 915 ret = of_property_read_u32(node, "reg", &id); 916 if (ret || id >= MAX_SESSIONS || id < 0) { 917 dev_err(dev, "valid dai id not found:%d\n", ret); 918 continue; 919 } 920 921 dai_drv = &q6asm_fe_dais[id]; 922 923 ret = of_property_read_u32(node, "direction", &dir); 924 if (ret) 925 continue; 926 927 if (dir == Q6ASM_DAI_RX) 928 dai_drv->capture = empty_stream; 929 else if (dir == Q6ASM_DAI_TX) 930 dai_drv->playback = empty_stream; 931 932 if (of_property_read_bool(node, "is-compress-dai")) 933 dai_drv->compress_new = snd_soc_new_compress; 934 } 935 936 return 0; 937 } 938 939 static int q6asm_dai_probe(struct platform_device *pdev) 940 { 941 struct device *dev = &pdev->dev; 942 struct device_node *node = dev->of_node; 943 struct of_phandle_args args; 944 struct q6asm_dai_data *pdata; 945 int rc; 946 947 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 948 if (!pdata) 949 return -ENOMEM; 950 951 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); 952 if (rc < 0) 953 pdata->sid = -1; 954 else 955 pdata->sid = args.args[0] & SID_MASK_DEFAULT; 956 957 dev_set_drvdata(dev, pdata); 958 959 of_q6asm_parse_dai_data(dev, pdata); 960 961 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, 962 q6asm_fe_dais, 963 ARRAY_SIZE(q6asm_fe_dais)); 964 } 965 966 static const struct of_device_id q6asm_dai_device_id[] = { 967 { .compatible = "qcom,q6asm-dais" }, 968 {}, 969 }; 970 MODULE_DEVICE_TABLE(of, q6asm_dai_device_id); 971 972 static struct platform_driver q6asm_dai_platform_driver = { 973 .driver = { 974 .name = "q6asm-dai", 975 .of_match_table = of_match_ptr(q6asm_dai_device_id), 976 }, 977 .probe = q6asm_dai_probe, 978 }; 979 module_platform_driver(q6asm_dai_platform_driver); 980 981 MODULE_DESCRIPTION("Q6ASM dai driver"); 982 MODULE_LICENSE("GPL v2"); 983