2019-04-05 14:49:59 +03:00
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (C) 2013 Freescale Semiconductor, Inc.
2013-08-28 08:04:46 +04:00
# include <linux/module.h>
# include <linux/of_platform.h>
# include <sound/soc.h>
struct imx_spdif_data {
2013-12-23 13:28:53 +04:00
struct snd_soc_dai_link dai ;
2013-08-28 08:04:46 +04:00
struct snd_soc_card card ;
} ;
static int imx_spdif_audio_probe ( struct platform_device * pdev )
{
struct device_node * spdif_np , * np = pdev - > dev . of_node ;
struct imx_spdif_data * data ;
2019-06-06 07:14:38 +03:00
struct snd_soc_dai_link_component * comp ;
2013-12-23 13:28:53 +04:00
int ret = 0 ;
2013-08-28 08:04:46 +04:00
spdif_np = of_parse_phandle ( np , " spdif-controller " , 0 ) ;
if ( ! spdif_np ) {
dev_err ( & pdev - > dev , " failed to find spdif-controller \n " ) ;
ret = - EINVAL ;
goto end ;
}
data = devm_kzalloc ( & pdev - > dev , sizeof ( * data ) , GFP_KERNEL ) ;
2019-06-28 04:47:30 +03:00
comp = devm_kzalloc ( & pdev - > dev , 3 * sizeof ( * comp ) , GFP_KERNEL ) ;
2019-06-06 07:14:38 +03:00
if ( ! data | | ! comp ) {
2013-08-28 08:04:46 +04:00
ret = - ENOMEM ;
goto end ;
}
2019-06-06 07:14:38 +03:00
data - > dai . cpus = & comp [ 0 ] ;
data - > dai . codecs = & comp [ 1 ] ;
2019-06-28 04:47:30 +03:00
data - > dai . platforms = & comp [ 2 ] ;
2019-06-06 07:14:38 +03:00
data - > dai . num_cpus = 1 ;
data - > dai . num_codecs = 1 ;
2019-06-28 04:47:30 +03:00
data - > dai . num_platforms = 1 ;
2019-06-06 07:14:38 +03:00
2013-12-23 13:28:53 +04:00
data - > dai . name = " S/PDIF PCM " ;
data - > dai . stream_name = " S/PDIF PCM " ;
2019-06-06 07:14:38 +03:00
data - > dai . codecs - > dai_name = " snd-soc-dummy-dai " ;
data - > dai . codecs - > name = " snd-soc-dummy " ;
data - > dai . cpus - > of_node = spdif_np ;
2019-06-28 04:47:30 +03:00
data - > dai . platforms - > of_node = spdif_np ;
2013-12-23 13:28:53 +04:00
data - > dai . playback_only = true ;
data - > dai . capture_only = true ;
2013-08-28 08:04:46 +04:00
2013-12-23 13:28:53 +04:00
if ( of_property_read_bool ( np , " spdif-out " ) )
data - > dai . capture_only = false ;
if ( of_property_read_bool ( np , " spdif-in " ) )
data - > dai . playback_only = false ;
2013-08-28 08:04:46 +04:00
2013-12-23 13:28:53 +04:00
if ( data - > dai . playback_only & & data - > dai . capture_only ) {
2013-08-28 08:04:46 +04:00
dev_err ( & pdev - > dev , " no enabled S/PDIF DAI link \n " ) ;
2013-12-23 13:28:53 +04:00
goto end ;
2013-08-28 08:04:46 +04:00
}
data - > card . dev = & pdev - > dev ;
2013-12-23 13:28:53 +04:00
data - > card . dai_link = & data - > dai ;
data - > card . num_links = 1 ;
2015-01-14 21:39:15 +03:00
data - > card . owner = THIS_MODULE ;
2013-08-28 08:04:46 +04:00
ret = snd_soc_of_parse_card_name ( & data - > card , " model " ) ;
if ( ret )
2013-12-23 13:28:53 +04:00
goto end ;
2013-08-28 08:04:46 +04:00
2013-09-17 08:12:47 +04:00
ret = devm_snd_soc_register_card ( & pdev - > dev , & data - > card ) ;
2021-12-14 05:08:34 +03:00
if ( ret )
dev_err_probe ( & pdev - > dev , ret , " snd_soc_register_card failed \n " ) ;
2013-08-28 08:04:46 +04:00
end :
2014-10-07 22:29:56 +04:00
of_node_put ( spdif_np ) ;
2013-08-28 08:04:46 +04:00
return ret ;
}
static const struct of_device_id imx_spdif_dt_ids [ ] = {
{ . compatible = " fsl,imx-audio-spdif " , } ,
{ /* sentinel */ }
} ;
MODULE_DEVICE_TABLE ( of , imx_spdif_dt_ids ) ;
static struct platform_driver imx_spdif_driver = {
. driver = {
. name = " imx-spdif " ,
2015-09-18 12:18:48 +03:00
. pm = & snd_soc_pm_ops ,
2013-08-28 08:04:46 +04:00
. of_match_table = imx_spdif_dt_ids ,
} ,
. probe = imx_spdif_audio_probe ,
} ;
module_platform_driver ( imx_spdif_driver ) ;
MODULE_AUTHOR ( " Freescale Semiconductor, Inc. " ) ;
MODULE_DESCRIPTION ( " Freescale i.MX S/PDIF machine driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_ALIAS ( " platform:imx-spdif " ) ;