diff options
author | Vinod Koul <vinod.koul@intel.com> | 2014-06-13 08:33:56 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-06-23 07:24:27 -0400 |
commit | 61b165caa686b8334379293d0e241f740fac195a (patch) | |
tree | bd192f4a4a3cdf617ef1d580140066dfec68f210 /sound/soc/intel/sst-mfld-platform-pcm.c | |
parent | a870cdce9edc57d0196e7ae9cad8acc5720cd709 (diff) |
ASoC: Intel: add mrfld pipelines
Merrifield DSP used various pipelines to identify the streams and processing
modules. Add these defination in the pcm driver and also add a table for device
entries to firmware pipeline id conversion
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/intel/sst-mfld-platform-pcm.c')
-rw-r--r-- | sound/soc/intel/sst-mfld-platform-pcm.c | 100 |
1 files changed, 91 insertions, 9 deletions
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index 6e7bfb1bc4aa..7de87887d9f8 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * sst_mfld_platform.c - Intel MID Platform driver | 2 | * sst_mfld_platform.c - Intel MID Platform driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2013 Intel Corp | 4 | * Copyright (C) 2010-2014 Intel Corp |
5 | * Author: Vinod Koul <vinod.koul@intel.com> | 5 | * Author: Vinod Koul <vinod.koul@intel.com> |
6 | * Author: Harsha Priya <priya.harsha@intel.com> | 6 | * Author: Harsha Priya <priya.harsha@intel.com> |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
@@ -27,7 +27,9 @@ | |||
27 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
28 | #include <sound/soc.h> | 28 | #include <sound/soc.h> |
29 | #include <sound/compress_driver.h> | 29 | #include <sound/compress_driver.h> |
30 | #include <asm/platform_sst_audio.h> | ||
30 | #include "sst-mfld-platform.h" | 31 | #include "sst-mfld-platform.h" |
32 | #include "sst-atom-controls.h" | ||
31 | 33 | ||
32 | struct sst_device *sst; | 34 | struct sst_device *sst; |
33 | static DEFINE_MUTEX(sst_lock); | 35 | static DEFINE_MUTEX(sst_lock); |
@@ -92,6 +94,13 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = { | |||
92 | .fifo_size = SST_FIFO_SIZE, | 94 | .fifo_size = SST_FIFO_SIZE, |
93 | }; | 95 | }; |
94 | 96 | ||
97 | static struct sst_dev_stream_map dpcm_strm_map[] = { | ||
98 | {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* Reserved, not in use */ | ||
99 | {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA1_IN, SST_TASK_ID_MEDIA, 0}, | ||
100 | {MERR_DPCM_COMPR, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA0_IN, SST_TASK_ID_MEDIA, 0}, | ||
101 | {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0}, | ||
102 | }; | ||
103 | |||
95 | /* MFLD - MSIC */ | 104 | /* MFLD - MSIC */ |
96 | static struct snd_soc_dai_driver sst_platform_dai[] = { | 105 | static struct snd_soc_dai_driver sst_platform_dai[] = { |
97 | { | 106 | { |
@@ -175,12 +184,36 @@ static void sst_fill_pcm_params(struct snd_pcm_substream *substream, | |||
175 | memset(param->uc.pcm_params.channel_map, 0, sizeof(u8)); | 184 | memset(param->uc.pcm_params.channel_map, 0, sizeof(u8)); |
176 | 185 | ||
177 | } | 186 | } |
187 | |||
188 | static int sst_get_stream_mapping(int dev, int sdev, int dir, | ||
189 | struct sst_dev_stream_map *map, int size) | ||
190 | { | ||
191 | int i; | ||
192 | |||
193 | if (map == NULL) | ||
194 | return -EINVAL; | ||
195 | |||
196 | |||
197 | /* index 0 is not used in stream map */ | ||
198 | for (i = 1; i < size; i++) { | ||
199 | if ((map[i].dev_num == dev) && (map[i].direction == dir)) | ||
200 | return i; | ||
201 | } | ||
202 | return 0; | ||
203 | } | ||
204 | |||
178 | int sst_fill_stream_params(void *substream, | 205 | int sst_fill_stream_params(void *substream, |
179 | struct snd_sst_params *str_params, bool is_compress) | 206 | const struct sst_data *ctx, struct snd_sst_params *str_params, bool is_compress) |
180 | { | 207 | { |
208 | int map_size; | ||
209 | int index; | ||
210 | struct sst_dev_stream_map *map; | ||
181 | struct snd_pcm_substream *pstream = NULL; | 211 | struct snd_pcm_substream *pstream = NULL; |
182 | struct snd_compr_stream *cstream = NULL; | 212 | struct snd_compr_stream *cstream = NULL; |
183 | 213 | ||
214 | map = ctx->pdata->pdev_strm_map; | ||
215 | map_size = ctx->pdata->strm_map_size; | ||
216 | |||
184 | if (is_compress == true) | 217 | if (is_compress == true) |
185 | cstream = (struct snd_compr_stream *)substream; | 218 | cstream = (struct snd_compr_stream *)substream; |
186 | else | 219 | else |
@@ -189,11 +222,32 @@ int sst_fill_stream_params(void *substream, | |||
189 | str_params->stream_type = SST_STREAM_TYPE_MUSIC; | 222 | str_params->stream_type = SST_STREAM_TYPE_MUSIC; |
190 | 223 | ||
191 | /* For pcm streams */ | 224 | /* For pcm streams */ |
192 | if (pstream) | 225 | if (pstream) { |
226 | index = sst_get_stream_mapping(pstream->pcm->device, | ||
227 | pstream->number, pstream->stream, | ||
228 | map, map_size); | ||
229 | if (index <= 0) | ||
230 | return -EINVAL; | ||
231 | |||
232 | str_params->stream_id = index; | ||
233 | str_params->device_type = map[index].device_id; | ||
234 | str_params->task = map[index].task_id; | ||
235 | |||
193 | str_params->ops = (u8)pstream->stream; | 236 | str_params->ops = (u8)pstream->stream; |
194 | if (cstream) | 237 | } |
195 | str_params->ops = (u8)cstream->direction; | 238 | |
239 | if (cstream) { | ||
240 | index = sst_get_stream_mapping(cstream->device->device, | ||
241 | 0, cstream->direction, | ||
242 | map, map_size); | ||
243 | if (index <= 0) | ||
244 | return -EINVAL; | ||
245 | str_params->stream_id = index; | ||
246 | str_params->device_type = map[index].device_id; | ||
247 | str_params->task = map[index].task_id; | ||
196 | 248 | ||
249 | str_params->ops = (u8)cstream->direction; | ||
250 | } | ||
197 | return 0; | 251 | return 0; |
198 | } | 252 | } |
199 | 253 | ||
@@ -206,6 +260,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream, | |||
206 | struct snd_sst_params str_params = {0}; | 260 | struct snd_sst_params str_params = {0}; |
207 | struct snd_sst_alloc_params_ext alloc_params = {0}; | 261 | struct snd_sst_alloc_params_ext alloc_params = {0}; |
208 | int ret_val = 0; | 262 | int ret_val = 0; |
263 | struct sst_data *ctx = snd_soc_platform_get_drvdata(platform); | ||
209 | 264 | ||
210 | /* set codec params and inform SST driver the same */ | 265 | /* set codec params and inform SST driver the same */ |
211 | sst_fill_pcm_params(substream, ¶m); | 266 | sst_fill_pcm_params(substream, ¶m); |
@@ -216,7 +271,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream, | |||
216 | str_params.codec = SST_CODEC_TYPE_PCM; | 271 | str_params.codec = SST_CODEC_TYPE_PCM; |
217 | 272 | ||
218 | /* fill the device type and stream id to pass to SST driver */ | 273 | /* fill the device type and stream id to pass to SST driver */ |
219 | ret_val = sst_fill_stream_params(substream, &str_params, false); | 274 | ret_val = sst_fill_stream_params(substream, ctx, &str_params, false); |
220 | if (ret_val < 0) | 275 | if (ret_val < 0) |
221 | return ret_val; | 276 | return ret_val; |
222 | 277 | ||
@@ -321,7 +376,22 @@ static void sst_media_close(struct snd_pcm_substream *substream, | |||
321 | ret_val = stream->ops->close(str_id); | 376 | ret_val = stream->ops->close(str_id); |
322 | module_put(sst->dev->driver->owner); | 377 | module_put(sst->dev->driver->owner); |
323 | kfree(stream); | 378 | kfree(stream); |
324 | return; | 379 | } |
380 | |||
381 | static inline unsigned int get_current_pipe_id(struct snd_soc_platform *platform, | ||
382 | struct snd_pcm_substream *substream) | ||
383 | { | ||
384 | struct sst_data *sst = snd_soc_platform_get_drvdata(platform); | ||
385 | struct sst_dev_stream_map *map = sst->pdata->pdev_strm_map; | ||
386 | struct sst_runtime_stream *stream = | ||
387 | substream->runtime->private_data; | ||
388 | u32 str_id = stream->stream_info.str_id; | ||
389 | unsigned int pipe_id; | ||
390 | pipe_id = map[str_id].device_id; | ||
391 | |||
392 | pr_debug("%s: got pipe_id = %#x for str_id = %d\n", | ||
393 | __func__, pipe_id, str_id); | ||
394 | return pipe_id; | ||
325 | } | 395 | } |
326 | 396 | ||
327 | static int sst_media_prepare(struct snd_pcm_substream *substream, | 397 | static int sst_media_prepare(struct snd_pcm_substream *substream, |
@@ -498,10 +568,22 @@ static const struct snd_soc_component_driver sst_component = { | |||
498 | 568 | ||
499 | static int sst_platform_probe(struct platform_device *pdev) | 569 | static int sst_platform_probe(struct platform_device *pdev) |
500 | { | 570 | { |
571 | struct sst_data *drv; | ||
501 | int ret; | 572 | int ret; |
573 | struct sst_platform_data *pdata = pdev->dev.platform_data; | ||
574 | |||
575 | drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); | ||
576 | if (sst == NULL) { | ||
577 | pr_err("kzalloc failed\n"); | ||
578 | return -ENOMEM; | ||
579 | } | ||
580 | |||
581 | pdata->pdev_strm_map = dpcm_strm_map; | ||
582 | pdata->strm_map_size = ARRAY_SIZE(dpcm_strm_map); | ||
583 | drv->pdata = pdata; | ||
584 | mutex_init(&drv->lock); | ||
585 | dev_set_drvdata(&pdev->dev, drv); | ||
502 | 586 | ||
503 | pr_debug("sst_platform_probe called\n"); | ||
504 | sst = NULL; | ||
505 | ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); | 587 | ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); |
506 | if (ret) { | 588 | if (ret) { |
507 | pr_err("registering soc platform failed\n"); | 589 | pr_err("registering soc platform failed\n"); |