]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - sound/soc/mid-x86/sst_platform.c
arm: imx6: defconfig: update tx6 defconfigs
[karo-tx-linux.git] / sound / soc / mid-x86 / sst_platform.c
1 /*
2  *  sst_platform.c - Intel MID Platform driver
3  *
4  *  Copyright (C) 2010-2013 Intel Corp
5  *  Author: Vinod Koul <vinod.koul@intel.com>
6  *  Author: Harsha Priya <priya.harsha@intel.com>
7  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; version 2 of the License.
12  *
13  *  This program is distributed in the hope that it will be useful, but
14  *  WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21  *
22  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23  *
24  *
25  */
26 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28 #include <linux/slab.h>
29 #include <linux/io.h>
30 #include <linux/module.h>
31 #include <sound/core.h>
32 #include <sound/pcm.h>
33 #include <sound/pcm_params.h>
34 #include <sound/soc.h>
35 #include <sound/compress_driver.h>
36 #include "sst_platform.h"
37
38 static struct sst_device *sst;
39 static DEFINE_MUTEX(sst_lock);
40
41 int sst_register_dsp(struct sst_device *dev)
42 {
43         BUG_ON(!dev);
44         if (!try_module_get(dev->dev->driver->owner))
45                 return -ENODEV;
46         mutex_lock(&sst_lock);
47         if (sst) {
48                 pr_err("we already have a device %s\n", sst->name);
49                 module_put(dev->dev->driver->owner);
50                 mutex_unlock(&sst_lock);
51                 return -EEXIST;
52         }
53         pr_debug("registering device %s\n", dev->name);
54         sst = dev;
55         mutex_unlock(&sst_lock);
56         return 0;
57 }
58 EXPORT_SYMBOL_GPL(sst_register_dsp);
59
60 int sst_unregister_dsp(struct sst_device *dev)
61 {
62         BUG_ON(!dev);
63         if (dev != sst)
64                 return -EINVAL;
65
66         mutex_lock(&sst_lock);
67
68         if (!sst) {
69                 mutex_unlock(&sst_lock);
70                 return -EIO;
71         }
72
73         module_put(sst->dev->driver->owner);
74         pr_debug("unreg %s\n", sst->name);
75         sst = NULL;
76         mutex_unlock(&sst_lock);
77         return 0;
78 }
79 EXPORT_SYMBOL_GPL(sst_unregister_dsp);
80
81 static struct snd_pcm_hardware sst_platform_pcm_hw = {
82         .info = (SNDRV_PCM_INFO_INTERLEAVED |
83                         SNDRV_PCM_INFO_DOUBLE |
84                         SNDRV_PCM_INFO_PAUSE |
85                         SNDRV_PCM_INFO_RESUME |
86                         SNDRV_PCM_INFO_MMAP|
87                         SNDRV_PCM_INFO_MMAP_VALID |
88                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
89                         SNDRV_PCM_INFO_SYNC_START),
90         .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
91                         SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
92                         SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
93         .rates = (SNDRV_PCM_RATE_8000|
94                         SNDRV_PCM_RATE_44100 |
95                         SNDRV_PCM_RATE_48000),
96         .rate_min = SST_MIN_RATE,
97         .rate_max = SST_MAX_RATE,
98         .channels_min = SST_MIN_CHANNEL,
99         .channels_max = SST_MAX_CHANNEL,
100         .buffer_bytes_max = SST_MAX_BUFFER,
101         .period_bytes_min = SST_MIN_PERIOD_BYTES,
102         .period_bytes_max = SST_MAX_PERIOD_BYTES,
103         .periods_min = SST_MIN_PERIODS,
104         .periods_max = SST_MAX_PERIODS,
105         .fifo_size = SST_FIFO_SIZE,
106 };
107
108 /* MFLD - MSIC */
109 static struct snd_soc_dai_driver sst_platform_dai[] = {
110 {
111         .name = "Headset-cpu-dai",
112         .id = 0,
113         .playback = {
114                 .channels_min = SST_STEREO,
115                 .channels_max = SST_STEREO,
116                 .rates = SNDRV_PCM_RATE_48000,
117                 .formats = SNDRV_PCM_FMTBIT_S24_LE,
118         },
119         .capture = {
120                 .channels_min = 1,
121                 .channels_max = 5,
122                 .rates = SNDRV_PCM_RATE_48000,
123                 .formats = SNDRV_PCM_FMTBIT_S24_LE,
124         },
125 },
126 {
127         .name = "Speaker-cpu-dai",
128         .id = 1,
129         .playback = {
130                 .channels_min = SST_MONO,
131                 .channels_max = SST_STEREO,
132                 .rates = SNDRV_PCM_RATE_48000,
133                 .formats = SNDRV_PCM_FMTBIT_S24_LE,
134         },
135 },
136 {
137         .name = "Vibra1-cpu-dai",
138         .id = 2,
139         .playback = {
140                 .channels_min = SST_MONO,
141                 .channels_max = SST_MONO,
142                 .rates = SNDRV_PCM_RATE_48000,
143                 .formats = SNDRV_PCM_FMTBIT_S24_LE,
144         },
145 },
146 {
147         .name = "Vibra2-cpu-dai",
148         .id = 3,
149         .playback = {
150                 .channels_min = SST_MONO,
151                 .channels_max = SST_STEREO,
152                 .rates = SNDRV_PCM_RATE_48000,
153                 .formats = SNDRV_PCM_FMTBIT_S24_LE,
154         },
155 },
156 {
157         .name = "Compress-cpu-dai",
158         .compress_dai = 1,
159         .playback = {
160                 .channels_min = SST_STEREO,
161                 .channels_max = SST_STEREO,
162                 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
163                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
164         },
165 },
166 };
167
168 static const struct snd_soc_component_driver sst_component = {
169         .name           = "sst",
170 };
171
172 /* helper functions */
173 static inline void sst_set_stream_status(struct sst_runtime_stream *stream,
174                                         int state)
175 {
176         unsigned long flags;
177         spin_lock_irqsave(&stream->status_lock, flags);
178         stream->stream_status = state;
179         spin_unlock_irqrestore(&stream->status_lock, flags);
180 }
181
182 static inline int sst_get_stream_status(struct sst_runtime_stream *stream)
183 {
184         int state;
185         unsigned long flags;
186
187         spin_lock_irqsave(&stream->status_lock, flags);
188         state = stream->stream_status;
189         spin_unlock_irqrestore(&stream->status_lock, flags);
190         return state;
191 }
192
193 static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
194                                 struct sst_pcm_params *param)
195 {
196
197         param->codec = SST_CODEC_TYPE_PCM;
198         param->num_chan = (u8) substream->runtime->channels;
199         param->pcm_wd_sz = substream->runtime->sample_bits;
200         param->reserved = 0;
201         param->sfreq = substream->runtime->rate;
202         param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream);
203         param->period_count = substream->runtime->period_size;
204         param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area);
205         pr_debug("period_cnt = %d\n", param->period_count);
206         pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz);
207 }
208
209 static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
210 {
211         struct sst_runtime_stream *stream =
212                         substream->runtime->private_data;
213         struct sst_pcm_params param = {0};
214         struct sst_stream_params str_params = {0};
215         int ret_val;
216
217         /* set codec params and inform SST driver the same */
218         sst_fill_pcm_params(substream, &param);
219         substream->runtime->dma_area = substream->dma_buffer.area;
220         str_params.sparams = param;
221         str_params.codec =  param.codec;
222         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
223                 str_params.ops = STREAM_OPS_PLAYBACK;
224                 str_params.device_type = substream->pcm->device + 1;
225                 pr_debug("Playbck stream,Device %d\n",
226                                         substream->pcm->device);
227         } else {
228                 str_params.ops = STREAM_OPS_CAPTURE;
229                 str_params.device_type = SND_SST_DEVICE_CAPTURE;
230                 pr_debug("Capture stream,Device %d\n",
231                                         substream->pcm->device);
232         }
233         ret_val = stream->ops->open(&str_params);
234         pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
235         if (ret_val < 0)
236                 return ret_val;
237
238         stream->stream_info.str_id = ret_val;
239         pr_debug("str id :  %d\n", stream->stream_info.str_id);
240         return ret_val;
241 }
242
243 static void sst_period_elapsed(void *mad_substream)
244 {
245         struct snd_pcm_substream *substream = mad_substream;
246         struct sst_runtime_stream *stream;
247         int status;
248
249         if (!substream || !substream->runtime)
250                 return;
251         stream = substream->runtime->private_data;
252         if (!stream)
253                 return;
254         status = sst_get_stream_status(stream);
255         if (status != SST_PLATFORM_RUNNING)
256                 return;
257         snd_pcm_period_elapsed(substream);
258 }
259
260 static int sst_platform_init_stream(struct snd_pcm_substream *substream)
261 {
262         struct sst_runtime_stream *stream =
263                         substream->runtime->private_data;
264         int ret_val;
265
266         pr_debug("setting buffer ptr param\n");
267         sst_set_stream_status(stream, SST_PLATFORM_INIT);
268         stream->stream_info.period_elapsed = sst_period_elapsed;
269         stream->stream_info.mad_substream = substream;
270         stream->stream_info.buffer_ptr = 0;
271         stream->stream_info.sfreq = substream->runtime->rate;
272         ret_val = stream->ops->device_control(
273                         SST_SND_STREAM_INIT, &stream->stream_info);
274         if (ret_val)
275                 pr_err("control_set ret error %d\n", ret_val);
276         return ret_val;
277
278 }
279 /* end -- helper functions */
280
281 static int sst_platform_open(struct snd_pcm_substream *substream)
282 {
283         struct snd_pcm_runtime *runtime = substream->runtime;
284         struct sst_runtime_stream *stream;
285         int ret_val;
286
287         pr_debug("sst_platform_open called\n");
288
289         snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw);
290         ret_val = snd_pcm_hw_constraint_integer(runtime,
291                                                 SNDRV_PCM_HW_PARAM_PERIODS);
292         if (ret_val < 0)
293                 return ret_val;
294
295         stream = kzalloc(sizeof(*stream), GFP_KERNEL);
296         if (!stream)
297                 return -ENOMEM;
298         spin_lock_init(&stream->status_lock);
299
300         /* get the sst ops */
301         mutex_lock(&sst_lock);
302         if (!sst) {
303                 pr_err("no device available to run\n");
304                 mutex_unlock(&sst_lock);
305                 kfree(stream);
306                 return -ENODEV;
307         }
308         if (!try_module_get(sst->dev->driver->owner)) {
309                 mutex_unlock(&sst_lock);
310                 kfree(stream);
311                 return -ENODEV;
312         }
313         stream->ops = sst->ops;
314         mutex_unlock(&sst_lock);
315
316         stream->stream_info.str_id = 0;
317         sst_set_stream_status(stream, SST_PLATFORM_INIT);
318         stream->stream_info.mad_substream = substream;
319         /* allocate memory for SST API set */
320         runtime->private_data = stream;
321
322         return 0;
323 }
324
325 static int sst_platform_close(struct snd_pcm_substream *substream)
326 {
327         struct sst_runtime_stream *stream;
328         int ret_val = 0, str_id;
329
330         pr_debug("sst_platform_close called\n");
331         stream = substream->runtime->private_data;
332         str_id = stream->stream_info.str_id;
333         if (str_id)
334                 ret_val = stream->ops->close(str_id);
335         module_put(sst->dev->driver->owner);
336         kfree(stream);
337         return ret_val;
338 }
339
340 static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
341 {
342         struct sst_runtime_stream *stream;
343         int ret_val = 0, str_id;
344
345         pr_debug("sst_platform_pcm_prepare called\n");
346         stream = substream->runtime->private_data;
347         str_id = stream->stream_info.str_id;
348         if (stream->stream_info.str_id) {
349                 ret_val = stream->ops->device_control(
350                                 SST_SND_DROP, &str_id);
351                 return ret_val;
352         }
353
354         ret_val = sst_platform_alloc_stream(substream);
355         if (ret_val < 0)
356                 return ret_val;
357         snprintf(substream->pcm->id, sizeof(substream->pcm->id),
358                         "%d", stream->stream_info.str_id);
359
360         ret_val = sst_platform_init_stream(substream);
361         if (ret_val)
362                 return ret_val;
363         substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER;
364         return ret_val;
365 }
366
367 static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
368                                         int cmd)
369 {
370         int ret_val = 0, str_id;
371         struct sst_runtime_stream *stream;
372         int str_cmd, status;
373
374         pr_debug("sst_platform_pcm_trigger called\n");
375         stream = substream->runtime->private_data;
376         str_id = stream->stream_info.str_id;
377         switch (cmd) {
378         case SNDRV_PCM_TRIGGER_START:
379                 pr_debug("sst: Trigger Start\n");
380                 str_cmd = SST_SND_START;
381                 status = SST_PLATFORM_RUNNING;
382                 stream->stream_info.mad_substream = substream;
383                 break;
384         case SNDRV_PCM_TRIGGER_STOP:
385                 pr_debug("sst: in stop\n");
386                 str_cmd = SST_SND_DROP;
387                 status = SST_PLATFORM_DROPPED;
388                 break;
389         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
390                 pr_debug("sst: in pause\n");
391                 str_cmd = SST_SND_PAUSE;
392                 status = SST_PLATFORM_PAUSED;
393                 break;
394         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
395                 pr_debug("sst: in pause release\n");
396                 str_cmd = SST_SND_RESUME;
397                 status = SST_PLATFORM_RUNNING;
398                 break;
399         default:
400                 return -EINVAL;
401         }
402         ret_val = stream->ops->device_control(str_cmd, &str_id);
403         if (!ret_val)
404                 sst_set_stream_status(stream, status);
405
406         return ret_val;
407 }
408
409
410 static snd_pcm_uframes_t sst_platform_pcm_pointer
411                         (struct snd_pcm_substream *substream)
412 {
413         struct sst_runtime_stream *stream;
414         int ret_val, status;
415         struct pcm_stream_info *str_info;
416
417         stream = substream->runtime->private_data;
418         status = sst_get_stream_status(stream);
419         if (status == SST_PLATFORM_INIT)
420                 return 0;
421         str_info = &stream->stream_info;
422         ret_val = stream->ops->device_control(
423                                 SST_SND_BUFFER_POINTER, str_info);
424         if (ret_val) {
425                 pr_err("sst: error code = %d\n", ret_val);
426                 return ret_val;
427         }
428         return stream->stream_info.buffer_ptr;
429 }
430
431 static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
432                 struct snd_pcm_hw_params *params)
433 {
434         snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
435         memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
436
437         return 0;
438 }
439
440 static int sst_platform_pcm_hw_free(struct snd_pcm_substream *substream)
441 {
442         return snd_pcm_lib_free_pages(substream);
443 }
444
445 static struct snd_pcm_ops sst_platform_ops = {
446         .open = sst_platform_open,
447         .close = sst_platform_close,
448         .ioctl = snd_pcm_lib_ioctl,
449         .prepare = sst_platform_pcm_prepare,
450         .trigger = sst_platform_pcm_trigger,
451         .pointer = sst_platform_pcm_pointer,
452         .hw_params = sst_platform_pcm_hw_params,
453         .hw_free = sst_platform_pcm_hw_free,
454 };
455
456 static void sst_pcm_free(struct snd_pcm *pcm)
457 {
458         pr_debug("sst_pcm_free called\n");
459         snd_pcm_lib_preallocate_free_for_all(pcm);
460 }
461
462 static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
463 {
464         struct snd_pcm *pcm = rtd->pcm;
465         int retval = 0;
466
467         pr_debug("sst_pcm_new called\n");
468         if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
469                         pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
470                 retval =  snd_pcm_lib_preallocate_pages_for_all(pcm,
471                         SNDRV_DMA_TYPE_CONTINUOUS,
472                         snd_dma_continuous_data(GFP_KERNEL),
473                         SST_MIN_BUFFER, SST_MAX_BUFFER);
474                 if (retval) {
475                         pr_err("dma buffer allocationf fail\n");
476                         return retval;
477                 }
478         }
479         return retval;
480 }
481
482 /* compress stream operations */
483 static void sst_compr_fragment_elapsed(void *arg)
484 {
485         struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;
486
487         pr_debug("fragment elapsed by driver\n");
488         if (cstream)
489                 snd_compr_fragment_elapsed(cstream);
490 }
491
492 static int sst_platform_compr_open(struct snd_compr_stream *cstream)
493 {
494
495         int ret_val = 0;
496         struct snd_compr_runtime *runtime = cstream->runtime;
497         struct sst_runtime_stream *stream;
498
499         stream = kzalloc(sizeof(*stream), GFP_KERNEL);
500         if (!stream)
501                 return -ENOMEM;
502
503         spin_lock_init(&stream->status_lock);
504
505         /* get the sst ops */
506         if (!sst || !try_module_get(sst->dev->driver->owner)) {
507                 pr_err("no device available to run\n");
508                 ret_val = -ENODEV;
509                 goto out_ops;
510         }
511         stream->compr_ops = sst->compr_ops;
512
513         stream->id = 0;
514         sst_set_stream_status(stream, SST_PLATFORM_INIT);
515         runtime->private_data = stream;
516         return 0;
517 out_ops:
518         kfree(stream);
519         return ret_val;
520 }
521
522 static int sst_platform_compr_free(struct snd_compr_stream *cstream)
523 {
524         struct sst_runtime_stream *stream;
525         int ret_val = 0, str_id;
526
527         stream = cstream->runtime->private_data;
528         /*need to check*/
529         str_id = stream->id;
530         if (str_id)
531                 ret_val = stream->compr_ops->close(str_id);
532         module_put(sst->dev->driver->owner);
533         kfree(stream);
534         pr_debug("%s: %d\n", __func__, ret_val);
535         return 0;
536 }
537
538 static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
539                                         struct snd_compr_params *params)
540 {
541         struct sst_runtime_stream *stream;
542         int retval;
543         struct snd_sst_params str_params;
544         struct sst_compress_cb cb;
545
546         stream = cstream->runtime->private_data;
547         /* construct fw structure for this*/
548         memset(&str_params, 0, sizeof(str_params));
549
550         str_params.ops = STREAM_OPS_PLAYBACK;
551         str_params.stream_type = SST_STREAM_TYPE_MUSIC;
552         str_params.device_type = SND_SST_DEVICE_COMPRESS;
553
554         switch (params->codec.id) {
555         case SND_AUDIOCODEC_MP3: {
556                 str_params.codec = SST_CODEC_TYPE_MP3;
557                 str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3;
558                 str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in;
559                 str_params.sparams.uc.mp3_params.pcm_wd_sz = 16;
560                 break;
561         }
562
563         case SND_AUDIOCODEC_AAC: {
564                 str_params.codec = SST_CODEC_TYPE_AAC;
565                 str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC;
566                 str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in;
567                 str_params.sparams.uc.aac_params.pcm_wd_sz = 16;
568                 if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS)
569                         str_params.sparams.uc.aac_params.bs_format =
570                                                         AAC_BIT_STREAM_ADTS;
571                 else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW)
572                         str_params.sparams.uc.aac_params.bs_format =
573                                                         AAC_BIT_STREAM_RAW;
574                 else {
575                         pr_err("Undefined format%d\n", params->codec.format);
576                         return -EINVAL;
577                 }
578                 str_params.sparams.uc.aac_params.externalsr =
579                                                 params->codec.sample_rate;
580                 break;
581         }
582
583         default:
584                 pr_err("codec not supported, id =%d\n", params->codec.id);
585                 return -EINVAL;
586         }
587
588         str_params.aparams.ring_buf_info[0].addr  =
589                                         virt_to_phys(cstream->runtime->buffer);
590         str_params.aparams.ring_buf_info[0].size =
591                                         cstream->runtime->buffer_size;
592         str_params.aparams.sg_count = 1;
593         str_params.aparams.frag_size = cstream->runtime->fragment_size;
594
595         cb.param = cstream;
596         cb.compr_cb = sst_compr_fragment_elapsed;
597
598         retval = stream->compr_ops->open(&str_params, &cb);
599         if (retval < 0) {
600                 pr_err("stream allocation failed %d\n", retval);
601                 return retval;
602         }
603
604         stream->id = retval;
605         return 0;
606 }
607
608 static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd)
609 {
610         struct sst_runtime_stream *stream =
611                 cstream->runtime->private_data;
612
613         return stream->compr_ops->control(cmd, stream->id);
614 }
615
616 static int sst_platform_compr_pointer(struct snd_compr_stream *cstream,
617                                         struct snd_compr_tstamp *tstamp)
618 {
619         struct sst_runtime_stream *stream;
620
621         stream  = cstream->runtime->private_data;
622         stream->compr_ops->tstamp(stream->id, tstamp);
623         tstamp->byte_offset = tstamp->copied_total %
624                                  (u32)cstream->runtime->buffer_size;
625         pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
626         return 0;
627 }
628
629 static int sst_platform_compr_ack(struct snd_compr_stream *cstream,
630                                         size_t bytes)
631 {
632         struct sst_runtime_stream *stream;
633
634         stream  = cstream->runtime->private_data;
635         stream->compr_ops->ack(stream->id, (unsigned long)bytes);
636         stream->bytes_written += bytes;
637
638         return 0;
639 }
640
641 static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream,
642                                         struct snd_compr_caps *caps)
643 {
644         struct sst_runtime_stream *stream =
645                 cstream->runtime->private_data;
646
647         return stream->compr_ops->get_caps(caps);
648 }
649
650 static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream,
651                                         struct snd_compr_codec_caps *codec)
652 {
653         struct sst_runtime_stream *stream =
654                 cstream->runtime->private_data;
655
656         return stream->compr_ops->get_codec_caps(codec);
657 }
658
659 static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream,
660                                         struct snd_compr_metadata *metadata)
661 {
662         struct sst_runtime_stream *stream  =
663                  cstream->runtime->private_data;
664
665         return stream->compr_ops->set_metadata(stream->id, metadata);
666 }
667
668 static struct snd_compr_ops sst_platform_compr_ops = {
669
670         .open = sst_platform_compr_open,
671         .free = sst_platform_compr_free,
672         .set_params = sst_platform_compr_set_params,
673         .set_metadata = sst_platform_compr_set_metadata,
674         .trigger = sst_platform_compr_trigger,
675         .pointer = sst_platform_compr_pointer,
676         .ack = sst_platform_compr_ack,
677         .get_caps = sst_platform_compr_get_caps,
678         .get_codec_caps = sst_platform_compr_get_codec_caps,
679 };
680
681 static struct snd_soc_platform_driver sst_soc_platform_drv = {
682         .ops            = &sst_platform_ops,
683         .compr_ops      = &sst_platform_compr_ops,
684         .pcm_new        = sst_pcm_new,
685         .pcm_free       = sst_pcm_free,
686 };
687
688 static int sst_platform_probe(struct platform_device *pdev)
689 {
690         int ret;
691
692         pr_debug("sst_platform_probe called\n");
693         sst = NULL;
694         ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
695         if (ret) {
696                 pr_err("registering soc platform failed\n");
697                 return ret;
698         }
699
700         ret = snd_soc_register_component(&pdev->dev, &sst_component,
701                                 sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
702         if (ret) {
703                 pr_err("registering cpu dais failed\n");
704                 snd_soc_unregister_platform(&pdev->dev);
705         }
706         return ret;
707 }
708
709 static int sst_platform_remove(struct platform_device *pdev)
710 {
711
712         snd_soc_unregister_component(&pdev->dev);
713         snd_soc_unregister_platform(&pdev->dev);
714         pr_debug("sst_platform_remove success\n");
715         return 0;
716 }
717
718 static struct platform_driver sst_platform_driver = {
719         .driver         = {
720                 .name           = "sst-platform",
721                 .owner          = THIS_MODULE,
722         },
723         .probe          = sst_platform_probe,
724         .remove         = sst_platform_remove,
725 };
726
727 module_platform_driver(sst_platform_driver);
728
729 MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
730 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
731 MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
732 MODULE_LICENSE("GPL v2");
733 MODULE_ALIAS("platform:sst-platform");