summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/sof-client.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2022-05-23 16:03:04 +0200
committerTakashi Iwai <tiwai@suse.de>2022-05-23 16:03:04 +0200
commit0163717ed5dec4fc3aaf937baa9f66f21ca11c1d (patch)
treeb0618a944385d1d35bd829c9aa09eddb5c9633fa /sound/soc/sof/sof-client.c
parent1693e265e0a5dbe11fba21b48272dd15dbb71ec0 (diff)
parente5cd20e0d6713138444cc3f3f982712cf9a36143 (diff)
downloadlinux-0163717ed5dec4fc3aaf937baa9f66f21ca11c1d.tar.gz
linux-0163717ed5dec4fc3aaf937baa9f66f21ca11c1d.tar.bz2
linux-0163717ed5dec4fc3aaf937baa9f66f21ca11c1d.zip
Merge tag 'asoc-v5.19' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v5.19 This is quite a big update, partly due to the addition of some larger drivers (more of which is to follow since at least the AVS driver is still a work in progress) and partly due to Charles' work sorting out our handling of endianness. As has been the case recently it's much more about drivers than the core. - Overhaul of endianness specification for data formats, avoiding needless restrictions due to CODECs. - Initial stages of Intel AVS driver merge. - Introduction of v4 IPC mechanism for SOF. - TDM mode support for AK4613. - Support for Analog Devices ADAU1361, Cirrus Logic CS35L45, Maxim MAX98396, MediaTek MT8186, NXP i.MX8 micfil and SAI interfaces, nVidia Tegra186 ASRC, and Texas Instruments TAS2764 and TAS2780
Diffstat (limited to 'sound/soc/sof/sof-client.c')
-rw-r--r--sound/soc/sof/sof-client.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c
index 686ad0c3bb61..16cca666bb85 100644
--- a/sound/soc/sof/sof-client.c
+++ b/sound/soc/sof/sof-client.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <sound/sof/ipc4/header.h>
#include "ops.h"
#include "sof-client.h"
#include "sof-priv.h"
@@ -72,6 +73,9 @@ static int sof_register_ipc_flood_test(struct snd_sof_dev *sdev)
int ret = 0;
int i;
+ if (sdev->pdata->ipc_type != SOF_IPC)
+ return 0;
+
for (i = 0; i < CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM; i++) {
ret = sof_client_dev_register(sdev, "ipc_flood", i, NULL, 0);
if (ret < 0)
@@ -245,10 +249,19 @@ EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, SND_SOC_SOF_CLIENT);
int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg,
void *reply_data, size_t reply_bytes)
{
- struct sof_ipc_cmd_hdr *hdr = ipc_msg;
+ if (cdev->sdev->pdata->ipc_type == SOF_IPC) {
+ struct sof_ipc_cmd_hdr *hdr = ipc_msg;
+
+ return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, hdr->size,
+ reply_data, reply_bytes);
+ } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ struct sof_ipc4_msg *msg = ipc_msg;
- return sof_ipc_tx_message(cdev->sdev->ipc, hdr->cmd, ipc_msg, hdr->size,
- reply_data, reply_bytes);
+ return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, msg->data_size,
+ reply_data, reply_bytes);
+ }
+
+ return -EINVAL;
}
EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT);
@@ -319,6 +332,22 @@ const struct sof_ipc_fw_version *sof_client_get_fw_version(struct sof_client_dev
}
EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_version, SND_SOC_SOF_CLIENT);
+size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev)
+{
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ return sdev->ipc->max_payload_size;
+}
+EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_max_payload_size, SND_SOC_SOF_CLIENT);
+
+enum sof_ipc_type sof_client_get_ipc_type(struct sof_client_dev *cdev)
+{
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ return sdev->pdata->ipc_type;
+}
+EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_type, SND_SOC_SOF_CLIENT);
+
/* module refcount management of SOF core */
int sof_client_core_module_get(struct sof_client_dev *cdev)
{
@@ -342,9 +371,22 @@ EXPORT_SYMBOL_NS_GPL(sof_client_core_module_put, SND_SOC_SOF_CLIENT);
/* IPC event handling */
void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf)
{
- struct sof_ipc_cmd_hdr *hdr = msg_buf;
- u32 msg_type = hdr->cmd & SOF_GLB_TYPE_MASK;
struct sof_ipc_event_entry *event;
+ u32 msg_type;
+
+ if (sdev->pdata->ipc_type == SOF_IPC) {
+ struct sof_ipc_cmd_hdr *hdr = msg_buf;
+
+ msg_type = hdr->cmd & SOF_GLB_TYPE_MASK;
+ } else if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ struct sof_ipc4_msg *msg = msg_buf;
+
+ msg_type = SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary);
+ } else {
+ dev_dbg_once(sdev->dev, "%s: Not supported IPC version: %d\n",
+ __func__, sdev->pdata->ipc_type);
+ return;
+ }
mutex_lock(&sdev->client_event_handler_mutex);
@@ -363,9 +405,21 @@ int sof_client_register_ipc_rx_handler(struct sof_client_dev *cdev,
struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
struct sof_ipc_event_entry *event;
- if (!callback || !(ipc_msg_type & SOF_GLB_TYPE_MASK))
+ if (!callback)
return -EINVAL;
+ if (cdev->sdev->pdata->ipc_type == SOF_IPC) {
+ if (!(ipc_msg_type & SOF_GLB_TYPE_MASK))
+ return -EINVAL;
+ } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ if (!(ipc_msg_type & SOF_IPC4_NOTIFICATION_TYPE_MASK))
+ return -EINVAL;
+ } else {
+ dev_warn(sdev->dev, "%s: Not supported IPC version: %d\n",
+ __func__, sdev->pdata->ipc_type);
+ return -EINVAL;
+ }
+
event = kmalloc(sizeof(*event), GFP_KERNEL);
if (!event)
return -ENOMEM;