struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
/* DAI data */
- struct hsw_pcm_data pcm[HSW_PCM_COUNT];
+ struct hsw_pcm_data pcm[HSW_PCM_COUNT][2];
+};
+
+
+/* static mappings between PCMs and modules - may be dynamic in future */
+static struct hsw_pcm_module_map mod_map[] = {
+ {HSW_PCM_DAI_ID_SYSTEM, 0, SST_HSW_MODULE_PCM_SYSTEM},
+ {HSW_PCM_DAI_ID_OFFLOAD0, 0, SST_HSW_MODULE_PCM},
+ {HSW_PCM_DAI_ID_OFFLOAD1, 0, SST_HSW_MODULE_PCM},
+ {HSW_PCM_DAI_ID_LOOPBACK, 1, SST_HSW_MODULE_PCM_REFERENCE},
+ {HSW_PCM_DAI_ID_SYSTEM, 1, SST_HSW_MODULE_PCM_CAPTURE},
};
static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
(struct soc_mixer_control *)kcontrol->private_value;
struct hsw_priv_data *pdata =
snd_soc_platform_get_drvdata(platform);
- struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
+ struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
u32 volume;
+ int dai, stream;
+
+ dai = mod_map[mc->reg].dai_id;
+ stream = mod_map[mc->reg].stream;
+ pcm_data = &pdata->pcm[dai][stream];
mutex_lock(&pcm_data->mutex);
pm_runtime_get_sync(pdata->dev);
(struct soc_mixer_control *)kcontrol->private_value;
struct hsw_priv_data *pdata =
snd_soc_platform_get_drvdata(platform);
- struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
+ struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
u32 volume;
+ int dai, stream;
+
+ dai = mod_map[mc->reg].dai_id;
+ stream = mod_map[mc->reg].stream;
+ pcm_data = &pdata->pcm[dai][stream];
mutex_lock(&pcm_data->mutex);
pm_runtime_get_sync(pdata->dev);
ARRAY_SIZE(volume_map) - 1, 0,
hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
/* Mic Capture volume */
- SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 0, 0, 8,
+ SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
ARRAY_SIZE(volume_map) - 1, 0,
hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
};
struct snd_pcm_runtime *runtime = substream->runtime;
struct hsw_priv_data *pdata =
snd_soc_platform_get_drvdata(rtd->platform);
- struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
+ struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
struct sst_module *module_data;
struct sst_dsp *dsp;
enum sst_hsw_stream_path_id path_id;
u32 rate, bits, map, pages, module_id;
u8 channels;
- int ret;
+ int ret, dai;
+
+ dai = mod_map[rtd->cpu_dai->id].dai_id;
+ pcm_data = &pdata->pcm[dai][substream->stream];
/* check if we are being called a subsequent time */
if (pcm_data->allocated) {
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct hsw_priv_data *pdata =
snd_soc_platform_get_drvdata(rtd->platform);
- struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
+ struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
+ int dai;
+
+ dai = mod_map[rtd->cpu_dai->id].dai_id;
+ pcm_data = &pdata->pcm[dai][substream->stream];
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
struct snd_pcm_runtime *runtime = substream->runtime;
struct hsw_priv_data *pdata =
snd_soc_platform_get_drvdata(rtd->platform);
- struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
+ struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
snd_pcm_uframes_t offset;
uint64_t ppos;
- u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
+ u32 position;
+ int dai;
+
+ dai = mod_map[rtd->cpu_dai->id].dai_id;
+ pcm_data = &pdata->pcm[dai][substream->stream];
+ position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
offset = bytes_to_frames(runtime, position);
ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
snd_soc_platform_get_drvdata(rtd->platform);
struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
+ int dai;
- pcm_data = &pdata->pcm[rtd->cpu_dai->id];
+ dai = mod_map[rtd->cpu_dai->id].dai_id;
+ pcm_data = &pdata->pcm[dai][substream->stream];
mutex_lock(&pcm_data->mutex);
pm_runtime_get_sync(pdata->dev);
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct hsw_priv_data *pdata =
snd_soc_platform_get_drvdata(rtd->platform);
- struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
+ struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
- int ret;
+ int ret, dai;
+
+ dai = mod_map[rtd->cpu_dai->id].dai_id;
+ pcm_data = &pdata->pcm[dai][substream->stream];
mutex_lock(&pcm_data->mutex);
ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
.page = snd_pcm_sgbuf_ops_page,
};
-/* static mappings between PCMs and modules - may be dynamic in future */
-static struct hsw_pcm_module_map mod_map[] = {
- {HSW_PCM_DAI_ID_SYSTEM, 0, SST_HSW_MODULE_PCM_SYSTEM},
- {HSW_PCM_DAI_ID_OFFLOAD0, 0, SST_HSW_MODULE_PCM},
- {HSW_PCM_DAI_ID_OFFLOAD1, 0, SST_HSW_MODULE_PCM},
- {HSW_PCM_DAI_ID_LOOPBACK, 1, SST_HSW_MODULE_PCM_REFERENCE},
- {HSW_PCM_DAI_ID_SYSTEM, 1, SST_HSW_MODULE_PCM_CAPTURE},
-};
-
static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
{
struct sst_hsw *hsw = pdata->hsw;
int i;
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
- pcm_data = &pdata->pcm[i];
+ pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
/* create new runtime module, use same offset if recreated */
pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
err:
for (--i; i >= 0; i--) {
- pcm_data = &pdata->pcm[i];
+ pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
sst_hsw_runtime_module_free(pcm_data->runtime);
}
int i;
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
- pcm_data = &pdata->pcm[i];
+ pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
sst_hsw_runtime_module_free(pcm_data->runtime);
}
return ret;
}
}
- priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm;
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
+ priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm;
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
+ priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm;
return ret;
}
/* allocate DSP buffer page tables */
for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
- mutex_init(&priv_data->pcm[i].mutex);
-
/* playback */
if (hsw_dais[i].playback.channels_min) {
+ mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_PLAYBACK].mutex);
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
PAGE_SIZE, &priv_data->dmab[i][0]);
if (ret < 0)
/* capture */
if (hsw_dais[i].capture.channels_min) {
+ mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_CAPTURE].mutex);
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
PAGE_SIZE, &priv_data->dmab[i][1]);
if (ret < 0)
}
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
- pcm_data = &pdata->pcm[i];
+ pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
if (!pcm_data->substream)
continue;
return 0;
/* suspend all active streams */
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
- pcm_data = &pdata->pcm[i];
+ pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
if (!pcm_data->substream)
continue;
/* preserve persistent memory */
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
- pcm_data = &pdata->pcm[i];
+ pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
if (!pcm_data->substream)
continue;