ASoC: Intel: Fix stream volume set no effect issue on Broadwell
The volume setting control for capture stream doesn't take effect on intel Broadwell platform. Root cause it at 2 points: 1. set stream volume with channel=2 is wrongly bapassed; 2. the saved stream volume should be restored after stream is commit. Here correct these 2 items to fix the stream volume set issue. Signed-off-by: Jie Yang <yang.jie@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
14cd792312
commit
f1e5982546
|
@ -1042,14 +1042,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
|
||||||
|
|
||||||
trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
|
trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
|
||||||
|
|
||||||
if (channel > 1)
|
if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (stream->mute[channel]) {
|
|
||||||
stream->mute_volume[channel] = volume;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
|
header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
|
||||||
IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
|
IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
|
||||||
header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
|
header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
|
||||||
|
@ -1057,9 +1052,28 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
|
||||||
header |= (stage_id << IPC_STG_ID_SHIFT);
|
header |= (stage_id << IPC_STG_ID_SHIFT);
|
||||||
|
|
||||||
req = &stream->vol_req;
|
req = &stream->vol_req;
|
||||||
req->channel = channel;
|
|
||||||
req->target_volume = volume;
|
req->target_volume = volume;
|
||||||
|
|
||||||
|
/* set both at same time ? */
|
||||||
|
if (channel == SST_HSW_CHANNELS_ALL) {
|
||||||
|
if (hsw->mute[0] && hsw->mute[1]) {
|
||||||
|
hsw->mute_volume[0] = hsw->mute_volume[1] = volume;
|
||||||
|
return 0;
|
||||||
|
} else if (hsw->mute[0])
|
||||||
|
req->channel = 1;
|
||||||
|
else if (hsw->mute[1])
|
||||||
|
req->channel = 0;
|
||||||
|
else
|
||||||
|
req->channel = SST_HSW_CHANNELS_ALL;
|
||||||
|
} else {
|
||||||
|
/* set only 1 channel */
|
||||||
|
if (hsw->mute[channel]) {
|
||||||
|
hsw->mute_volume[channel] = volume;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
req->channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ipc_tx_message_wait(hsw, header, req, sizeof(*req), NULL, 0);
|
ret = ipc_tx_message_wait(hsw, header, req, sizeof(*req), NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(hsw->dev, "error: set stream volume failed\n");
|
dev_err(hsw->dev, "error: set stream volume failed\n");
|
||||||
|
@ -1138,8 +1152,11 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
|
||||||
|
|
||||||
trace_ipc_request("set mixer volume", volume);
|
trace_ipc_request("set mixer volume", volume);
|
||||||
|
|
||||||
|
if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* set both at same time ? */
|
/* set both at same time ? */
|
||||||
if (channel == 2) {
|
if (channel == SST_HSW_CHANNELS_ALL) {
|
||||||
if (hsw->mute[0] && hsw->mute[1]) {
|
if (hsw->mute[0] && hsw->mute[1]) {
|
||||||
hsw->mute_volume[0] = hsw->mute_volume[1] = volume;
|
hsw->mute_volume[0] = hsw->mute_volume[1] = volume;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1148,7 +1165,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
|
||||||
else if (hsw->mute[1])
|
else if (hsw->mute[1])
|
||||||
req.channel = 0;
|
req.channel = 0;
|
||||||
else
|
else
|
||||||
req.channel = 0xffffffff;
|
req.channel = SST_HSW_CHANNELS_ALL;
|
||||||
} else {
|
} else {
|
||||||
/* set only 1 channel */
|
/* set only 1 channel */
|
||||||
if (hsw->mute[channel]) {
|
if (hsw->mute[channel]) {
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define SST_HSW_NO_CHANNELS 4
|
#define SST_HSW_NO_CHANNELS 4
|
||||||
#define SST_HSW_MAX_DX_REGIONS 14
|
#define SST_HSW_MAX_DX_REGIONS 14
|
||||||
#define SST_HSW_DX_CONTEXT_SIZE (640 * 1024)
|
#define SST_HSW_DX_CONTEXT_SIZE (640 * 1024)
|
||||||
|
#define SST_HSW_CHANNELS_ALL 0xffffffff
|
||||||
|
|
||||||
#define SST_HSW_FW_LOG_CONFIG_DWORDS 12
|
#define SST_HSW_FW_LOG_CONFIG_DWORDS 12
|
||||||
#define SST_HSW_GLOBAL_LOG 15
|
#define SST_HSW_GLOBAL_LOG 15
|
||||||
|
|
|
@ -189,7 +189,8 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
|
||||||
if (ucontrol->value.integer.value[0] ==
|
if (ucontrol->value.integer.value[0] ==
|
||||||
ucontrol->value.integer.value[1]) {
|
ucontrol->value.integer.value[1]) {
|
||||||
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
||||||
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume);
|
/* apply volume value to all channels */
|
||||||
|
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, SST_HSW_CHANNELS_ALL, volume);
|
||||||
} else {
|
} else {
|
||||||
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
||||||
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume);
|
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume);
|
||||||
|
@ -255,7 +256,7 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol,
|
||||||
ucontrol->value.integer.value[1]) {
|
ucontrol->value.integer.value[1]) {
|
||||||
|
|
||||||
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
||||||
sst_hsw_mixer_set_volume(hsw, 0, 2, volume);
|
sst_hsw_mixer_set_volume(hsw, 0, SST_HSW_CHANNELS_ALL, volume);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
|
||||||
|
@ -525,7 +526,15 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||||
dev_err(rtd->dev, "error: failed to commit stream %d\n", ret);
|
dev_err(rtd->dev, "error: failed to commit stream %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
pcm_data->allocated = true;
|
|
||||||
|
if (!pcm_data->allocated) {
|
||||||
|
/* Set previous saved volume */
|
||||||
|
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
|
||||||
|
0, pcm_data->volume[0]);
|
||||||
|
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
|
||||||
|
1, pcm_data->volume[1]);
|
||||||
|
pcm_data->allocated = true;
|
||||||
|
}
|
||||||
|
|
||||||
ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1);
|
ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -632,12 +641,6 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set previous saved volume */
|
|
||||||
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
|
|
||||||
0, pcm_data->volume[0]);
|
|
||||||
sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
|
|
||||||
1, pcm_data->volume[1]);
|
|
||||||
|
|
||||||
mutex_unlock(&pcm_data->mutex);
|
mutex_unlock(&pcm_data->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue