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
;
16 extern struct snd_sof_dsp_ops sof_imx8x_ops
;
18 /* platform specific devices */
19 #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
20 static struct sof_dev_desc sof_of_imx8qxp_desc
= {
21 .default_fw_path
= "imx/sof",
22 .default_tplg_path
= "imx/sof-tplg",
23 .default_fw_filename
= "sof-imx8x.ri",
24 .nocodec_tplg_filename
= "sof-imx8-nocodec.tplg",
25 .ops
= &sof_imx8x_ops
,
28 static struct sof_dev_desc sof_of_imx8qm_desc
= {
29 .default_fw_path
= "imx/sof",
30 .default_tplg_path
= "imx/sof-tplg",
31 .default_fw_filename
= "sof-imx8.ri",
32 .nocodec_tplg_filename
= "sof-imx8-nocodec.tplg",
37 static const struct dev_pm_ops sof_of_pm
= {
38 SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend
, snd_sof_resume
)
39 SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend
, snd_sof_runtime_resume
,
43 static void sof_of_probe_complete(struct device
*dev
)
45 /* allow runtime_pm */
46 pm_runtime_set_autosuspend_delay(dev
, SND_SOF_SUSPEND_DELAY_MS
);
47 pm_runtime_use_autosuspend(dev
);
48 pm_runtime_enable(dev
);
51 static int sof_of_probe(struct platform_device
*pdev
)
53 struct device
*dev
= &pdev
->dev
;
54 const struct sof_dev_desc
*desc
;
55 struct snd_sof_pdata
*sof_pdata
;
56 const struct snd_sof_dsp_ops
*ops
;
59 dev_info(&pdev
->dev
, "DT DSP detected");
61 sof_pdata
= devm_kzalloc(dev
, sizeof(*sof_pdata
), GFP_KERNEL
);
65 desc
= device_get_match_data(dev
);
69 /* get ops for platform */
72 dev_err(dev
, "error: no matching DT descriptor ops\n");
76 sof_pdata
->desc
= desc
;
77 sof_pdata
->dev
= &pdev
->dev
;
78 sof_pdata
->fw_filename
= desc
->default_fw_filename
;
80 /* TODO: read alternate fw and tplg filenames from DT */
81 sof_pdata
->fw_filename_prefix
= sof_pdata
->desc
->default_fw_path
;
82 sof_pdata
->tplg_filename_prefix
= sof_pdata
->desc
->default_tplg_path
;
84 #if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
85 /* set callback to enable runtime_pm */
86 sof_pdata
->sof_probe_complete
= sof_of_probe_complete
;
88 /* call sof helper for DSP hardware probe */
89 ret
= snd_sof_device_probe(dev
, sof_pdata
);
91 dev_err(dev
, "error: failed to probe DSP hardware\n");
95 #if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
96 sof_of_probe_complete(dev
);
102 static int sof_of_remove(struct platform_device
*pdev
)
104 pm_runtime_disable(&pdev
->dev
);
106 /* call sof helper for DSP hardware remove */
107 snd_sof_device_remove(&pdev
->dev
);
112 static const struct of_device_id sof_of_ids
[] = {
113 #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
114 { .compatible
= "fsl,imx8qxp-dsp", .data
= &sof_of_imx8qxp_desc
},
115 { .compatible
= "fsl,imx8qm-dsp", .data
= &sof_of_imx8qm_desc
},
119 MODULE_DEVICE_TABLE(of
, sof_of_ids
);
121 /* DT driver definition */
122 static struct platform_driver snd_sof_of_driver
= {
123 .probe
= sof_of_probe
,
124 .remove
= sof_of_remove
,
126 .name
= "sof-audio-of",
128 .of_match_table
= sof_of_ids
,
131 module_platform_driver(snd_sof_of_driver
);
133 MODULE_LICENSE("Dual BSD/GPL");