1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2021, Linaro Limited 3 4 #include <linux/init.h> 5 #include <linux/err.h> 6 #include <linux/module.h> 7 #include <linux/of.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 <linux/spinlock.h> 13 #include <sound/pcm.h> 14 #include <asm/dma.h> 15 #include <linux/dma-mapping.h> 16 #include <sound/pcm_params.h> 17 #include "q6apm.h" 18 19 #define DRV_NAME "q6apm-dai" 20 21 #define PLAYBACK_MIN_NUM_PERIODS 2 22 #define PLAYBACK_MAX_NUM_PERIODS 8 23 #define PLAYBACK_MAX_PERIOD_SIZE 65536 24 #define PLAYBACK_MIN_PERIOD_SIZE 128 25 #define CAPTURE_MIN_NUM_PERIODS 2 26 #define CAPTURE_MAX_NUM_PERIODS 8 27 #define CAPTURE_MAX_PERIOD_SIZE 65536 28 #define CAPTURE_MIN_PERIOD_SIZE 6144 29 #define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE) 30 #define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE) 31 #define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024) 32 #define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4) 33 #define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024) 34 #define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4) 35 #define SID_MASK_DEFAULT 0xF 36 37 static const struct snd_compr_codec_caps q6apm_compr_caps = { 38 .num_descriptors = 1, 39 .descriptor[0].max_ch = 2, 40 .descriptor[0].sample_rates = { 8000, 11025, 12000, 16000, 22050, 41 24000, 32000, 44100, 48000, 88200, 42 96000, 176400, 192000 }, 43 .descriptor[0].num_sample_rates = 13, 44 .descriptor[0].bit_rate[0] = 320, 45 .descriptor[0].bit_rate[1] = 128, 46 .descriptor[0].num_bitrates = 2, 47 .descriptor[0].profiles = 0, 48 .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, 49 .descriptor[0].formats = 0, 50 }; 51 52 enum stream_state { 53 Q6APM_STREAM_IDLE = 0, 54 Q6APM_STREAM_STOPPED, 55 Q6APM_STREAM_RUNNING, 56 }; 57 58 struct q6apm_dai_rtd { 59 struct snd_pcm_substream *substream; 60 struct snd_compr_stream *cstream; 61 struct snd_codec codec; 62 struct snd_compr_params codec_param; 63 struct snd_dma_buffer dma_buffer; 64 phys_addr_t phys; 65 unsigned int pcm_size; 66 unsigned int pcm_count; 67 unsigned int periods; 68 unsigned int bytes_sent; 69 unsigned int bytes_received; 70 unsigned int copied_total; 71 uint16_t bits_per_sample; 72 snd_pcm_uframes_t queue_ptr; 73 bool next_track; 74 enum stream_state state; 75 struct q6apm_graph *graph; 76 spinlock_t lock; 77 bool notify_on_drain; 78 }; 79 80 struct q6apm_dai_data { 81 long long sid; 82 }; 83 84 static const struct snd_pcm_hardware q6apm_dai_hardware_capture = { 85 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | 86 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | 87 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 88 SNDRV_PCM_INFO_BATCH), 89 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), 90 .rates = SNDRV_PCM_RATE_8000_48000, 91 .rate_min = 8000, 92 .rate_max = 48000, 93 .channels_min = 2, 94 .channels_max = 4, 95 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, 96 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, 97 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, 98 .periods_min = CAPTURE_MIN_NUM_PERIODS, 99 .periods_max = CAPTURE_MAX_NUM_PERIODS, 100 .fifo_size = 0, 101 }; 102 103 static const struct snd_pcm_hardware q6apm_dai_hardware_playback = { 104 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | 105 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | 106 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 107 SNDRV_PCM_INFO_BATCH), 108 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), 109 .rates = SNDRV_PCM_RATE_8000_192000, 110 .rate_min = 8000, 111 .rate_max = 192000, 112 .channels_min = 2, 113 .channels_max = 8, 114 .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE), 115 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, 116 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, 117 .periods_min = PLAYBACK_MIN_NUM_PERIODS, 118 .periods_max = PLAYBACK_MAX_NUM_PERIODS, 119 .fifo_size = 0, 120 }; 121 122 static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) 123 { 124 struct q6apm_dai_rtd *prtd = priv; 125 struct snd_pcm_substream *substream = prtd->substream; 126 127 switch (opcode) { 128 case APM_CLIENT_EVENT_CMD_EOS_DONE: 129 prtd->state = Q6APM_STREAM_STOPPED; 130 break; 131 case APM_CLIENT_EVENT_DATA_WRITE_DONE: 132 snd_pcm_period_elapsed(substream); 133 134 break; 135 case APM_CLIENT_EVENT_DATA_READ_DONE: 136 snd_pcm_period_elapsed(substream); 137 if (prtd->state == Q6APM_STREAM_RUNNING) 138 q6apm_read(prtd->graph); 139 140 break; 141 default: 142 break; 143 } 144 } 145 146 static void event_handler_compr(uint32_t opcode, uint32_t token, 147 void *payload, void *priv) 148 { 149 struct q6apm_dai_rtd *prtd = priv; 150 struct snd_compr_stream *substream = prtd->cstream; 151 unsigned long flags; 152 uint32_t wflags = 0; 153 uint64_t avail; 154 uint32_t bytes_written, bytes_to_write; 155 bool is_last_buffer = false; 156 157 switch (opcode) { 158 case APM_CLIENT_EVENT_CMD_EOS_DONE: 159 spin_lock_irqsave(&prtd->lock, flags); 160 if (prtd->notify_on_drain) { 161 snd_compr_drain_notify(prtd->cstream); 162 prtd->notify_on_drain = false; 163 } else { 164 prtd->state = Q6APM_STREAM_STOPPED; 165 } 166 spin_unlock_irqrestore(&prtd->lock, flags); 167 break; 168 case APM_CLIENT_EVENT_DATA_WRITE_DONE: 169 spin_lock_irqsave(&prtd->lock, flags); 170 bytes_written = token >> APM_WRITE_TOKEN_LEN_SHIFT; 171 prtd->copied_total += bytes_written; 172 snd_compr_fragment_elapsed(substream); 173 174 if (prtd->state != Q6APM_STREAM_RUNNING) { 175 spin_unlock_irqrestore(&prtd->lock, flags); 176 break; 177 } 178 179 avail = prtd->bytes_received - prtd->bytes_sent; 180 181 if (avail > prtd->pcm_count) { 182 bytes_to_write = prtd->pcm_count; 183 } else { 184 if (substream->partial_drain || prtd->notify_on_drain) 185 is_last_buffer = true; 186 bytes_to_write = avail; 187 } 188 189 if (bytes_to_write) { 190 if (substream->partial_drain && is_last_buffer) 191 wflags |= APM_LAST_BUFFER_FLAG; 192 193 q6apm_write_async(prtd->graph, 194 bytes_to_write, 0, 0, wflags); 195 196 prtd->bytes_sent += bytes_to_write; 197 198 if (prtd->notify_on_drain && is_last_buffer) 199 audioreach_shared_memory_send_eos(prtd->graph); 200 } 201 202 spin_unlock_irqrestore(&prtd->lock, flags); 203 break; 204 default: 205 break; 206 } 207 } 208 209 static int q6apm_dai_prepare(struct snd_soc_component *component, 210 struct snd_pcm_substream *substream) 211 { 212 struct snd_pcm_runtime *runtime = substream->runtime; 213 struct q6apm_dai_rtd *prtd = runtime->private_data; 214 struct audioreach_module_config cfg; 215 struct device *dev = component->dev; 216 struct q6apm_dai_data *pdata; 217 int ret; 218 219 pdata = snd_soc_component_get_drvdata(component); 220 if (!pdata) 221 return -EINVAL; 222 223 if (!prtd || !prtd->graph) { 224 dev_err(dev, "%s: private data null or audio client freed\n", __func__); 225 return -EINVAL; 226 } 227 228 cfg.direction = substream->stream; 229 cfg.sample_rate = runtime->rate; 230 cfg.num_channels = runtime->channels; 231 cfg.bit_width = prtd->bits_per_sample; 232 cfg.fmt = SND_AUDIOCODEC_PCM; 233 audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels); 234 235 if (prtd->state) { 236 /* clear the previous setup if any */ 237 q6apm_graph_stop(prtd->graph); 238 q6apm_unmap_memory_regions(prtd->graph, substream->stream); 239 } 240 241 prtd->pcm_count = snd_pcm_lib_period_bytes(substream); 242 /* rate and channels are sent to audio driver */ 243 ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg); 244 if (ret < 0) { 245 dev_err(dev, "%s: q6apm_open_write failed\n", __func__); 246 return ret; 247 } 248 249 ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg); 250 if (ret < 0) 251 dev_err(dev, "%s: CMD Format block failed\n", __func__); 252 253 ret = q6apm_map_memory_regions(prtd->graph, substream->stream, prtd->phys, 254 (prtd->pcm_size / prtd->periods), prtd->periods); 255 256 if (ret < 0) { 257 dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", ret); 258 return -ENOMEM; 259 } 260 261 ret = q6apm_graph_prepare(prtd->graph); 262 if (ret) { 263 dev_err(dev, "Failed to prepare Graph %d\n", ret); 264 return ret; 265 } 266 267 ret = q6apm_graph_start(prtd->graph); 268 if (ret) { 269 dev_err(dev, "Failed to Start Graph %d\n", ret); 270 return ret; 271 } 272 273 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 274 int i; 275 /* Queue the buffers for Capture ONLY after graph is started */ 276 for (i = 0; i < runtime->periods; i++) 277 q6apm_read(prtd->graph); 278 279 } 280 281 /* Now that graph as been prepared and started update the internal state accordingly */ 282 prtd->state = Q6APM_STREAM_RUNNING; 283 284 return 0; 285 } 286 287 static int q6apm_dai_ack(struct snd_soc_component *component, struct snd_pcm_substream *substream) 288 { 289 struct snd_pcm_runtime *runtime = substream->runtime; 290 struct q6apm_dai_rtd *prtd = runtime->private_data; 291 int i, ret = 0, avail_periods; 292 293 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 294 avail_periods = (runtime->control->appl_ptr - prtd->queue_ptr)/runtime->period_size; 295 for (i = 0; i < avail_periods; i++) { 296 ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP); 297 if (ret < 0) { 298 dev_err(component->dev, "Error queuing playback buffer %d\n", ret); 299 return ret; 300 } 301 prtd->queue_ptr += runtime->period_size; 302 } 303 } 304 305 return ret; 306 } 307 308 static int q6apm_dai_trigger(struct snd_soc_component *component, 309 struct snd_pcm_substream *substream, int cmd) 310 { 311 struct snd_pcm_runtime *runtime = substream->runtime; 312 struct q6apm_dai_rtd *prtd = runtime->private_data; 313 int ret = 0; 314 315 switch (cmd) { 316 case SNDRV_PCM_TRIGGER_START: 317 case SNDRV_PCM_TRIGGER_RESUME: 318 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 319 break; 320 case SNDRV_PCM_TRIGGER_STOP: 321 /* TODO support be handled via SoftPause Module */ 322 prtd->state = Q6APM_STREAM_STOPPED; 323 break; 324 case SNDRV_PCM_TRIGGER_SUSPEND: 325 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 326 break; 327 default: 328 ret = -EINVAL; 329 break; 330 } 331 332 return ret; 333 } 334 335 static int q6apm_dai_open(struct snd_soc_component *component, 336 struct snd_pcm_substream *substream) 337 { 338 struct snd_pcm_runtime *runtime = substream->runtime; 339 struct snd_soc_pcm_runtime *soc_prtd = snd_soc_substream_to_rtd(substream); 340 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0); 341 struct device *dev = component->dev; 342 struct q6apm_dai_data *pdata; 343 struct q6apm_dai_rtd *prtd; 344 int graph_id, ret; 345 346 graph_id = cpu_dai->driver->id; 347 348 pdata = snd_soc_component_get_drvdata(component); 349 if (!pdata) { 350 dev_err(dev, "Drv data not found ..\n"); 351 return -EINVAL; 352 } 353 354 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 355 if (prtd == NULL) 356 return -ENOMEM; 357 358 spin_lock_init(&prtd->lock); 359 prtd->substream = substream; 360 prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id); 361 if (IS_ERR(prtd->graph)) { 362 dev_err(dev, "%s: Could not allocate memory\n", __func__); 363 ret = PTR_ERR(prtd->graph); 364 goto err; 365 } 366 367 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 368 runtime->hw = q6apm_dai_hardware_playback; 369 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 370 runtime->hw = q6apm_dai_hardware_capture; 371 372 /* Ensure that buffer size is a multiple of period size */ 373 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 374 if (ret < 0) { 375 dev_err(dev, "snd_pcm_hw_constraint_integer failed\n"); 376 goto err; 377 } 378 379 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 380 ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 381 BUFFER_BYTES_MIN, BUFFER_BYTES_MAX); 382 if (ret < 0) { 383 dev_err(dev, "constraint for buffer bytes min max ret = %d\n", ret); 384 goto err; 385 } 386 } 387 388 /* setup 10ms latency to accommodate DSP restrictions */ 389 ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 480); 390 if (ret < 0) { 391 dev_err(dev, "constraint for period bytes step ret = %d\n", ret); 392 goto err; 393 } 394 395 ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 480); 396 if (ret < 0) { 397 dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret); 398 goto err; 399 } 400 401 runtime->private_data = prtd; 402 runtime->dma_bytes = BUFFER_BYTES_MAX; 403 if (pdata->sid < 0) 404 prtd->phys = substream->dma_buffer.addr; 405 else 406 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); 407 408 return 0; 409 err: 410 kfree(prtd); 411 412 return ret; 413 } 414 415 static int q6apm_dai_close(struct snd_soc_component *component, 416 struct snd_pcm_substream *substream) 417 { 418 struct snd_pcm_runtime *runtime = substream->runtime; 419 struct q6apm_dai_rtd *prtd = runtime->private_data; 420 421 if (prtd->state) { /* only stop graph that is started */ 422 q6apm_graph_stop(prtd->graph); 423 q6apm_unmap_memory_regions(prtd->graph, substream->stream); 424 } 425 426 q6apm_graph_close(prtd->graph); 427 prtd->graph = NULL; 428 kfree(prtd); 429 runtime->private_data = NULL; 430 431 return 0; 432 } 433 434 static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component, 435 struct snd_pcm_substream *substream) 436 { 437 struct snd_pcm_runtime *runtime = substream->runtime; 438 struct q6apm_dai_rtd *prtd = runtime->private_data; 439 snd_pcm_uframes_t ptr; 440 441 ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size; 442 if (ptr) 443 return ptr - 1; 444 445 return 0; 446 } 447 448 static int q6apm_dai_hw_params(struct snd_soc_component *component, 449 struct snd_pcm_substream *substream, 450 struct snd_pcm_hw_params *params) 451 { 452 struct snd_pcm_runtime *runtime = substream->runtime; 453 struct q6apm_dai_rtd *prtd = runtime->private_data; 454 455 prtd->pcm_size = params_buffer_bytes(params); 456 prtd->periods = params_periods(params); 457 458 switch (params_format(params)) { 459 case SNDRV_PCM_FORMAT_S16_LE: 460 prtd->bits_per_sample = 16; 461 break; 462 case SNDRV_PCM_FORMAT_S24_LE: 463 prtd->bits_per_sample = 24; 464 break; 465 default: 466 return -EINVAL; 467 } 468 469 return 0; 470 } 471 472 static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) 473 { 474 int size = BUFFER_BYTES_MAX; 475 476 return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, component->dev, size); 477 } 478 479 static int q6apm_dai_compr_open(struct snd_soc_component *component, 480 struct snd_compr_stream *stream) 481 { 482 struct snd_soc_pcm_runtime *rtd = stream->private_data; 483 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 484 struct snd_compr_runtime *runtime = stream->runtime; 485 struct q6apm_dai_rtd *prtd; 486 struct q6apm_dai_data *pdata; 487 struct device *dev = component->dev; 488 int ret, size; 489 int graph_id; 490 491 graph_id = cpu_dai->driver->id; 492 pdata = snd_soc_component_get_drvdata(component); 493 if (!pdata) 494 return -EINVAL; 495 496 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 497 if (prtd == NULL) 498 return -ENOMEM; 499 500 prtd->cstream = stream; 501 prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id); 502 if (IS_ERR(prtd->graph)) { 503 ret = PTR_ERR(prtd->graph); 504 kfree(prtd); 505 return ret; 506 } 507 508 runtime->private_data = prtd; 509 runtime->dma_bytes = BUFFER_BYTES_MAX; 510 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 511 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &prtd->dma_buffer); 512 if (ret) 513 return ret; 514 515 if (pdata->sid < 0) 516 prtd->phys = prtd->dma_buffer.addr; 517 else 518 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); 519 520 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); 521 spin_lock_init(&prtd->lock); 522 523 q6apm_enable_compress_module(dev, prtd->graph, true); 524 return 0; 525 } 526 527 static int q6apm_dai_compr_free(struct snd_soc_component *component, 528 struct snd_compr_stream *stream) 529 { 530 struct snd_compr_runtime *runtime = stream->runtime; 531 struct q6apm_dai_rtd *prtd = runtime->private_data; 532 533 q6apm_graph_stop(prtd->graph); 534 q6apm_unmap_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK); 535 q6apm_graph_close(prtd->graph); 536 snd_dma_free_pages(&prtd->dma_buffer); 537 prtd->graph = NULL; 538 kfree(prtd); 539 runtime->private_data = NULL; 540 541 return 0; 542 } 543 544 static int q6apm_dai_compr_get_caps(struct snd_soc_component *component, 545 struct snd_compr_stream *stream, 546 struct snd_compr_caps *caps) 547 { 548 caps->direction = SND_COMPRESS_PLAYBACK; 549 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; 550 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 551 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 552 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 553 caps->num_codecs = 3; 554 caps->codecs[0] = SND_AUDIOCODEC_MP3; 555 caps->codecs[1] = SND_AUDIOCODEC_AAC; 556 caps->codecs[2] = SND_AUDIOCODEC_FLAC; 557 558 return 0; 559 } 560 561 static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component, 562 struct snd_compr_stream *stream, 563 struct snd_compr_codec_caps *codec) 564 { 565 switch (codec->codec) { 566 case SND_AUDIOCODEC_MP3: 567 *codec = q6apm_compr_caps; 568 break; 569 default: 570 break; 571 } 572 573 return 0; 574 } 575 576 static int q6apm_dai_compr_pointer(struct snd_soc_component *component, 577 struct snd_compr_stream *stream, 578 struct snd_compr_tstamp *tstamp) 579 { 580 struct snd_compr_runtime *runtime = stream->runtime; 581 struct q6apm_dai_rtd *prtd = runtime->private_data; 582 unsigned long flags; 583 584 spin_lock_irqsave(&prtd->lock, flags); 585 tstamp->copied_total = prtd->copied_total; 586 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; 587 spin_unlock_irqrestore(&prtd->lock, flags); 588 589 return 0; 590 } 591 592 static int q6apm_dai_compr_trigger(struct snd_soc_component *component, 593 struct snd_compr_stream *stream, int cmd) 594 { 595 struct snd_compr_runtime *runtime = stream->runtime; 596 struct q6apm_dai_rtd *prtd = runtime->private_data; 597 int ret = 0; 598 599 switch (cmd) { 600 case SNDRV_PCM_TRIGGER_START: 601 case SNDRV_PCM_TRIGGER_RESUME: 602 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 603 ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP); 604 break; 605 case SNDRV_PCM_TRIGGER_STOP: 606 break; 607 case SNDRV_PCM_TRIGGER_SUSPEND: 608 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 609 break; 610 case SND_COMPR_TRIGGER_NEXT_TRACK: 611 prtd->next_track = true; 612 break; 613 case SND_COMPR_TRIGGER_DRAIN: 614 case SND_COMPR_TRIGGER_PARTIAL_DRAIN: 615 prtd->notify_on_drain = true; 616 break; 617 default: 618 ret = -EINVAL; 619 break; 620 } 621 622 return ret; 623 } 624 625 static int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream, 626 size_t count) 627 { 628 struct snd_compr_runtime *runtime = stream->runtime; 629 struct q6apm_dai_rtd *prtd = runtime->private_data; 630 unsigned long flags; 631 632 spin_lock_irqsave(&prtd->lock, flags); 633 prtd->bytes_received += count; 634 spin_unlock_irqrestore(&prtd->lock, flags); 635 636 return count; 637 } 638 639 static int q6apm_dai_compr_set_params(struct snd_soc_component *component, 640 struct snd_compr_stream *stream, 641 struct snd_compr_params *params) 642 { 643 struct snd_compr_runtime *runtime = stream->runtime; 644 struct q6apm_dai_rtd *prtd = runtime->private_data; 645 struct q6apm_dai_data *pdata; 646 struct audioreach_module_config cfg; 647 struct snd_codec *codec = ¶ms->codec; 648 int dir = stream->direction; 649 int ret; 650 651 pdata = snd_soc_component_get_drvdata(component); 652 if (!pdata) 653 return -EINVAL; 654 655 prtd->periods = runtime->fragments; 656 prtd->pcm_count = runtime->fragment_size; 657 prtd->pcm_size = runtime->fragments * runtime->fragment_size; 658 prtd->bits_per_sample = 16; 659 660 if (prtd->next_track != true) { 661 memcpy(&prtd->codec, codec, sizeof(*codec)); 662 663 ret = q6apm_set_real_module_id(component->dev, prtd->graph, codec->id); 664 if (ret) 665 return ret; 666 667 cfg.direction = dir; 668 cfg.sample_rate = codec->sample_rate; 669 cfg.num_channels = 2; 670 cfg.bit_width = prtd->bits_per_sample; 671 cfg.fmt = codec->id; 672 audioreach_set_default_channel_mapping(cfg.channel_map, 673 cfg.num_channels); 674 memcpy(&cfg.codec, codec, sizeof(*codec)); 675 676 ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg); 677 if (ret < 0) 678 return ret; 679 680 ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg); 681 if (ret) 682 return ret; 683 684 ret = q6apm_map_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK, 685 prtd->phys, (prtd->pcm_size / prtd->periods), 686 prtd->periods); 687 if (ret < 0) 688 return -ENOMEM; 689 690 ret = q6apm_graph_prepare(prtd->graph); 691 if (ret) 692 return ret; 693 694 ret = q6apm_graph_start(prtd->graph); 695 if (ret) 696 return ret; 697 698 } else { 699 cfg.direction = dir; 700 cfg.sample_rate = codec->sample_rate; 701 cfg.num_channels = 2; 702 cfg.bit_width = prtd->bits_per_sample; 703 cfg.fmt = codec->id; 704 memcpy(&cfg.codec, codec, sizeof(*codec)); 705 706 ret = audioreach_compr_set_param(prtd->graph, &cfg); 707 if (ret < 0) 708 return ret; 709 } 710 prtd->state = Q6APM_STREAM_RUNNING; 711 712 return 0; 713 } 714 715 static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component, 716 struct snd_compr_stream *stream, 717 struct snd_compr_metadata *metadata) 718 { 719 struct snd_compr_runtime *runtime = stream->runtime; 720 struct q6apm_dai_rtd *prtd = runtime->private_data; 721 int ret = 0; 722 723 switch (metadata->key) { 724 case SNDRV_COMPRESS_ENCODER_PADDING: 725 q6apm_remove_trailing_silence(component->dev, prtd->graph, 726 metadata->value[0]); 727 break; 728 case SNDRV_COMPRESS_ENCODER_DELAY: 729 q6apm_remove_initial_silence(component->dev, prtd->graph, 730 metadata->value[0]); 731 break; 732 default: 733 ret = -EINVAL; 734 break; 735 } 736 737 return ret; 738 } 739 740 static int q6apm_dai_compr_mmap(struct snd_soc_component *component, 741 struct snd_compr_stream *stream, 742 struct vm_area_struct *vma) 743 { 744 struct snd_compr_runtime *runtime = stream->runtime; 745 struct q6apm_dai_rtd *prtd = runtime->private_data; 746 struct device *dev = component->dev; 747 748 return dma_mmap_coherent(dev, vma, prtd->dma_buffer.area, prtd->dma_buffer.addr, 749 prtd->dma_buffer.bytes); 750 } 751 752 static int q6apm_compr_copy(struct snd_soc_component *component, 753 struct snd_compr_stream *stream, char __user *buf, 754 size_t count) 755 { 756 struct snd_compr_runtime *runtime = stream->runtime; 757 struct q6apm_dai_rtd *prtd = runtime->private_data; 758 void *dstn; 759 unsigned long flags; 760 size_t copy; 761 u32 wflags = 0; 762 u32 app_pointer; 763 u32 bytes_received; 764 uint32_t bytes_to_write; 765 int avail, bytes_in_flight = 0; 766 767 bytes_received = prtd->bytes_received; 768 769 /** 770 * Make sure that next track data pointer is aligned at 32 bit boundary 771 * This is a Mandatory requirement from DSP data buffers alignment 772 */ 773 if (prtd->next_track) 774 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count); 775 776 app_pointer = bytes_received/prtd->pcm_size; 777 app_pointer = bytes_received - (app_pointer * prtd->pcm_size); 778 dstn = prtd->dma_buffer.area + app_pointer; 779 780 if (count < prtd->pcm_size - app_pointer) { 781 if (copy_from_user(dstn, buf, count)) 782 return -EFAULT; 783 } else { 784 copy = prtd->pcm_size - app_pointer; 785 if (copy_from_user(dstn, buf, copy)) 786 return -EFAULT; 787 if (copy_from_user(prtd->dma_buffer.area, buf + copy, count - copy)) 788 return -EFAULT; 789 } 790 791 spin_lock_irqsave(&prtd->lock, flags); 792 bytes_in_flight = prtd->bytes_received - prtd->copied_total; 793 794 if (prtd->next_track) { 795 prtd->next_track = false; 796 prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count); 797 prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count); 798 } 799 800 prtd->bytes_received = bytes_received + count; 801 802 /* Kick off the data to dsp if its starving!! */ 803 if (prtd->state == Q6APM_STREAM_RUNNING && (bytes_in_flight == 0)) { 804 bytes_to_write = prtd->pcm_count; 805 avail = prtd->bytes_received - prtd->bytes_sent; 806 807 if (avail < prtd->pcm_count) 808 bytes_to_write = avail; 809 810 q6apm_write_async(prtd->graph, bytes_to_write, 0, 0, wflags); 811 prtd->bytes_sent += bytes_to_write; 812 } 813 814 spin_unlock_irqrestore(&prtd->lock, flags); 815 816 return count; 817 } 818 819 static const struct snd_compress_ops q6apm_dai_compress_ops = { 820 .open = q6apm_dai_compr_open, 821 .free = q6apm_dai_compr_free, 822 .get_caps = q6apm_dai_compr_get_caps, 823 .get_codec_caps = q6apm_dai_compr_get_codec_caps, 824 .pointer = q6apm_dai_compr_pointer, 825 .trigger = q6apm_dai_compr_trigger, 826 .ack = q6apm_dai_compr_ack, 827 .set_params = q6apm_dai_compr_set_params, 828 .set_metadata = q6apm_dai_compr_set_metadata, 829 .mmap = q6apm_dai_compr_mmap, 830 .copy = q6apm_compr_copy, 831 }; 832 833 static const struct snd_soc_component_driver q6apm_fe_dai_component = { 834 .name = DRV_NAME, 835 .open = q6apm_dai_open, 836 .close = q6apm_dai_close, 837 .prepare = q6apm_dai_prepare, 838 .pcm_construct = q6apm_dai_pcm_new, 839 .hw_params = q6apm_dai_hw_params, 840 .pointer = q6apm_dai_pointer, 841 .trigger = q6apm_dai_trigger, 842 .ack = q6apm_dai_ack, 843 .compress_ops = &q6apm_dai_compress_ops, 844 .use_dai_pcm_id = true, 845 }; 846 847 static int q6apm_dai_probe(struct platform_device *pdev) 848 { 849 struct device *dev = &pdev->dev; 850 struct device_node *node = dev->of_node; 851 struct q6apm_dai_data *pdata; 852 struct of_phandle_args args; 853 int rc; 854 855 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 856 if (!pdata) 857 return -ENOMEM; 858 859 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); 860 if (rc < 0) 861 pdata->sid = -1; 862 else 863 pdata->sid = args.args[0] & SID_MASK_DEFAULT; 864 865 dev_set_drvdata(dev, pdata); 866 867 return devm_snd_soc_register_component(dev, &q6apm_fe_dai_component, NULL, 0); 868 } 869 870 #ifdef CONFIG_OF 871 static const struct of_device_id q6apm_dai_device_id[] = { 872 { .compatible = "qcom,q6apm-dais" }, 873 {}, 874 }; 875 MODULE_DEVICE_TABLE(of, q6apm_dai_device_id); 876 #endif 877 878 static struct platform_driver q6apm_dai_platform_driver = { 879 .driver = { 880 .name = "q6apm-dai", 881 .of_match_table = of_match_ptr(q6apm_dai_device_id), 882 }, 883 .probe = q6apm_dai_probe, 884 }; 885 module_platform_driver(q6apm_dai_platform_driver); 886 887 MODULE_DESCRIPTION("Q6APM dai driver"); 888 MODULE_LICENSE("GPL"); 889