1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // Copyright(c) 2020 Intel Corporation. All rights reserved. 4 // 5 // Author: Cezary Rojewski <cezary.rojewski@intel.com> 6 // 7 8 #include <linux/pm_runtime.h> 9 #include <sound/soc.h> 10 #include <sound/pcm_params.h> 11 #include <uapi/sound/tlv.h> 12 #include "core.h" 13 #include "messages.h" 14 15 struct catpt_stream_template { 16 enum catpt_path_id path_id; 17 enum catpt_stream_type type; 18 u32 persistent_size; 19 u8 num_entries; 20 struct catpt_module_entry entries[]; 21 }; 22 23 static struct catpt_stream_template system_pb = { 24 .path_id = CATPT_PATH_SSP0_OUT, 25 .type = CATPT_STRM_TYPE_SYSTEM, 26 .num_entries = 1, 27 .entries = {{ CATPT_MODID_PCM_SYSTEM, 0 }}, 28 }; 29 30 static struct catpt_stream_template system_cp = { 31 .path_id = CATPT_PATH_SSP0_IN, 32 .type = CATPT_STRM_TYPE_CAPTURE, 33 .num_entries = 1, 34 .entries = {{ CATPT_MODID_PCM_CAPTURE, 0 }}, 35 }; 36 37 static struct catpt_stream_template offload_pb = { 38 .path_id = CATPT_PATH_SSP0_OUT, 39 .type = CATPT_STRM_TYPE_RENDER, 40 .num_entries = 1, 41 .entries = {{ CATPT_MODID_PCM, 0 }}, 42 }; 43 44 static struct catpt_stream_template loopback_cp = { 45 .path_id = CATPT_PATH_SSP0_OUT, 46 .type = CATPT_STRM_TYPE_LOOPBACK, 47 .num_entries = 1, 48 .entries = {{ CATPT_MODID_PCM_REFERENCE, 0 }}, 49 }; 50 51 static struct catpt_stream_template bluetooth_pb = { 52 .path_id = CATPT_PATH_SSP1_OUT, 53 .type = CATPT_STRM_TYPE_BLUETOOTH_RENDER, 54 .num_entries = 1, 55 .entries = {{ CATPT_MODID_BLUETOOTH_RENDER, 0 }}, 56 }; 57 58 static struct catpt_stream_template bluetooth_cp = { 59 .path_id = CATPT_PATH_SSP1_IN, 60 .type = CATPT_STRM_TYPE_BLUETOOTH_CAPTURE, 61 .num_entries = 1, 62 .entries = {{ CATPT_MODID_BLUETOOTH_CAPTURE, 0 }}, 63 }; 64 65 static struct catpt_stream_template *catpt_topology[] = { 66 [CATPT_STRM_TYPE_RENDER] = &offload_pb, 67 [CATPT_STRM_TYPE_SYSTEM] = &system_pb, 68 [CATPT_STRM_TYPE_CAPTURE] = &system_cp, 69 [CATPT_STRM_TYPE_LOOPBACK] = &loopback_cp, 70 [CATPT_STRM_TYPE_BLUETOOTH_RENDER] = &bluetooth_pb, 71 [CATPT_STRM_TYPE_BLUETOOTH_CAPTURE] = &bluetooth_cp, 72 }; 73 74 static struct catpt_stream_template * 75 catpt_get_stream_template(struct snd_pcm_substream *substream) 76 { 77 struct snd_soc_pcm_runtime *rtm = substream->private_data; 78 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtm, 0); 79 enum catpt_stream_type type; 80 81 type = cpu_dai->driver->id; 82 83 /* account for capture in bidirectional dais */ 84 switch (type) { 85 case CATPT_STRM_TYPE_SYSTEM: 86 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 87 type = CATPT_STRM_TYPE_CAPTURE; 88 break; 89 case CATPT_STRM_TYPE_BLUETOOTH_RENDER: 90 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 91 type = CATPT_STRM_TYPE_BLUETOOTH_CAPTURE; 92 break; 93 default: 94 break; 95 }; 96 97 return catpt_topology[type]; 98 } 99 100 struct catpt_stream_runtime * 101 catpt_stream_find(struct catpt_dev *cdev, u8 stream_hw_id) 102 { 103 struct catpt_stream_runtime *pos, *result = NULL; 104 105 spin_lock(&cdev->list_lock); 106 list_for_each_entry(pos, &cdev->stream_list, node) { 107 if (pos->info.stream_hw_id == stream_hw_id) { 108 result = pos; 109 break; 110 } 111 } 112 113 spin_unlock(&cdev->list_lock); 114 return result; 115 } 116 117 static u32 catpt_stream_read_position(struct catpt_dev *cdev, 118 struct catpt_stream_runtime *stream) 119 { 120 u32 pos; 121 122 memcpy_fromio(&pos, cdev->lpe_ba + stream->info.read_pos_regaddr, 123 sizeof(pos)); 124 return pos; 125 } 126 127 static u32 catpt_stream_volume(struct catpt_dev *cdev, 128 struct catpt_stream_runtime *stream, u32 channel) 129 { 130 u32 volume, offset; 131 132 if (channel >= CATPT_CHANNELS_MAX) 133 channel = 0; 134 135 offset = stream->info.volume_regaddr[channel]; 136 memcpy_fromio(&volume, cdev->lpe_ba + offset, sizeof(volume)); 137 return volume; 138 } 139 140 static u32 catpt_mixer_volume(struct catpt_dev *cdev, 141 struct catpt_mixer_stream_info *info, u32 channel) 142 { 143 u32 volume, offset; 144 145 if (channel >= CATPT_CHANNELS_MAX) 146 channel = 0; 147 148 offset = info->volume_regaddr[channel]; 149 memcpy_fromio(&volume, cdev->lpe_ba + offset, sizeof(volume)); 150 return volume; 151 } 152 153 static void catpt_arrange_page_table(struct snd_pcm_substream *substream, 154 struct snd_dma_buffer *pgtbl) 155 { 156 struct snd_pcm_runtime *rtm = substream->runtime; 157 struct snd_dma_buffer *databuf = snd_pcm_get_dma_buf(substream); 158 int i, pages; 159 160 pages = snd_sgbuf_aligned_pages(rtm->dma_bytes); 161 162 for (i = 0; i < pages; i++) { 163 u32 pfn, offset; 164 u32 *page_table; 165 166 pfn = PFN_DOWN(snd_sgbuf_get_addr(databuf, i * PAGE_SIZE)); 167 /* incrementing by 2 on even and 3 on odd */ 168 offset = ((i << 2) + i) >> 1; 169 page_table = (u32 *)(pgtbl->area + offset); 170 171 if (i & 1) 172 *page_table |= (pfn << 4); 173 else 174 *page_table |= pfn; 175 } 176 } 177 178 static u32 catpt_get_channel_map(enum catpt_channel_config config) 179 { 180 switch (config) { 181 case CATPT_CHANNEL_CONFIG_MONO: 182 return GENMASK(31, 4) | CATPT_CHANNEL_CENTER; 183 184 case CATPT_CHANNEL_CONFIG_STEREO: 185 return GENMASK(31, 8) | CATPT_CHANNEL_LEFT 186 | (CATPT_CHANNEL_RIGHT << 4); 187 188 case CATPT_CHANNEL_CONFIG_2_POINT_1: 189 return GENMASK(31, 12) | CATPT_CHANNEL_LEFT 190 | (CATPT_CHANNEL_RIGHT << 4) 191 | (CATPT_CHANNEL_LFE << 8); 192 193 case CATPT_CHANNEL_CONFIG_3_POINT_0: 194 return GENMASK(31, 12) | CATPT_CHANNEL_LEFT 195 | (CATPT_CHANNEL_CENTER << 4) 196 | (CATPT_CHANNEL_RIGHT << 8); 197 198 case CATPT_CHANNEL_CONFIG_3_POINT_1: 199 return GENMASK(31, 16) | CATPT_CHANNEL_LEFT 200 | (CATPT_CHANNEL_CENTER << 4) 201 | (CATPT_CHANNEL_RIGHT << 8) 202 | (CATPT_CHANNEL_LFE << 12); 203 204 case CATPT_CHANNEL_CONFIG_QUATRO: 205 return GENMASK(31, 16) | CATPT_CHANNEL_LEFT 206 | (CATPT_CHANNEL_RIGHT << 4) 207 | (CATPT_CHANNEL_LEFT_SURROUND << 8) 208 | (CATPT_CHANNEL_RIGHT_SURROUND << 12); 209 210 case CATPT_CHANNEL_CONFIG_4_POINT_0: 211 return GENMASK(31, 16) | CATPT_CHANNEL_LEFT 212 | (CATPT_CHANNEL_CENTER << 4) 213 | (CATPT_CHANNEL_RIGHT << 8) 214 | (CATPT_CHANNEL_CENTER_SURROUND << 12); 215 216 case CATPT_CHANNEL_CONFIG_5_POINT_0: 217 return GENMASK(31, 20) | CATPT_CHANNEL_LEFT 218 | (CATPT_CHANNEL_CENTER << 4) 219 | (CATPT_CHANNEL_RIGHT << 8) 220 | (CATPT_CHANNEL_LEFT_SURROUND << 12) 221 | (CATPT_CHANNEL_RIGHT_SURROUND << 16); 222 223 case CATPT_CHANNEL_CONFIG_5_POINT_1: 224 return GENMASK(31, 24) | CATPT_CHANNEL_CENTER 225 | (CATPT_CHANNEL_LEFT << 4) 226 | (CATPT_CHANNEL_RIGHT << 8) 227 | (CATPT_CHANNEL_LEFT_SURROUND << 12) 228 | (CATPT_CHANNEL_RIGHT_SURROUND << 16) 229 | (CATPT_CHANNEL_LFE << 20); 230 231 case CATPT_CHANNEL_CONFIG_DUAL_MONO: 232 return GENMASK(31, 8) | CATPT_CHANNEL_LEFT 233 | (CATPT_CHANNEL_LEFT << 4); 234 235 default: 236 return U32_MAX; 237 } 238 } 239 240 static enum catpt_channel_config catpt_get_channel_config(u32 num_channels) 241 { 242 switch (num_channels) { 243 case 6: 244 return CATPT_CHANNEL_CONFIG_5_POINT_1; 245 case 5: 246 return CATPT_CHANNEL_CONFIG_5_POINT_0; 247 case 4: 248 return CATPT_CHANNEL_CONFIG_QUATRO; 249 case 3: 250 return CATPT_CHANNEL_CONFIG_2_POINT_1; 251 case 1: 252 return CATPT_CHANNEL_CONFIG_MONO; 253 case 2: 254 default: 255 return CATPT_CHANNEL_CONFIG_STEREO; 256 } 257 } 258 259 static int catpt_dai_startup(struct snd_pcm_substream *substream, 260 struct snd_soc_dai *dai) 261 { 262 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 263 struct catpt_stream_template *template; 264 struct catpt_stream_runtime *stream; 265 struct resource *res; 266 int ret; 267 268 template = catpt_get_stream_template(substream); 269 270 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 271 if (!stream) 272 return -ENOMEM; 273 274 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, cdev->dev, PAGE_SIZE, 275 &stream->pgtbl); 276 if (ret) 277 goto err_pgtbl; 278 279 res = catpt_request_region(&cdev->dram, template->persistent_size); 280 if (!res) { 281 ret = -EBUSY; 282 goto err_request; 283 } 284 285 catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); 286 287 stream->template = template; 288 stream->persistent = res; 289 stream->substream = substream; 290 INIT_LIST_HEAD(&stream->node); 291 snd_soc_dai_set_dma_data(dai, substream, stream); 292 293 spin_lock(&cdev->list_lock); 294 list_add_tail(&stream->node, &cdev->stream_list); 295 spin_unlock(&cdev->list_lock); 296 297 return 0; 298 299 err_request: 300 snd_dma_free_pages(&stream->pgtbl); 301 err_pgtbl: 302 kfree(stream); 303 return ret; 304 } 305 306 static void catpt_dai_shutdown(struct snd_pcm_substream *substream, 307 struct snd_soc_dai *dai) 308 { 309 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 310 struct catpt_stream_runtime *stream; 311 312 stream = snd_soc_dai_get_dma_data(dai, substream); 313 314 spin_lock(&cdev->list_lock); 315 list_del(&stream->node); 316 spin_unlock(&cdev->list_lock); 317 318 release_resource(stream->persistent); 319 kfree(stream->persistent); 320 catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask); 321 322 snd_dma_free_pages(&stream->pgtbl); 323 kfree(stream); 324 snd_soc_dai_set_dma_data(dai, substream, NULL); 325 } 326 327 static int catpt_dai_hw_params(struct snd_pcm_substream *substream, 328 struct snd_pcm_hw_params *params, 329 struct snd_soc_dai *dai) 330 { 331 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 332 struct catpt_stream_runtime *stream; 333 struct catpt_audio_format afmt; 334 struct catpt_ring_info rinfo; 335 struct snd_pcm_runtime *rtm = substream->runtime; 336 struct snd_dma_buffer *dmab; 337 int ret; 338 339 stream = snd_soc_dai_get_dma_data(dai, substream); 340 if (stream->allocated) 341 return 0; 342 343 memset(&afmt, 0, sizeof(afmt)); 344 afmt.sample_rate = params_rate(params); 345 afmt.bit_depth = params_physical_width(params); 346 afmt.valid_bit_depth = params_width(params); 347 afmt.num_channels = params_channels(params); 348 afmt.channel_config = catpt_get_channel_config(afmt.num_channels); 349 afmt.channel_map = catpt_get_channel_map(afmt.channel_config); 350 afmt.interleaving = CATPT_INTERLEAVING_PER_CHANNEL; 351 352 dmab = snd_pcm_get_dma_buf(substream); 353 catpt_arrange_page_table(substream, &stream->pgtbl); 354 355 memset(&rinfo, 0, sizeof(rinfo)); 356 rinfo.page_table_addr = stream->pgtbl.addr; 357 rinfo.num_pages = DIV_ROUND_UP(rtm->dma_bytes, PAGE_SIZE); 358 rinfo.size = rtm->dma_bytes; 359 rinfo.offset = 0; 360 rinfo.ring_first_page_pfn = PFN_DOWN(snd_sgbuf_get_addr(dmab, 0)); 361 362 ret = catpt_ipc_alloc_stream(cdev, stream->template->path_id, 363 stream->template->type, 364 &afmt, &rinfo, 365 stream->template->num_entries, 366 stream->template->entries, 367 stream->persistent, 368 cdev->scratch, 369 &stream->info); 370 if (ret) 371 return CATPT_IPC_ERROR(ret); 372 373 stream->allocated = true; 374 return 0; 375 } 376 377 static int catpt_dai_hw_free(struct snd_pcm_substream *substream, 378 struct snd_soc_dai *dai) 379 { 380 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 381 struct catpt_stream_runtime *stream; 382 383 stream = snd_soc_dai_get_dma_data(dai, substream); 384 if (!stream->allocated) 385 return 0; 386 387 catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id); 388 catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); 389 390 stream->allocated = false; 391 return 0; 392 } 393 394 static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol); 395 396 static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, 397 struct catpt_stream_runtime *stream) 398 { 399 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 400 struct snd_soc_component *component = dai->component; 401 struct snd_kcontrol *pos, *kctl = NULL; 402 const char *name; 403 int ret; 404 u32 id = stream->info.stream_hw_id; 405 406 /* only selected streams have individual controls */ 407 switch (id) { 408 case CATPT_PIN_ID_OFFLOAD1: 409 name = "Media0 Playback Volume"; 410 break; 411 case CATPT_PIN_ID_OFFLOAD2: 412 name = "Media1 Playback Volume"; 413 break; 414 case CATPT_PIN_ID_CAPTURE1: 415 name = "Mic Capture Volume"; 416 break; 417 case CATPT_PIN_ID_REFERENCE: 418 name = "Loopback Mute"; 419 break; 420 default: 421 return 0; 422 }; 423 424 list_for_each_entry(pos, &component->card->snd_card->controls, list) { 425 if (pos->private_data == component && 426 !strncmp(name, pos->id.name, sizeof(pos->id.name))) { 427 kctl = pos; 428 break; 429 } 430 } 431 if (!kctl) 432 return -ENOENT; 433 434 if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK) 435 return catpt_set_dspvol(cdev, id, (long *)kctl->private_value); 436 ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value); 437 if (ret) 438 return CATPT_IPC_ERROR(ret); 439 return 0; 440 } 441 442 static int catpt_dai_prepare(struct snd_pcm_substream *substream, 443 struct snd_soc_dai *dai) 444 { 445 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 446 struct catpt_stream_runtime *stream; 447 int ret; 448 449 stream = snd_soc_dai_get_dma_data(dai, substream); 450 if (stream->prepared) 451 return 0; 452 453 ret = catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id); 454 if (ret) 455 return CATPT_IPC_ERROR(ret); 456 457 ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id); 458 if (ret) 459 return CATPT_IPC_ERROR(ret); 460 461 ret = catpt_dsp_update_lpclock(cdev); 462 if (ret) 463 return ret; 464 465 ret = catpt_dai_apply_usettings(dai, stream); 466 if (ret) 467 return ret; 468 469 stream->prepared = true; 470 return 0; 471 } 472 473 static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd, 474 struct snd_soc_dai *dai) 475 { 476 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 477 struct catpt_stream_runtime *stream; 478 struct snd_pcm_runtime *runtime = substream->runtime; 479 snd_pcm_uframes_t pos; 480 int ret; 481 482 stream = snd_soc_dai_get_dma_data(dai, substream); 483 484 switch (cmd) { 485 case SNDRV_PCM_TRIGGER_START: 486 /* only offload is set_write_pos driven */ 487 if (stream->template->type != CATPT_STRM_TYPE_RENDER) 488 goto resume_stream; 489 490 pos = frames_to_bytes(runtime, runtime->start_threshold); 491 /* 492 * Dsp operates on buffer halves, thus max 2x set_write_pos 493 * (entire buffer filled) prior to stream start. 494 */ 495 ret = catpt_ipc_set_write_pos(cdev, stream->info.stream_hw_id, 496 pos, false, false); 497 if (ret) 498 return CATPT_IPC_ERROR(ret); 499 fallthrough; 500 case SNDRV_PCM_TRIGGER_RESUME: 501 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 502 resume_stream: 503 ret = catpt_ipc_resume_stream(cdev, stream->info.stream_hw_id); 504 if (ret) 505 return CATPT_IPC_ERROR(ret); 506 break; 507 508 case SNDRV_PCM_TRIGGER_STOP: 509 stream->prepared = false; 510 catpt_dsp_update_lpclock(cdev); 511 fallthrough; 512 case SNDRV_PCM_TRIGGER_SUSPEND: 513 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 514 ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id); 515 if (ret) 516 return CATPT_IPC_ERROR(ret); 517 break; 518 519 default: 520 break; 521 } 522 523 return 0; 524 } 525 526 void catpt_stream_update_position(struct catpt_dev *cdev, 527 struct catpt_stream_runtime *stream, 528 struct catpt_notify_position *pos) 529 { 530 struct snd_pcm_substream *substream = stream->substream; 531 struct snd_pcm_runtime *r = substream->runtime; 532 snd_pcm_uframes_t dsppos, newpos; 533 int ret; 534 535 dsppos = bytes_to_frames(r, pos->stream_position); 536 537 /* only offload is set_write_pos driven */ 538 if (stream->template->type != CATPT_STRM_TYPE_RENDER) 539 goto exit; 540 541 if (dsppos >= r->buffer_size / 2) 542 newpos = r->buffer_size / 2; 543 else 544 newpos = 0; 545 /* 546 * Dsp operates on buffer halves, thus on every notify position 547 * (buffer half consumed) update wp to allow stream progression. 548 */ 549 ret = catpt_ipc_set_write_pos(cdev, stream->info.stream_hw_id, 550 frames_to_bytes(r, newpos), 551 false, false); 552 if (ret) { 553 dev_err(cdev->dev, "update position for stream %d failed: %d\n", 554 stream->info.stream_hw_id, ret); 555 return; 556 } 557 exit: 558 snd_pcm_period_elapsed(substream); 559 } 560 561 /* 200 ms for 2 32-bit channels at 48kHz (native format) */ 562 #define CATPT_BUFFER_MAX_SIZE 76800 563 #define CATPT_PCM_PERIODS_MAX 4 564 #define CATPT_PCM_PERIODS_MIN 2 565 566 static const struct snd_pcm_hardware catpt_pcm_hardware = { 567 .info = SNDRV_PCM_INFO_MMAP | 568 SNDRV_PCM_INFO_MMAP_VALID | 569 SNDRV_PCM_INFO_INTERLEAVED | 570 SNDRV_PCM_INFO_PAUSE | 571 SNDRV_PCM_INFO_RESUME | 572 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, 573 .formats = SNDRV_PCM_FMTBIT_S16_LE | 574 SNDRV_PCM_FMTBIT_S24_LE | 575 SNDRV_PCM_FMTBIT_S32_LE, 576 .period_bytes_min = PAGE_SIZE, 577 .period_bytes_max = CATPT_BUFFER_MAX_SIZE / CATPT_PCM_PERIODS_MIN, 578 .periods_min = CATPT_PCM_PERIODS_MIN, 579 .periods_max = CATPT_PCM_PERIODS_MAX, 580 .buffer_bytes_max = CATPT_BUFFER_MAX_SIZE, 581 }; 582 583 static int catpt_component_pcm_construct(struct snd_soc_component *component, 584 struct snd_soc_pcm_runtime *rtm) 585 { 586 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 587 588 snd_pcm_set_managed_buffer_all(rtm->pcm, SNDRV_DMA_TYPE_DEV_SG, 589 cdev->dev, 590 catpt_pcm_hardware.buffer_bytes_max, 591 catpt_pcm_hardware.buffer_bytes_max); 592 593 return 0; 594 } 595 596 static int catpt_component_open(struct snd_soc_component *component, 597 struct snd_pcm_substream *substream) 598 { 599 struct snd_soc_pcm_runtime *rtm = substream->private_data; 600 601 if (rtm->dai_link->no_pcm) 602 return 0; 603 snd_soc_set_runtime_hwparams(substream, &catpt_pcm_hardware); 604 return 0; 605 } 606 607 static snd_pcm_uframes_t 608 catpt_component_pointer(struct snd_soc_component *component, 609 struct snd_pcm_substream *substream) 610 { 611 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 612 struct catpt_stream_runtime *stream; 613 struct snd_soc_pcm_runtime *rtm = substream->private_data; 614 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtm, 0); 615 u32 pos; 616 617 if (rtm->dai_link->no_pcm) 618 return 0; 619 620 stream = snd_soc_dai_get_dma_data(cpu_dai, substream); 621 pos = catpt_stream_read_position(cdev, stream); 622 623 return bytes_to_frames(substream->runtime, pos); 624 } 625 626 static const struct snd_soc_dai_ops catpt_fe_dai_ops = { 627 .startup = catpt_dai_startup, 628 .shutdown = catpt_dai_shutdown, 629 .hw_params = catpt_dai_hw_params, 630 .hw_free = catpt_dai_hw_free, 631 .prepare = catpt_dai_prepare, 632 .trigger = catpt_dai_trigger, 633 }; 634 635 static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtm, 636 struct snd_soc_dai *dai) 637 { 638 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtm, 0); 639 struct catpt_dev *cdev = dev_get_drvdata(dai->dev); 640 struct catpt_ssp_device_format devfmt; 641 int ret; 642 643 devfmt.iface = dai->driver->id; 644 devfmt.channels = codec_dai->driver->capture.channels_max; 645 646 switch (devfmt.iface) { 647 case CATPT_SSP_IFACE_0: 648 devfmt.mclk = CATPT_MCLK_FREQ_24_MHZ; 649 650 switch (devfmt.channels) { 651 case 4: 652 devfmt.mode = CATPT_SSP_MODE_TDM_PROVIDER; 653 devfmt.clock_divider = 4; 654 break; 655 case 2: 656 default: 657 devfmt.mode = CATPT_SSP_MODE_I2S_PROVIDER; 658 devfmt.clock_divider = 9; 659 break; 660 } 661 break; 662 663 case CATPT_SSP_IFACE_1: 664 devfmt.mclk = CATPT_MCLK_OFF; 665 devfmt.mode = CATPT_SSP_MODE_I2S_CONSUMER; 666 devfmt.clock_divider = 0; 667 break; 668 } 669 670 /* see if this is a new configuration */ 671 if (!memcmp(&cdev->devfmt[devfmt.iface], &devfmt, sizeof(devfmt))) 672 return 0; 673 674 pm_runtime_get_sync(cdev->dev); 675 676 ret = catpt_ipc_set_device_format(cdev, &devfmt); 677 678 pm_runtime_mark_last_busy(cdev->dev); 679 pm_runtime_put_autosuspend(cdev->dev); 680 681 if (ret) 682 return CATPT_IPC_ERROR(ret); 683 684 /* store device format set for given SSP */ 685 memcpy(&cdev->devfmt[devfmt.iface], &devfmt, sizeof(devfmt)); 686 return 0; 687 } 688 689 static struct snd_soc_dai_driver dai_drivers[] = { 690 /* FE DAIs */ 691 { 692 .name = "System Pin", 693 .id = CATPT_STRM_TYPE_SYSTEM, 694 .ops = &catpt_fe_dai_ops, 695 .playback = { 696 .stream_name = "System Playback", 697 .channels_min = 2, 698 .channels_max = 2, 699 .rates = SNDRV_PCM_RATE_48000, 700 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 701 }, 702 .capture = { 703 .stream_name = "Analog Capture", 704 .channels_min = 2, 705 .channels_max = 4, 706 .rates = SNDRV_PCM_RATE_48000, 707 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 708 }, 709 }, 710 { 711 .name = "Offload0 Pin", 712 .id = CATPT_STRM_TYPE_RENDER, 713 .ops = &catpt_fe_dai_ops, 714 .playback = { 715 .stream_name = "Offload0 Playback", 716 .channels_min = 2, 717 .channels_max = 2, 718 .rates = SNDRV_PCM_RATE_8000_192000, 719 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 720 }, 721 }, 722 { 723 .name = "Offload1 Pin", 724 .id = CATPT_STRM_TYPE_RENDER, 725 .ops = &catpt_fe_dai_ops, 726 .playback = { 727 .stream_name = "Offload1 Playback", 728 .channels_min = 2, 729 .channels_max = 2, 730 .rates = SNDRV_PCM_RATE_8000_192000, 731 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 732 }, 733 }, 734 { 735 .name = "Loopback Pin", 736 .id = CATPT_STRM_TYPE_LOOPBACK, 737 .ops = &catpt_fe_dai_ops, 738 .capture = { 739 .stream_name = "Loopback Capture", 740 .channels_min = 2, 741 .channels_max = 2, 742 .rates = SNDRV_PCM_RATE_48000, 743 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 744 }, 745 }, 746 { 747 .name = "Bluetooth Pin", 748 .id = CATPT_STRM_TYPE_BLUETOOTH_RENDER, 749 .ops = &catpt_fe_dai_ops, 750 .playback = { 751 .stream_name = "Bluetooth Playback", 752 .channels_min = 1, 753 .channels_max = 1, 754 .rates = SNDRV_PCM_RATE_8000, 755 .formats = SNDRV_PCM_FMTBIT_S16_LE, 756 }, 757 .capture = { 758 .stream_name = "Bluetooth Capture", 759 .channels_min = 1, 760 .channels_max = 1, 761 .rates = SNDRV_PCM_RATE_8000, 762 .formats = SNDRV_PCM_FMTBIT_S16_LE, 763 }, 764 }, 765 /* BE DAIs */ 766 { 767 .name = "ssp0-port", 768 .id = CATPT_SSP_IFACE_0, 769 .pcm_new = catpt_dai_pcm_new, 770 .playback = { 771 .channels_min = 1, 772 .channels_max = 8, 773 }, 774 .capture = { 775 .channels_min = 1, 776 .channels_max = 8, 777 }, 778 }, 779 { 780 .name = "ssp1-port", 781 .id = CATPT_SSP_IFACE_1, 782 .pcm_new = catpt_dai_pcm_new, 783 .playback = { 784 .channels_min = 1, 785 .channels_max = 8, 786 }, 787 .capture = { 788 .channels_min = 1, 789 .channels_max = 8, 790 }, 791 }, 792 }; 793 794 #define DSP_VOLUME_MAX S32_MAX /* 0db */ 795 #define DSP_VOLUME_STEP_MAX 30 796 797 static u32 ctlvol_to_dspvol(u32 value) 798 { 799 if (value > DSP_VOLUME_STEP_MAX) 800 value = 0; 801 return DSP_VOLUME_MAX >> (DSP_VOLUME_STEP_MAX - value); 802 } 803 804 static u32 dspvol_to_ctlvol(u32 volume) 805 { 806 if (volume > DSP_VOLUME_MAX) 807 return DSP_VOLUME_STEP_MAX; 808 return volume ? __fls(volume) : 0; 809 } 810 811 static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol) 812 { 813 u32 dspvol; 814 int ret, i; 815 816 for (i = 1; i < CATPT_CHANNELS_MAX; i++) 817 if (ctlvol[i] != ctlvol[0]) 818 break; 819 820 if (i == CATPT_CHANNELS_MAX) { 821 dspvol = ctlvol_to_dspvol(ctlvol[0]); 822 823 ret = catpt_ipc_set_volume(cdev, stream_id, 824 CATPT_ALL_CHANNELS_MASK, dspvol, 825 0, CATPT_AUDIO_CURVE_NONE); 826 } else { 827 for (i = 0; i < CATPT_CHANNELS_MAX; i++) { 828 dspvol = ctlvol_to_dspvol(ctlvol[i]); 829 830 ret = catpt_ipc_set_volume(cdev, stream_id, 831 i, dspvol, 832 0, CATPT_AUDIO_CURVE_NONE); 833 if (ret) 834 break; 835 } 836 } 837 838 if (ret) 839 return CATPT_IPC_ERROR(ret); 840 return 0; 841 } 842 843 static int catpt_volume_info(struct snd_kcontrol *kcontrol, 844 struct snd_ctl_elem_info *uinfo) 845 { 846 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 847 uinfo->count = CATPT_CHANNELS_MAX; 848 uinfo->value.integer.min = 0; 849 uinfo->value.integer.max = DSP_VOLUME_STEP_MAX; 850 return 0; 851 } 852 853 static int catpt_mixer_volume_get(struct snd_kcontrol *kcontrol, 854 struct snd_ctl_elem_value *ucontrol) 855 { 856 struct snd_soc_component *component = 857 snd_soc_kcontrol_component(kcontrol); 858 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 859 u32 dspvol; 860 int i; 861 862 pm_runtime_get_sync(cdev->dev); 863 864 for (i = 0; i < CATPT_CHANNELS_MAX; i++) { 865 dspvol = catpt_mixer_volume(cdev, &cdev->mixer, i); 866 ucontrol->value.integer.value[i] = dspvol_to_ctlvol(dspvol); 867 } 868 869 pm_runtime_mark_last_busy(cdev->dev); 870 pm_runtime_put_autosuspend(cdev->dev); 871 872 return 0; 873 } 874 875 static int catpt_mixer_volume_put(struct snd_kcontrol *kcontrol, 876 struct snd_ctl_elem_value *ucontrol) 877 { 878 struct snd_soc_component *component = 879 snd_soc_kcontrol_component(kcontrol); 880 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 881 int ret; 882 883 pm_runtime_get_sync(cdev->dev); 884 885 ret = catpt_set_dspvol(cdev, cdev->mixer.mixer_hw_id, 886 ucontrol->value.integer.value); 887 888 pm_runtime_mark_last_busy(cdev->dev); 889 pm_runtime_put_autosuspend(cdev->dev); 890 891 return ret; 892 } 893 894 static int catpt_stream_volume_get(struct snd_kcontrol *kcontrol, 895 struct snd_ctl_elem_value *ucontrol, 896 enum catpt_pin_id pin_id) 897 { 898 struct snd_soc_component *component = 899 snd_soc_kcontrol_component(kcontrol); 900 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 901 struct catpt_stream_runtime *stream; 902 long *ctlvol = (long *)kcontrol->private_value; 903 u32 dspvol; 904 int i; 905 906 stream = catpt_stream_find(cdev, pin_id); 907 if (!stream) { 908 for (i = 0; i < CATPT_CHANNELS_MAX; i++) 909 ucontrol->value.integer.value[i] = ctlvol[i]; 910 return 0; 911 } 912 913 pm_runtime_get_sync(cdev->dev); 914 915 for (i = 0; i < CATPT_CHANNELS_MAX; i++) { 916 dspvol = catpt_stream_volume(cdev, stream, i); 917 ucontrol->value.integer.value[i] = dspvol_to_ctlvol(dspvol); 918 } 919 920 pm_runtime_mark_last_busy(cdev->dev); 921 pm_runtime_put_autosuspend(cdev->dev); 922 923 return 0; 924 } 925 926 static int catpt_stream_volume_put(struct snd_kcontrol *kcontrol, 927 struct snd_ctl_elem_value *ucontrol, 928 enum catpt_pin_id pin_id) 929 { 930 struct snd_soc_component *component = 931 snd_soc_kcontrol_component(kcontrol); 932 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 933 struct catpt_stream_runtime *stream; 934 long *ctlvol = (long *)kcontrol->private_value; 935 int ret, i; 936 937 stream = catpt_stream_find(cdev, pin_id); 938 if (!stream) { 939 for (i = 0; i < CATPT_CHANNELS_MAX; i++) 940 ctlvol[i] = ucontrol->value.integer.value[i]; 941 return 0; 942 } 943 944 pm_runtime_get_sync(cdev->dev); 945 946 ret = catpt_set_dspvol(cdev, stream->info.stream_hw_id, 947 ucontrol->value.integer.value); 948 949 pm_runtime_mark_last_busy(cdev->dev); 950 pm_runtime_put_autosuspend(cdev->dev); 951 952 if (ret) 953 return ret; 954 955 for (i = 0; i < CATPT_CHANNELS_MAX; i++) 956 ctlvol[i] = ucontrol->value.integer.value[i]; 957 return 0; 958 } 959 960 static int catpt_offload1_volume_get(struct snd_kcontrol *kctl, 961 struct snd_ctl_elem_value *uctl) 962 { 963 return catpt_stream_volume_get(kctl, uctl, CATPT_PIN_ID_OFFLOAD1); 964 } 965 966 static int catpt_offload1_volume_put(struct snd_kcontrol *kctl, 967 struct snd_ctl_elem_value *uctl) 968 { 969 return catpt_stream_volume_put(kctl, uctl, CATPT_PIN_ID_OFFLOAD1); 970 } 971 972 static int catpt_offload2_volume_get(struct snd_kcontrol *kctl, 973 struct snd_ctl_elem_value *uctl) 974 { 975 return catpt_stream_volume_get(kctl, uctl, CATPT_PIN_ID_OFFLOAD2); 976 } 977 978 static int catpt_offload2_volume_put(struct snd_kcontrol *kctl, 979 struct snd_ctl_elem_value *uctl) 980 { 981 return catpt_stream_volume_put(kctl, uctl, CATPT_PIN_ID_OFFLOAD2); 982 } 983 984 static int catpt_capture_volume_get(struct snd_kcontrol *kctl, 985 struct snd_ctl_elem_value *uctl) 986 { 987 return catpt_stream_volume_get(kctl, uctl, CATPT_PIN_ID_CAPTURE1); 988 } 989 990 static int catpt_capture_volume_put(struct snd_kcontrol *kctl, 991 struct snd_ctl_elem_value *uctl) 992 { 993 return catpt_stream_volume_put(kctl, uctl, CATPT_PIN_ID_CAPTURE1); 994 } 995 996 static int catpt_loopback_switch_get(struct snd_kcontrol *kcontrol, 997 struct snd_ctl_elem_value *ucontrol) 998 { 999 ucontrol->value.integer.value[0] = *(bool *)kcontrol->private_value; 1000 return 0; 1001 } 1002 1003 static int catpt_loopback_switch_put(struct snd_kcontrol *kcontrol, 1004 struct snd_ctl_elem_value *ucontrol) 1005 { 1006 struct snd_soc_component *component = 1007 snd_soc_kcontrol_component(kcontrol); 1008 struct catpt_dev *cdev = dev_get_drvdata(component->dev); 1009 struct catpt_stream_runtime *stream; 1010 bool mute; 1011 int ret; 1012 1013 mute = (bool)ucontrol->value.integer.value[0]; 1014 stream = catpt_stream_find(cdev, CATPT_PIN_ID_REFERENCE); 1015 if (!stream) { 1016 *(bool *)kcontrol->private_value = mute; 1017 return 0; 1018 } 1019 1020 pm_runtime_get_sync(cdev->dev); 1021 1022 ret = catpt_ipc_mute_loopback(cdev, stream->info.stream_hw_id, mute); 1023 1024 pm_runtime_mark_last_busy(cdev->dev); 1025 pm_runtime_put_autosuspend(cdev->dev); 1026 1027 if (ret) 1028 return CATPT_IPC_ERROR(ret); 1029 1030 *(bool *)kcontrol->private_value = mute; 1031 return 0; 1032 } 1033 1034 static int catpt_waves_switch_get(struct snd_kcontrol *kcontrol, 1035 struct snd_ctl_elem_value *ucontrol) 1036 { 1037 return 0; 1038 } 1039 1040 static int catpt_waves_switch_put(struct snd_kcontrol *kcontrol, 1041 struct snd_ctl_elem_value *ucontrol) 1042 { 1043 return 0; 1044 } 1045 1046 static int catpt_waves_param_get(struct snd_kcontrol *kcontrol, 1047 unsigned int __user *bytes, 1048 unsigned int size) 1049 { 1050 return 0; 1051 } 1052 1053 static int catpt_waves_param_put(struct snd_kcontrol *kcontrol, 1054 const unsigned int __user *bytes, 1055 unsigned int size) 1056 { 1057 return 0; 1058 } 1059 1060 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(catpt_volume_tlv, -9000, 300, 1); 1061 1062 #define CATPT_VOLUME_CTL(kname, sname) \ 1063 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1064 .name = (kname), \ 1065 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 1066 SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 1067 .info = catpt_volume_info, \ 1068 .get = catpt_##sname##_volume_get, \ 1069 .put = catpt_##sname##_volume_put, \ 1070 .tlv.p = catpt_volume_tlv, \ 1071 .private_value = (unsigned long) \ 1072 &(long[CATPT_CHANNELS_MAX]) {0} } 1073 1074 static const struct snd_kcontrol_new component_kcontrols[] = { 1075 /* Master volume (mixer stream) */ 1076 CATPT_VOLUME_CTL("Master Playback Volume", mixer), 1077 /* Individual volume controls for offload and capture */ 1078 CATPT_VOLUME_CTL("Media0 Playback Volume", offload1), 1079 CATPT_VOLUME_CTL("Media1 Playback Volume", offload2), 1080 CATPT_VOLUME_CTL("Mic Capture Volume", capture), 1081 SOC_SINGLE_BOOL_EXT("Loopback Mute", (unsigned long)&(bool[1]) {0}, 1082 catpt_loopback_switch_get, catpt_loopback_switch_put), 1083 /* Enable or disable WAVES module */ 1084 SOC_SINGLE_BOOL_EXT("Waves Switch", 0, 1085 catpt_waves_switch_get, catpt_waves_switch_put), 1086 /* WAVES module parameter control */ 1087 SND_SOC_BYTES_TLV("Waves Set Param", 128, 1088 catpt_waves_param_get, catpt_waves_param_put), 1089 }; 1090 1091 static const struct snd_soc_dapm_widget component_widgets[] = { 1092 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0), 1093 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0), 1094 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0), 1095 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0), 1096 1097 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0), 1098 }; 1099 1100 static const struct snd_soc_dapm_route component_routes[] = { 1101 {"Playback VMixer", NULL, "System Playback"}, 1102 {"Playback VMixer", NULL, "Offload0 Playback"}, 1103 {"Playback VMixer", NULL, "Offload1 Playback"}, 1104 1105 {"SSP0 CODEC OUT", NULL, "Playback VMixer"}, 1106 1107 {"Analog Capture", NULL, "SSP0 CODEC IN"}, 1108 {"Loopback Capture", NULL, "SSP0 CODEC IN"}, 1109 1110 {"SSP1 BT OUT", NULL, "Bluetooth Playback"}, 1111 {"Bluetooth Capture", NULL, "SSP1 BT IN"}, 1112 }; 1113 1114 static const struct snd_soc_component_driver catpt_comp_driver = { 1115 .name = "catpt-platform", 1116 1117 .pcm_construct = catpt_component_pcm_construct, 1118 .open = catpt_component_open, 1119 .pointer = catpt_component_pointer, 1120 1121 .controls = component_kcontrols, 1122 .num_controls = ARRAY_SIZE(component_kcontrols), 1123 .dapm_widgets = component_widgets, 1124 .num_dapm_widgets = ARRAY_SIZE(component_widgets), 1125 .dapm_routes = component_routes, 1126 .num_dapm_routes = ARRAY_SIZE(component_routes), 1127 }; 1128 1129 int catpt_arm_stream_templates(struct catpt_dev *cdev) 1130 { 1131 struct resource *res; 1132 u32 scratch_size = 0; 1133 int i, j; 1134 1135 for (i = 0; i < ARRAY_SIZE(catpt_topology); i++) { 1136 struct catpt_stream_template *template; 1137 struct catpt_module_entry *entry; 1138 struct catpt_module_type *type; 1139 1140 template = catpt_topology[i]; 1141 template->persistent_size = 0; 1142 1143 for (j = 0; j < template->num_entries; j++) { 1144 entry = &template->entries[j]; 1145 type = &cdev->modules[entry->module_id]; 1146 1147 if (!type->loaded) 1148 return -ENOENT; 1149 1150 entry->entry_point = type->entry_point; 1151 template->persistent_size += type->persistent_size; 1152 if (type->scratch_size > scratch_size) 1153 scratch_size = type->scratch_size; 1154 } 1155 } 1156 1157 if (scratch_size) { 1158 /* allocate single scratch area for all modules */ 1159 res = catpt_request_region(&cdev->dram, scratch_size); 1160 if (!res) 1161 return -EBUSY; 1162 cdev->scratch = res; 1163 } 1164 1165 return 0; 1166 } 1167 1168 int catpt_register_plat_component(struct catpt_dev *cdev) 1169 { 1170 struct snd_soc_component *component; 1171 int ret; 1172 1173 component = devm_kzalloc(cdev->dev, sizeof(*component), GFP_KERNEL); 1174 if (!component) 1175 return -ENOMEM; 1176 1177 ret = snd_soc_component_initialize(component, &catpt_comp_driver, 1178 cdev->dev); 1179 if (ret) 1180 return ret; 1181 1182 component->name = catpt_comp_driver.name; 1183 return snd_soc_add_component(component, dai_drivers, 1184 ARRAY_SIZE(dai_drivers)); 1185 } 1186