ASoC: SOF: ipc4: Support for sending payload along with LARGE_CONFIG_GET
[ Upstream commit d96cb0b86d6e8bbbbfa425771606f6c1aebc318e ] There are message types when we would need to send a payload along with the LARGE_CONFIG_GET message to provide information to the firmware on what data is requested. Such cases are the ALSA Kcontrol related messages when the high level param_id tells only the type of the control, but the ID/index of the exact control is specified in the payload area. The caller must place the payload for TX before calling the set_get_data() and this payload will be sent alongside with the message to the firmware. The data area will be overwritten by the received data from firmware. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Link: https://patch.msgid.link/20251217143945.2667-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
59b8881988
commit
f88cd8da2d
|
|
@ -15,6 +15,7 @@
|
|||
#include "sof-audio.h"
|
||||
#include "ipc4-fw-reg.h"
|
||||
#include "ipc4-priv.h"
|
||||
#include "ipc4-topology.h"
|
||||
#include "ipc4-telemetry.h"
|
||||
#include "ops.h"
|
||||
|
||||
|
|
@ -433,6 +434,23 @@ static int sof_ipc4_tx_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool sof_ipc4_tx_payload_for_get_data(struct sof_ipc4_msg *tx)
|
||||
{
|
||||
/*
|
||||
* Messages that require TX payload with LARGE_CONFIG_GET.
|
||||
* The TX payload is placed into the IPC message data section by caller,
|
||||
* which needs to be copied to temporary buffer since the received data
|
||||
* will overwrite it.
|
||||
*/
|
||||
switch (tx->extension & SOF_IPC4_MOD_EXT_MSG_PARAM_ID_MASK) {
|
||||
case SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID):
|
||||
case SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
|
||||
size_t payload_bytes, bool set)
|
||||
{
|
||||
|
|
@ -444,6 +462,8 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
|
|||
struct sof_ipc4_msg tx = {{ 0 }};
|
||||
struct sof_ipc4_msg rx = {{ 0 }};
|
||||
size_t remaining = payload_bytes;
|
||||
void *tx_payload_for_get = NULL;
|
||||
size_t tx_data_size = 0;
|
||||
size_t offset = 0;
|
||||
size_t chunk_size;
|
||||
int ret;
|
||||
|
|
@ -469,10 +489,20 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
|
|||
|
||||
tx.extension |= SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK(1);
|
||||
|
||||
if (sof_ipc4_tx_payload_for_get_data(&tx)) {
|
||||
tx_data_size = min(ipc4_msg->data_size, payload_limit);
|
||||
tx_payload_for_get = kmemdup(ipc4_msg->data_ptr, tx_data_size,
|
||||
GFP_KERNEL);
|
||||
if (!tx_payload_for_get)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* ensure the DSP is in D0i0 before sending IPC */
|
||||
ret = snd_sof_dsp_set_power_state(sdev, &target_state);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
kfree(tx_payload_for_get);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Serialise IPC TX */
|
||||
mutex_lock(&sdev->ipc->tx_mutex);
|
||||
|
|
@ -506,7 +536,15 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
|
|||
rx.data_size = chunk_size;
|
||||
rx.data_ptr = ipc4_msg->data_ptr + offset;
|
||||
|
||||
tx_size = 0;
|
||||
if (tx_payload_for_get) {
|
||||
tx_size = tx_data_size;
|
||||
tx.data_size = tx_size;
|
||||
tx.data_ptr = tx_payload_for_get;
|
||||
} else {
|
||||
tx_size = 0;
|
||||
tx.data_size = 0;
|
||||
tx.data_ptr = NULL;
|
||||
}
|
||||
rx_size = chunk_size;
|
||||
}
|
||||
|
||||
|
|
@ -553,6 +591,8 @@ out:
|
|||
|
||||
mutex_unlock(&sdev->ipc->tx_mutex);
|
||||
|
||||
kfree(tx_payload_for_get);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue