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 addr = ((void __iomem *)(ctx->mailbox + ctx->tstamp)) + 270 (str_id * sizeof(fw_tstamp)); 271 272 memcpy_fromio(&fw_tstamp, addr, 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 offset = offsetof(struct snd_sst_tstamp, bytes_copied); 279 sst_shim_write(addr, offset, fw_tstamp.bytes_copied); 280 return 0; 281 } 282 283 static int sst_cdev_set_metadata(struct device *dev, 284 unsigned int str_id, struct snd_compr_metadata *metadata) 285 { 286 int retval = 0; 287 struct stream_info *str_info; 288 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 289 290 dev_dbg(dev, "set metadata for stream %d\n", str_id); 291 292 str_info = get_stream_info(ctx, str_id); 293 if (!str_info) 294 return -EINVAL; 295 296 dev_dbg(dev, "pipe id = %d\n", str_info->pipe_id); 297 retval = sst_prepare_and_post_msg(ctx, str_info->task_id, IPC_CMD, 298 IPC_IA_SET_STREAM_PARAMS_MRFLD, str_info->pipe_id, 299 sizeof(*metadata), metadata, NULL, 300 true, true, true, false); 301 302 return retval; 303 } 304 305 static int sst_cdev_stream_pause(struct device *dev, unsigned int str_id) 306 { 307 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 308 309 return sst_pause_stream(ctx, str_id); 310 } 311 312 static int sst_cdev_stream_pause_release(struct device *dev, 313 unsigned int str_id) 314 { 315 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 316 317 return sst_resume_stream(ctx, str_id); 318 } 319 320 static int sst_cdev_stream_start(struct device *dev, unsigned int str_id) 321 { 322 struct stream_info *str_info; 323 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 324 325 str_info = get_stream_info(ctx, str_id); 326 if (!str_info) 327 return -EINVAL; 328 str_info->prev = str_info->status; 329 str_info->status = STREAM_RUNNING; 330 return sst_start_stream(ctx, str_id); 331 } 332 333 static int sst_cdev_stream_drop(struct device *dev, unsigned int str_id) 334 { 335 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 336 337 return sst_drop_stream(ctx, str_id); 338 } 339 340 static int sst_cdev_stream_drain(struct device *dev, unsigned int str_id) 341 { 342 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 343 344 return sst_drain_stream(ctx, str_id, false); 345 } 346 347 static int sst_cdev_stream_partial_drain(struct device *dev, 348 unsigned int str_id) 349 { 350 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 351 352 return sst_drain_stream(ctx, str_id, true); 353 } 354 355 static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, 356 struct snd_compr_tstamp *tstamp) 357 { 358 struct snd_sst_tstamp fw_tstamp = {0,}; 359 struct stream_info *stream; 360 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 361 void __iomem *addr; 362 363 addr = (void __iomem *)(ctx->mailbox + ctx->tstamp) + 364 (str_id * sizeof(fw_tstamp)); 365 366 memcpy_fromio(&fw_tstamp, addr, sizeof(fw_tstamp)); 367 368 stream = get_stream_info(ctx, str_id); 369 if (!stream) 370 return -EINVAL; 371 dev_dbg(dev, "rb_counter %llu in bytes\n", fw_tstamp.ring_buffer_counter); 372 373 tstamp->copied_total = fw_tstamp.ring_buffer_counter; 374 tstamp->pcm_frames = fw_tstamp.frames_decoded; 375 tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter, 376 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24)); 377 tstamp->sampling_rate = fw_tstamp.sampling_frequency; 378 379 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames); 380 dev_dbg(dev, "Ptr Query on strid = %d copied_total %d, decodec %d\n", 381 str_id, tstamp->copied_total, tstamp->pcm_frames); 382 dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames); 383 384 return 0; 385 } 386 387 static int sst_cdev_caps(struct snd_compr_caps *caps) 388 { 389 caps->num_codecs = NUM_CODEC; 390 caps->min_fragment_size = MIN_FRAGMENT_SIZE; /* 50KB */ 391 caps->max_fragment_size = MAX_FRAGMENT_SIZE; /* 1024KB */ 392 caps->min_fragments = MIN_FRAGMENT; 393 caps->max_fragments = MAX_FRAGMENT; 394 caps->codecs[0] = SND_AUDIOCODEC_MP3; 395 caps->codecs[1] = SND_AUDIOCODEC_AAC; 396 return 0; 397 } 398 399 static const struct snd_compr_codec_caps caps_mp3 = { 400 .num_descriptors = 1, 401 .descriptor[0].max_ch = 2, 402 .descriptor[0].sample_rates[0] = 48000, 403 .descriptor[0].sample_rates[1] = 44100, 404 .descriptor[0].sample_rates[2] = 32000, 405 .descriptor[0].sample_rates[3] = 16000, 406 .descriptor[0].sample_rates[4] = 8000, 407 .descriptor[0].num_sample_rates = 5, 408 .descriptor[0].bit_rate[0] = 320, 409 .descriptor[0].bit_rate[1] = 192, 410 .descriptor[0].num_bitrates = 2, 411 .descriptor[0].profiles = 0, 412 .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, 413 .descriptor[0].formats = 0, 414 }; 415 416 static const struct snd_compr_codec_caps caps_aac = { 417 .num_descriptors = 2, 418 .descriptor[1].max_ch = 2, 419 .descriptor[0].sample_rates[0] = 48000, 420 .descriptor[0].sample_rates[1] = 44100, 421 .descriptor[0].sample_rates[2] = 32000, 422 .descriptor[0].sample_rates[3] = 16000, 423 .descriptor[0].sample_rates[4] = 8000, 424 .descriptor[0].num_sample_rates = 5, 425 .descriptor[1].bit_rate[0] = 320, 426 .descriptor[1].bit_rate[1] = 192, 427 .descriptor[1].num_bitrates = 2, 428 .descriptor[1].profiles = 0, 429 .descriptor[1].modes = 0, 430 .descriptor[1].formats = 431 (SND_AUDIOSTREAMFORMAT_MP4ADTS | 432 SND_AUDIOSTREAMFORMAT_RAW), 433 }; 434 435 static int sst_cdev_codec_caps(struct snd_compr_codec_caps *codec) 436 { 437 if (codec->codec == SND_AUDIOCODEC_MP3) 438 *codec = caps_mp3; 439 else if (codec->codec == SND_AUDIOCODEC_AAC) 440 *codec = caps_aac; 441 else 442 return -EINVAL; 443 444 return 0; 445 } 446 447 void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id) 448 { 449 struct stream_info *stream; 450 451 dev_dbg(ctx->dev, "fragment elapsed from firmware for str_id %d\n", 452 str_id); 453 stream = &ctx->streams[str_id]; 454 if (stream->compr_cb) 455 stream->compr_cb(stream->compr_cb_param); 456 } 457 458 /* 459 * sst_close_pcm_stream - Close PCM interface 460 * 461 * @str_id: stream id to be closed 462 * 463 * This function is called by MID sound card driver to close 464 * an existing pcm interface 465 */ 466 static int sst_close_pcm_stream(struct device *dev, unsigned int str_id) 467 { 468 struct stream_info *stream; 469 int retval = 0; 470 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 471 472 stream = get_stream_info(ctx, str_id); 473 if (!stream) { 474 dev_err(ctx->dev, "stream info is NULL for str %d!!!\n", str_id); 475 return -EINVAL; 476 } 477 478 retval = free_stream_context(ctx, str_id); 479 stream->pcm_substream = NULL; 480 stream->status = STREAM_UN_INIT; 481 stream->period_elapsed = NULL; 482 ctx->stream_cnt--; 483 484 if (retval) 485 dev_err(ctx->dev, "free stream returned err %d\n", retval); 486 487 dev_dbg(ctx->dev, "Exit\n"); 488 return 0; 489 } 490 491 static inline int sst_calc_tstamp(struct intel_sst_drv *ctx, 492 struct pcm_stream_info *info, 493 struct snd_pcm_substream *substream, 494 struct snd_sst_tstamp *fw_tstamp) 495 { 496 size_t delay_bytes, delay_frames; 497 size_t buffer_sz; 498 u32 pointer_bytes, pointer_samples; 499 500 dev_dbg(ctx->dev, "mrfld ring_buffer_counter %llu in bytes\n", 501 fw_tstamp->ring_buffer_counter); 502 dev_dbg(ctx->dev, "mrfld hardware_counter %llu in bytes\n", 503 fw_tstamp->hardware_counter); 504 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 505 delay_bytes = (size_t) (fw_tstamp->ring_buffer_counter - 506 fw_tstamp->hardware_counter); 507 else 508 delay_bytes = (size_t) (fw_tstamp->hardware_counter - 509 fw_tstamp->ring_buffer_counter); 510 delay_frames = bytes_to_frames(substream->runtime, delay_bytes); 511 buffer_sz = snd_pcm_lib_buffer_bytes(substream); 512 div_u64_rem(fw_tstamp->ring_buffer_counter, buffer_sz, &pointer_bytes); 513 pointer_samples = bytes_to_samples(substream->runtime, pointer_bytes); 514 515 dev_dbg(ctx->dev, "pcm delay %zu in bytes\n", delay_bytes); 516 517 info->buffer_ptr = pointer_samples / substream->runtime->channels; 518 519 info->pcm_delay = delay_frames; 520 dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n", 521 info->buffer_ptr, info->pcm_delay); 522 return 0; 523 } 524 525 static int sst_read_timestamp(struct device *dev, struct pcm_stream_info *info) 526 { 527 struct stream_info *stream; 528 struct snd_pcm_substream *substream; 529 struct snd_sst_tstamp fw_tstamp; 530 unsigned int str_id; 531 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 532 void __iomem *addr; 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 addr = (void __iomem *)(ctx->mailbox + ctx->tstamp) + 544 (str_id * sizeof(fw_tstamp)); 545 546 memcpy_fromio(&fw_tstamp, addr, sizeof(fw_tstamp)); 547 548 return sst_calc_tstamp(ctx, info, substream, &fw_tstamp); 549 } 550 551 static int sst_stream_start(struct device *dev, int str_id) 552 { 553 struct stream_info *str_info; 554 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 555 556 if (ctx->sst_state != SST_FW_RUNNING) 557 return 0; 558 str_info = get_stream_info(ctx, str_id); 559 if (!str_info) 560 return -EINVAL; 561 str_info->prev = str_info->status; 562 str_info->status = STREAM_RUNNING; 563 sst_start_stream(ctx, str_id); 564 565 return 0; 566 } 567 568 static int sst_stream_drop(struct device *dev, int str_id) 569 { 570 struct stream_info *str_info; 571 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 572 573 if (ctx->sst_state != SST_FW_RUNNING) 574 return 0; 575 576 str_info = get_stream_info(ctx, str_id); 577 if (!str_info) 578 return -EINVAL; 579 str_info->prev = STREAM_UN_INIT; 580 str_info->status = STREAM_INIT; 581 return sst_drop_stream(ctx, str_id); 582 } 583 584 static int sst_stream_pause(struct device *dev, int str_id) 585 { 586 struct stream_info *str_info; 587 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 588 589 if (ctx->sst_state != SST_FW_RUNNING) 590 return 0; 591 592 str_info = get_stream_info(ctx, str_id); 593 if (!str_info) 594 return -EINVAL; 595 596 return sst_pause_stream(ctx, str_id); 597 } 598 599 static int sst_stream_resume(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 return sst_resume_stream(ctx, str_id); 611 } 612 613 static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info) 614 { 615 int str_id = 0; 616 struct stream_info *stream; 617 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 618 619 str_id = str_info->str_id; 620 621 if (ctx->sst_state != SST_FW_RUNNING) 622 return 0; 623 624 stream = get_stream_info(ctx, str_id); 625 if (!stream) 626 return -EINVAL; 627 628 dev_dbg(ctx->dev, "setting the period ptrs\n"); 629 stream->pcm_substream = str_info->arg; 630 stream->period_elapsed = str_info->period_elapsed; 631 stream->sfreq = str_info->sfreq; 632 stream->prev = stream->status; 633 stream->status = STREAM_INIT; 634 dev_dbg(ctx->dev, 635 "pcm_substream %p, period_elapsed %p, sfreq %d, status %d\n", 636 stream->pcm_substream, stream->period_elapsed, 637 stream->sfreq, stream->status); 638 639 return 0; 640 } 641 642 /* 643 * sst_set_byte_stream - Set generic params 644 * 645 * @cmd: control cmd to be set 646 * @arg: command argument 647 * 648 * This function is called by MID sound card driver to configure 649 * SST runtime params. 650 */ 651 static int sst_send_byte_stream(struct device *dev, 652 struct snd_sst_bytes_v2 *bytes) 653 { 654 int ret_val = 0; 655 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 656 657 if (NULL == bytes) 658 return -EINVAL; 659 ret_val = pm_runtime_get_sync(ctx->dev); 660 if (ret_val < 0) { 661 pm_runtime_put_sync(ctx->dev); 662 return ret_val; 663 } 664 665 ret_val = sst_send_byte_stream_mrfld(ctx, bytes); 666 sst_pm_runtime_put(ctx); 667 668 return ret_val; 669 } 670 671 static struct sst_ops pcm_ops = { 672 .open = sst_open_pcm_stream, 673 .stream_init = sst_stream_init, 674 .stream_start = sst_stream_start, 675 .stream_drop = sst_stream_drop, 676 .stream_pause = sst_stream_pause, 677 .stream_pause_release = sst_stream_resume, 678 .stream_read_tstamp = sst_read_timestamp, 679 .send_byte_stream = sst_send_byte_stream, 680 .close = sst_close_pcm_stream, 681 .power = sst_power_control, 682 }; 683 684 static struct compress_sst_ops compr_ops = { 685 .open = sst_cdev_open, 686 .close = sst_cdev_close, 687 .stream_pause = sst_cdev_stream_pause, 688 .stream_pause_release = sst_cdev_stream_pause_release, 689 .stream_start = sst_cdev_stream_start, 690 .stream_drop = sst_cdev_stream_drop, 691 .stream_drain = sst_cdev_stream_drain, 692 .stream_partial_drain = sst_cdev_stream_partial_drain, 693 .tstamp = sst_cdev_tstamp, 694 .ack = sst_cdev_ack, 695 .get_caps = sst_cdev_caps, 696 .get_codec_caps = sst_cdev_codec_caps, 697 .set_metadata = sst_cdev_set_metadata, 698 .power = sst_power_control, 699 }; 700 701 static struct sst_device sst_dsp_device = { 702 .name = "Intel(R) SST LPE", 703 .dev = NULL, 704 .ops = &pcm_ops, 705 .compr_ops = &compr_ops, 706 }; 707 708 /* 709 * sst_register - function to register DSP 710 * 711 * This functions registers DSP with the platform driver 712 */ 713 int sst_register(struct device *dev) 714 { 715 int ret_val; 716 717 sst_dsp_device.dev = dev; 718 ret_val = sst_register_dsp(&sst_dsp_device); 719 if (ret_val) 720 dev_err(dev, "Unable to register DSP with platform driver\n"); 721 722 return ret_val; 723 } 724 725 int sst_unregister(struct device *dev) 726 { 727 return sst_unregister_dsp(&sst_dsp_device); 728 } 729