Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us