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_pcm_substream *substream) 210 { 211 struct snd_pcm_runtime *runtime = substream->runtime; 212 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 213 struct q6asm_dai_rtd *prtd = runtime->private_data; 214 struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); 215 struct q6asm_dai_data *pdata; 216 int ret, i; 217 218 pdata = snd_soc_component_get_drvdata(c); 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_pcm_substream *substream, int cmd) 298 { 299 int ret = 0; 300 struct snd_pcm_runtime *runtime = substream->runtime; 301 struct q6asm_dai_rtd *prtd = runtime->private_data; 302 303 switch (cmd) { 304 case SNDRV_PCM_TRIGGER_START: 305 case SNDRV_PCM_TRIGGER_RESUME: 306 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 307 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); 308 break; 309 case SNDRV_PCM_TRIGGER_STOP: 310 prtd->state = Q6ASM_STREAM_STOPPED; 311 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); 312 break; 313 case SNDRV_PCM_TRIGGER_SUSPEND: 314 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 315 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); 316 break; 317 default: 318 ret = -EINVAL; 319 break; 320 } 321 322 return ret; 323 } 324 325 static int q6asm_dai_open(struct snd_pcm_substream *substream) 326 { 327 struct snd_pcm_runtime *runtime = substream->runtime; 328 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 329 struct snd_soc_dai *cpu_dai = soc_prtd->cpu_dai; 330 struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); 331 struct q6asm_dai_rtd *prtd; 332 struct q6asm_dai_data *pdata; 333 struct device *dev = c->dev; 334 int ret = 0; 335 int stream_id; 336 337 stream_id = cpu_dai->driver->id; 338 339 pdata = snd_soc_component_get_drvdata(c); 340 if (!pdata) { 341 pr_err("Drv data not found ..\n"); 342 return -EINVAL; 343 } 344 345 prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL); 346 if (prtd == NULL) 347 return -ENOMEM; 348 349 prtd->substream = substream; 350 prtd->audio_client = q6asm_audio_client_alloc(dev, 351 (q6asm_cb)event_handler, prtd, stream_id, 352 LEGACY_PCM_MODE); 353 if (IS_ERR(prtd->audio_client)) { 354 pr_info("%s: Could not allocate memory\n", __func__); 355 ret = PTR_ERR(prtd->audio_client); 356 kfree(prtd); 357 return ret; 358 } 359 360 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 361 runtime->hw = q6asm_dai_hardware_playback; 362 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 363 runtime->hw = q6asm_dai_hardware_capture; 364 365 ret = snd_pcm_hw_constraint_list(runtime, 0, 366 SNDRV_PCM_HW_PARAM_RATE, 367 &constraints_sample_rates); 368 if (ret < 0) 369 pr_info("snd_pcm_hw_constraint_list failed\n"); 370 /* Ensure that buffer size is a multiple of period size */ 371 ret = snd_pcm_hw_constraint_integer(runtime, 372 SNDRV_PCM_HW_PARAM_PERIODS); 373 if (ret < 0) 374 pr_info("snd_pcm_hw_constraint_integer failed\n"); 375 376 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 377 ret = snd_pcm_hw_constraint_minmax(runtime, 378 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 379 PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE, 380 PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE); 381 if (ret < 0) { 382 pr_err("constraint for buffer bytes min max ret = %d\n", 383 ret); 384 } 385 } 386 387 ret = snd_pcm_hw_constraint_step(runtime, 0, 388 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 389 if (ret < 0) { 390 pr_err("constraint for period bytes step ret = %d\n", 391 ret); 392 } 393 ret = snd_pcm_hw_constraint_step(runtime, 0, 394 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 395 if (ret < 0) { 396 pr_err("constraint for buffer bytes step ret = %d\n", 397 ret); 398 } 399 400 runtime->private_data = prtd; 401 402 snd_soc_set_runtime_hwparams(substream, &q6asm_dai_hardware_playback); 403 404 runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max; 405 406 407 if (pdata->sid < 0) 408 prtd->phys = substream->dma_buffer.addr; 409 else 410 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); 411 412 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 413 414 return 0; 415 } 416 417 static int q6asm_dai_close(struct snd_pcm_substream *substream) 418 { 419 struct snd_pcm_runtime *runtime = substream->runtime; 420 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 421 struct q6asm_dai_rtd *prtd = runtime->private_data; 422 423 if (prtd->audio_client) { 424 if (prtd->state) 425 q6asm_cmd(prtd->audio_client, CMD_CLOSE); 426 427 q6asm_unmap_memory_regions(substream->stream, 428 prtd->audio_client); 429 q6asm_audio_client_free(prtd->audio_client); 430 prtd->audio_client = NULL; 431 } 432 q6routing_stream_close(soc_prtd->dai_link->id, 433 substream->stream); 434 kfree(prtd); 435 return 0; 436 } 437 438 static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_pcm_substream *substream) 439 { 440 441 struct snd_pcm_runtime *runtime = substream->runtime; 442 struct q6asm_dai_rtd *prtd = runtime->private_data; 443 444 if (prtd->pcm_irq_pos >= prtd->pcm_size) 445 prtd->pcm_irq_pos = 0; 446 447 return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); 448 } 449 450 static int q6asm_dai_mmap(struct snd_pcm_substream *substream, 451 struct vm_area_struct *vma) 452 { 453 454 struct snd_pcm_runtime *runtime = substream->runtime; 455 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 456 struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); 457 struct device *dev = c->dev; 458 459 return dma_mmap_coherent(dev, vma, 460 runtime->dma_area, runtime->dma_addr, 461 runtime->dma_bytes); 462 } 463 464 static int q6asm_dai_hw_params(struct snd_pcm_substream *substream, 465 struct snd_pcm_hw_params *params) 466 { 467 struct snd_pcm_runtime *runtime = substream->runtime; 468 struct q6asm_dai_rtd *prtd = runtime->private_data; 469 470 prtd->pcm_size = params_buffer_bytes(params); 471 prtd->periods = params_periods(params); 472 473 switch (params_format(params)) { 474 case SNDRV_PCM_FORMAT_S16_LE: 475 prtd->bits_per_sample = 16; 476 break; 477 case SNDRV_PCM_FORMAT_S24_LE: 478 prtd->bits_per_sample = 24; 479 break; 480 } 481 482 return 0; 483 } 484 485 static struct snd_pcm_ops q6asm_dai_ops = { 486 .open = q6asm_dai_open, 487 .hw_params = q6asm_dai_hw_params, 488 .close = q6asm_dai_close, 489 .ioctl = snd_pcm_lib_ioctl, 490 .prepare = q6asm_dai_prepare, 491 .trigger = q6asm_dai_trigger, 492 .pointer = q6asm_dai_pointer, 493 .mmap = q6asm_dai_mmap, 494 }; 495 496 static void compress_event_handler(uint32_t opcode, uint32_t token, 497 uint32_t *payload, void *priv) 498 { 499 struct q6asm_dai_rtd *prtd = priv; 500 struct snd_compr_stream *substream = prtd->cstream; 501 unsigned long flags; 502 uint64_t avail; 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_write_async(prtd->audio_client, prtd->pcm_count, 509 0, 0, NO_TIMESTAMP); 510 prtd->bytes_sent += prtd->pcm_count; 511 } 512 513 spin_unlock_irqrestore(&prtd->lock, flags); 514 break; 515 516 case ASM_CLIENT_EVENT_CMD_EOS_DONE: 517 prtd->state = Q6ASM_STREAM_STOPPED; 518 break; 519 520 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: 521 spin_lock_irqsave(&prtd->lock, flags); 522 523 prtd->copied_total += prtd->pcm_count; 524 snd_compr_fragment_elapsed(substream); 525 526 if (prtd->state != Q6ASM_STREAM_RUNNING) { 527 spin_unlock_irqrestore(&prtd->lock, flags); 528 break; 529 } 530 531 avail = prtd->bytes_received - prtd->bytes_sent; 532 533 if (avail >= prtd->pcm_count) { 534 q6asm_write_async(prtd->audio_client, 535 prtd->pcm_count, 0, 0, NO_TIMESTAMP); 536 prtd->bytes_sent += prtd->pcm_count; 537 } 538 539 spin_unlock_irqrestore(&prtd->lock, flags); 540 break; 541 542 default: 543 break; 544 } 545 } 546 547 static int q6asm_dai_compr_open(struct snd_compr_stream *stream) 548 { 549 struct snd_soc_pcm_runtime *rtd = stream->private_data; 550 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 551 struct snd_compr_runtime *runtime = stream->runtime; 552 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 553 struct q6asm_dai_data *pdata; 554 struct device *dev = c->dev; 555 struct q6asm_dai_rtd *prtd; 556 int stream_id, size, ret; 557 558 stream_id = cpu_dai->driver->id; 559 pdata = snd_soc_component_get_drvdata(c); 560 if (!pdata) { 561 dev_err(dev, "Drv data not found ..\n"); 562 return -EINVAL; 563 } 564 565 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 566 if (!prtd) 567 return -ENOMEM; 568 569 prtd->cstream = stream; 570 prtd->audio_client = q6asm_audio_client_alloc(dev, 571 (q6asm_cb)compress_event_handler, 572 prtd, stream_id, LEGACY_PCM_MODE); 573 if (!prtd->audio_client) { 574 dev_err(dev, "Could not allocate memory\n"); 575 kfree(prtd); 576 return -ENOMEM; 577 } 578 579 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * 580 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 581 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 582 &prtd->dma_buffer); 583 if (ret) { 584 dev_err(dev, "Cannot allocate buffer(s)\n"); 585 return ret; 586 } 587 588 if (pdata->sid < 0) 589 prtd->phys = prtd->dma_buffer.addr; 590 else 591 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); 592 593 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); 594 spin_lock_init(&prtd->lock); 595 runtime->private_data = prtd; 596 597 return 0; 598 } 599 600 static int q6asm_dai_compr_free(struct snd_compr_stream *stream) 601 { 602 struct snd_compr_runtime *runtime = stream->runtime; 603 struct q6asm_dai_rtd *prtd = runtime->private_data; 604 struct snd_soc_pcm_runtime *rtd = stream->private_data; 605 606 if (prtd->audio_client) { 607 if (prtd->state) 608 q6asm_cmd(prtd->audio_client, CMD_CLOSE); 609 610 snd_dma_free_pages(&prtd->dma_buffer); 611 q6asm_unmap_memory_regions(stream->direction, 612 prtd->audio_client); 613 q6asm_audio_client_free(prtd->audio_client); 614 prtd->audio_client = NULL; 615 } 616 q6routing_stream_close(rtd->dai_link->id, stream->direction); 617 kfree(prtd); 618 619 return 0; 620 } 621 622 static int q6asm_dai_compr_set_params(struct snd_compr_stream *stream, 623 struct snd_compr_params *params) 624 { 625 struct snd_compr_runtime *runtime = stream->runtime; 626 struct q6asm_dai_rtd *prtd = runtime->private_data; 627 struct snd_soc_pcm_runtime *rtd = stream->private_data; 628 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 629 int dir = stream->direction; 630 struct q6asm_dai_data *pdata; 631 struct device *dev = c->dev; 632 int ret; 633 634 memcpy(&prtd->codec_param, params, sizeof(*params)); 635 636 pdata = snd_soc_component_get_drvdata(c); 637 if (!pdata) 638 return -EINVAL; 639 640 if (!prtd || !prtd->audio_client) { 641 dev_err(dev, "private data null or audio client freed\n"); 642 return -EINVAL; 643 } 644 645 prtd->periods = runtime->fragments; 646 prtd->pcm_count = runtime->fragment_size; 647 prtd->pcm_size = runtime->fragments * runtime->fragment_size; 648 prtd->bits_per_sample = 16; 649 if (dir == SND_COMPRESS_PLAYBACK) { 650 ret = q6asm_open_write(prtd->audio_client, params->codec.id, 651 prtd->bits_per_sample); 652 653 if (ret < 0) { 654 dev_err(dev, "q6asm_open_write failed\n"); 655 q6asm_audio_client_free(prtd->audio_client); 656 prtd->audio_client = NULL; 657 return ret; 658 } 659 } 660 661 prtd->session_id = q6asm_get_session_id(prtd->audio_client); 662 ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE, 663 prtd->session_id, dir); 664 if (ret) { 665 dev_err(dev, "Stream reg failed ret:%d\n", ret); 666 return ret; 667 } 668 669 ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys, 670 (prtd->pcm_size / prtd->periods), 671 prtd->periods); 672 673 if (ret < 0) { 674 dev_err(dev, "Buffer Mapping failed ret:%d\n", ret); 675 return -ENOMEM; 676 } 677 678 prtd->state = Q6ASM_STREAM_RUNNING; 679 680 return 0; 681 } 682 683 static int q6asm_dai_compr_trigger(struct snd_compr_stream *stream, int cmd) 684 { 685 struct snd_compr_runtime *runtime = stream->runtime; 686 struct q6asm_dai_rtd *prtd = runtime->private_data; 687 int ret = 0; 688 689 switch (cmd) { 690 case SNDRV_PCM_TRIGGER_START: 691 case SNDRV_PCM_TRIGGER_RESUME: 692 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 693 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); 694 break; 695 case SNDRV_PCM_TRIGGER_STOP: 696 prtd->state = Q6ASM_STREAM_STOPPED; 697 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); 698 break; 699 case SNDRV_PCM_TRIGGER_SUSPEND: 700 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 701 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); 702 break; 703 default: 704 ret = -EINVAL; 705 break; 706 } 707 708 return ret; 709 } 710 711 static int q6asm_dai_compr_pointer(struct snd_compr_stream *stream, 712 struct snd_compr_tstamp *tstamp) 713 { 714 struct snd_compr_runtime *runtime = stream->runtime; 715 struct q6asm_dai_rtd *prtd = runtime->private_data; 716 unsigned long flags; 717 718 spin_lock_irqsave(&prtd->lock, flags); 719 720 tstamp->copied_total = prtd->copied_total; 721 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; 722 723 spin_unlock_irqrestore(&prtd->lock, flags); 724 725 return 0; 726 } 727 728 static int q6asm_dai_compr_ack(struct snd_compr_stream *stream, 729 size_t count) 730 { 731 struct snd_compr_runtime *runtime = stream->runtime; 732 struct q6asm_dai_rtd *prtd = runtime->private_data; 733 unsigned long flags; 734 735 spin_lock_irqsave(&prtd->lock, flags); 736 prtd->bytes_received += count; 737 spin_unlock_irqrestore(&prtd->lock, flags); 738 739 return count; 740 } 741 742 static int q6asm_dai_compr_mmap(struct snd_compr_stream *stream, 743 struct vm_area_struct *vma) 744 { 745 struct snd_compr_runtime *runtime = stream->runtime; 746 struct q6asm_dai_rtd *prtd = runtime->private_data; 747 struct snd_soc_pcm_runtime *rtd = stream->private_data; 748 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 749 struct device *dev = c->dev; 750 751 return dma_mmap_coherent(dev, vma, 752 prtd->dma_buffer.area, prtd->dma_buffer.addr, 753 prtd->dma_buffer.bytes); 754 } 755 756 static int q6asm_dai_compr_get_caps(struct snd_compr_stream *stream, 757 struct snd_compr_caps *caps) 758 { 759 caps->direction = SND_COMPRESS_PLAYBACK; 760 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; 761 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 762 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 763 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 764 caps->num_codecs = 1; 765 caps->codecs[0] = SND_AUDIOCODEC_MP3; 766 767 return 0; 768 } 769 770 static int q6asm_dai_compr_get_codec_caps(struct snd_compr_stream *stream, 771 struct snd_compr_codec_caps *codec) 772 { 773 switch (codec->codec) { 774 case SND_AUDIOCODEC_MP3: 775 *codec = q6asm_compr_caps; 776 break; 777 default: 778 break; 779 } 780 781 return 0; 782 } 783 784 static struct snd_compr_ops q6asm_dai_compr_ops = { 785 .open = q6asm_dai_compr_open, 786 .free = q6asm_dai_compr_free, 787 .set_params = q6asm_dai_compr_set_params, 788 .pointer = q6asm_dai_compr_pointer, 789 .trigger = q6asm_dai_compr_trigger, 790 .get_caps = q6asm_dai_compr_get_caps, 791 .get_codec_caps = q6asm_dai_compr_get_codec_caps, 792 .mmap = q6asm_dai_compr_mmap, 793 .ack = q6asm_dai_compr_ack, 794 }; 795 796 static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd) 797 { 798 struct snd_pcm_substream *psubstream, *csubstream; 799 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 800 struct snd_pcm *pcm = rtd->pcm; 801 struct device *dev; 802 int size, ret; 803 804 dev = c->dev; 805 size = q6asm_dai_hardware_playback.buffer_bytes_max; 806 psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 807 if (psubstream) { 808 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 809 &psubstream->dma_buffer); 810 if (ret) { 811 dev_err(dev, "Cannot allocate buffer(s)\n"); 812 return ret; 813 } 814 } 815 816 csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 817 if (csubstream) { 818 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, 819 &csubstream->dma_buffer); 820 if (ret) { 821 dev_err(dev, "Cannot allocate buffer(s)\n"); 822 if (psubstream) 823 snd_dma_free_pages(&psubstream->dma_buffer); 824 return ret; 825 } 826 } 827 828 return 0; 829 } 830 831 static void q6asm_dai_pcm_free(struct snd_pcm *pcm) 832 { 833 struct snd_pcm_substream *substream; 834 int i; 835 836 for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) { 837 substream = pcm->streams[i].substream; 838 if (substream) { 839 snd_dma_free_pages(&substream->dma_buffer); 840 substream->dma_buffer.area = NULL; 841 substream->dma_buffer.addr = 0; 842 } 843 } 844 } 845 846 static const struct snd_soc_component_driver q6asm_fe_dai_component = { 847 .name = DRV_NAME, 848 .ops = &q6asm_dai_ops, 849 .pcm_new = q6asm_dai_pcm_new, 850 .pcm_free = q6asm_dai_pcm_free, 851 .compr_ops = &q6asm_dai_compr_ops, 852 }; 853 854 static struct snd_soc_dai_driver q6asm_fe_dais[] = { 855 Q6ASM_FEDAI_DRIVER(1), 856 Q6ASM_FEDAI_DRIVER(2), 857 Q6ASM_FEDAI_DRIVER(3), 858 Q6ASM_FEDAI_DRIVER(4), 859 Q6ASM_FEDAI_DRIVER(5), 860 Q6ASM_FEDAI_DRIVER(6), 861 Q6ASM_FEDAI_DRIVER(7), 862 Q6ASM_FEDAI_DRIVER(8), 863 }; 864 865 static int of_q6asm_parse_dai_data(struct device *dev, 866 struct q6asm_dai_data *pdata) 867 { 868 static struct snd_soc_dai_driver *dai_drv; 869 struct snd_soc_pcm_stream empty_stream; 870 struct device_node *node; 871 int ret, id, dir; 872 873 memset(&empty_stream, 0, sizeof(empty_stream)); 874 875 for_each_child_of_node(dev->of_node, node) { 876 ret = of_property_read_u32(node, "reg", &id); 877 if (ret || id > MAX_SESSIONS || id < 0) { 878 dev_err(dev, "valid dai id not found:%d\n", ret); 879 continue; 880 } 881 882 dai_drv = &q6asm_fe_dais[id]; 883 884 ret = of_property_read_u32(node, "direction", &dir); 885 if (ret) 886 continue; 887 888 if (dir == Q6ASM_DAI_RX) 889 dai_drv->capture = empty_stream; 890 else if (dir == Q6ASM_DAI_TX) 891 dai_drv->playback = empty_stream; 892 893 if (of_property_read_bool(node, "is-compress-dai")) 894 dai_drv->compress_new = snd_soc_new_compress; 895 } 896 897 return 0; 898 } 899 900 static int q6asm_dai_probe(struct platform_device *pdev) 901 { 902 struct device *dev = &pdev->dev; 903 struct device_node *node = dev->of_node; 904 struct of_phandle_args args; 905 struct q6asm_dai_data *pdata; 906 int rc; 907 908 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 909 if (!pdata) 910 return -ENOMEM; 911 912 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); 913 if (rc < 0) 914 pdata->sid = -1; 915 else 916 pdata->sid = args.args[0] & SID_MASK_DEFAULT; 917 918 dev_set_drvdata(dev, pdata); 919 920 of_q6asm_parse_dai_data(dev, pdata); 921 922 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, 923 q6asm_fe_dais, 924 ARRAY_SIZE(q6asm_fe_dais)); 925 } 926 927 static const struct of_device_id q6asm_dai_device_id[] = { 928 { .compatible = "qcom,q6asm-dais" }, 929 {}, 930 }; 931 MODULE_DEVICE_TABLE(of, q6asm_dai_device_id); 932 933 static struct platform_driver q6asm_dai_platform_driver = { 934 .driver = { 935 .name = "q6asm-dai", 936 .of_match_table = of_match_ptr(q6asm_dai_device_id), 937 }, 938 .probe = q6asm_dai_probe, 939 }; 940 module_platform_driver(q6asm_dai_platform_driver); 941 942 MODULE_DESCRIPTION("Q6ASM dai driver"); 943 MODULE_LICENSE("GPL v2"); 944