2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-06-22 14:59:25 +02:00
/*
* sound / soc / codecs / wm8782 . c
* simple , strap - pin configured 24 bit 2 ch ADC
*
* Copyright : 2011 Raumfeld GmbH
* Author : Johannes Stezenbach < js @ sig21 . net >
*
* based on ad73311 . c
2020-04-16 12:30:58 +02:00
* Copyright : Analog Devices Inc .
2011-06-22 14:59:25 +02:00
* Author : Cliff Cai < cliff . cai @ analog . com >
*/
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/device.h>
2018-10-03 21:34:36 +02:00
# include <linux/regulator/consumer.h>
2011-06-22 14:59:25 +02:00
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/ac97_codec.h>
# include <sound/initval.h>
# include <sound/soc.h>
2013-08-18 18:36:06 +01:00
static const struct snd_soc_dapm_widget wm8782_dapm_widgets [ ] = {
SND_SOC_DAPM_INPUT ( " AINL " ) ,
SND_SOC_DAPM_INPUT ( " AINR " ) ,
} ;
static const struct snd_soc_dapm_route wm8782_dapm_routes [ ] = {
{ " Capture " , NULL , " AINL " } ,
{ " Capture " , NULL , " AINR " } ,
} ;
2011-06-22 14:59:25 +02:00
static struct snd_soc_dai_driver wm8782_dai = {
. name = " wm8782 " ,
. capture = {
. stream_name = " Capture " ,
. channels_min = 2 ,
. channels_max = 2 ,
/* For configurations with FSAMPEN=0 */
. rates = SNDRV_PCM_RATE_8000_48000 ,
. formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE |
SNDRV_PCM_FMTBIT_S24_LE ,
} ,
} ;
2018-10-03 21:34:36 +02:00
/* regulator power supply names */
static const char * supply_names [ ] = {
" Vdda " , /* analog supply, 2.7V - 3.6V */
" Vdd " , /* digital supply, 2.7V - 5.5V */
} ;
struct wm8782_priv {
struct regulator_bulk_data supplies [ ARRAY_SIZE ( supply_names ) ] ;
} ;
static int wm8782_soc_probe ( struct snd_soc_component * component )
{
struct wm8782_priv * priv = snd_soc_component_get_drvdata ( component ) ;
return regulator_bulk_enable ( ARRAY_SIZE ( priv - > supplies ) , priv - > supplies ) ;
}
static void wm8782_soc_remove ( struct snd_soc_component * component )
{
struct wm8782_priv * priv = snd_soc_component_get_drvdata ( component ) ;
regulator_bulk_disable ( ARRAY_SIZE ( priv - > supplies ) , priv - > supplies ) ;
}
# ifdef CONFIG_PM
static int wm8782_soc_suspend ( struct snd_soc_component * component )
{
struct wm8782_priv * priv = snd_soc_component_get_drvdata ( component ) ;
regulator_bulk_disable ( ARRAY_SIZE ( priv - > supplies ) , priv - > supplies ) ;
return 0 ;
}
static int wm8782_soc_resume ( struct snd_soc_component * component )
{
struct wm8782_priv * priv = snd_soc_component_get_drvdata ( component ) ;
return regulator_bulk_enable ( ARRAY_SIZE ( priv - > supplies ) , priv - > supplies ) ;
}
# else
# define wm8782_soc_suspend NULL
# define wm8782_soc_resume NULL
# endif /* CONFIG_PM */
2018-01-29 03:03:17 +00:00
static const struct snd_soc_component_driver soc_component_dev_wm8782 = {
2018-10-03 21:34:36 +02:00
. probe = wm8782_soc_probe ,
. remove = wm8782_soc_remove ,
. suspend = wm8782_soc_suspend ,
. resume = wm8782_soc_resume ,
2018-01-29 03:03:17 +00:00
. dapm_widgets = wm8782_dapm_widgets ,
. num_dapm_widgets = ARRAY_SIZE ( wm8782_dapm_widgets ) ,
. dapm_routes = wm8782_dapm_routes ,
. num_dapm_routes = ARRAY_SIZE ( wm8782_dapm_routes ) ,
. idle_bias_on = 1 ,
. use_pmdown_time = 1 ,
. endianness = 1 ,
2013-08-18 18:36:06 +01:00
} ;
2011-06-22 14:59:25 +02:00
2012-12-07 09:26:37 -05:00
static int wm8782_probe ( struct platform_device * pdev )
2011-06-22 14:59:25 +02:00
{
2018-10-03 21:34:36 +02:00
struct device * dev = & pdev - > dev ;
struct wm8782_priv * priv ;
int ret , i ;
priv = devm_kzalloc ( dev , sizeof ( * priv ) , GFP_KERNEL ) ;
if ( ! priv )
return - ENOMEM ;
dev_set_drvdata ( dev , priv ) ;
for ( i = 0 ; i < ARRAY_SIZE ( supply_names ) ; i + + )
priv - > supplies [ i ] . supply = supply_names [ i ] ;
ret = devm_regulator_bulk_get ( dev , ARRAY_SIZE ( priv - > supplies ) ,
priv - > supplies ) ;
if ( ret < 0 )
return ret ;
2018-01-29 03:03:17 +00:00
return devm_snd_soc_register_component ( & pdev - > dev ,
& soc_component_dev_wm8782 , & wm8782_dai , 1 ) ;
2011-06-22 14:59:25 +02:00
}
2018-05-21 23:54:49 +02:00
# ifdef CONFIG_OF
static const struct of_device_id wm8782_of_match [ ] = {
{ . compatible = " wlf,wm8782 " , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , wm8782_of_match ) ;
# endif
2011-06-22 14:59:25 +02:00
static struct platform_driver wm8782_codec_driver = {
. driver = {
. name = " wm8782 " ,
2018-05-21 23:54:49 +02:00
. of_match_table = of_match_ptr ( wm8782_of_match ) ,
2011-06-22 14:59:25 +02:00
} ,
. probe = wm8782_probe ,
} ;
2011-11-23 22:52:08 +00:00
module_platform_driver ( wm8782_codec_driver ) ;
2011-06-22 14:59:25 +02:00
MODULE_DESCRIPTION ( " ASoC WM8782 driver " ) ;
MODULE_AUTHOR ( " Johannes Stezenbach <js@sig21.net> " ) ;
MODULE_LICENSE ( " GPL " ) ;