2014-03-05 16:34:36 +08:00
/*
* SiRF audio card driver
*
* Copyright ( c ) 2011 Cambridge Silicon Radio Limited , a CSR plc group company .
*
* Licensed under GPLv2 or later .
*/
# include <linux/platform_device.h>
# include <linux/module.h>
# include <linux/of.h>
# include <linux/gpio.h>
# include <linux/of_gpio.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/soc.h>
struct sirf_audio_card {
unsigned int gpio_hp_pa ;
unsigned int gpio_spk_pa ;
} ;
static int sirf_audio_hp_event ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * ctrl , int event )
{
struct snd_soc_dapm_context * dapm = w - > dapm ;
struct snd_soc_card * card = dapm - > card ;
struct sirf_audio_card * sirf_audio_card = snd_soc_card_get_drvdata ( card ) ;
int on = ! SND_SOC_DAPM_EVENT_OFF ( event ) ;
2017-02-25 21:59:33 +02:00
2014-03-05 16:34:36 +08:00
if ( gpio_is_valid ( sirf_audio_card - > gpio_hp_pa ) )
gpio_set_value ( sirf_audio_card - > gpio_hp_pa , on ) ;
return 0 ;
}
static int sirf_audio_spk_event ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * ctrl , int event )
{
struct snd_soc_dapm_context * dapm = w - > dapm ;
struct snd_soc_card * card = dapm - > card ;
struct sirf_audio_card * sirf_audio_card = snd_soc_card_get_drvdata ( card ) ;
int on = ! SND_SOC_DAPM_EVENT_OFF ( event ) ;
if ( gpio_is_valid ( sirf_audio_card - > gpio_spk_pa ) )
gpio_set_value ( sirf_audio_card - > gpio_spk_pa , on ) ;
return 0 ;
}
static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets [ ] = {
SND_SOC_DAPM_HP ( " Hp " , sirf_audio_hp_event ) ,
SND_SOC_DAPM_SPK ( " Ext Spk " , sirf_audio_spk_event ) ,
SND_SOC_DAPM_MIC ( " Ext Mic " , NULL ) ,
} ;
static const struct snd_soc_dapm_route intercon [ ] = {
{ " Hp " , NULL , " HPOUTL " } ,
{ " Hp " , NULL , " HPOUTR " } ,
{ " Ext Spk " , NULL , " SPKOUT " } ,
{ " MICIN1 " , NULL , " Mic Bias " } ,
{ " Mic Bias " , NULL , " Ext Mic " } ,
} ;
/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link sirf_audio_dai_link [ ] = {
{
. name = " SiRF audio card " ,
. stream_name = " SiRF audio HiFi " ,
. codec_dai_name = " sirf-audio-codec " ,
} ,
} ;
/* Audio machine driver */
static struct snd_soc_card snd_soc_sirf_audio_card = {
. name = " SiRF audio card " ,
. owner = THIS_MODULE ,
. dai_link = sirf_audio_dai_link ,
. num_links = ARRAY_SIZE ( sirf_audio_dai_link ) ,
. dapm_widgets = sirf_audio_dapm_widgets ,
. num_dapm_widgets = ARRAY_SIZE ( sirf_audio_dapm_widgets ) ,
. dapm_routes = intercon ,
. num_dapm_routes = ARRAY_SIZE ( intercon ) ,
} ;
static int sirf_audio_probe ( struct platform_device * pdev )
{
struct snd_soc_card * card = & snd_soc_sirf_audio_card ;
struct sirf_audio_card * sirf_audio_card ;
int ret ;
sirf_audio_card = devm_kzalloc ( & pdev - > dev , sizeof ( struct sirf_audio_card ) ,
GFP_KERNEL ) ;
if ( sirf_audio_card = = NULL )
return - ENOMEM ;
sirf_audio_dai_link [ 0 ] . cpu_of_node =
of_parse_phandle ( pdev - > dev . of_node , " sirf,audio-platform " , 0 ) ;
sirf_audio_dai_link [ 0 ] . platform_of_node =
of_parse_phandle ( pdev - > dev . of_node , " sirf,audio-platform " , 0 ) ;
sirf_audio_dai_link [ 0 ] . codec_of_node =
of_parse_phandle ( pdev - > dev . of_node , " sirf,audio-codec " , 0 ) ;
sirf_audio_card - > gpio_spk_pa = of_get_named_gpio ( pdev - > dev . of_node ,
" spk-pa-gpios " , 0 ) ;
sirf_audio_card - > gpio_hp_pa = of_get_named_gpio ( pdev - > dev . of_node ,
" hp-pa-gpios " , 0 ) ;
if ( gpio_is_valid ( sirf_audio_card - > gpio_spk_pa ) ) {
ret = devm_gpio_request_one ( & pdev - > dev ,
sirf_audio_card - > gpio_spk_pa ,
GPIOF_OUT_INIT_LOW , " SPA_PA_SD " ) ;
if ( ret ) {
dev_err ( & pdev - > dev ,
" Failed to request GPIO_%d for reset: %d \n " ,
sirf_audio_card - > gpio_spk_pa , ret ) ;
return ret ;
}
}
if ( gpio_is_valid ( sirf_audio_card - > gpio_hp_pa ) ) {
ret = devm_gpio_request_one ( & pdev - > dev ,
sirf_audio_card - > gpio_hp_pa ,
GPIOF_OUT_INIT_LOW , " HP_PA_SD " ) ;
if ( ret ) {
dev_err ( & pdev - > dev ,
" Failed to request GPIO_%d for reset: %d \n " ,
sirf_audio_card - > gpio_hp_pa , ret ) ;
return ret ;
}
}
card - > dev = & pdev - > dev ;
snd_soc_card_set_drvdata ( card , sirf_audio_card ) ;
ret = devm_snd_soc_register_card ( & pdev - > dev , card ) ;
if ( ret )
dev_err ( & pdev - > dev , " snd_soc_register_card() failed:%d \n " , ret ) ;
return ret ;
}
static const struct of_device_id sirf_audio_of_match [ ] = {
{ . compatible = " sirf,sirf-audio-card " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , sirf_audio_of_match ) ;
static struct platform_driver sirf_audio_driver = {
. driver = {
. name = " sirf-audio-card " ,
. pm = & snd_soc_pm_ops ,
. of_match_table = sirf_audio_of_match ,
} ,
. probe = sirf_audio_probe ,
} ;
module_platform_driver ( sirf_audio_driver ) ;
MODULE_AUTHOR ( " RongJun Ying <RongJun.Ying@csr.com> " ) ;
MODULE_DESCRIPTION ( " ALSA SoC SIRF audio card driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;