diff mbox series

[1/2] ASoC: SOF: Introduce optional callback of_machine_select

Message ID 20220804091359.31449-2-chunxu.li@mediatek.com (mailing list archive)
State New, archived
Headers show
Series ASoC: SOF: Introduce of_machine_select | expand

Commit Message

Chunxu Li Aug. 4, 2022, 9:13 a.m. UTC
From current design in sof_machine_check and snd_sof_new_platform_drv,
the SOF can only support ACPI type machine.

1. In sof_machine_check if there is no ACPI machine exist, the function
will return -ENODEV directly, that's we don't expected if we do not
base on ACPI machine.

2. In snd_sof_new_platform_drv the component driver need a driver name
to do ignore_machine, currently the driver name is obtained from
machine->drv_name, and the type of machine is snd_soc_acpi_mach.

So we add a new function snd_sof_of_machine_select that we can pass
sof_machine_check and obtain info required by snd_sof_new_platform_drv.
this callback is optional, each machine that do not based on ACPI can
use common code implemented in sof-of-dev.c or implement their customized
specific routine.

Signed-off-by: Chunxu Li <chunxu.li@mediatek.com>
---
 include/sound/sof.h        |  2 ++
 sound/soc/sof/ops.h        |  9 +++++++++
 sound/soc/sof/pcm.c        |  8 +++++++-
 sound/soc/sof/sof-audio.c  |  7 +++++++
 sound/soc/sof/sof-of-dev.c | 23 +++++++++++++++++++++++
 sound/soc/sof/sof-of-dev.h |  8 ++++++++
 sound/soc/sof/sof-priv.h   |  1 +
 7 files changed, 57 insertions(+), 1 deletion(-)

 				struct snd_sof_dev *sdev); /* optional */

Comments

Mark Brown Aug. 4, 2022, 1:17 p.m. UTC | #1
On Thu, Aug 04, 2022 at 05:13:58PM +0800, Chunxu Li wrote:

> @@ -284,6 +284,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);

I don't understand why we pass this in as a function when as far as I
can see it should always be the standard operation provided by the core
- why not just always call the function?  We can tell at runtime if the
system is using DT so there's no issue there and there shouldn't be any
concerns with ACPI or other firmware interfaces.
Chunxu Li Aug. 4, 2022, 2:36 p.m. UTC | #2
On Thu, 2022-08-04 at 14:17 +0100, Mark Brown wrote:
> On Thu, Aug 04, 2022 at 05:13:58PM +0800, Chunxu Li wrote:
> 
> > @@ -284,6 +284,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);
> 
> I don't understand why we pass this in as a function when as far as I
> can see it should always be the standard operation provided by the
> core
> - why not just always call the function?  We can tell at runtime if
> the
> system is using DT so there's no issue there and there shouldn't be
> any
> concerns with ACPI or other firmware interfaces.

Thanks for you advice, I'll remove the callback function, and directly
call sof_of_machine_select() in sof_machine_check() as following.

int sof_machine_check(struct snd_sof_dev *sdev)
{
snip...
	const struct snd_sof_of_mach *of_mach;
	/* find machine */
	mach = snd_sof_machine_select(sdev);
	if (mach) {
		sof_pdata->machine = mach;
		snd_sof_set_mach_params(mach, sdev);
		return 0;
	}

	
+	of_mach = sof_of_machine_select(sdev);
+	if (of_mach) {
+		sof_pdata->of_machine = of_mach;
+		return 0;
+	}
snip ...
}
Mark Brown Aug. 4, 2022, 2:59 p.m. UTC | #3
On Thu, Aug 04, 2022 at 10:36:07PM +0800, chunxu.li wrote:

> Thanks for you advice, I'll remove the callback function, and directly
> call sof_of_machine_select() in sof_machine_check() as following.
> 
> int sof_machine_check(struct snd_sof_dev *sdev)
> {
> 	}
> 
> 	
> +	of_mach = sof_of_machine_select(sdev);
> +	if (of_mach) {
> +		sof_pdata->of_machine = of_mach;
> +		return 0;
> +	}

Looks good.
diff mbox series

Patch

diff --git a/include/sound/sof.h b/include/sound/sof.h
index 367dccfea7ad..341fef19e612 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/ops.h b/sound/soc/sof/ops.h
index 55d43adb6a29..e20720c09744 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 6cb6a432be5e..49f7cb049f62 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -13,6 +13,7 @@ 
 #include <linux/pm_runtime.h>
 #include <sound/pcm_params.h>
 #include <sound/sof.h>
+#include "sof-of-dev.h"
 #include "sof-priv.h"
 #include "sof-audio.h"
 #include "sof-utils.h"
@@ -655,7 +656,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 28976098a89e..7b3c99d1b2a4 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -794,6 +794,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);
@@ -803,6 +804,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 53faeccedd4f..8df588f9349a 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 fd950a222ba4..2ab81ced139d 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 823583086279..c5ed18f99d00 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -284,6 +284,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,