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/platform_device.h> 8 #include <linux/slab.h> 9 #include <sound/soc.h> 10 #include <sound/soc-dapm.h> 11 #include <linux/spinlock.h> 12 #include <sound/pcm.h> 13 #include <asm/dma.h> 14 #include <linux/dma-mapping.h> 15 #include <linux/of_device.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 4096 28 #define CAPTURE_MIN_PERIOD_SIZE 320 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 pos; /* Buffer position */ 68 unsigned int periods; 69 unsigned int bytes_sent; 70 unsigned int bytes_received; 71 unsigned int copied_total; 72 uint16_t bits_per_sample; 73 uint16_t source; /* Encoding source bit mask */ 74 uint16_t session_id; 75 bool next_track; 76 enum stream_state state; 77 struct q6apm_graph *graph; 78 spinlock_t lock; 79 uint32_t initial_samples_drop; 80 uint32_t trailing_samples_drop; 81 bool notify_on_drain; 82 }; 83 84 struct q6apm_dai_data { 85 long long sid; 86 }; 87 88 static struct snd_pcm_hardware q6apm_dai_hardware_capture = { 89 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | 90 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | 91 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 92 SNDRV_PCM_INFO_BATCH), 93 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), 94 .rates = SNDRV_PCM_RATE_8000_48000, 95 .rate_min = 8000, 96 .rate_max = 48000, 97 .channels_min = 2, 98 .channels_max = 4, 99 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, 100 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, 101 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, 102 .periods_min = CAPTURE_MIN_NUM_PERIODS, 103 .periods_max = CAPTURE_MAX_NUM_PERIODS, 104 .fifo_size = 0, 105 }; 106 107 static struct snd_pcm_hardware q6apm_dai_hardware_playback = { 108 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | 109 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | 110 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 111 SNDRV_PCM_INFO_BATCH), 112 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), 113 .rates = SNDRV_PCM_RATE_8000_192000, 114 .rate_min = 8000, 115 .rate_max = 192000, 116 .channels_min = 2, 117 .channels_max = 8, 118 .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE), 119 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, 120 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, 121 .periods_min = PLAYBACK_MIN_NUM_PERIODS, 122 .periods_max = PLAYBACK_MAX_NUM_PERIODS, 123 .fifo_size = 0, 124 }; 125 126 static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv) 127 { 128 struct q6apm_dai_rtd *prtd = priv; 129 struct snd_pcm_substream *substream = prtd->substream; 130 unsigned long flags; 131 132 switch (opcode) { 133 case APM_CLIENT_EVENT_CMD_EOS_DONE: 134 prtd->state = Q6APM_STREAM_STOPPED; 135 break; 136 case APM_CLIENT_EVENT_DATA_WRITE_DONE: 137 spin_lock_irqsave(&prtd->lock, flags); 138 prtd->pos += prtd->pcm_count; 139 spin_unlock_irqrestore(&prtd->lock, flags); 140 snd_pcm_period_elapsed(substream); 141 if (prtd->state == Q6APM_STREAM_RUNNING) 142 q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0); 143 144 break; 145 case APM_CLIENT_EVENT_DATA_READ_DONE: 146 spin_lock_irqsave(&prtd->lock, flags); 147 prtd->pos += prtd->pcm_count; 148 spin_unlock_irqrestore(&prtd->lock, flags); 149 snd_pcm_period_elapsed(substream); 150 if (prtd->state == Q6APM_STREAM_RUNNING) 151 q6apm_read(prtd->graph); 152 153 break; 154 default: 155 break; 156 } 157 } 158 159 static void event_handler_compr(uint32_t opcode, uint32_t token, 160 uint32_t *payload, void *priv) 161 { 162 struct q6apm_dai_rtd *prtd = priv; 163 struct snd_compr_stream *substream = prtd->cstream; 164 unsigned long flags; 165 uint32_t wflags = 0; 166 uint64_t avail; 167 uint32_t bytes_written, bytes_to_write; 168 bool is_last_buffer = false; 169 170 switch (opcode) { 171 case APM_CLIENT_EVENT_CMD_EOS_DONE: 172 spin_lock_irqsave(&prtd->lock, flags); 173 if (prtd->notify_on_drain) { 174 snd_compr_drain_notify(prtd->cstream); 175 prtd->notify_on_drain = false; 176 } else { 177 prtd->state = Q6APM_STREAM_STOPPED; 178 } 179 spin_unlock_irqrestore(&prtd->lock, flags); 180 break; 181 case APM_CLIENT_EVENT_DATA_WRITE_DONE: 182 spin_lock_irqsave(&prtd->lock, flags); 183 bytes_written = token >> APM_WRITE_TOKEN_LEN_SHIFT; 184 prtd->copied_total += bytes_written; 185 snd_compr_fragment_elapsed(substream); 186 187 if (prtd->state != Q6APM_STREAM_RUNNING) { 188 spin_unlock_irqrestore(&prtd->lock, flags); 189 break; 190 } 191 192 avail = prtd->bytes_received - prtd->bytes_sent; 193 194 if (avail > prtd->pcm_count) { 195 bytes_to_write = prtd->pcm_count; 196 } else { 197 if (substream->partial_drain || prtd->notify_on_drain) 198 is_last_buffer = true; 199 bytes_to_write = avail; 200 } 201 202 if (bytes_to_write) { 203 if (substream->partial_drain && is_last_buffer) 204 wflags |= APM_LAST_BUFFER_FLAG; 205 206 q6apm_write_async(prtd->graph, 207 bytes_to_write, 0, 0, wflags); 208 209 prtd->bytes_sent += bytes_to_write; 210 211 if (prtd->notify_on_drain && is_last_buffer) 212 audioreach_shared_memory_send_eos(prtd->graph); 213 } 214 215 spin_unlock_irqrestore(&prtd->lock, flags); 216 break; 217 default: 218 break; 219 } 220 } 221 222 static int q6apm_dai_prepare(struct snd_soc_component *component, 223 struct snd_pcm_substream *substream) 224 { 225 struct snd_pcm_runtime *runtime = substream->runtime; 226 struct q6apm_dai_rtd *prtd = runtime->private_data; 227 struct audioreach_module_config cfg; 228 struct device *dev = component->dev; 229 struct q6apm_dai_data *pdata; 230 int ret; 231 232 pdata = snd_soc_component_get_drvdata(component); 233 if (!pdata) 234 return -EINVAL; 235 236 if (!prtd || !prtd->graph) { 237 dev_err(dev, "%s: private data null or audio client freed\n", __func__); 238 return -EINVAL; 239 } 240 241 cfg.direction = substream->stream; 242 cfg.sample_rate = runtime->rate; 243 cfg.num_channels = runtime->channels; 244 cfg.bit_width = prtd->bits_per_sample; 245 cfg.fmt = SND_AUDIOCODEC_PCM; 246 247 if (prtd->state) { 248 /* clear the previous setup if any */ 249 q6apm_graph_stop(prtd->graph); 250 q6apm_unmap_memory_regions(prtd->graph, substream->stream); 251 } 252 253 prtd->pcm_count = snd_pcm_lib_period_bytes(substream); 254 prtd->pos = 0; 255 /* rate and channels are sent to audio driver */ 256 ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg); 257 if (ret < 0) { 258 dev_err(dev, "%s: q6apm_open_write failed\n", __func__); 259 return ret; 260 } 261 262 ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg); 263 if (ret < 0) 264 dev_err(dev, "%s: CMD Format block failed\n", __func__); 265 266 ret = q6apm_map_memory_regions(prtd->graph, substream->stream, prtd->phys, 267 (prtd->pcm_size / prtd->periods), prtd->periods); 268 269 if (ret < 0) { 270 dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", ret); 271 return -ENOMEM; 272 } 273 274 ret = q6apm_graph_prepare(prtd->graph); 275 if (ret) { 276 dev_err(dev, "Failed to prepare Graph %d\n", ret); 277 return ret; 278 } 279 280 ret = q6apm_graph_start(prtd->graph); 281 if (ret) { 282 dev_err(dev, "Failed to Start Graph %d\n", ret); 283 return ret; 284 } 285 286 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 287 int i; 288 /* Queue the buffers for Capture ONLY after graph is started */ 289 for (i = 0; i < runtime->periods; i++) 290 q6apm_read(prtd->graph); 291 292 } 293 294 /* Now that graph as been prepared and started update the internal state accordingly */ 295 prtd->state = Q6APM_STREAM_RUNNING; 296 297 return 0; 298 } 299 300 static int q6apm_dai_trigger(struct snd_soc_component *component, 301 struct snd_pcm_substream *substream, int cmd) 302 { 303 struct snd_pcm_runtime *runtime = substream->runtime; 304 struct q6apm_dai_rtd *prtd = runtime->private_data; 305 int ret = 0; 306 307 switch (cmd) { 308 case SNDRV_PCM_TRIGGER_START: 309 case SNDRV_PCM_TRIGGER_RESUME: 310 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 311 /* start writing buffers for playback only as we already queued capture buffers */ 312 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 313 ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0); 314 break; 315 case SNDRV_PCM_TRIGGER_STOP: 316 /* TODO support be handled via SoftPause Module */ 317 prtd->state = Q6APM_STREAM_STOPPED; 318 break; 319 case SNDRV_PCM_TRIGGER_SUSPEND: 320 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 321 break; 322 default: 323 ret = -EINVAL; 324 break; 325 } 326 327 return ret; 328 } 329 330 static int q6apm_dai_open(struct snd_soc_component *component, 331 struct snd_pcm_substream *substream) 332 { 333 struct snd_pcm_runtime *runtime = substream->runtime; 334 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 335 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_prtd, 0); 336 struct device *dev = component->dev; 337 struct q6apm_dai_data *pdata; 338 struct q6apm_dai_rtd *prtd; 339 int graph_id, ret; 340 341 graph_id = cpu_dai->driver->id; 342 343 pdata = snd_soc_component_get_drvdata(component); 344 if (!pdata) { 345 dev_err(dev, "Drv data not found ..\n"); 346 return -EINVAL; 347 } 348 349 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 350 if (prtd == NULL) 351 return -ENOMEM; 352 353 spin_lock_init(&prtd->lock); 354 prtd->substream = substream; 355 prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler, prtd, graph_id); 356 if (IS_ERR(prtd->graph)) { 357 dev_err(dev, "%s: Could not allocate memory\n", __func__); 358 ret = PTR_ERR(prtd->graph); 359 goto err; 360 } 361 362 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 363 runtime->hw = q6apm_dai_hardware_playback; 364 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 365 runtime->hw = q6apm_dai_hardware_capture; 366 367 /* Ensure that buffer size is a multiple of period size */ 368 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 369 if (ret < 0) { 370 dev_err(dev, "snd_pcm_hw_constraint_integer failed\n"); 371 goto err; 372 } 373 374 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 375 ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 376 BUFFER_BYTES_MIN, BUFFER_BYTES_MAX); 377 if (ret < 0) { 378 dev_err(dev, "constraint for buffer bytes min max ret = %d\n", ret); 379 goto err; 380 } 381 } 382 383 ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 384 if (ret < 0) { 385 dev_err(dev, "constraint for period bytes step ret = %d\n", ret); 386 goto err; 387 } 388 389 ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 390 if (ret < 0) { 391 dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret); 392 goto err; 393 } 394 395 runtime->private_data = prtd; 396 runtime->dma_bytes = BUFFER_BYTES_MAX; 397 if (pdata->sid < 0) 398 prtd->phys = substream->dma_buffer.addr; 399 else 400 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); 401 402 return 0; 403 err: 404 kfree(prtd); 405 406 return ret; 407 } 408 409 static int q6apm_dai_close(struct snd_soc_component *component, 410 struct snd_pcm_substream *substream) 411 { 412 struct snd_pcm_runtime *runtime = substream->runtime; 413 struct q6apm_dai_rtd *prtd = runtime->private_data; 414 415 if (prtd->state) { /* only stop graph that is started */ 416 q6apm_graph_stop(prtd->graph); 417 q6apm_unmap_memory_regions(prtd->graph, substream->stream); 418 } 419 420 q6apm_graph_close(prtd->graph); 421 prtd->graph = NULL; 422 kfree(prtd); 423 runtime->private_data = NULL; 424 425 return 0; 426 } 427 428 static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component, 429 struct snd_pcm_substream *substream) 430 { 431 struct snd_pcm_runtime *runtime = substream->runtime; 432 struct q6apm_dai_rtd *prtd = runtime->private_data; 433 snd_pcm_uframes_t ptr; 434 unsigned long flags; 435 436 spin_lock_irqsave(&prtd->lock, flags); 437 if (prtd->pos == prtd->pcm_size) 438 prtd->pos = 0; 439 440 ptr = bytes_to_frames(runtime, prtd->pos); 441 spin_unlock_irqrestore(&prtd->lock, flags); 442 443 return ptr; 444 } 445 446 static int q6apm_dai_hw_params(struct snd_soc_component *component, 447 struct snd_pcm_substream *substream, 448 struct snd_pcm_hw_params *params) 449 { 450 struct snd_pcm_runtime *runtime = substream->runtime; 451 struct q6apm_dai_rtd *prtd = runtime->private_data; 452 453 prtd->pcm_size = params_buffer_bytes(params); 454 prtd->periods = params_periods(params); 455 456 switch (params_format(params)) { 457 case SNDRV_PCM_FORMAT_S16_LE: 458 prtd->bits_per_sample = 16; 459 break; 460 case SNDRV_PCM_FORMAT_S24_LE: 461 prtd->bits_per_sample = 24; 462 break; 463 default: 464 return -EINVAL; 465 } 466 467 return 0; 468 } 469 470 static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) 471 { 472 int size = BUFFER_BYTES_MAX; 473 474 return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, component->dev, size); 475 } 476 477 static int q6apm_dai_compr_open(struct snd_soc_component *component, 478 struct snd_compr_stream *stream) 479 { 480 struct snd_soc_pcm_runtime *rtd = stream->private_data; 481 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 482 struct snd_compr_runtime *runtime = stream->runtime; 483 struct q6apm_dai_rtd *prtd; 484 struct q6apm_dai_data *pdata; 485 struct device *dev = component->dev; 486 int ret, size; 487 int graph_id; 488 489 graph_id = cpu_dai->driver->id; 490 pdata = snd_soc_component_get_drvdata(component); 491 if (!pdata) 492 return -EINVAL; 493 494 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 495 if (prtd == NULL) 496 return -ENOMEM; 497 498 prtd->cstream = stream; 499 prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler_compr, prtd, graph_id); 500 if (IS_ERR(prtd->graph)) { 501 ret = PTR_ERR(prtd->graph); 502 kfree(prtd); 503 return ret; 504 } 505 506 runtime->private_data = prtd; 507 runtime->dma_bytes = BUFFER_BYTES_MAX; 508 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 509 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &prtd->dma_buffer); 510 if (ret) 511 return ret; 512 513 if (pdata->sid < 0) 514 prtd->phys = prtd->dma_buffer.addr; 515 else 516 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); 517 518 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); 519 spin_lock_init(&prtd->lock); 520 521 q6apm_enable_compress_module(dev, prtd->graph, true); 522 return 0; 523 } 524 525 static int q6apm_dai_compr_free(struct snd_soc_component *component, 526 struct snd_compr_stream *stream) 527 { 528 struct snd_compr_runtime *runtime = stream->runtime; 529 struct q6apm_dai_rtd *prtd = runtime->private_data; 530 531 q6apm_graph_stop(prtd->graph); 532 q6apm_unmap_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK); 533 q6apm_graph_close(prtd->graph); 534 snd_dma_free_pages(&prtd->dma_buffer); 535 prtd->graph = NULL; 536 kfree(prtd); 537 runtime->private_data = NULL; 538 539 return 0; 540 } 541 542 static int q6apm_dai_compr_get_caps(struct snd_soc_component *component, 543 struct snd_compr_stream *stream, 544 struct snd_compr_caps *caps) 545 { 546 caps->direction = SND_COMPRESS_PLAYBACK; 547 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; 548 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 549 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 550 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 551 caps->num_codecs = 3; 552 caps->codecs[0] = SND_AUDIOCODEC_MP3; 553 caps->codecs[1] = SND_AUDIOCODEC_AAC; 554 caps->codecs[2] = SND_AUDIOCODEC_FLAC; 555 556 return 0; 557 } 558 559 static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component, 560 struct snd_compr_stream *stream, 561 struct snd_compr_codec_caps *codec) 562 { 563 switch (codec->codec) { 564 case SND_AUDIOCODEC_MP3: 565 *codec = q6apm_compr_caps; 566 break; 567 default: 568 break; 569 } 570 571 return 0; 572 } 573 574 static int q6apm_dai_compr_pointer(struct snd_soc_component *component, 575 struct snd_compr_stream *stream, 576 struct snd_compr_tstamp *tstamp) 577 { 578 struct snd_compr_runtime *runtime = stream->runtime; 579 struct q6apm_dai_rtd *prtd = runtime->private_data; 580 unsigned long flags; 581 582 spin_lock_irqsave(&prtd->lock, flags); 583 tstamp->copied_total = prtd->copied_total; 584 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; 585 spin_unlock_irqrestore(&prtd->lock, flags); 586 587 return 0; 588 } 589 590 static int q6apm_dai_compr_trigger(struct snd_soc_component *component, 591 struct snd_compr_stream *stream, int cmd) 592 { 593 struct snd_compr_runtime *runtime = stream->runtime; 594 struct q6apm_dai_rtd *prtd = runtime->private_data; 595 int ret = 0; 596 597 switch (cmd) { 598 case SNDRV_PCM_TRIGGER_START: 599 case SNDRV_PCM_TRIGGER_RESUME: 600 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 601 ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP); 602 break; 603 case SNDRV_PCM_TRIGGER_STOP: 604 break; 605 case SNDRV_PCM_TRIGGER_SUSPEND: 606 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 607 break; 608 case SND_COMPR_TRIGGER_NEXT_TRACK: 609 prtd->next_track = true; 610 break; 611 case SND_COMPR_TRIGGER_DRAIN: 612 case SND_COMPR_TRIGGER_PARTIAL_DRAIN: 613 prtd->notify_on_drain = true; 614 break; 615 default: 616 ret = -EINVAL; 617 break; 618 } 619 620 return ret; 621 } 622 623 static int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream, 624 size_t count) 625 { 626 struct snd_compr_runtime *runtime = stream->runtime; 627 struct q6apm_dai_rtd *prtd = runtime->private_data; 628 unsigned long flags; 629 630 spin_lock_irqsave(&prtd->lock, flags); 631 prtd->bytes_received += count; 632 spin_unlock_irqrestore(&prtd->lock, flags); 633 634 return count; 635 } 636 637 static int q6apm_dai_compr_set_params(struct snd_soc_component *component, 638 struct snd_compr_stream *stream, 639 struct snd_compr_params *params) 640 { 641 struct snd_compr_runtime *runtime = stream->runtime; 642 struct q6apm_dai_rtd *prtd = runtime->private_data; 643 struct q6apm_dai_data *pdata; 644 struct audioreach_module_config cfg; 645 struct snd_codec *codec = ¶ms->codec; 646 int dir = stream->direction; 647 int ret; 648 649 pdata = snd_soc_component_get_drvdata(component); 650 if (!pdata) 651 return -EINVAL; 652 653 prtd->periods = runtime->fragments; 654 prtd->pcm_count = runtime->fragment_size; 655 prtd->pcm_size = runtime->fragments * runtime->fragment_size; 656 prtd->bits_per_sample = 16; 657 658 prtd->pos = 0; 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 memcpy(&cfg.codec, codec, sizeof(*codec)); 673 674 ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg); 675 if (ret < 0) 676 return ret; 677 678 ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg); 679 if (ret) 680 return ret; 681 682 ret = q6apm_map_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK, 683 prtd->phys, (prtd->pcm_size / prtd->periods), 684 prtd->periods); 685 if (ret < 0) 686 return -ENOMEM; 687 688 ret = q6apm_graph_prepare(prtd->graph); 689 if (ret) 690 return ret; 691 692 ret = q6apm_graph_start(prtd->graph); 693 if (ret) 694 return ret; 695 696 } else { 697 cfg.direction = dir; 698 cfg.sample_rate = codec->sample_rate; 699 cfg.num_channels = 2; 700 cfg.bit_width = prtd->bits_per_sample; 701 cfg.fmt = codec->id; 702 memcpy(&cfg.codec, codec, sizeof(*codec)); 703 704 ret = audioreach_compr_set_param(prtd->graph, &cfg); 705 if (ret < 0) 706 return ret; 707 } 708 prtd->state = Q6APM_STREAM_RUNNING; 709 710 return 0; 711 } 712 713 static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component, 714 struct snd_compr_stream *stream, 715 struct snd_compr_metadata *metadata) 716 { 717 struct snd_compr_runtime *runtime = stream->runtime; 718 struct q6apm_dai_rtd *prtd = runtime->private_data; 719 int ret = 0; 720 721 switch (metadata->key) { 722 case SNDRV_COMPRESS_ENCODER_PADDING: 723 prtd->trailing_samples_drop = metadata->value[0]; 724 q6apm_remove_trailing_silence(component->dev, prtd->graph, 725 prtd->trailing_samples_drop); 726 break; 727 case SNDRV_COMPRESS_ENCODER_DELAY: 728 prtd->initial_samples_drop = metadata->value[0]; 729 q6apm_remove_initial_silence(component->dev, prtd->graph, 730 prtd->initial_samples_drop); 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 .compress_ops = &q6apm_dai_compress_ops, 843 }; 844 845 static int q6apm_dai_probe(struct platform_device *pdev) 846 { 847 struct device *dev = &pdev->dev; 848 struct device_node *node = dev->of_node; 849 struct q6apm_dai_data *pdata; 850 struct of_phandle_args args; 851 int rc; 852 853 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 854 if (!pdata) 855 return -ENOMEM; 856 857 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); 858 if (rc < 0) 859 pdata->sid = -1; 860 else 861 pdata->sid = args.args[0] & SID_MASK_DEFAULT; 862 863 dev_set_drvdata(dev, pdata); 864 865 return devm_snd_soc_register_component(dev, &q6apm_fe_dai_component, NULL, 0); 866 } 867 868 #ifdef CONFIG_OF 869 static const struct of_device_id q6apm_dai_device_id[] = { 870 { .compatible = "qcom,q6apm-dais" }, 871 {}, 872 }; 873 MODULE_DEVICE_TABLE(of, q6apm_dai_device_id); 874 #endif 875 876 static struct platform_driver q6apm_dai_platform_driver = { 877 .driver = { 878 .name = "q6apm-dai", 879 .of_match_table = of_match_ptr(q6apm_dai_device_id), 880 }, 881 .probe = q6apm_dai_probe, 882 }; 883 module_platform_driver(q6apm_dai_platform_driver); 884 885 MODULE_DESCRIPTION("Q6APM dai driver"); 886 MODULE_LICENSE("GPL"); 887