diff --git a/include/sound/sof.h b/include/sound/sof.h index 367dccfea7ade8..341fef19e61244 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -89,6 +89,7 @@ struct snd_sof_pdata { /* machine */ struct platform_device *pdev_mach; const struct snd_soc_acpi_mach *machine; + const struct snd_sof_of_mach *of_machine; void *hw_pdata; @@ -102,6 +103,7 @@ struct snd_sof_pdata { struct sof_dev_desc { /* list of machines using this configuration */ struct snd_soc_acpi_mach *machines; + struct snd_sof_of_mach *of_machines; /* alternate list of machines using this configuration */ struct snd_soc_acpi_mach *alt_machines; diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index e006532caf2f05..dfa684e0f94c40 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -460,13 +460,36 @@ static int mt8186_get_bar_index(struct snd_sof_dev *sdev, u32 type) return type; } -static int mt8186_ipc_msg_data(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - void *p, size_t sz) +static struct snd_soc_dai_driver mt8186_dai[] = { { - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); - return 0; -} + .name = "SOF_DL1", + .playback = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_DL2", + .playback = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_UL1", + .capture = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_UL2", + .capture = { + .channels_min = 1, + .channels_max = 2, + }, +}, +}; /* mt8186 ops */ static struct snd_sof_dsp_ops sof_mt8186_ops = { @@ -481,6 +504,10 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* Register IO */ .write = sof_io_write, .read = sof_io_read, @@ -491,18 +518,29 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = { .send_msg = mt8186_send_msg, .get_mailbox_offset = mt8186_get_mailbox_offset, .get_window_offset = mt8186_get_window_offset, - .ipc_msg_data = mt8186_ipc_msg_data, + .ipc_msg_data = sof_ipc_msg_data, .set_stream_data_offset = sof_set_stream_data_offset, /* misc */ .get_bar_index = mt8186_get_bar_index, + /* machine driver */ + .of_machine_select = sof_of_machine_select, + + /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, + /* firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops, + /* DAI drivers */ + .drv = mt8186_dai, + .num_drv = ARRAY_SIZE(mt8186_dai), + /* PM */ .suspend = mt8186_dsp_suspend, .resume = mt8186_dsp_resume, @@ -515,7 +553,24 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = { SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, }; +static struct snd_sof_of_mach sof_mt8186_machs[] = { + { + .board = "google,kingler", + .sof_tplg_filename = "sof-mt8186-mt6366-da7219-max98357.tplg", + }, + { + .board = "google,krabby", + .sof_tplg_filename = "sof-mt8186-mt6366-rt1019-rt5682s.tplg", + }, + { + .board = "google,steelix", + .sof_tplg_filename = "sof-mt8186-mt6366-rt1019-rt5682s.tplg", + }, + {} +}; + static const struct sof_dev_desc sof_of_mt8186_desc = { + .of_machines = sof_mt8186_machs, .ipc_supported_mask = BIT(SOF_IPC), .ipc_default = SOF_IPC, .default_fw_path = { diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 55d43adb6a2951..e20720c09744e6 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -522,6 +522,15 @@ snd_sof_set_mach_params(struct snd_soc_acpi_mach *mach, sof_ops(sdev)->set_mach_params(mach, sdev); } +static inline struct snd_sof_of_mach * +snd_sof_of_machine_select(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev) && sof_ops(sdev)->of_machine_select) + return sof_ops(sdev)->of_machine_select(sdev); + + return NULL; +} + /** * snd_sof_dsp_register_poll_timeout - Periodically poll an address * until a condition is met or a timeout occurs diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 29d9bff03ebb27..38fda571c38436 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -14,6 +14,7 @@ #include #include #include +#include "sof-of-dev.h" #include "sof-priv.h" #include "sof-audio.h" #include "sof-utils.h" @@ -654,7 +655,12 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) struct snd_sof_pdata *plat_data = sdev->pdata; const char *drv_name; - drv_name = plat_data->machine->drv_name; + if (plat_data->machine) + drv_name = plat_data->machine->drv_name; + else if (plat_data->of_machine) + drv_name = plat_data->of_machine->drv_name; + else + drv_name = NULL; pd->name = "sof-audio-component"; pd->probe = sof_pcm_probe; diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 789d0a1f1a77eb..c364c856d51d90 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -799,6 +799,7 @@ int sof_machine_check(struct snd_sof_dev *sdev) struct snd_soc_acpi_mach *mach; if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) { + const struct snd_sof_of_mach *of_mach; /* find machine */ mach = snd_sof_machine_select(sdev); @@ -808,6 +809,12 @@ int sof_machine_check(struct snd_sof_dev *sdev) return 0; } + of_mach = snd_sof_of_machine_select(sdev); + if (of_mach) { + sof_pdata->of_machine = of_mach; + return 0; + } + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) { dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n"); return -ENODEV; diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c index 53faeccedd4f0d..8df588f9349ad4 100644 --- a/sound/soc/sof/sof-of-dev.c +++ b/sound/soc/sof/sof-of-dev.c @@ -31,6 +31,29 @@ const struct dev_pm_ops sof_of_pm = { }; EXPORT_SYMBOL(sof_of_pm); +struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev) +{ + struct snd_sof_pdata *sof_pdata = sdev->pdata; + const struct sof_dev_desc *desc = sof_pdata->desc; + struct snd_sof_of_mach *mach = desc->of_machines; + + if (!mach) + return NULL; + + for (; mach->board; mach++) { + if (of_machine_is_compatible(mach->board)) { + sof_pdata->tplg_filename = mach->sof_tplg_filename; + if (mach->fw_filename) + sof_pdata->fw_filename = mach->fw_filename; + + return mach; + } + } + + return NULL; +} +EXPORT_SYMBOL(sof_of_machine_select); + static void sof_of_probe_complete(struct device *dev) { /* allow runtime_pm */ diff --git a/sound/soc/sof/sof-of-dev.h b/sound/soc/sof/sof-of-dev.h index fd950a222ba484..2ab81ced139d2f 100644 --- a/sound/soc/sof/sof-of-dev.h +++ b/sound/soc/sof/sof-of-dev.h @@ -9,8 +9,16 @@ #ifndef __SOUND_SOC_SOF_OF_H #define __SOUND_SOC_SOF_OF_H +struct snd_sof_of_mach { + const char *board; + const char *drv_name; + const char *fw_filename; + const char *sof_tplg_filename; +}; + extern const struct dev_pm_ops sof_of_pm; +struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev); int sof_of_probe(struct platform_device *pdev); int sof_of_remove(struct platform_device *pdev); void sof_of_shutdown(struct platform_device *pdev); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 8bbc94907c624b..9f90cf80fab109 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -283,6 +283,7 @@ struct snd_sof_dsp_ops { void (*machine_unregister)(struct snd_sof_dev *sdev, void *pdata); /* optional */ struct snd_soc_acpi_mach * (*machine_select)(struct snd_sof_dev *sdev); /* optional */ + struct snd_sof_of_mach * (*of_machine_select)(struct snd_sof_dev *sdev); /* optional */ void (*set_mach_params)(struct snd_soc_acpi_mach *mach, struct snd_sof_dev *sdev); /* optional */