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