2020-05-01 09:58:50 -05:00
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2019-08-21 11:47:29 -05:00
//
// Copyright 2019 NXP
//
// Author: Daniel Baluta <daniel.baluta@nxp.com>
//
# include <linux/firmware.h>
# include <linux/module.h>
2021-10-05 10:19:49 +03:00
# include <linux/moduleparam.h>
2019-08-21 11:47:29 -05:00
# include <linux/pm_runtime.h>
# include <sound/sof.h>
2021-12-15 10:57:03 +02:00
# include "sof-of-dev.h"
2019-08-21 11:47:29 -05:00
# include "ops.h"
2021-10-05 10:19:49 +03:00
static char * fw_path ;
module_param ( fw_path , charp , 0444 ) ;
MODULE_PARM_DESC ( fw_path , " alternate path for SOF firmware. " ) ;
static char * tplg_path ;
module_param ( tplg_path , charp , 0444 ) ;
MODULE_PARM_DESC ( tplg_path , " alternate path for SOF topology. " ) ;
2021-12-15 10:57:03 +02:00
const struct dev_pm_ops sof_of_pm = {
2020-09-24 18:15:18 +03:00
. prepare = snd_sof_prepare ,
. complete = snd_sof_complete ,
2019-08-21 11:47:29 -05:00
SET_SYSTEM_SLEEP_PM_OPS ( snd_sof_suspend , snd_sof_resume )
SET_RUNTIME_PM_OPS ( snd_sof_runtime_suspend , snd_sof_runtime_resume ,
NULL )
} ;
2021-12-15 10:57:03 +02:00
EXPORT_SYMBOL ( sof_of_pm ) ;
2019-08-21 11:47:29 -05:00
static void sof_of_probe_complete ( struct device * dev )
{
/* allow runtime_pm */
pm_runtime_set_autosuspend_delay ( dev , SND_SOF_SUSPEND_DELAY_MS ) ;
pm_runtime_use_autosuspend ( dev ) ;
2021-12-09 22:08:30 +02:00
pm_runtime_mark_last_busy ( dev ) ;
2020-09-24 18:15:17 +03:00
pm_runtime_set_active ( dev ) ;
2019-08-21 11:47:29 -05:00
pm_runtime_enable ( dev ) ;
}
2021-12-15 10:57:03 +02:00
int sof_of_probe ( struct platform_device * pdev )
2019-08-21 11:47:29 -05:00
{
struct device * dev = & pdev - > dev ;
const struct sof_dev_desc * desc ;
struct snd_sof_pdata * sof_pdata ;
dev_info ( & pdev - > dev , " DT DSP detected " ) ;
sof_pdata = devm_kzalloc ( dev , sizeof ( * sof_pdata ) , GFP_KERNEL ) ;
if ( ! sof_pdata )
return - ENOMEM ;
desc = device_get_match_data ( dev ) ;
if ( ! desc )
return - ENODEV ;
2021-05-21 12:27:58 +03:00
if ( ! desc - > ops ) {
2019-08-21 11:47:29 -05:00
dev_err ( dev , " error: no matching DT descriptor ops \n " ) ;
return - ENODEV ;
}
sof_pdata - > desc = desc ;
sof_pdata - > dev = & pdev - > dev ;
2022-04-14 13:48:06 -05:00
sof_pdata - > fw_filename = desc - > default_fw_filename [ SOF_IPC ] ;
2019-08-21 11:47:29 -05:00
2021-10-05 10:19:49 +03:00
if ( fw_path )
sof_pdata - > fw_filename_prefix = fw_path ;
else
2022-04-14 13:48:04 -05:00
sof_pdata - > fw_filename_prefix = sof_pdata - > desc - > default_fw_path [ SOF_IPC ] ;
2021-10-05 10:19:49 +03:00
if ( tplg_path )
sof_pdata - > tplg_filename_prefix = tplg_path ;
else
2022-04-14 13:48:04 -05:00
sof_pdata - > tplg_filename_prefix = sof_pdata - > desc - > default_tplg_path [ SOF_IPC ] ;
2019-08-21 11:47:29 -05:00
2021-04-09 15:09:59 -07:00
/* set callback to be called on successful device probe to enable runtime_pm */
2019-08-21 11:47:29 -05:00
sof_pdata - > sof_probe_complete = sof_of_probe_complete ;
2021-04-09 15:09:59 -07:00
/* call sof helper for DSP hardware probe */
return snd_sof_device_probe ( dev , sof_pdata ) ;
2019-08-21 11:47:29 -05:00
}
2021-12-15 10:57:03 +02:00
EXPORT_SYMBOL ( sof_of_probe ) ;
2019-08-21 11:47:29 -05:00
2021-12-15 10:57:03 +02:00
int sof_of_remove ( struct platform_device * pdev )
2019-08-21 11:47:29 -05:00
{
pm_runtime_disable ( & pdev - > dev ) ;
/* call sof helper for DSP hardware remove */
snd_sof_device_remove ( & pdev - > dev ) ;
return 0 ;
}
2021-12-15 10:57:03 +02:00
EXPORT_SYMBOL ( sof_of_remove ) ;
2019-08-21 11:47:29 -05:00
2022-04-06 14:40:45 -05:00
void sof_of_shutdown ( struct platform_device * pdev )
{
snd_sof_device_shutdown ( & pdev - > dev ) ;
}
EXPORT_SYMBOL ( sof_of_shutdown ) ;
2019-08-21 11:47:29 -05:00
MODULE_LICENSE ( " Dual BSD/GPL " ) ;