aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/control.c')
-rw-r--r--sound/soc/sof/control.c270
1 files changed, 38 insertions, 232 deletions
diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c
index 84e2cbfbbcbb..a4983f90ff5b 100644
--- a/sound/soc/sof/control.c
+++ b/sound/soc/sof/control.c
@@ -39,26 +39,8 @@ int snd_sof_volume_get(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *sm =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_sof_control *scontrol = sm->dobj.private;
- struct snd_sof_dev *sdev = scontrol->sdev;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
unsigned int i, channels = scontrol->num_channels;
- int err, ret;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: volume get failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
-
- /* get all the mixer data from DSP */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_GET_VALUE,
- SOF_CTRL_TYPE_VALUE_CHAN_GET,
- SOF_CTRL_CMD_VOLUME,
- false);
/* read back each channel */
for (i = 0; i < channels; i++)
@@ -66,12 +48,6 @@ int snd_sof_volume_get(struct snd_kcontrol *kcontrol,
ipc_to_mixer(cdata->chanv[i].value,
scontrol->volume_table, sm->max + 1);
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: volume get failed to idle %d\n",
- err);
return 0;
}
@@ -84,16 +60,6 @@ int snd_sof_volume_put(struct snd_kcontrol *kcontrol,
struct snd_sof_dev *sdev = scontrol->sdev;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
unsigned int i, channels = scontrol->num_channels;
- int ret, err;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: volume put failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
/* update each channel */
for (i = 0; i < channels; i++) {
@@ -104,18 +70,13 @@ int snd_sof_volume_put(struct snd_kcontrol *kcontrol,
}
/* notify DSP of mixer updates */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_SET_VALUE,
- SOF_CTRL_TYPE_VALUE_CHAN_GET,
- SOF_CTRL_CMD_VOLUME,
- true);
-
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: volume put failed to idle %d\n",
- err);
+ if (pm_runtime_active(sdev->dev))
+ snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
+ SOF_IPC_COMP_SET_VALUE,
+ SOF_CTRL_TYPE_VALUE_CHAN_GET,
+ SOF_CTRL_CMD_VOLUME,
+ true);
+
return 0;
}
@@ -125,37 +86,13 @@ int snd_sof_switch_get(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *sm =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_sof_control *scontrol = sm->dobj.private;
- struct snd_sof_dev *sdev = scontrol->sdev;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
unsigned int i, channels = scontrol->num_channels;
- int err, ret;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: switch get failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
-
- /* get all the mixer data from DSP */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_GET_VALUE,
- SOF_CTRL_TYPE_VALUE_CHAN_GET,
- SOF_CTRL_CMD_SWITCH,
- false);
/* read back each channel */
for (i = 0; i < channels; i++)
ucontrol->value.integer.value[i] = cdata->chanv[i].value;
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: switch get failed to idle %d\n",
- err);
return 0;
}
@@ -168,16 +105,6 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol,
struct snd_sof_dev *sdev = scontrol->sdev;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
unsigned int i, channels = scontrol->num_channels;
- int ret, err;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: switch put failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
/* update each channel */
for (i = 0; i < channels; i++) {
@@ -186,18 +113,13 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol,
}
/* notify DSP of mixer updates */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_SET_VALUE,
- SOF_CTRL_TYPE_VALUE_CHAN_GET,
- SOF_CTRL_CMD_SWITCH,
- true);
-
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: switch put failed to idle %d\n",
- err);
+ if (pm_runtime_active(sdev->dev))
+ snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
+ SOF_IPC_COMP_SET_VALUE,
+ SOF_CTRL_TYPE_VALUE_CHAN_GET,
+ SOF_CTRL_CMD_SWITCH,
+ true);
+
return 0;
}
@@ -207,37 +129,13 @@ int snd_sof_enum_get(struct snd_kcontrol *kcontrol,
struct soc_enum *se =
(struct soc_enum *)kcontrol->private_value;
struct snd_sof_control *scontrol = se->dobj.private;
- struct snd_sof_dev *sdev = scontrol->sdev;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
unsigned int i, channels = scontrol->num_channels;
- int err, ret;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: enum get failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
-
- /* get all the enum data from DSP */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_GET_VALUE,
- SOF_CTRL_TYPE_VALUE_CHAN_GET,
- SOF_CTRL_CMD_ENUM,
- false);
/* read back each channel */
for (i = 0; i < channels; i++)
ucontrol->value.enumerated.item[i] = cdata->chanv[i].value;
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: enum get failed to idle %d\n",
- err);
return 0;
}
@@ -250,16 +148,6 @@ int snd_sof_enum_put(struct snd_kcontrol *kcontrol,
struct snd_sof_dev *sdev = scontrol->sdev;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
unsigned int i, channels = scontrol->num_channels;
- int ret, err;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: enum put failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
/* update each channel */
for (i = 0; i < channels; i++) {
@@ -268,18 +156,13 @@ int snd_sof_enum_put(struct snd_kcontrol *kcontrol,
}
/* notify DSP of enum updates */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_SET_VALUE,
- SOF_CTRL_TYPE_VALUE_CHAN_GET,
- SOF_CTRL_CMD_ENUM,
- true);
-
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: enum put failed to idle %d\n",
- err);
+ if (pm_runtime_active(sdev->dev))
+ snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
+ SOF_IPC_COMP_SET_VALUE,
+ SOF_CTRL_TYPE_VALUE_CHAN_GET,
+ SOF_CTRL_CMD_ENUM,
+ true);
+
return 0;
}
@@ -293,7 +176,7 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
struct sof_abi_hdr *data = cdata->data;
size_t size;
- int ret, err;
+ int ret = 0;
if (be->max > sizeof(ucontrol->value.bytes.data)) {
dev_err_ratelimited(sdev->dev,
@@ -302,22 +185,6 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: bytes get failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
-
- /* get all the binary data from DSP */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_GET_DATA,
- SOF_CTRL_TYPE_DATA_GET,
- scontrol->cmd,
- false);
-
size = data->size + sizeof(*data);
if (size > be->max) {
dev_err_ratelimited(sdev->dev,
@@ -331,12 +198,6 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
memcpy(ucontrol->value.bytes.data, data, size);
out:
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: bytes get failed to idle %d\n",
- err);
return ret;
}
@@ -350,7 +211,6 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
struct sof_abi_hdr *data = cdata->data;
size_t size = data->size + sizeof(*data);
- int ret, err;
if (be->max > sizeof(ucontrol->value.bytes.data)) {
dev_err_ratelimited(sdev->dev,
@@ -366,32 +226,18 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: bytes put failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
-
/* copy from kcontrol */
memcpy(data, ucontrol->value.bytes.data, size);
/* notify DSP of byte control updates */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_SET_DATA,
- SOF_CTRL_TYPE_DATA_SET,
- scontrol->cmd,
- true);
-
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: bytes put failed to idle %d\n",
- err);
- return ret;
+ if (pm_runtime_active(sdev->dev))
+ snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
+ SOF_IPC_COMP_SET_DATA,
+ SOF_CTRL_TYPE_DATA_SET,
+ scontrol->cmd,
+ true);
+
+ return 0;
}
int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
@@ -406,8 +252,6 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_tlv header;
const struct snd_ctl_tlv __user *tlvd =
(const struct snd_ctl_tlv __user *)binary_data;
- int ret;
- int err;
/*
* The beginning of bytes data contains a header from where
@@ -453,30 +297,15 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: bytes_ext put failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
-
/* notify DSP of byte control updates */
- snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_SET_DATA,
- SOF_CTRL_TYPE_DATA_SET,
- scontrol->cmd,
- true);
-
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: bytes_ext put failed to idle %d\n",
- err);
+ if (pm_runtime_active(sdev->dev))
+ snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
+ SOF_IPC_COMP_SET_DATA,
+ SOF_CTRL_TYPE_DATA_SET,
+ scontrol->cmd,
+ true);
- return ret;
+ return 0;
}
int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
@@ -492,17 +321,7 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_tlv __user *tlvd =
(struct snd_ctl_tlv __user *)binary_data;
int data_size;
- int err;
- int ret;
-
- ret = pm_runtime_get_sync(sdev->dev);
- if (ret < 0) {
- dev_err_ratelimited(sdev->dev,
- "error: bytes_ext get failed to resume %d\n",
- ret);
- pm_runtime_put_noidle(sdev->dev);
- return ret;
- }
+ int ret = 0;
/*
* Decrement the limit by ext bytes header size to
@@ -514,13 +333,6 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
cdata->data->magic = SOF_ABI_MAGIC;
cdata->data->abi = SOF_ABI_VERSION;
- /* get all the component data from DSP */
- ret = snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol,
- SOF_IPC_COMP_GET_DATA,
- SOF_CTRL_TYPE_DATA_GET,
- scontrol->cmd,
- false);
-
/* Prevent read of other kernel data or possibly corrupt response */
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
@@ -543,11 +355,5 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
ret = -EFAULT;
out:
- pm_runtime_mark_last_busy(sdev->dev);
- err = pm_runtime_put_autosuspend(sdev->dev);
- if (err < 0)
- dev_err_ratelimited(sdev->dev,
- "error: bytes_ext get failed to idle %d\n",
- err);
return ret;
}