1 /* 2 * sst_drv_interface.c - Intel SST Driver for audio engine 3 * 4 * Copyright (C) 2008-14 Intel Corp 5 * Authors: Vinod Koul <vinod.koul@intel.com> 6 * Harsha Priya <priya.harsha@intel.com> 7 * Dharageswari R <dharageswari.r@intel.com) 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2 of the License. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 */ 21 #include <linux/delay.h> 22 #include <linux/pci.h> 23 #include <linux/fs.h> 24 #include <linux/firmware.h> 25 #include <linux/pm_runtime.h> 26 #include <linux/pm_qos.h> 27 #include <linux/math64.h> 28 #include <sound/core.h> 29 #include <sound/pcm.h> 30 #include <sound/soc.h> 31 #include <sound/compress_driver.h> 32 #include <asm/platform_sst_audio.h> 33 #include "../sst-mfld-platform.h" 34 #include "sst.h" 35 #include "../../common/sst-dsp.h" 36 37 38 39 #define NUM_CODEC 2 40 #define MIN_FRAGMENT 2 41 #define MAX_FRAGMENT 4 42 #define MIN_FRAGMENT_SIZE (50 * 1024) 43 #define MAX_FRAGMENT_SIZE (1024 * 1024) 44 #define SST_GET_BYTES_PER_SAMPLE(pcm_wd_sz) (((pcm_wd_sz + 15) >> 4) << 1) 45 46 int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id) 47 { 48 struct stream_info *stream; 49 int ret = 0; 50 51 stream = get_stream_info(ctx, str_id); 52 if (stream) { 53 /* str_id is valid, so stream is alloacted */ 54 ret = sst_free_stream(ctx, str_id); 55 if (ret) 56 sst_clean_stream(&ctx->streams[str_id]); 57 return ret; 58 } else { 59 dev_err(ctx->dev, "we tried to free stream context %d which was freed!!!\n", str_id); 60 } 61 return ret; 62 } 63 64 int sst_get_stream_allocated(struct intel_sst_drv *ctx, 65 struct snd_sst_params *str_param, 66 struct snd_sst_lib_download **lib_dnld) 67 { 68 int retval; 69 70 retval = ctx->ops->alloc_stream(ctx, str_param); 71 if (retval > 0) 72 dev_dbg(ctx->dev, "Stream allocated %d\n", retval); 73 return retval; 74 75 } 76 77 /* 78 * sst_get_sfreq - this function returns the frequency of the stream 79 * 80 * @str_param : stream params 81 */ 82 int sst_get_sfreq(struct snd_sst_params *str_param) 83 { 84 switch (str_param->codec) { 85 case SST_CODEC_TYPE_PCM: 86 return str_param->sparams.uc.pcm_params.sfreq; 87 case SST_CODEC_TYPE_AAC: 88 return str_param->sparams.uc.aac_params.externalsr; 89 case SST_CODEC_TYPE_MP3: 90 return 0; 91 default: 92 return -EINVAL; 93 } 94 } 95 96 /* 97 * sst_get_num_channel - get number of channels for the stream 98 * 99 * @str_param : stream params 100 */ 101 int sst_get_num_channel(struct snd_sst_params *str_param) 102 { 103 switch (str_param->codec) { 104 case SST_CODEC_TYPE_PCM: 105 return str_param->sparams.uc.pcm_params.num_chan; 106 case SST_CODEC_TYPE_MP3: 107 return str_param->sparams.uc.mp3_params.num_chan; 108 case SST_CODEC_TYPE_AAC: 109 return str_param->sparams.uc.aac_params.num_chan; 110 default: 111 return -EINVAL; 112 } 113 } 114 115 /* 116 * sst_get_stream - this function prepares for stream allocation 117 * 118 * @str_param : stream param 119 */ 120 int sst_get_stream(struct intel_sst_drv *ctx, 121 struct snd_sst_params *str_param) 122 { 123 int retval; 124 struct stream_info *str_info; 125 126 /* stream is not allocated, we are allocating */ 127 retval = ctx->ops->alloc_stream(ctx, str_param); 128 if (retval <= 0) { 129 return -EIO; 130 } 131 /* store sampling freq */ 132 str_info = &ctx->streams[retval]; 133 str_info->sfreq = sst_get_sfreq(str_param); 134 135 return retval; 136 } 137 138 static int sst_power_control(struct device *dev, bool state) 139 { 140 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 141 int ret = 0; 142 int usage_count = 0; 143 144 #ifdef CONFIG_PM 145 usage_count = atomic_read(&dev->power.usage_count); 146 #else 147 usage_count = 1; 148 #endif 149 150 if (state == true) { 151 ret = pm_runtime_get_sync(dev); 152 153 dev_dbg(ctx->dev, "Enable: pm usage count: %d\n", usage_count); 154 if (ret < 0) { 155 dev_err(ctx->dev, "Runtime get failed with err: %d\n", ret); 156 return ret; 157 } 158 if ((ctx->sst_state == SST_RESET) && (usage_count == 1)) { 159 ret = sst_load_fw(ctx); 160 if (ret) { 161 dev_err(dev, "FW download fail %d\n", ret); 162 sst_set_fw_state_locked(ctx, SST_RESET); 163 ret = sst_pm_runtime_put(ctx); 164 } 165 } 166 } else { 167 dev_dbg(ctx->dev, "Disable: pm usage count: %d\n", usage_count); 168 return sst_pm_runtime_put(ctx); 169 } 170 return ret; 171 } 172 173 /* 174 * sst_open_pcm_stream - Open PCM interface 175 * 176 * @str_param: parameters of pcm stream 177 * 178 * This function is called by MID sound card driver to open 179 * a new pcm interface 180 */ 181 static int sst_open_pcm_stream(struct device *dev, 182 struct snd_sst_params *str_param) 183 { 184 int retval; 185 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 186 187 if (!str_param) 188 return -EINVAL; 189 190 retval = sst_get_stream(ctx, str_param); 191 if (retval > 0) 192 ctx->stream_cnt++; 193 else 194 dev_err(ctx->dev, "sst_get_stream returned err %d\n", retval); 195 196 return retval; 197 } 198 199 static int sst_cdev_open(struct device *dev, 200 struct snd_sst_params *str_params, struct sst_compress_cb *cb) 201 { 202 int str_id, retval; 203 struct stream_info *stream; 204 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 205 206 retval = pm_runtime_get_sync(ctx->dev); 207 if (retval < 0) 208 return retval; 209 210 str_id = sst_get_stream(ctx, str_params); 211 if (str_id > 0) { 212 dev_dbg(dev, "stream allocated in sst_cdev_open %d\n", str_id); 213 stream = &ctx->streams[str_id]; 214 stream->compr_cb = cb->compr_cb; 215 stream->compr_cb_param = cb->param; 216 stream->drain_notify = cb->drain_notify; 217 stream->drain_cb_param = cb->drain_cb_param; 218 } else { 219 dev_err(dev, "stream encountered error during alloc %d\n", str_id); 220 str_id = -EINVAL; 221 sst_pm_runtime_put(ctx); 222 } 223 return str_id; 224 } 225 226 static int sst_cdev_close(struct device *dev, unsigned int str_id) 227 { 228 int retval; 229 struct stream_info *stream; 230 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 231 232 stream = get_stream_info(ctx, str_id); 233 if (!stream) { 234 dev_err(dev, "stream info is NULL for str %d!!!\n", str_id); 235 return -EINVAL; 236 } 237 238 if (stream->status == STREAM_RESET) { 239 dev_dbg(dev, "stream in reset state...\n"); 240 stream->status = STREAM_UN_INIT; 241 242 retval = 0; 243 goto put; 244 } 245 246 retval = sst_free_stream(ctx, str_id); 247 put: 248 stream->compr_cb_param = NULL; 249 stream->compr_cb = NULL; 250 251 if (retval) 252 dev_err(dev, "free stream returned err %d\n", retval); 253 254 dev_dbg(dev, "End\n"); 255 return retval; 256 257 } 258 259 static int sst_cdev_ack(struct device *dev, unsigned int str_id, 260 unsigned long bytes) 261 { 262 struct stream_info *stream; 263 struct snd_sst_tstamp fw_tstamp = {0,}; 264 int offset; 265 void __iomem *addr; 266 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 267 268 stream = get_stream_info(ctx, str_id); 269 if (!stream) 270 return -EINVAL; 271 272 /* update bytes sent */ 273 stream->cumm_bytes += bytes; 274 dev_dbg(dev, "bytes copied %d inc by %ld\n", stream->cumm_bytes, bytes); 275 276 memcpy_fromio(&fw_tstamp, 277 ((void *)(ctx->mailbox + ctx->tstamp) 278 +(str_id * sizeof(fw_tstamp))), 279 sizeof(fw_tstamp)); 280 281 fw_tstamp.bytes_copied = stream->cumm_bytes; 282 dev_dbg(dev, "bytes sent to fw %llu inc by %ld\n", 283 fw_tstamp.bytes_copied, bytes); 284 285 addr = ((void *)(ctx->mailbox + ctx->tstamp)) + 286 (str_id * sizeof(fw_tstamp)); 287 offset = offsetof(struct snd_sst_tstamp, bytes_copied); 288 sst_shim_write(addr, offset, fw_tstamp.bytes_copied); 289 return 0; 290 } 291 292 static int sst_cdev_set_metadata(struct device *dev, 293 unsigned int str_id, struct snd_compr_metadata *metadata) 294 { 295 int retval = 0; 296 struct stream_info *str_info; 297 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 298 299 dev_dbg(dev, "set metadata for stream %d\n", str_id); 300 301 str_info = get_stream_info(ctx, str_id); 302 if (!str_info) 303 return -EINVAL; 304 305 dev_dbg(dev, "pipe id = %d\n", str_info->pipe_id); 306 retval = sst_prepare_and_post_msg(ctx, str_info->task_id, IPC_CMD, 307 IPC_IA_SET_STREAM_PARAMS_MRFLD, str_info->pipe_id, 308 sizeof(*metadata), metadata, NULL, 309 true, true, true, false); 310 311 return retval; 312 } 313 314 static int sst_cdev_stream_pause(struct device *dev, unsigned int str_id) 315 { 316 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 317 318 return sst_pause_stream(ctx, str_id); 319 } 320 321 static int sst_cdev_stream_pause_release(struct device *dev, 322 unsigned int str_id) 323 { 324 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 325 326 return sst_resume_stream(ctx, str_id); 327 } 328 329 static int sst_cdev_stream_start(struct device *dev, unsigned int str_id) 330 { 331 struct stream_info *str_info; 332 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 333 334 str_info = get_stream_info(ctx, str_id); 335 if (!str_info) 336 return -EINVAL; 337 str_info->prev = str_info->status; 338 str_info->status = STREAM_RUNNING; 339 return sst_start_stream(ctx, str_id); 340 } 341 342 static int sst_cdev_stream_drop(struct device *dev, unsigned int str_id) 343 { 344 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 345 346 return sst_drop_stream(ctx, str_id); 347 } 348 349 static int sst_cdev_stream_drain(struct device *dev, unsigned int str_id) 350 { 351 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 352 353 return sst_drain_stream(ctx, str_id, false); 354 } 355 356 static int sst_cdev_stream_partial_drain(struct device *dev, 357 unsigned int str_id) 358 { 359 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 360 361 return sst_drain_stream(ctx, str_id, true); 362 } 363 364 static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, 365 struct snd_compr_tstamp *tstamp) 366 { 367 struct snd_sst_tstamp fw_tstamp = {0,}; 368 struct stream_info *stream; 369 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 370 371 memcpy_fromio(&fw_tstamp, 372 ((void *)(ctx->mailbox + ctx->tstamp) 373 +(str_id * sizeof(fw_tstamp))), 374 sizeof(fw_tstamp)); 375 376 stream = get_stream_info(ctx, str_id); 377 if (!stream) 378 return -EINVAL; 379 dev_dbg(dev, "rb_counter %llu in bytes\n", fw_tstamp.ring_buffer_counter); 380 381 tstamp->copied_total = fw_tstamp.ring_buffer_counter; 382 tstamp->pcm_frames = fw_tstamp.frames_decoded; 383 tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter, 384 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24)); 385 tstamp->sampling_rate = fw_tstamp.sampling_frequency; 386 387 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames); 388 dev_dbg(dev, "Ptr Query on strid = %d copied_total %d, decodec %d\n", 389 str_id, tstamp->copied_total, tstamp->pcm_frames); 390 dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames); 391 392 return 0; 393 } 394 395 static int sst_cdev_caps(struct snd_compr_caps *caps) 396 { 397 caps->num_codecs = NUM_CODEC; 398 caps->min_fragment_size = MIN_FRAGMENT_SIZE; /* 50KB */ 399 caps->max_fragment_size = MAX_FRAGMENT_SIZE; /* 1024KB */ 400 caps->min_fragments = MIN_FRAGMENT; 401 caps->max_fragments = MAX_FRAGMENT; 402 caps->codecs[0] = SND_AUDIOCODEC_MP3; 403 caps->codecs[1] = SND_AUDIOCODEC_AAC; 404 return 0; 405 } 406 407 static struct snd_compr_codec_caps caps_mp3 = { 408 .num_descriptors = 1, 409 .descriptor[0].max_ch = 2, 410 .descriptor[0].sample_rates[0] = 48000, 411 .descriptor[0].sample_rates[1] = 44100, 412 .descriptor[0].sample_rates[2] = 32000, 413 .descriptor[0].sample_rates[3] = 16000, 414 .descriptor[0].sample_rates[4] = 8000, 415 .descriptor[0].num_sample_rates = 5, 416 .descriptor[0].bit_rate[0] = 320, 417 .descriptor[0].bit_rate[1] = 192, 418 .descriptor[0].num_bitrates = 2, 419 .descriptor[0].profiles = 0, 420 .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, 421 .descriptor[0].formats = 0, 422 }; 423 424 static struct snd_compr_codec_caps caps_aac = { 425 .num_descriptors = 2, 426 .descriptor[1].max_ch = 2, 427 .descriptor[0].sample_rates[0] = 48000, 428 .descriptor[0].sample_rates[1] = 44100, 429 .descriptor[0].sample_rates[2] = 32000, 430 .descriptor[0].sample_rates[3] = 16000, 431 .descriptor[0].sample_rates[4] = 8000, 432 .descriptor[0].num_sample_rates = 5, 433 .descriptor[1].bit_rate[0] = 320, 434 .descriptor[1].bit_rate[1] = 192, 435 .descriptor[1].num_bitrates = 2, 436 .descriptor[1].profiles = 0, 437 .descriptor[1].modes = 0, 438 .descriptor[1].formats = 439 (SND_AUDIOSTREAMFORMAT_MP4ADTS | 440 SND_AUDIOSTREAMFORMAT_RAW), 441 }; 442 443 static int sst_cdev_codec_caps(struct snd_compr_codec_caps *codec) 444 { 445 if (codec->codec == SND_AUDIOCODEC_MP3) 446 *codec = caps_mp3; 447 else if (codec->codec == SND_AUDIOCODEC_AAC) 448 *codec = caps_aac; 449 else 450 return -EINVAL; 451 452 return 0; 453 } 454 455 void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id) 456 { 457 struct stream_info *stream; 458 459 dev_dbg(ctx->dev, "fragment elapsed from firmware for str_id %d\n", 460 str_id); 461 stream = &ctx->streams[str_id]; 462 if (stream->compr_cb) 463 stream->compr_cb(stream->compr_cb_param); 464 } 465 466 /* 467 * sst_close_pcm_stream - Close PCM interface 468 * 469 * @str_id: stream id to be closed 470 * 471 * This function is called by MID sound card driver to close 472 * an existing pcm interface 473 */ 474 static int sst_close_pcm_stream(struct device *dev, unsigned int str_id) 475 { 476 struct stream_info *stream; 477 int retval = 0; 478 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 479 480 stream = get_stream_info(ctx, str_id); 481 if (!stream) { 482 dev_err(ctx->dev, "stream info is NULL for str %d!!!\n", str_id); 483 return -EINVAL; 484 } 485 486 if (stream->status == STREAM_RESET) { 487 /* silently fail here as we have cleaned the stream earlier */ 488 dev_dbg(ctx->dev, "stream in reset state...\n"); 489 490 retval = 0; 491 goto put; 492 } 493 494 retval = free_stream_context(ctx, str_id); 495 put: 496 stream->pcm_substream = NULL; 497 stream->status = STREAM_UN_INIT; 498 stream->period_elapsed = NULL; 499 ctx->stream_cnt--; 500 501 if (retval) 502 dev_err(ctx->dev, "free stream returned err %d\n", retval); 503 504 dev_dbg(ctx->dev, "Exit\n"); 505 return 0; 506 } 507 508 static inline int sst_calc_tstamp(struct intel_sst_drv *ctx, 509 struct pcm_stream_info *info, 510 struct snd_pcm_substream *substream, 511 struct snd_sst_tstamp *fw_tstamp) 512 { 513 size_t delay_bytes, delay_frames; 514 size_t buffer_sz; 515 u32 pointer_bytes, pointer_samples; 516 517 dev_dbg(ctx->dev, "mrfld ring_buffer_counter %llu in bytes\n", 518 fw_tstamp->ring_buffer_counter); 519 dev_dbg(ctx->dev, "mrfld hardware_counter %llu in bytes\n", 520 fw_tstamp->hardware_counter); 521 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 522 delay_bytes = (size_t) (fw_tstamp->ring_buffer_counter - 523 fw_tstamp->hardware_counter); 524 else 525 delay_bytes = (size_t) (fw_tstamp->hardware_counter - 526 fw_tstamp->ring_buffer_counter); 527 delay_frames = bytes_to_frames(substream->runtime, delay_bytes); 528 buffer_sz = snd_pcm_lib_buffer_bytes(substream); 529 div_u64_rem(fw_tstamp->ring_buffer_counter, buffer_sz, &pointer_bytes); 530 pointer_samples = bytes_to_samples(substream->runtime, pointer_bytes); 531 532 dev_dbg(ctx->dev, "pcm delay %zu in bytes\n", delay_bytes); 533 534 info->buffer_ptr = pointer_samples / substream->runtime->channels; 535 536 info->pcm_delay = delay_frames / substream->runtime->channels; 537 dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n", 538 info->buffer_ptr, info->pcm_delay); 539 return 0; 540 } 541 542 static int sst_read_timestamp(struct device *dev, struct pcm_stream_info *info) 543 { 544 struct stream_info *stream; 545 struct snd_pcm_substream *substream; 546 struct snd_sst_tstamp fw_tstamp; 547 unsigned int str_id; 548 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 549 550 str_id = info->str_id; 551 stream = get_stream_info(ctx, str_id); 552 if (!stream) 553 return -EINVAL; 554 555 if (!stream->pcm_substream) 556 return -EINVAL; 557 substream = stream->pcm_substream; 558 559 memcpy_fromio(&fw_tstamp, 560 ((void *)(ctx->mailbox + ctx->tstamp) 561 + (str_id * sizeof(fw_tstamp))), 562 sizeof(fw_tstamp)); 563 return sst_calc_tstamp(ctx, info, substream, &fw_tstamp); 564 } 565 566 static int sst_stream_start(struct device *dev, int str_id) 567 { 568 struct stream_info *str_info; 569 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 570 571 if (ctx->sst_state != SST_FW_RUNNING) 572 return 0; 573 str_info = get_stream_info(ctx, str_id); 574 if (!str_info) 575 return -EINVAL; 576 str_info->prev = str_info->status; 577 str_info->status = STREAM_RUNNING; 578 sst_start_stream(ctx, str_id); 579 580 return 0; 581 } 582 583 static int sst_stream_drop(struct device *dev, int str_id) 584 { 585 struct stream_info *str_info; 586 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 587 588 if (ctx->sst_state != SST_FW_RUNNING) 589 return 0; 590 591 str_info = get_stream_info(ctx, str_id); 592 if (!str_info) 593 return -EINVAL; 594 str_info->prev = STREAM_UN_INIT; 595 str_info->status = STREAM_INIT; 596 return sst_drop_stream(ctx, str_id); 597 } 598 599 static int sst_stream_pause(struct device *dev, int str_id) 600 { 601 struct stream_info *str_info; 602 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 603 604 if (ctx->sst_state != SST_FW_RUNNING) 605 return 0; 606 607 str_info = get_stream_info(ctx, str_id); 608 if (!str_info) 609 return -EINVAL; 610 611 return sst_pause_stream(ctx, str_id); 612 } 613 614 static int sst_stream_resume(struct device *dev, int str_id) 615 { 616 struct stream_info *str_info; 617 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 618 619 if (ctx->sst_state != SST_FW_RUNNING) 620 return 0; 621 622 str_info = get_stream_info(ctx, str_id); 623 if (!str_info) 624 return -EINVAL; 625 return sst_resume_stream(ctx, str_id); 626 } 627 628 static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info) 629 { 630 int str_id = 0; 631 struct stream_info *stream; 632 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 633 634 str_id = str_info->str_id; 635 636 if (ctx->sst_state != SST_FW_RUNNING) 637 return 0; 638 639 stream = get_stream_info(ctx, str_id); 640 if (!stream) 641 return -EINVAL; 642 643 dev_dbg(ctx->dev, "setting the period ptrs\n"); 644 stream->pcm_substream = str_info->arg; 645 stream->period_elapsed = str_info->period_elapsed; 646 stream->sfreq = str_info->sfreq; 647 stream->prev = stream->status; 648 stream->status = STREAM_INIT; 649 dev_dbg(ctx->dev, 650 "pcm_substream %p, period_elapsed %p, sfreq %d, status %d\n", 651 stream->pcm_substream, stream->period_elapsed, 652 stream->sfreq, stream->status); 653 654 return 0; 655 } 656 657 /* 658 * sst_set_byte_stream - Set generic params 659 * 660 * @cmd: control cmd to be set 661 * @arg: command argument 662 * 663 * This function is called by MID sound card driver to configure 664 * SST runtime params. 665 */ 666 static int sst_send_byte_stream(struct device *dev, 667 struct snd_sst_bytes_v2 *bytes) 668 { 669 int ret_val = 0; 670 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 671 672 if (NULL == bytes) 673 return -EINVAL; 674 ret_val = pm_runtime_get_sync(ctx->dev); 675 if (ret_val < 0) 676 return ret_val; 677 678 ret_val = sst_send_byte_stream_mrfld(ctx, bytes); 679 sst_pm_runtime_put(ctx); 680 681 return ret_val; 682 } 683 684 static struct sst_ops pcm_ops = { 685 .open = sst_open_pcm_stream, 686 .stream_init = sst_stream_init, 687 .stream_start = sst_stream_start, 688 .stream_drop = sst_stream_drop, 689 .stream_pause = sst_stream_pause, 690 .stream_pause_release = sst_stream_resume, 691 .stream_read_tstamp = sst_read_timestamp, 692 .send_byte_stream = sst_send_byte_stream, 693 .close = sst_close_pcm_stream, 694 .power = sst_power_control, 695 }; 696 697 static struct compress_sst_ops compr_ops = { 698 .open = sst_cdev_open, 699 .close = sst_cdev_close, 700 .stream_pause = sst_cdev_stream_pause, 701 .stream_pause_release = sst_cdev_stream_pause_release, 702 .stream_start = sst_cdev_stream_start, 703 .stream_drop = sst_cdev_stream_drop, 704 .stream_drain = sst_cdev_stream_drain, 705 .stream_partial_drain = sst_cdev_stream_partial_drain, 706 .tstamp = sst_cdev_tstamp, 707 .ack = sst_cdev_ack, 708 .get_caps = sst_cdev_caps, 709 .get_codec_caps = sst_cdev_codec_caps, 710 .set_metadata = sst_cdev_set_metadata, 711 .power = sst_power_control, 712 }; 713 714 static struct sst_device sst_dsp_device = { 715 .name = "Intel(R) SST LPE", 716 .dev = NULL, 717 .ops = &pcm_ops, 718 .compr_ops = &compr_ops, 719 }; 720 721 /* 722 * sst_register - function to register DSP 723 * 724 * This functions registers DSP with the platform driver 725 */ 726 int sst_register(struct device *dev) 727 { 728 int ret_val; 729 730 sst_dsp_device.dev = dev; 731 ret_val = sst_register_dsp(&sst_dsp_device); 732 if (ret_val) 733 dev_err(dev, "Unable to register DSP with platform driver\n"); 734 735 return ret_val; 736 } 737 738 int sst_unregister(struct device *dev) 739 { 740 return sst_unregister_dsp(&sst_dsp_device); 741 } 742