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