1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
5 // Author: Daniel Baluta <daniel.baluta@nxp.com>
8 #include <linux/firmware.h>
9 #include <linux/module.h>
10 #include <linux/pm_runtime.h>
11 #include <sound/sof.h>
15 extern struct snd_sof_dsp_ops sof_imx8_ops
;
17 /* platform specific devices */
18 #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
19 static struct sof_dev_desc sof_of_imx8qxp_desc
= {
20 .default_fw_path
= "imx/sof",
21 .default_tplg_path
= "imx/sof-tplg",
22 .default_fw_filename
= "sof-imx8.ri",
23 .nocodec_tplg_filename
= "sof-imx8-nocodec.tplg",
28 static const struct dev_pm_ops sof_of_pm
= {
29 SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend
, snd_sof_resume
)
30 SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend
, snd_sof_runtime_resume
,
34 static void sof_of_probe_complete(struct device
*dev
)
36 /* allow runtime_pm */
37 pm_runtime_set_autosuspend_delay(dev
, SND_SOF_SUSPEND_DELAY_MS
);
38 pm_runtime_use_autosuspend(dev
);
39 pm_runtime_enable(dev
);
42 static int sof_of_probe(struct platform_device
*pdev
)
44 struct device
*dev
= &pdev
->dev
;
45 const struct sof_dev_desc
*desc
;
46 struct snd_sof_pdata
*sof_pdata
;
47 const struct snd_sof_dsp_ops
*ops
;
50 dev_info(&pdev
->dev
, "DT DSP detected");
52 sof_pdata
= devm_kzalloc(dev
, sizeof(*sof_pdata
), GFP_KERNEL
);
56 desc
= device_get_match_data(dev
);
60 /* get ops for platform */
63 dev_err(dev
, "error: no matching DT descriptor ops\n");
67 sof_pdata
->desc
= desc
;
68 sof_pdata
->dev
= &pdev
->dev
;
69 sof_pdata
->fw_filename
= desc
->default_fw_filename
;
71 /* TODO: read alternate fw and tplg filenames from DT */
72 sof_pdata
->fw_filename_prefix
= sof_pdata
->desc
->default_fw_path
;
73 sof_pdata
->tplg_filename_prefix
= sof_pdata
->desc
->default_tplg_path
;
75 #if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
76 /* set callback to enable runtime_pm */
77 sof_pdata
->sof_probe_complete
= sof_of_probe_complete
;
79 /* call sof helper for DSP hardware probe */
80 ret
= snd_sof_device_probe(dev
, sof_pdata
);
82 dev_err(dev
, "error: failed to probe DSP hardware\n");
86 #if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
87 sof_of_probe_complete(dev
);
93 static int sof_of_remove(struct platform_device
*pdev
)
95 pm_runtime_disable(&pdev
->dev
);
97 /* call sof helper for DSP hardware remove */
98 snd_sof_device_remove(&pdev
->dev
);
103 static const struct of_device_id sof_of_ids
[] = {
104 #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
105 { .compatible
= "fsl,imx8qxp-dsp", .data
= &sof_of_imx8qxp_desc
},
109 MODULE_DEVICE_TABLE(of
, sof_of_ids
);
111 /* DT driver definition */
112 static struct platform_driver snd_sof_of_driver
= {
113 .probe
= sof_of_probe
,
114 .remove
= sof_of_remove
,
116 .name
= "sof-audio-of",
118 .of_match_table
= sof_of_ids
,
121 module_platform_driver(snd_sof_of_driver
);
123 MODULE_LICENSE("Dual BSD/GPL");