2018-07-02 06:30:28 +00:00
// SPDX-License-Identifier: GPL-2.0
//
// ASoC simple sound card support
//
// Copyright (C) 2012 Renesas Solutions Corp.
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
2013-11-20 15:25:02 +09:00
# include <linux/clk.h>
2014-02-14 09:34:36 +08:00
# include <linux/device.h>
2012-04-08 21:17:50 -07:00
# include <linux/module.h>
2013-11-20 15:25:02 +09:00
# include <linux/of.h>
2019-04-04 09:52:52 +09:00
# include <linux/of_device.h>
2012-04-08 21:17:50 -07:00
# include <linux/platform_device.h>
2014-01-14 12:35:32 +08:00
# include <linux/string.h>
2012-04-08 21:17:50 -07:00
# include <sound/simple_card.h>
2014-02-14 09:34:36 +08:00
# include <sound/soc-dai.h>
# include <sound/soc.h>
2012-04-08 21:17:50 -07:00
2019-04-04 09:52:52 +09:00
# define DPCM_SELECTABLE 1
2016-08-08 06:02:07 +00:00
# define DAI "sound-dai"
# define CELL "#sound-dai-cells"
2016-05-31 08:59:01 +00:00
# define PREFIX "simple-audio-card,"
2018-12-20 10:47:34 +09:00
static const struct snd_soc_ops simple_ops = {
2019-03-20 13:55:14 +09:00
. startup = asoc_simple_startup ,
2019-03-20 13:55:27 +09:00
. shutdown = asoc_simple_shutdown ,
2019-03-20 13:55:39 +09:00
. hw_params = asoc_simple_hw_params ,
2014-05-22 17:31:49 +02:00
} ;
2022-01-07 15:47:10 -06:00
static int asoc_simple_parse_platform ( struct device_node * node ,
struct snd_soc_dai_link_component * dlc )
{
struct of_phandle_args args ;
int ret ;
if ( ! node )
return 0 ;
/*
* Get node via " sound-dai = <&phandle port> "
* it will be used as xxx_of_node on soc_bind_dai_link ( )
*/
ret = of_parse_phandle_with_args ( node , DAI , CELL , 0 , & args ) ;
if ( ret )
return ret ;
/* dai_name is not required and may not exist for plat component */
dlc - > of_node = args . np ;
return 0 ;
}
2019-03-20 13:56:50 +09:00
static int asoc_simple_parse_dai ( struct device_node * node ,
struct snd_soc_dai_link_component * dlc ,
int * is_single_link )
2019-03-20 13:56:36 +09:00
{
struct of_phandle_args args ;
int ret ;
if ( ! node )
return 0 ;
/*
* Get node via " sound-dai = <&phandle port> "
* it will be used as xxx_of_node on soc_bind_dai_link ( )
*/
ret = of_parse_phandle_with_args ( node , DAI , CELL , 0 , & args ) ;
if ( ret )
return ret ;
2019-09-03 17:15:54 +09:00
/*
* FIXME
*
* Here , dlc - > dai_name is pointer to CPU / Codec DAI name .
* If user unbinded CPU or Codec driver , but not for Sound Card ,
* dlc - > dai_name is keeping unbinded CPU or Codec
* driver ' s pointer .
*
* If user re - bind CPU or Codec driver again , ALSA SoC will try
* to rebind Card via snd_soc_try_rebind_card ( ) , but because of
* above reason , it might can ' t bind Sound Card .
* Because Sound Card is pointing to released dai_name pointer .
*
* To avoid this rebind Card issue ,
* 1 ) It needs to alloc memory to keep dai_name eventhough
* CPU or Codec driver was unbinded , or
* 2 ) user need to rebind Sound Card everytime
* if he unbinded CPU or Codec .
*/
2019-06-06 13:07:35 +09:00
ret = snd_soc_of_get_dai_name ( node , & dlc - > dai_name ) ;
if ( ret < 0 )
return ret ;
2019-03-20 13:56:36 +09:00
2019-06-06 13:07:35 +09:00
dlc - > of_node = args . np ;
2019-03-20 13:56:36 +09:00
if ( is_single_link )
* is_single_link = ! args . args_count ;
return 0 ;
}
2019-03-18 13:50:08 +09:00
static void simple_parse_convert ( struct device * dev ,
struct device_node * np ,
2019-03-20 13:56:50 +09:00
struct asoc_simple_data * adata )
2018-12-20 10:46:42 +09:00
{
struct device_node * top = dev - > of_node ;
struct device_node * node = of_get_parent ( np ) ;
2021-04-12 08:53:00 +09:00
asoc_simple_parse_convert ( top , PREFIX , adata ) ;
asoc_simple_parse_convert ( node , PREFIX , adata ) ;
asoc_simple_parse_convert ( node , NULL , adata ) ;
asoc_simple_parse_convert ( np , NULL , adata ) ;
2018-12-20 10:46:42 +09:00
of_node_put ( node ) ;
}
2019-03-18 13:50:17 +09:00
static void simple_parse_mclk_fs ( struct device_node * top ,
2021-05-11 10:17:07 +09:00
struct device_node * np ,
2019-03-18 13:50:17 +09:00
struct simple_dai_props * props ,
char * prefix )
{
2021-05-11 10:17:07 +09:00
struct device_node * node = of_get_parent ( np ) ;
2019-03-18 13:50:17 +09:00
char prop [ 128 ] ;
snprintf ( prop , sizeof ( prop ) , " %smclk-fs " , PREFIX ) ;
of_property_read_u32 ( top , prop , & props - > mclk_fs ) ;
snprintf ( prop , sizeof ( prop ) , " %smclk-fs " , prefix ) ;
of_property_read_u32 ( node , prop , & props - > mclk_fs ) ;
2021-05-11 10:17:07 +09:00
of_property_read_u32 ( np , prop , & props - > mclk_fs ) ;
2019-03-18 13:50:17 +09:00
of_node_put ( node ) ;
}
2021-05-11 10:17:07 +09:00
static int simple_parse_node ( struct asoc_simple_priv * priv ,
struct device_node * np ,
struct link_info * li ,
char * prefix ,
int * cpu )
{
struct device * dev = simple_priv_to_dev ( priv ) ;
struct device_node * top = dev - > of_node ;
struct snd_soc_dai_link * dai_link = simple_priv_to_link ( priv , li - > link ) ;
struct simple_dai_props * dai_props = simple_priv_to_props ( priv , li - > link ) ;
struct snd_soc_dai_link_component * dlc ;
struct asoc_simple_dai * dai ;
int ret ;
if ( cpu ) {
dlc = asoc_link_to_cpu ( dai_link , 0 ) ;
dai = simple_props_to_dai_cpu ( dai_props , 0 ) ;
} else {
dlc = asoc_link_to_codec ( dai_link , 0 ) ;
dai = simple_props_to_dai_codec ( dai_props , 0 ) ;
}
simple_parse_mclk_fs ( top , np , dai_props , prefix ) ;
ret = asoc_simple_parse_dai ( np , dlc , cpu ) ;
if ( ret )
return ret ;
ret = asoc_simple_parse_clk ( dev , np , dai , dlc ) ;
if ( ret )
return ret ;
ret = asoc_simple_parse_tdm ( np , dai ) ;
if ( ret )
return ret ;
return 0 ;
}
2021-05-11 10:17:47 +09:00
static int simple_link_init ( struct asoc_simple_priv * priv ,
struct device_node * node ,
struct device_node * codec ,
struct link_info * li ,
char * prefix , char * name )
{
struct device * dev = simple_priv_to_dev ( priv ) ;
struct snd_soc_dai_link * dai_link = simple_priv_to_link ( priv , li - > link ) ;
int ret ;
ret = asoc_simple_parse_daifmt ( dev , node , codec ,
prefix , & dai_link - > dai_fmt ) ;
if ( ret < 0 )
return 0 ;
dai_link - > init = asoc_simple_dai_init ;
dai_link - > ops = & simple_ops ;
return asoc_simple_set_dailink_name ( dev , dai_link , name ) ;
}
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
static int simple_dai_link_of_dpcm ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:34 +09:00
struct device_node * np ,
struct device_node * codec ,
struct link_info * li ,
bool is_top )
2018-12-14 11:35:10 +09:00
{
struct device * dev = simple_priv_to_dev ( priv ) ;
2018-12-20 10:46:53 +09:00
struct snd_soc_dai_link * dai_link = simple_priv_to_link ( priv , li - > link ) ;
struct simple_dai_props * dai_props = simple_priv_to_props ( priv , li - > link ) ;
2018-12-20 10:47:23 +09:00
struct device_node * top = dev - > of_node ;
struct device_node * node = of_get_parent ( np ) ;
2018-12-14 11:35:10 +09:00
char * prefix = " " ;
2021-05-11 10:17:47 +09:00
char dai_name [ 64 ] ;
2018-12-14 11:35:10 +09:00
int ret ;
2018-12-20 10:46:53 +09:00
dev_dbg ( dev , " link_of DPCM (%pOF) \n " , np ) ;
2018-12-14 11:35:10 +09:00
/* For single DAI link & old style of DT node */
2018-12-20 10:47:23 +09:00
if ( is_top )
2018-12-14 11:35:10 +09:00
prefix = PREFIX ;
2018-12-20 10:47:23 +09:00
if ( li - > cpu ) {
2021-05-11 10:17:07 +09:00
struct snd_soc_dai_link_component * cpus = asoc_link_to_cpu ( dai_link , 0 ) ;
struct snd_soc_dai_link_component * platforms = asoc_link_to_platform ( dai_link , 0 ) ;
2021-04-23 18:07:54 +01:00
int is_single_links = 0 ;
2019-10-15 11:52:41 +09:00
/* Codec is dummy */
2018-12-14 11:35:10 +09:00
/* FE settings */
dai_link - > dynamic = 1 ;
dai_link - > dpcm_merged_format = 1 ;
2021-05-11 10:17:07 +09:00
ret = simple_parse_node ( priv , np , li , prefix , & is_single_links ) ;
2021-04-23 18:07:54 +01:00
if ( ret < 0 )
goto out_put_node ;
2021-05-11 10:17:47 +09:00
snprintf ( dai_name , sizeof ( dai_name ) , " fe.%s " , cpus - > dai_name ) ;
2018-12-14 11:35:10 +09:00
2021-04-23 18:07:54 +01:00
asoc_simple_canonicalize_cpu ( cpus , is_single_links ) ;
asoc_simple_canonicalize_platform ( platforms , cpus ) ;
2018-12-14 11:35:10 +09:00
} else {
2021-05-11 10:17:07 +09:00
struct snd_soc_dai_link_component * codecs = asoc_link_to_codec ( dai_link , 0 ) ;
2018-12-14 11:35:10 +09:00
struct snd_soc_codec_conf * cconf ;
2019-10-15 11:52:41 +09:00
/* CPU is dummy */
2018-12-14 11:35:10 +09:00
/* BE settings */
dai_link - > no_pcm = 1 ;
2019-03-20 13:56:06 +09:00
dai_link - > be_hw_params_fixup = asoc_simple_be_hw_params_fixup ;
2018-12-14 11:35:10 +09:00
2021-04-14 08:20:10 +09:00
cconf = simple_props_to_codec_conf ( dai_props , 0 ) ;
2018-12-14 11:35:10 +09:00
2021-05-11 10:17:07 +09:00
ret = simple_parse_node ( priv , np , li , prefix , NULL ) ;
2021-04-23 18:07:54 +01:00
if ( ret < 0 )
goto out_put_node ;
2021-05-11 10:17:47 +09:00
snprintf ( dai_name , sizeof ( dai_name ) , " be.%s " , codecs - > dai_name ) ;
2018-12-14 11:35:10 +09:00
/* check "prefix" from top node */
2018-12-14 11:35:24 +09:00
snd_soc_of_parse_node_prefix ( top , cconf , codecs - > of_node ,
2018-12-14 11:35:10 +09:00
PREFIX " prefix " ) ;
2018-12-14 11:35:24 +09:00
snd_soc_of_parse_node_prefix ( node , cconf , codecs - > of_node ,
" prefix " ) ;
snd_soc_of_parse_node_prefix ( np , cconf , codecs - > of_node ,
" prefix " ) ;
2018-12-14 11:35:10 +09:00
}
2019-03-18 13:50:08 +09:00
simple_parse_convert ( dev , np , & dai_props - > adata ) ;
2021-04-23 18:07:54 +01:00
2020-07-07 16:04:37 -05:00
snd_soc_dai_link_set_capabilities ( dai_link ) ;
2021-05-11 10:17:47 +09:00
ret = simple_link_init ( priv , node , codec , li , prefix , dai_name ) ;
2018-12-14 11:35:10 +09:00
2019-07-10 15:25:06 +08:00
out_put_node :
2021-05-11 10:17:07 +09:00
li - > link + + ;
2019-07-10 15:25:06 +08:00
of_node_put ( node ) ;
return ret ;
2018-12-14 11:35:10 +09:00
}
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
static int simple_dai_link_of ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:34 +09:00
struct device_node * np ,
struct device_node * codec ,
struct link_info * li ,
bool is_top )
2014-03-20 11:49:55 +01:00
{
2014-09-09 21:37:57 -07:00
struct device * dev = simple_priv_to_dev ( priv ) ;
2018-12-20 10:46:53 +09:00
struct snd_soc_dai_link * dai_link = simple_priv_to_link ( priv , li - > link ) ;
2021-04-14 08:20:04 +09:00
struct snd_soc_dai_link_component * cpus = asoc_link_to_cpu ( dai_link , 0 ) ;
struct snd_soc_dai_link_component * codecs = asoc_link_to_codec ( dai_link , 0 ) ;
struct snd_soc_dai_link_component * platforms = asoc_link_to_platform ( dai_link , 0 ) ;
2014-10-27 18:04:52 -07:00
struct device_node * cpu = NULL ;
2018-12-20 10:47:23 +09:00
struct device_node * node = NULL ;
2015-04-29 18:11:07 +08:00
struct device_node * plat = NULL ;
2021-05-11 10:17:47 +09:00
char dai_name [ 64 ] ;
2014-03-24 12:15:25 +02:00
char prop [ 128 ] ;
char * prefix = " " ;
2021-04-23 18:07:54 +01:00
int ret , single_cpu = 0 ;
2014-03-20 11:49:55 +01:00
2018-12-20 10:47:23 +09:00
cpu = np ;
node = of_get_parent ( np ) ;
2018-12-20 10:46:53 +09:00
dev_dbg ( dev , " link_of (%pOF) \n " , node ) ;
2014-09-03 10:23:39 +08:00
/* For single DAI link & old style of DT node */
2018-12-20 10:47:23 +09:00
if ( is_top )
2016-05-31 08:59:01 +00:00
prefix = PREFIX ;
2014-03-24 12:15:25 +02:00
2015-04-29 18:11:07 +08:00
snprintf ( prop , sizeof ( prop ) , " %splat " , prefix ) ;
plat = of_get_child_by_name ( node , prop ) ;
2021-05-11 10:17:07 +09:00
ret = simple_parse_node ( priv , cpu , li , prefix , & single_cpu ) ;
2016-08-08 06:02:07 +00:00
if ( ret < 0 )
goto dai_link_of_err ;
2021-05-11 10:17:07 +09:00
ret = simple_parse_node ( priv , codec , li , prefix , NULL ) ;
2016-08-08 06:02:07 +00:00
if ( ret < 0 )
goto dai_link_of_err ;
2022-01-07 15:47:10 -06:00
ret = asoc_simple_parse_platform ( plat , platforms ) ;
2016-08-08 06:02:07 +00:00
if ( ret < 0 )
goto dai_link_of_err ;
2021-05-11 10:17:47 +09:00
snprintf ( dai_name , sizeof ( dai_name ) ,
" %s-%s " , cpus - > dai_name , codecs - > dai_name ) ;
2021-04-23 18:07:54 +01:00
asoc_simple_canonicalize_cpu ( cpus , single_cpu ) ;
asoc_simple_canonicalize_platform ( platforms , cpus ) ;
2021-05-11 10:17:47 +09:00
ret = simple_link_init ( priv , node , codec , li , prefix , dai_name ) ;
2014-03-24 12:15:25 +02:00
dai_link_of_err :
2019-02-19 16:46:48 +01:00
of_node_put ( plat ) ;
2018-12-20 10:47:23 +09:00
of_node_put ( node ) ;
2014-10-27 18:04:52 -07:00
2021-05-11 10:17:07 +09:00
li - > link + + ;
2014-03-20 11:49:55 +01:00
return ret ;
}
2021-03-26 12:26:40 +09:00
static int __simple_for_each_link ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:28 +09:00
struct link_info * li ,
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
int ( * func_noml ) ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:28 +09:00
struct device_node * np ,
struct device_node * codec ,
struct link_info * li , bool is_top ) ,
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
int ( * func_dpcm ) ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:28 +09:00
struct device_node * np ,
struct device_node * codec ,
struct link_info * li , bool is_top ) )
{
struct device * dev = simple_priv_to_dev ( priv ) ;
struct device_node * top = dev - > of_node ;
struct device_node * node ;
2019-04-04 09:52:52 +09:00
uintptr_t dpcm_selectable = ( uintptr_t ) of_device_get_match_data ( dev ) ;
2018-12-20 10:47:28 +09:00
bool is_top = 0 ;
2019-02-19 16:46:49 +01:00
int ret = 0 ;
2018-12-20 10:47:28 +09:00
/* Check if it has dai-link */
node = of_get_child_by_name ( top , PREFIX " dai-link " ) ;
if ( ! node ) {
2019-02-16 10:09:42 +00:00
node = of_node_get ( top ) ;
2018-12-20 10:47:28 +09:00
is_top = 1 ;
}
/* loop for all dai-link */
do {
2019-03-20 13:56:50 +09:00
struct asoc_simple_data adata ;
2018-12-20 10:47:28 +09:00
struct device_node * codec ;
2019-12-09 15:53:53 +02:00
struct device_node * plat ;
2018-12-20 10:47:28 +09:00
struct device_node * np ;
int num = of_get_child_count ( node ) ;
/* get codec */
codec = of_get_child_by_name ( node , is_top ?
PREFIX " codec " : " codec " ) ;
2019-02-19 16:46:49 +01:00
if ( ! codec ) {
ret = - ENODEV ;
goto error ;
}
2019-12-09 15:53:53 +02:00
/* get platform */
plat = of_get_child_by_name ( node , is_top ?
PREFIX " plat " : " plat " ) ;
2018-12-20 10:47:28 +09:00
/* get convert-xxx property */
memset ( & adata , 0 , sizeof ( adata ) ) ;
for_each_child_of_node ( node , np )
2019-03-18 13:50:08 +09:00
simple_parse_convert ( dev , np , & adata ) ;
2018-12-20 10:47:28 +09:00
/* loop for all CPU/Codec node */
for_each_child_of_node ( node , np ) {
2019-12-09 15:53:53 +02:00
if ( plat = = np )
continue ;
2018-12-20 10:47:28 +09:00
/*
* It is DPCM
* if it has many CPUs ,
* or has convert - xxx property
*/
2019-04-04 09:52:52 +09:00
if ( dpcm_selectable & &
2022-10-19 02:23:02 +01:00
( num > 2 | | asoc_simple_is_convert_required ( & adata ) ) ) {
2021-03-26 12:26:40 +09:00
/*
* np
* | 1 ( CPU ) | 0 ( Codec ) li - > cpu
* CPU | Pass | return
* Codec | return | Pass
*/
if ( li - > cpu ! = ( np = = codec ) )
ret = func_dpcm ( priv , np , codec , li , is_top ) ;
2018-12-20 10:47:28 +09:00
/* else normal sound */
2021-03-26 12:26:40 +09:00
} else {
/*
* np
* | 1 ( CPU ) | 0 ( Codec ) li - > cpu
* CPU | Pass | return
* Codec | return | return
*/
if ( li - > cpu & & ( np ! = codec ) )
ret = func_noml ( priv , np , codec , li , is_top ) ;
}
2018-12-20 10:47:28 +09:00
2019-02-19 16:46:49 +01:00
if ( ret < 0 ) {
2019-07-10 15:25:07 +08:00
of_node_put ( codec ) ;
2019-02-19 16:46:49 +01:00
of_node_put ( np ) ;
goto error ;
}
2018-12-20 10:47:28 +09:00
}
2019-07-10 15:25:07 +08:00
of_node_put ( codec ) ;
2023-03-23 22:56:08 +00:00
of_node_put ( plat ) ;
2018-12-20 10:47:28 +09:00
node = of_get_next_child ( top , node ) ;
} while ( ! is_top & & node ) ;
2019-02-19 16:46:49 +01:00
error :
of_node_put ( node ) ;
return ret ;
2018-12-20 10:47:28 +09:00
}
2021-03-26 12:26:40 +09:00
static int simple_for_each_link ( struct asoc_simple_priv * priv ,
struct link_info * li ,
int ( * func_noml ) ( struct asoc_simple_priv * priv ,
struct device_node * np ,
struct device_node * codec ,
struct link_info * li , bool is_top ) ,
int ( * func_dpcm ) ( struct asoc_simple_priv * priv ,
struct device_node * np ,
struct device_node * codec ,
struct link_info * li , bool is_top ) )
{
int ret ;
/*
* Detect all CPU first , and Detect all Codec 2 nd .
*
* In Normal sound case , all DAIs are detected
* as " CPU-Codec " .
*
* In DPCM sound case ,
* all CPUs are detected as " CPU-dummy " , and
* all Codecs are detected as " dummy-Codec " .
* To avoid random sub - device numbering ,
* detect " dummy-Codec " in last ;
*/
for ( li - > cpu = 1 ; li - > cpu > = 0 ; li - > cpu - - ) {
ret = __simple_for_each_link ( priv , li , func_noml , func_dpcm ) ;
if ( ret < 0 )
break ;
}
return ret ;
}
2021-04-19 18:41:17 +02:00
static int simple_parse_of ( struct asoc_simple_priv * priv , struct link_info * li )
2013-11-20 15:25:02 +09:00
{
2017-03-15 04:44:00 +00:00
struct snd_soc_card * card = simple_priv_to_card ( priv ) ;
2018-12-20 10:47:28 +09:00
int ret ;
2018-12-14 11:35:10 +09:00
2019-03-20 13:56:50 +09:00
ret = asoc_simple_parse_widgets ( card , PREFIX ) ;
2017-06-16 01:39:11 +00:00
if ( ret < 0 )
2018-12-14 11:35:10 +09:00
return ret ;
2014-02-08 15:59:53 +08:00
2019-03-20 13:56:50 +09:00
ret = asoc_simple_parse_routing ( card , PREFIX ) ;
2017-06-15 00:25:17 +00:00
if ( ret < 0 )
2018-12-14 11:35:10 +09:00
return ret ;
2013-12-23 12:57:01 +08:00
2019-04-26 04:25:50 +02:00
ret = asoc_simple_parse_pin_switches ( card , PREFIX ) ;
if ( ret < 0 )
return ret ;
2014-09-03 10:23:39 +08:00
/* Single/Muti DAI link(s) & New style of DT node */
2021-04-19 18:41:17 +02:00
memset ( li , 0 , sizeof ( * li ) ) ;
ret = simple_for_each_link ( priv , li ,
2021-03-26 12:26:40 +09:00
simple_dai_link_of ,
simple_dai_link_of_dpcm ) ;
if ( ret < 0 )
return ret ;
2018-12-20 10:47:23 +09:00
2019-03-20 13:56:50 +09:00
ret = asoc_simple_parse_card_name ( card , PREFIX ) ;
2016-09-26 12:56:51 +03:00
if ( ret < 0 )
2018-12-14 11:35:10 +09:00
return ret ;
2014-02-27 18:25:24 -08:00
2020-08-01 12:02:56 +02:00
ret = snd_soc_of_parse_aux_devs ( card , PREFIX " aux-devs " ) ;
2016-08-26 03:05:16 +00:00
return ret ;
2013-11-20 15:25:02 +09:00
}
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
static int simple_count_noml ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:34 +09:00
struct device_node * np ,
struct device_node * codec ,
struct link_info * li , bool is_top )
2018-12-20 10:47:23 +09:00
{
2021-04-16 09:11:47 +02:00
if ( li - > link > = SNDRV_MAX_LINKS ) {
2021-04-01 13:15:23 +09:00
struct device * dev = simple_priv_to_dev ( priv ) ;
dev_err ( dev , " too many links \n " ) ;
return - EINVAL ;
}
2023-03-22 01:12:24 +00:00
/*
* DON ' T REMOVE platforms
*
* Some CPU might be using soc - generic - dmaengine - pcm . This means CPU and Platform
* are different Component , but are sharing same component - > dev .
* Simple Card had been supported it without special Platform selection .
* We need platforms here .
*
* In case of no Platform , it will be Platform = = CPU , but Platform will be
* ignored by snd_soc_rtd_add_component ( ) .
*
* see
* simple - card - utils . c : : asoc_simple_canonicalize_platform ( )
*/
2021-04-01 13:15:23 +09:00
li - > num [ li - > link ] . cpus = 1 ;
li - > num [ li - > link ] . platforms = 1 ;
2023-03-22 01:12:24 +00:00
li - > num [ li - > link ] . codecs = 1 ;
ASoC: simple-card: count DAI / link numbers as in order
simple-card checks DT links 2 times. 1st is for counting DAIs / links
to allocating memory, 2nd is for detecting DAIs.
To detecting DAIs as CPU-dummy -> dummy-Codec order when DPCM case,
it uses loops 2 times at 2nd DT link check.
But it doesn't do it at 1st DT link check.
for (li.cpu = 1; li.cpu >= 0; li.cpu--) {
/*
* Detect all CPU first, and Detect all Codec 2n
*
* In Normal sound case, all DAIs are detected
* as "CPU-Codec".
*
* In DPCM sound case,
* all CPUs are detected as "CPU-dummy", and
* all Codecs are detected as "dummy-Codec".
* To avoid random sub-device numbering,
* detect "dummy-Codec" in last;
*/
ret = simple_for_each_link(...);
...
}
To prepare supporting multi-CPU/Codec, and code cleanup,
this patch use same loop for 1st DT link check, too.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/877dlu1tp2.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-26 12:26:33 +09:00
li - > link + = 1 ;
2018-12-20 10:47:23 +09:00
return 0 ;
}
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
static int simple_count_dpcm ( struct asoc_simple_priv * priv ,
2018-12-20 10:47:34 +09:00
struct device_node * np ,
struct device_node * codec ,
struct link_info * li , bool is_top )
2018-12-20 10:47:23 +09:00
{
2021-04-16 09:11:47 +02:00
if ( li - > link > = SNDRV_MAX_LINKS ) {
2021-04-01 13:15:23 +09:00
struct device * dev = simple_priv_to_dev ( priv ) ;
dev_err ( dev , " too many links \n " ) ;
return - EINVAL ;
}
ASoC: simple-card: count DAI / link numbers as in order
simple-card checks DT links 2 times. 1st is for counting DAIs / links
to allocating memory, 2nd is for detecting DAIs.
To detecting DAIs as CPU-dummy -> dummy-Codec order when DPCM case,
it uses loops 2 times at 2nd DT link check.
But it doesn't do it at 1st DT link check.
for (li.cpu = 1; li.cpu >= 0; li.cpu--) {
/*
* Detect all CPU first, and Detect all Codec 2n
*
* In Normal sound case, all DAIs are detected
* as "CPU-Codec".
*
* In DPCM sound case,
* all CPUs are detected as "CPU-dummy", and
* all Codecs are detected as "dummy-Codec".
* To avoid random sub-device numbering,
* detect "dummy-Codec" in last;
*/
ret = simple_for_each_link(...);
...
}
To prepare supporting multi-CPU/Codec, and code cleanup,
this patch use same loop for 1st DT link check, too.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/877dlu1tp2.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-26 12:26:33 +09:00
if ( li - > cpu ) {
2023-03-22 01:12:24 +00:00
/*
* DON ' T REMOVE platforms
* see
* simple_count_noml ( )
*/
2021-04-01 13:15:23 +09:00
li - > num [ li - > link ] . cpus = 1 ;
li - > num [ li - > link ] . platforms = 1 ;
ASoC: simple-card: count DAI / link numbers as in order
simple-card checks DT links 2 times. 1st is for counting DAIs / links
to allocating memory, 2nd is for detecting DAIs.
To detecting DAIs as CPU-dummy -> dummy-Codec order when DPCM case,
it uses loops 2 times at 2nd DT link check.
But it doesn't do it at 1st DT link check.
for (li.cpu = 1; li.cpu >= 0; li.cpu--) {
/*
* Detect all CPU first, and Detect all Codec 2n
*
* In Normal sound case, all DAIs are detected
* as "CPU-Codec".
*
* In DPCM sound case,
* all CPUs are detected as "CPU-dummy", and
* all Codecs are detected as "dummy-Codec".
* To avoid random sub-device numbering,
* detect "dummy-Codec" in last;
*/
ret = simple_for_each_link(...);
...
}
To prepare supporting multi-CPU/Codec, and code cleanup,
this patch use same loop for 1st DT link check, too.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/877dlu1tp2.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-26 12:26:33 +09:00
li - > link + + ; /* CPU-dummy */
} else {
2021-04-01 13:15:23 +09:00
li - > num [ li - > link ] . codecs = 1 ;
ASoC: simple-card: count DAI / link numbers as in order
simple-card checks DT links 2 times. 1st is for counting DAIs / links
to allocating memory, 2nd is for detecting DAIs.
To detecting DAIs as CPU-dummy -> dummy-Codec order when DPCM case,
it uses loops 2 times at 2nd DT link check.
But it doesn't do it at 1st DT link check.
for (li.cpu = 1; li.cpu >= 0; li.cpu--) {
/*
* Detect all CPU first, and Detect all Codec 2n
*
* In Normal sound case, all DAIs are detected
* as "CPU-Codec".
*
* In DPCM sound case,
* all CPUs are detected as "CPU-dummy", and
* all Codecs are detected as "dummy-Codec".
* To avoid random sub-device numbering,
* detect "dummy-Codec" in last;
*/
ret = simple_for_each_link(...);
...
}
To prepare supporting multi-CPU/Codec, and code cleanup,
this patch use same loop for 1st DT link check, too.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/877dlu1tp2.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-03-26 12:26:33 +09:00
li - > link + + ; /* dummy-Codec */
}
2018-12-20 10:47:23 +09:00
return 0 ;
}
2021-04-16 09:11:46 +02:00
static int simple_get_dais_count ( struct asoc_simple_priv * priv ,
struct link_info * li )
2018-12-14 11:35:10 +09:00
{
2018-12-20 10:47:23 +09:00
struct device * dev = simple_priv_to_dev ( priv ) ;
2018-12-14 11:35:10 +09:00
struct device_node * top = dev - > of_node ;
/*
* link_num : number of links .
* CPU - Codec / CPU - dummy / dummy - Codec
* dais_num : number of DAIs
* ccnf_num : number of codec_conf
* same number for " dummy-Codec "
*
* ex1 )
* CPU0 - - - Codec0 link : 5
* CPU1 - - - Codec1 dais : 7
* CPU2 - / ccnf : 1
* CPU3 - - - Codec2
*
* = > 5 links = 2 xCPU - Codec + 2 xCPU - dummy + 1 xdummy - Codec
* = > 7 DAIs = 4 xCPU + 3 xCodec
* = > 1 ccnf = 1 xdummy - Codec
*
* ex2 )
* CPU0 - - - Codec0 link : 5
* CPU1 - - - Codec1 dais : 6
* CPU2 - / ccnf : 1
* CPU3 - /
*
* = > 5 links = 1 xCPU - Codec + 3 xCPU - dummy + 1 xdummy - Codec
* = > 6 DAIs = 4 xCPU + 2 xCodec
* = > 1 ccnf = 1 xdummy - Codec
*
* ex3 )
* CPU0 - - - Codec0 link : 6
* CPU1 - / dais : 6
* CPU2 - - - Codec1 ccnf : 2
* CPU3 - /
*
* = > 6 links = 0xC PU - Codec + 4 xCPU - dummy + 2 xdummy - Codec
* = > 6 DAIs = 4 xCPU + 2 xCodec
* = > 2 ccnf = 2 xdummy - Codec
2018-12-20 10:46:47 +09:00
*
* ex4 )
* CPU0 - - - Codec0 ( convert - rate ) link : 3
* CPU1 - - - Codec1 dais : 4
* ccnf : 1
*
* = > 3 links = 1 xCPU - Codec + 1 xCPU - dummy + 1 xdummy - Codec
* = > 4 DAIs = 2 xCPU + 2 xCodec
* = > 1 ccnf = 1 xdummy - Codec
2018-12-14 11:35:10 +09:00
*/
if ( ! top ) {
2021-04-01 13:15:23 +09:00
li - > num [ 0 ] . cpus = 1 ;
li - > num [ 0 ] . codecs = 1 ;
li - > num [ 0 ] . platforms = 1 ;
2018-12-20 10:46:53 +09:00
li - > link = 1 ;
2021-04-16 09:11:46 +02:00
return 0 ;
2018-12-14 11:35:10 +09:00
}
2021-04-16 09:11:46 +02:00
return simple_for_each_link ( priv , li ,
simple_count_noml ,
simple_count_dpcm ) ;
2018-12-14 11:35:10 +09:00
}
2018-12-20 10:47:34 +09:00
static int simple_soc_probe ( struct snd_soc_card * card )
2018-06-11 17:32:13 +09:00
{
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
struct asoc_simple_priv * priv = snd_soc_card_get_drvdata ( card ) ;
2018-06-11 17:32:13 +09:00
int ret ;
2019-03-20 13:56:50 +09:00
ret = asoc_simple_init_hp ( card , & priv - > hp_jack , PREFIX ) ;
2018-06-11 17:32:13 +09:00
if ( ret < 0 )
return ret ;
2019-03-20 13:56:50 +09:00
ret = asoc_simple_init_mic ( card , & priv - > mic_jack , PREFIX ) ;
2018-06-11 17:32:13 +09:00
if ( ret < 0 )
return ret ;
2023-01-23 14:59:12 +01:00
ret = asoc_simple_init_aux_jacks ( priv , PREFIX ) ;
if ( ret < 0 )
return ret ;
2018-06-11 17:32:13 +09:00
return 0 ;
}
2019-05-16 13:26:28 +03:00
static int asoc_simple_probe ( struct platform_device * pdev )
2012-04-08 21:17:50 -07:00
{
ASoC: simple_card_utils: share common priv for simple-card/audio-graph
Historically, simple-card/simple-scu-card/audio-graph/audio-graph-scu
are similar but different generic sound card.
simple-scu-card which was for DPCM was merged into simple-card, and
audio-graph-scu which was for DPCM was merged into audio-graph.
simple-card is for non OF graph sound card, and
audio-graph is for OF graph sound card.
And, small detail difference (= function parameter, naming, etc)
between simple-card/audio-graph has been unified.
So today, the difference between simple-card/audio-graph are
just using OF graph style, or not.
In other words, there should no difference other than OF graph sytle.
simple-card/audio-graph are using own priv today , but we can merge it.
This patch merge it at simple_card_utils.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-03-20 13:54:59 +09:00
struct asoc_simple_priv * priv ;
2012-12-25 22:52:33 -08:00
struct device * dev = & pdev - > dev ;
2017-03-15 04:43:21 +00:00
struct device_node * np = dev - > of_node ;
2017-03-15 04:44:00 +00:00
struct snd_soc_card * card ;
2021-04-19 18:41:17 +02:00
struct link_info * li ;
2019-03-20 13:56:26 +09:00
int ret ;
2012-04-08 21:17:50 -07:00
2014-09-10 09:59:55 +08:00
/* Allocate the private data and the DAI link array */
2016-08-26 03:10:25 +00:00
priv = devm_kzalloc ( dev , sizeof ( * priv ) , GFP_KERNEL ) ;
2014-01-15 16:51:52 +01:00
if ( ! priv )
2014-01-14 12:35:32 +08:00
return - ENOMEM ;
2018-12-20 10:47:23 +09:00
card = simple_priv_to_card ( priv ) ;
card - > owner = THIS_MODULE ;
card - > dev = dev ;
2018-12-20 10:47:34 +09:00
card - > probe = simple_soc_probe ;
2021-06-22 10:27:09 +02:00
card - > driver_name = " simple-card " ;
2018-12-20 10:47:23 +09:00
2021-04-19 18:41:17 +02:00
li = devm_kzalloc ( dev , sizeof ( * li ) , GFP_KERNEL ) ;
if ( ! li )
return - ENOMEM ;
ret = simple_get_dais_count ( priv , li ) ;
2021-04-16 09:11:46 +02:00
if ( ret < 0 )
return ret ;
2021-04-19 18:41:17 +02:00
if ( ! li - > link )
2018-12-14 11:35:10 +09:00
return - EINVAL ;
2021-04-19 18:41:17 +02:00
ret = asoc_simple_init_priv ( priv , li ) ;
2019-03-20 13:56:26 +09:00
if ( ret < 0 )
return ret ;
2014-01-15 16:51:41 +01:00
2013-11-20 15:25:02 +09:00
if ( np & & of_device_is_available ( np ) ) {
2014-01-14 12:35:32 +08:00
2021-04-19 18:41:17 +02:00
ret = simple_parse_of ( priv , li ) ;
2014-01-14 12:35:32 +08:00
if ( ret < 0 ) {
2021-12-14 11:08:35 +09:00
dev_err_probe ( dev , ret , " parse error \n " ) ;
2014-03-11 10:03:40 +01:00
goto err ;
2013-11-20 15:25:02 +09:00
}
2014-03-20 11:49:55 +01:00
2013-11-20 15:25:02 +09:00
} else {
2014-01-15 16:51:52 +01:00
struct asoc_simple_card_info * cinfo ;
2019-06-06 13:07:35 +09:00
struct snd_soc_dai_link_component * cpus ;
2018-08-31 03:08:24 +00:00
struct snd_soc_dai_link_component * codecs ;
2018-08-31 03:10:33 +00:00
struct snd_soc_dai_link_component * platform ;
2019-03-20 13:56:26 +09:00
struct snd_soc_dai_link * dai_link = priv - > dai_link ;
struct simple_dai_props * dai_props = priv - > dai_props ;
2014-01-15 16:51:52 +01:00
cinfo = dev - > platform_data ;
if ( ! cinfo ) {
2014-01-09 17:49:40 +08:00
dev_err ( dev , " no info for asoc-simple-card \n " ) ;
return - EINVAL ;
}
2013-11-20 15:25:02 +09:00
2014-04-24 19:14:00 +08:00
if ( ! cinfo - > name | |
! cinfo - > codec_dai . name | |
! cinfo - > codec | |
! cinfo - > platform | |
2014-01-15 16:51:33 +01:00
! cinfo - > cpu_dai . name ) {
dev_err ( dev , " insufficient asoc_simple_card_info settings \n " ) ;
return - EINVAL ;
}
2014-01-15 16:51:37 +01:00
2019-06-06 13:07:35 +09:00
cpus = dai_link - > cpus ;
cpus - > dai_name = cinfo - > cpu_dai . name ;
2018-08-31 03:08:24 +00:00
codecs = dai_link - > codecs ;
codecs - > name = cinfo - > codec ;
codecs - > dai_name = cinfo - > codec_dai . name ;
2019-01-21 09:32:32 +09:00
platform = dai_link - > platforms ;
2018-08-31 03:10:33 +00:00
platform - > name = cinfo - > platform ;
2017-03-15 04:44:00 +00:00
card - > name = ( cinfo - > card ) ? cinfo - > card : cinfo - > name ;
2014-01-15 16:51:45 +01:00
dai_link - > name = cinfo - > name ;
dai_link - > stream_name = cinfo - > name ;
2015-03-24 01:07:08 +00:00
dai_link - > dai_fmt = cinfo - > daifmt ;
2019-03-20 13:55:52 +09:00
dai_link - > init = asoc_simple_dai_init ;
2019-03-20 13:56:26 +09:00
memcpy ( dai_props - > cpu_dai , & cinfo - > cpu_dai ,
sizeof ( * dai_props - > cpu_dai ) ) ;
memcpy ( dai_props - > codec_dai , & cinfo - > codec_dai ,
sizeof ( * dai_props - > codec_dai ) ) ;
2012-04-08 21:17:50 -07:00
}
2017-03-15 04:44:00 +00:00
snd_soc_card_set_drvdata ( card , priv ) ;
2012-04-08 21:17:50 -07:00
2019-03-20 13:54:42 +09:00
asoc_simple_debug_info ( priv ) ;
2017-03-15 04:44:00 +00:00
ret = devm_snd_soc_register_card ( dev , card ) ;
2017-05-19 00:57:21 +00:00
if ( ret < 0 )
goto err ;
2021-04-19 18:41:17 +02:00
devm_kfree ( dev , li ) ;
2017-05-19 00:57:21 +00:00
return 0 ;
2014-03-11 10:03:40 +01:00
err :
2019-03-20 13:56:50 +09:00
asoc_simple_clean_reference ( card ) ;
2016-08-26 03:07:59 +00:00
2014-03-11 10:03:40 +01:00
return ret ;
2012-04-08 21:17:50 -07:00
}
2018-12-20 10:47:34 +09:00
static const struct of_device_id simple_of_match [ ] = {
2013-11-20 15:25:02 +09:00
{ . compatible = " simple-audio-card " , } ,
2019-04-04 09:52:52 +09:00
{ . compatible = " simple-scu-audio-card " ,
. data = ( void * ) DPCM_SELECTABLE } ,
2013-11-20 15:25:02 +09:00
{ } ,
} ;
2018-12-20 10:47:34 +09:00
MODULE_DEVICE_TABLE ( of , simple_of_match ) ;
2013-11-20 15:25:02 +09:00
2012-04-08 21:17:50 -07:00
static struct platform_driver asoc_simple_card = {
. driver = {
2014-04-24 19:14:00 +08:00
. name = " asoc-simple-card " ,
2016-05-09 13:38:10 +03:00
. pm = & snd_soc_pm_ops ,
2018-12-20 10:47:34 +09:00
. of_match_table = simple_of_match ,
2012-04-08 21:17:50 -07:00
} ,
2019-05-16 13:26:28 +03:00
. probe = asoc_simple_probe ,
. remove = asoc_simple_remove ,
2012-04-08 21:17:50 -07:00
} ;
module_platform_driver ( asoc_simple_card ) ;
2013-08-23 14:35:17 -03:00
MODULE_ALIAS ( " platform:asoc-simple-card " ) ;
2016-08-26 03:07:28 +00:00
MODULE_LICENSE ( " GPL v2 " ) ;
2012-04-08 21:17:50 -07:00
MODULE_DESCRIPTION ( " ASoC Simple Sound Card " ) ;
MODULE_AUTHOR ( " Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> " ) ;