Merge remote-tracking branches 'asoc/topic/hdmi', 'asoc/topic/intel', 'asoc/topic...
[firefly-linux-kernel-4.4.55.git] / sound / soc / intel / sst / sst_drv_interface.c
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 "../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
142         dev_dbg(ctx->dev, "state:%d", state);
143         if (state == true)
144                 return pm_runtime_get_sync(dev);
145         else
146                 return sst_pm_runtime_put(ctx);
147 }
148
149 /*
150  * sst_open_pcm_stream - Open PCM interface
151  *
152  * @str_param: parameters of pcm stream
153  *
154  * This function is called by MID sound card driver to open
155  * a new pcm interface
156  */
157 static int sst_open_pcm_stream(struct device *dev,
158                 struct snd_sst_params *str_param)
159 {
160         int retval;
161         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
162
163         if (!str_param)
164                 return -EINVAL;
165
166         retval = sst_get_stream(ctx, str_param);
167         if (retval > 0)
168                 ctx->stream_cnt++;
169         else
170                 dev_err(ctx->dev, "sst_get_stream returned err %d\n", retval);
171
172         return retval;
173 }
174
175 static int sst_cdev_open(struct device *dev,
176                 struct snd_sst_params *str_params, struct sst_compress_cb *cb)
177 {
178         int str_id, retval;
179         struct stream_info *stream;
180         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
181
182         retval = pm_runtime_get_sync(ctx->dev);
183         if (retval < 0)
184                 return retval;
185
186         str_id = sst_get_stream(ctx, str_params);
187         if (str_id > 0) {
188                 dev_dbg(dev, "stream allocated in sst_cdev_open %d\n", str_id);
189                 stream = &ctx->streams[str_id];
190                 stream->compr_cb = cb->compr_cb;
191                 stream->compr_cb_param = cb->param;
192                 stream->drain_notify = cb->drain_notify;
193                 stream->drain_cb_param = cb->drain_cb_param;
194         } else {
195                 dev_err(dev, "stream encountered error during alloc %d\n", str_id);
196                 str_id = -EINVAL;
197                 sst_pm_runtime_put(ctx);
198         }
199         return str_id;
200 }
201
202 static int sst_cdev_close(struct device *dev, unsigned int str_id)
203 {
204         int retval;
205         struct stream_info *stream;
206         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
207
208         stream = get_stream_info(ctx, str_id);
209         if (!stream) {
210                 dev_err(dev, "stream info is NULL for str %d!!!\n", str_id);
211                 return -EINVAL;
212         }
213
214         if (stream->status == STREAM_RESET) {
215                 dev_dbg(dev, "stream in reset state...\n");
216                 stream->status = STREAM_UN_INIT;
217
218                 retval = 0;
219                 goto put;
220         }
221
222         retval = sst_free_stream(ctx, str_id);
223 put:
224         stream->compr_cb_param = NULL;
225         stream->compr_cb = NULL;
226
227         if (retval)
228                 dev_err(dev, "free stream returned err %d\n", retval);
229
230         dev_dbg(dev, "End\n");
231         return retval;
232
233 }
234
235 static int sst_cdev_ack(struct device *dev, unsigned int str_id,
236                 unsigned long bytes)
237 {
238         struct stream_info *stream;
239         struct snd_sst_tstamp fw_tstamp = {0,};
240         int offset;
241         void __iomem *addr;
242         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
243
244         stream = get_stream_info(ctx, str_id);
245         if (!stream)
246                 return -EINVAL;
247
248         /* update bytes sent */
249         stream->cumm_bytes += bytes;
250         dev_dbg(dev, "bytes copied %d inc by %ld\n", stream->cumm_bytes, bytes);
251
252         memcpy_fromio(&fw_tstamp,
253                 ((void *)(ctx->mailbox + ctx->tstamp)
254                 +(str_id * sizeof(fw_tstamp))),
255                 sizeof(fw_tstamp));
256
257         fw_tstamp.bytes_copied = stream->cumm_bytes;
258         dev_dbg(dev, "bytes sent to fw %llu inc by %ld\n",
259                         fw_tstamp.bytes_copied, bytes);
260
261         addr =  ((void *)(ctx->mailbox + ctx->tstamp)) +
262                         (str_id * sizeof(fw_tstamp));
263         offset =  offsetof(struct snd_sst_tstamp, bytes_copied);
264         sst_shim_write(addr, offset, fw_tstamp.bytes_copied);
265         return 0;
266 }
267
268 static int sst_cdev_set_metadata(struct device *dev,
269                 unsigned int str_id, struct snd_compr_metadata *metadata)
270 {
271         int retval = 0;
272         struct stream_info *str_info;
273         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
274
275         dev_dbg(dev, "set metadata for stream %d\n", str_id);
276
277         str_info = get_stream_info(ctx, str_id);
278         if (!str_info)
279                 return -EINVAL;
280
281         dev_dbg(dev, "pipe id = %d\n", str_info->pipe_id);
282         retval = sst_prepare_and_post_msg(ctx, str_info->task_id, IPC_CMD,
283                         IPC_IA_SET_STREAM_PARAMS_MRFLD, str_info->pipe_id,
284                         sizeof(*metadata), metadata, NULL,
285                         true, true, true, false);
286
287         return retval;
288 }
289
290 static int sst_cdev_stream_pause(struct device *dev, unsigned int str_id)
291 {
292         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
293
294         return sst_pause_stream(ctx, str_id);
295 }
296
297 static int sst_cdev_stream_pause_release(struct device *dev,
298                 unsigned int str_id)
299 {
300         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
301
302         return sst_resume_stream(ctx, str_id);
303 }
304
305 static int sst_cdev_stream_start(struct device *dev, unsigned int str_id)
306 {
307         struct stream_info *str_info;
308         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
309
310         str_info = get_stream_info(ctx, str_id);
311         if (!str_info)
312                 return -EINVAL;
313         str_info->prev = str_info->status;
314         str_info->status = STREAM_RUNNING;
315         return sst_start_stream(ctx, str_id);
316 }
317
318 static int sst_cdev_stream_drop(struct device *dev, unsigned int str_id)
319 {
320         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
321
322         return sst_drop_stream(ctx, str_id);
323 }
324
325 static int sst_cdev_stream_drain(struct device *dev, unsigned int str_id)
326 {
327         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
328
329         return sst_drain_stream(ctx, str_id, false);
330 }
331
332 static int sst_cdev_stream_partial_drain(struct device *dev,
333                 unsigned int str_id)
334 {
335         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
336
337         return sst_drain_stream(ctx, str_id, true);
338 }
339
340 static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
341                 struct snd_compr_tstamp *tstamp)
342 {
343         struct snd_sst_tstamp fw_tstamp = {0,};
344         struct stream_info *stream;
345         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
346
347         memcpy_fromio(&fw_tstamp,
348                 ((void *)(ctx->mailbox + ctx->tstamp)
349                 +(str_id * sizeof(fw_tstamp))),
350                 sizeof(fw_tstamp));
351
352         stream = get_stream_info(ctx, str_id);
353         if (!stream)
354                 return -EINVAL;
355         dev_dbg(dev, "rb_counter %llu in bytes\n", fw_tstamp.ring_buffer_counter);
356
357         tstamp->copied_total = fw_tstamp.ring_buffer_counter;
358         tstamp->pcm_frames = fw_tstamp.frames_decoded;
359         tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter,
360                         (u64)((stream->num_ch) * SST_GET_BYTES_PER_SAMPLE(24)));
361         tstamp->sampling_rate = fw_tstamp.sampling_frequency;
362
363         dev_dbg(dev, "PCM  = %u\n", tstamp->pcm_io_frames);
364         dev_dbg(dev, "Ptr Query on strid = %d  copied_total %d, decodec %d\n",
365                 str_id, tstamp->copied_total, tstamp->pcm_frames);
366         dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames);
367
368         return 0;
369 }
370
371 static int sst_cdev_caps(struct snd_compr_caps *caps)
372 {
373         caps->num_codecs = NUM_CODEC;
374         caps->min_fragment_size = MIN_FRAGMENT_SIZE;  /* 50KB */
375         caps->max_fragment_size = MAX_FRAGMENT_SIZE;  /* 1024KB */
376         caps->min_fragments = MIN_FRAGMENT;
377         caps->max_fragments = MAX_FRAGMENT;
378         caps->codecs[0] = SND_AUDIOCODEC_MP3;
379         caps->codecs[1] = SND_AUDIOCODEC_AAC;
380         return 0;
381 }
382
383 static struct snd_compr_codec_caps caps_mp3 = {
384         .num_descriptors = 1,
385         .descriptor[0].max_ch = 2,
386         .descriptor[0].sample_rates[0] = 48000,
387         .descriptor[0].sample_rates[1] = 44100,
388         .descriptor[0].sample_rates[2] = 32000,
389         .descriptor[0].sample_rates[3] = 16000,
390         .descriptor[0].sample_rates[4] = 8000,
391         .descriptor[0].num_sample_rates = 5,
392         .descriptor[0].bit_rate[0] = 320,
393         .descriptor[0].bit_rate[1] = 192,
394         .descriptor[0].num_bitrates = 2,
395         .descriptor[0].profiles = 0,
396         .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO,
397         .descriptor[0].formats = 0,
398 };
399
400 static struct snd_compr_codec_caps caps_aac = {
401         .num_descriptors = 2,
402         .descriptor[1].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[1].bit_rate[0] = 320,
410         .descriptor[1].bit_rate[1] = 192,
411         .descriptor[1].num_bitrates = 2,
412         .descriptor[1].profiles = 0,
413         .descriptor[1].modes = 0,
414         .descriptor[1].formats =
415                         (SND_AUDIOSTREAMFORMAT_MP4ADTS |
416                                 SND_AUDIOSTREAMFORMAT_RAW),
417 };
418
419 static int sst_cdev_codec_caps(struct snd_compr_codec_caps *codec)
420 {
421         if (codec->codec == SND_AUDIOCODEC_MP3)
422                 *codec = caps_mp3;
423         else if (codec->codec == SND_AUDIOCODEC_AAC)
424                 *codec = caps_aac;
425         else
426                 return -EINVAL;
427
428         return 0;
429 }
430
431 void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id)
432 {
433         struct stream_info *stream;
434
435         dev_dbg(ctx->dev, "fragment elapsed from firmware for str_id %d\n",
436                         str_id);
437         stream = &ctx->streams[str_id];
438         if (stream->compr_cb)
439                 stream->compr_cb(stream->compr_cb_param);
440 }
441
442 /*
443  * sst_close_pcm_stream - Close PCM interface
444  *
445  * @str_id: stream id to be closed
446  *
447  * This function is called by MID sound card driver to close
448  * an existing pcm interface
449  */
450 static int sst_close_pcm_stream(struct device *dev, unsigned int str_id)
451 {
452         struct stream_info *stream;
453         int retval = 0;
454         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
455
456         stream = get_stream_info(ctx, str_id);
457         if (!stream) {
458                 dev_err(ctx->dev, "stream info is NULL for str %d!!!\n", str_id);
459                 return -EINVAL;
460         }
461
462         if (stream->status == STREAM_RESET) {
463                 /* silently fail here as we have cleaned the stream earlier */
464                 dev_dbg(ctx->dev, "stream in reset state...\n");
465
466                 retval = 0;
467                 goto put;
468         }
469
470         retval = free_stream_context(ctx, str_id);
471 put:
472         stream->pcm_substream = NULL;
473         stream->status = STREAM_UN_INIT;
474         stream->period_elapsed = NULL;
475         ctx->stream_cnt--;
476
477         if (retval)
478                 dev_err(ctx->dev, "free stream returned err %d\n", retval);
479
480         dev_dbg(ctx->dev, "Exit\n");
481         return 0;
482 }
483
484 static inline int sst_calc_tstamp(struct intel_sst_drv *ctx,
485                 struct pcm_stream_info *info,
486                 struct snd_pcm_substream *substream,
487                 struct snd_sst_tstamp *fw_tstamp)
488 {
489         size_t delay_bytes, delay_frames;
490         size_t buffer_sz;
491         u32 pointer_bytes, pointer_samples;
492
493         dev_dbg(ctx->dev, "mrfld ring_buffer_counter %llu in bytes\n",
494                         fw_tstamp->ring_buffer_counter);
495         dev_dbg(ctx->dev, "mrfld hardware_counter %llu in bytes\n",
496                          fw_tstamp->hardware_counter);
497         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
498                 delay_bytes = (size_t) (fw_tstamp->ring_buffer_counter -
499                                         fw_tstamp->hardware_counter);
500         else
501                 delay_bytes = (size_t) (fw_tstamp->hardware_counter -
502                                         fw_tstamp->ring_buffer_counter);
503         delay_frames = bytes_to_frames(substream->runtime, delay_bytes);
504         buffer_sz = snd_pcm_lib_buffer_bytes(substream);
505         div_u64_rem(fw_tstamp->ring_buffer_counter, buffer_sz, &pointer_bytes);
506         pointer_samples = bytes_to_samples(substream->runtime, pointer_bytes);
507
508         dev_dbg(ctx->dev, "pcm delay %zu in bytes\n", delay_bytes);
509
510         info->buffer_ptr = pointer_samples / substream->runtime->channels;
511
512         info->pcm_delay = delay_frames / substream->runtime->channels;
513         dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n",
514                         info->buffer_ptr, info->pcm_delay);
515         return 0;
516 }
517
518 static int sst_read_timestamp(struct device *dev, struct pcm_stream_info *info)
519 {
520         struct stream_info *stream;
521         struct snd_pcm_substream *substream;
522         struct snd_sst_tstamp fw_tstamp;
523         unsigned int str_id;
524         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
525
526         str_id = info->str_id;
527         stream = get_stream_info(ctx, str_id);
528         if (!stream)
529                 return -EINVAL;
530
531         if (!stream->pcm_substream)
532                 return -EINVAL;
533         substream = stream->pcm_substream;
534
535         memcpy_fromio(&fw_tstamp,
536                 ((void *)(ctx->mailbox + ctx->tstamp)
537                         + (str_id * sizeof(fw_tstamp))),
538                 sizeof(fw_tstamp));
539         return sst_calc_tstamp(ctx, info, substream, &fw_tstamp);
540 }
541
542 static int sst_stream_start(struct device *dev, int str_id)
543 {
544         struct stream_info *str_info;
545         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
546
547         if (ctx->sst_state != SST_FW_RUNNING)
548                 return 0;
549         str_info = get_stream_info(ctx, str_id);
550         if (!str_info)
551                 return -EINVAL;
552         str_info->prev = str_info->status;
553         str_info->status = STREAM_RUNNING;
554         sst_start_stream(ctx, str_id);
555
556         return 0;
557 }
558
559 static int sst_stream_drop(struct device *dev, int str_id)
560 {
561         struct stream_info *str_info;
562         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
563
564         if (ctx->sst_state != SST_FW_RUNNING)
565                 return 0;
566
567         str_info = get_stream_info(ctx, str_id);
568         if (!str_info)
569                 return -EINVAL;
570         str_info->prev = STREAM_UN_INIT;
571         str_info->status = STREAM_INIT;
572         return sst_drop_stream(ctx, str_id);
573 }
574
575 static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info)
576 {
577         int str_id = 0;
578         struct stream_info *stream;
579         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
580
581         str_id = str_info->str_id;
582
583         if (ctx->sst_state != SST_FW_RUNNING)
584                 return 0;
585
586         stream = get_stream_info(ctx, str_id);
587         if (!stream)
588                 return -EINVAL;
589
590         dev_dbg(ctx->dev, "setting the period ptrs\n");
591         stream->pcm_substream = str_info->arg;
592         stream->period_elapsed = str_info->period_elapsed;
593         stream->sfreq = str_info->sfreq;
594         stream->prev = stream->status;
595         stream->status = STREAM_INIT;
596         dev_dbg(ctx->dev,
597                 "pcm_substream %p, period_elapsed %p, sfreq %d, status %d\n",
598                 stream->pcm_substream, stream->period_elapsed,
599                 stream->sfreq, stream->status);
600
601         return 0;
602 }
603
604 /*
605  * sst_set_byte_stream - Set generic params
606  *
607  * @cmd: control cmd to be set
608  * @arg: command argument
609  *
610  * This function is called by MID sound card driver to configure
611  * SST runtime params.
612  */
613 static int sst_send_byte_stream(struct device *dev,
614                 struct snd_sst_bytes_v2 *bytes)
615 {
616         int ret_val = 0;
617         struct intel_sst_drv *ctx = dev_get_drvdata(dev);
618
619         if (NULL == bytes)
620                 return -EINVAL;
621         ret_val = pm_runtime_get_sync(ctx->dev);
622         if (ret_val < 0)
623                 return ret_val;
624
625         ret_val = sst_send_byte_stream_mrfld(ctx, bytes);
626         sst_pm_runtime_put(ctx);
627
628         return ret_val;
629 }
630
631 static struct sst_ops pcm_ops = {
632         .open = sst_open_pcm_stream,
633         .stream_init = sst_stream_init,
634         .stream_start = sst_stream_start,
635         .stream_drop = sst_stream_drop,
636         .stream_read_tstamp = sst_read_timestamp,
637         .send_byte_stream = sst_send_byte_stream,
638         .close = sst_close_pcm_stream,
639         .power = sst_power_control,
640 };
641
642 static struct compress_sst_ops compr_ops = {
643         .open = sst_cdev_open,
644         .close = sst_cdev_close,
645         .stream_pause = sst_cdev_stream_pause,
646         .stream_pause_release = sst_cdev_stream_pause_release,
647         .stream_start = sst_cdev_stream_start,
648         .stream_drop = sst_cdev_stream_drop,
649         .stream_drain = sst_cdev_stream_drain,
650         .stream_partial_drain = sst_cdev_stream_partial_drain,
651         .tstamp = sst_cdev_tstamp,
652         .ack = sst_cdev_ack,
653         .get_caps = sst_cdev_caps,
654         .get_codec_caps = sst_cdev_codec_caps,
655         .set_metadata = sst_cdev_set_metadata,
656         .power = sst_power_control,
657 };
658
659 static struct sst_device sst_dsp_device = {
660         .name = "Intel(R) SST LPE",
661         .dev = NULL,
662         .ops = &pcm_ops,
663         .compr_ops = &compr_ops,
664 };
665
666 /*
667  * sst_register - function to register DSP
668  *
669  * This functions registers DSP with the platform driver
670  */
671 int sst_register(struct device *dev)
672 {
673         int ret_val;
674
675         sst_dsp_device.dev = dev;
676         ret_val = sst_register_dsp(&sst_dsp_device);
677         if (ret_val)
678                 dev_err(dev, "Unable to register DSP with platform driver\n");
679
680         return ret_val;
681 }
682
683 int sst_unregister(struct device *dev)
684 {
685         return sst_unregister_dsp(&sst_dsp_device);
686 }