2010-05-05 11:14:22 +03:00
/*
* rx51 . c - - SoC audio for Nokia RX - 51
*
* Copyright ( C ) 2008 - 2009 Nokia Corporation
*
2011-05-03 18:15:10 +03:00
* Contact : Peter Ujfalusi < peter . ujfalusi @ ti . com >
2010-05-05 11:14:22 +03:00
* Eduardo Valentin < eduardo . valentin @ nokia . com >
2011-08-11 15:44:57 +03:00
* Jarkko Nikula < jarkko . nikula @ bitmer . com >
2010-05-05 11:14:22 +03:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA
* 02110 - 1301 USA
*
*/
# include <linux/delay.h>
# include <linux/gpio.h>
# include <linux/platform_device.h>
2014-04-28 16:07:24 +02:00
# include <linux/gpio/consumer.h>
2011-07-15 12:38:28 -04:00
# include <linux/module.h>
2010-05-05 11:14:22 +03:00
# include <sound/core.h>
2010-06-21 14:15:00 +03:00
# include <sound/jack.h>
2010-05-05 11:14:22 +03:00
# include <sound/pcm.h>
# include <sound/soc.h>
2012-08-24 15:21:06 +02:00
# include <linux/platform_data/asoc-ti-mcbsp.h>
2010-05-05 11:14:22 +03:00
# include <asm/mach-types.h>
# include "omap-mcbsp.h"
2010-06-21 14:14:59 +03:00
enum {
RX51_JACK_DISABLED ,
2011-01-27 16:47:11 +02:00
RX51_JACK_TVOUT , /* tv-out with stereo output */
RX51_JACK_HP , /* headphone: stereo output, no mic */
2011-02-14 17:20:21 +02:00
RX51_JACK_HS , /* headset: stereo output with mic */
2010-06-21 14:14:59 +03:00
} ;
2014-04-28 16:07:24 +02:00
struct rx51_audio_pdata {
struct gpio_desc * tvout_selection_gpio ;
struct gpio_desc * jack_detection_gpio ;
struct gpio_desc * eci_sw_gpio ;
struct gpio_desc * speaker_amp_gpio ;
} ;
2010-05-05 11:14:22 +03:00
static int rx51_spk_func ;
static int rx51_dmic_func ;
2010-06-21 14:14:59 +03:00
static int rx51_jack_func ;
2010-05-05 11:14:22 +03:00
2012-02-03 17:43:09 +00:00
static void rx51_ext_control ( struct snd_soc_dapm_context * dapm )
2010-05-05 11:14:22 +03:00
{
2014-04-28 16:07:24 +02:00
struct snd_soc_card * card = dapm - > card ;
struct rx51_audio_pdata * pdata = snd_soc_card_get_drvdata ( card ) ;
2011-02-14 17:20:21 +02:00
int hp = 0 , hs = 0 , tvout = 0 ;
2011-01-27 16:47:11 +02:00
switch ( rx51_jack_func ) {
case RX51_JACK_TVOUT :
tvout = 1 ;
2011-02-14 17:20:21 +02:00
hp = 1 ;
break ;
case RX51_JACK_HS :
hs = 1 ;
2011-01-27 16:47:11 +02:00
case RX51_JACK_HP :
hp = 1 ;
break ;
}
2010-11-05 15:53:46 +02:00
2014-02-18 15:22:24 +00:00
snd_soc_dapm_mutex_lock ( dapm ) ;
2010-05-05 11:14:22 +03:00
if ( rx51_spk_func )
2014-02-18 15:22:24 +00:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " Ext Spk " ) ;
2010-05-05 11:14:22 +03:00
else
2014-02-18 15:22:24 +00:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " Ext Spk " ) ;
2010-05-05 11:14:22 +03:00
if ( rx51_dmic_func )
2014-02-18 15:22:24 +00:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " DMic " ) ;
2010-05-05 11:14:22 +03:00
else
2014-02-18 15:22:24 +00:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " DMic " ) ;
2011-01-27 16:47:11 +02:00
if ( hp )
2014-02-18 15:22:24 +00:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " Headphone Jack " ) ;
2011-01-27 16:47:11 +02:00
else
2014-02-18 15:22:24 +00:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " Headphone Jack " ) ;
2011-02-14 17:20:21 +02:00
if ( hs )
2014-02-18 15:22:24 +00:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " HS Mic " ) ;
2011-02-14 17:20:21 +02:00
else
2014-02-18 15:22:24 +00:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " HS Mic " ) ;
2010-05-05 11:14:22 +03:00
2014-04-28 16:07:24 +02:00
gpiod_set_value ( pdata - > tvout_selection_gpio , tvout ) ;
2010-06-21 14:14:59 +03:00
2014-02-18 15:22:24 +00:00
snd_soc_dapm_sync_unlocked ( dapm ) ;
snd_soc_dapm_mutex_unlock ( dapm ) ;
2010-05-05 11:14:22 +03:00
}
static int rx51_startup ( struct snd_pcm_substream * substream )
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
2012-02-03 17:43:09 +00:00
struct snd_soc_card * card = rtd - > card ;
2010-05-05 11:14:22 +03:00
2015-10-18 15:39:27 +02:00
snd_pcm_hw_constraint_single ( runtime , SNDRV_PCM_HW_PARAM_CHANNELS , 2 ) ;
2012-02-03 17:43:09 +00:00
rx51_ext_control ( & card - > dapm ) ;
2010-05-05 11:14:22 +03:00
return 0 ;
}
static int rx51_hw_params ( struct snd_pcm_substream * substream ,
struct snd_pcm_hw_params * params )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
2010-03-17 20:15:21 +00:00
struct snd_soc_dai * codec_dai = rtd - > codec_dai ;
2010-05-05 11:14:22 +03:00
/* Set the codec system clock for DAC and ADC */
return snd_soc_dai_set_sysclk ( codec_dai , 0 , 19200000 ,
SND_SOC_CLOCK_IN ) ;
}
2017-03-18 19:34:11 +05:30
static const struct snd_soc_ops rx51_ops = {
2010-05-05 11:14:22 +03:00
. startup = rx51_startup ,
. hw_params = rx51_hw_params ,
} ;
static int rx51_get_spk ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2016-02-29 17:26:22 +01:00
ucontrol - > value . enumerated . item [ 0 ] = rx51_spk_func ;
2010-05-05 11:14:22 +03:00
return 0 ;
}
static int rx51_set_spk ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2012-02-03 17:43:09 +00:00
struct snd_soc_card * card = snd_kcontrol_chip ( kcontrol ) ;
2010-05-05 11:14:22 +03:00
2016-02-29 17:26:22 +01:00
if ( rx51_spk_func = = ucontrol - > value . enumerated . item [ 0 ] )
2010-05-05 11:14:22 +03:00
return 0 ;
2016-02-29 17:26:22 +01:00
rx51_spk_func = ucontrol - > value . enumerated . item [ 0 ] ;
2012-02-03 17:43:09 +00:00
rx51_ext_control ( & card - > dapm ) ;
2010-05-05 11:14:22 +03:00
return 1 ;
}
static int rx51_spk_event ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * k , int event )
{
2014-04-28 16:07:24 +02:00
struct snd_soc_dapm_context * dapm = w - > dapm ;
struct snd_soc_card * card = dapm - > card ;
struct rx51_audio_pdata * pdata = snd_soc_card_get_drvdata ( card ) ;
gpiod_set_raw_value_cansleep ( pdata - > speaker_amp_gpio ,
! ! SND_SOC_DAPM_EVENT_ON ( event ) ) ;
2010-05-05 11:14:22 +03:00
return 0 ;
}
static int rx51_get_input ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2016-02-29 17:26:22 +01:00
ucontrol - > value . enumerated . item [ 0 ] = rx51_dmic_func ;
2010-05-05 11:14:22 +03:00
return 0 ;
}
static int rx51_set_input ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2012-02-03 17:43:09 +00:00
struct snd_soc_card * card = snd_kcontrol_chip ( kcontrol ) ;
2010-05-05 11:14:22 +03:00
2016-02-29 17:26:22 +01:00
if ( rx51_dmic_func = = ucontrol - > value . enumerated . item [ 0 ] )
2010-05-05 11:14:22 +03:00
return 0 ;
2016-02-29 17:26:22 +01:00
rx51_dmic_func = ucontrol - > value . enumerated . item [ 0 ] ;
2012-02-03 17:43:09 +00:00
rx51_ext_control ( & card - > dapm ) ;
2010-05-05 11:14:22 +03:00
return 1 ;
}
2010-06-21 14:14:59 +03:00
static int rx51_get_jack ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2016-02-29 17:26:22 +01:00
ucontrol - > value . enumerated . item [ 0 ] = rx51_jack_func ;
2010-06-21 14:14:59 +03:00
return 0 ;
}
static int rx51_set_jack ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2012-02-03 17:43:09 +00:00
struct snd_soc_card * card = snd_kcontrol_chip ( kcontrol ) ;
2010-06-21 14:14:59 +03:00
2016-02-29 17:26:22 +01:00
if ( rx51_jack_func = = ucontrol - > value . enumerated . item [ 0 ] )
2010-06-21 14:14:59 +03:00
return 0 ;
2016-02-29 17:26:22 +01:00
rx51_jack_func = ucontrol - > value . enumerated . item [ 0 ] ;
2012-02-03 17:43:09 +00:00
rx51_ext_control ( & card - > dapm ) ;
2010-06-21 14:14:59 +03:00
return 1 ;
}
2010-06-21 14:15:00 +03:00
static struct snd_soc_jack rx51_av_jack ;
static struct snd_soc_jack_gpio rx51_av_jack_gpios [ ] = {
{
. name = " avdet-gpio " ,
2011-02-14 17:20:22 +02:00
. report = SND_JACK_HEADSET ,
2010-06-21 14:15:00 +03:00
. invert = 1 ,
. debounce_time = 200 ,
} ,
} ;
2010-05-05 11:14:22 +03:00
static const struct snd_soc_dapm_widget aic34_dapm_widgets [ ] = {
SND_SOC_DAPM_SPK ( " Ext Spk " , rx51_spk_event ) ,
SND_SOC_DAPM_MIC ( " DMic " , NULL ) ,
2016-06-23 16:23:13 -03:00
SND_SOC_DAPM_HP ( " Headphone Jack " , NULL ) ,
2011-02-14 17:20:21 +02:00
SND_SOC_DAPM_MIC ( " HS Mic " , NULL ) ,
2011-02-21 14:57:22 +02:00
SND_SOC_DAPM_LINE ( " FM Transmitter " , NULL ) ,
2011-01-31 14:43:48 +02:00
SND_SOC_DAPM_SPK ( " Earphone " , NULL ) ,
} ;
2010-05-05 11:14:22 +03:00
static const struct snd_soc_dapm_route audio_map [ ] = {
{ " Ext Spk " , NULL , " HPLOUT " } ,
{ " Ext Spk " , NULL , " HPROUT " } ,
2015-06-04 16:13:51 +02:00
{ " Ext Spk " , NULL , " HPLCOM " } ,
{ " Ext Spk " , NULL , " HPRCOM " } ,
2011-02-21 14:57:22 +02:00
{ " FM Transmitter " , NULL , " LLOUT " } ,
{ " FM Transmitter " , NULL , " RLOUT " } ,
2010-05-05 11:14:22 +03:00
2016-06-23 16:23:13 -03:00
{ " Headphone Jack " , NULL , " TPA6130A2 HPLEFT " } ,
{ " Headphone Jack " , NULL , " TPA6130A2 HPRIGHT " } ,
{ " TPA6130A2 LEFTIN " , NULL , " LLOUT " } ,
{ " TPA6130A2 RIGHTIN " , NULL , " RLOUT " } ,
2015-01-30 09:32:43 +02:00
{ " DMic Rate 64 " , NULL , " DMic " } ,
{ " DMic " , NULL , " Mic Bias " } ,
2010-05-05 11:14:22 +03:00
2011-01-31 14:43:48 +02:00
{ " b LINE2R " , NULL , " MONO_LOUT " } ,
{ " Earphone " , NULL , " b HPLOUT " } ,
2011-02-14 17:20:21 +02:00
2015-01-30 09:32:43 +02:00
{ " LINE1L " , NULL , " HS Mic " } ,
{ " HS Mic " , NULL , " b Mic Bias " } ,
2011-01-31 14:43:48 +02:00
} ;
2014-04-28 16:07:19 +02:00
static const char * const spk_function [ ] = { " Off " , " On " } ;
static const char * const input_function [ ] = { " ADC " , " Digital Mic " } ;
static const char * const jack_function [ ] = {
" Off " , " TV-OUT " , " Headphone " , " Headset "
} ;
2010-05-05 11:14:22 +03:00
static const struct soc_enum rx51_enum [ ] = {
SOC_ENUM_SINGLE_EXT ( ARRAY_SIZE ( spk_function ) , spk_function ) ,
SOC_ENUM_SINGLE_EXT ( ARRAY_SIZE ( input_function ) , input_function ) ,
2010-06-21 14:14:59 +03:00
SOC_ENUM_SINGLE_EXT ( ARRAY_SIZE ( jack_function ) , jack_function ) ,
2010-05-05 11:14:22 +03:00
} ;
static const struct snd_kcontrol_new aic34_rx51_controls [ ] = {
SOC_ENUM_EXT ( " Speaker Function " , rx51_enum [ 0 ] ,
rx51_get_spk , rx51_set_spk ) ,
SOC_ENUM_EXT ( " Input Select " , rx51_enum [ 1 ] ,
rx51_get_input , rx51_set_input ) ,
2010-06-21 14:14:59 +03:00
SOC_ENUM_EXT ( " Jack Function " , rx51_enum [ 2 ] ,
rx51_get_jack , rx51_set_jack ) ,
2011-02-21 14:57:22 +02:00
SOC_DAPM_PIN_SWITCH ( " FM Transmitter " ) ,
2011-01-31 14:43:48 +02:00
SOC_DAPM_PIN_SWITCH ( " Earphone " ) ,
} ;
2010-03-17 20:15:21 +00:00
static int rx51_aic34_init ( struct snd_soc_pcm_runtime * rtd )
2010-05-05 11:14:22 +03:00
{
2014-05-19 11:41:46 +02:00
struct snd_soc_card * card = rtd - > card ;
2014-04-28 16:07:24 +02:00
struct rx51_audio_pdata * pdata = snd_soc_card_get_drvdata ( card ) ;
2010-05-05 11:14:22 +03:00
int err ;
2015-10-18 17:04:33 +02:00
snd_soc_limit_volume ( card , " TPA6130A2 Headphone Playback Volume " , 42 ) ;
2011-01-27 16:47:11 +02:00
2014-04-28 16:07:23 +02:00
err = omap_mcbsp_st_add_controls ( rtd , 2 ) ;
2014-04-28 16:07:25 +02:00
if ( err < 0 ) {
dev_err ( card - > dev , " Failed to add MCBSP controls \n " ) ;
2011-03-09 11:25:00 +02:00
return err ;
2014-04-28 16:07:25 +02:00
}
2011-03-09 11:25:00 +02:00
2010-06-21 14:15:00 +03:00
/* AV jack detection */
2015-03-04 10:33:28 +01:00
err = snd_soc_card_jack_new ( rtd - > card , " AV Jack " ,
SND_JACK_HEADSET | SND_JACK_VIDEOOUT ,
& rx51_av_jack , NULL , 0 ) ;
2014-04-28 16:07:25 +02:00
if ( err ) {
dev_err ( card - > dev , " Failed to add AV Jack \n " ) ;
2010-06-21 14:15:00 +03:00
return err ;
2014-04-28 16:07:25 +02:00
}
2014-04-28 16:07:24 +02:00
/* prepare gpio for snd_soc_jack_add_gpios */
rx51_av_jack_gpios [ 0 ] . gpio = desc_to_gpio ( pdata - > jack_detection_gpio ) ;
devm_gpiod_put ( card - > dev , pdata - > jack_detection_gpio ) ;
2010-06-21 14:15:00 +03:00
err = snd_soc_jack_add_gpios ( & rx51_av_jack ,
ARRAY_SIZE ( rx51_av_jack_gpios ) ,
rx51_av_jack_gpios ) ;
2014-04-28 16:07:25 +02:00
if ( err ) {
dev_err ( card - > dev , " Failed to add GPIOs \n " ) ;
return err ;
}
2010-06-21 14:15:00 +03:00
return err ;
2010-05-05 11:14:22 +03:00
}
/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link rx51_dai [ ] = {
{
. name = " TLV320AIC34 " ,
. stream_name = " AIC34 " ,
2012-02-14 18:20:58 +02:00
. cpu_dai_name = " omap-mcbsp.2 " ,
2010-03-17 20:15:21 +00:00
. codec_dai_name = " tlv320aic3x-hifi " ,
2014-04-16 15:46:28 +03:00
. platform_name = " omap-mcbsp.2 " ,
2010-03-17 20:15:21 +00:00
. codec_name = " tlv320aic3x-codec.2-0018 " ,
2011-09-30 16:07:45 +03:00
. dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
SND_SOC_DAIFMT_CBM_CFM ,
2010-05-05 11:14:22 +03:00
. init = rx51_aic34_init ,
. ops = & rx51_ops ,
} ,
} ;
2011-12-13 10:13:13 +08:00
static struct snd_soc_aux_dev rx51_aux_dev [ ] = {
2011-01-31 14:43:48 +02:00
{
. name = " TLV320AIC34b " ,
. codec_name = " tlv320aic3x-codec.2-0019 " ,
} ,
2016-06-20 14:12:29 -03:00
{
. name = " TPA61320A2 " ,
. codec_name = " tpa6130a2.2-0060 " ,
} ,
2011-01-31 14:43:48 +02:00
} ;
static struct snd_soc_codec_conf rx51_codec_conf [ ] = {
{
. dev_name = " tlv320aic3x-codec.2-0019 " ,
. name_prefix = " b " ,
} ,
2016-06-20 14:12:29 -03:00
{
. dev_name = " tpa6130a2.2-0060 " ,
. name_prefix = " TPA6130A2 " ,
} ,
2011-01-31 14:43:48 +02:00
} ;
2010-05-05 11:14:22 +03:00
/* Audio card */
static struct snd_soc_card rx51_sound_card = {
. name = " RX-51 " ,
2011-12-22 11:08:59 +08:00
. owner = THIS_MODULE ,
2010-05-05 11:14:22 +03:00
. dai_link = rx51_dai ,
. num_links = ARRAY_SIZE ( rx51_dai ) ,
2011-01-31 14:43:48 +02:00
. aux_dev = rx51_aux_dev ,
. num_aux_devs = ARRAY_SIZE ( rx51_aux_dev ) ,
. codec_conf = rx51_codec_conf ,
. num_configs = ARRAY_SIZE ( rx51_codec_conf ) ,
2015-06-04 16:13:51 +02:00
. fully_routed = true ,
2014-03-12 15:27:33 +01:00
. controls = aic34_rx51_controls ,
. num_controls = ARRAY_SIZE ( aic34_rx51_controls ) ,
. dapm_widgets = aic34_dapm_widgets ,
. num_dapm_widgets = ARRAY_SIZE ( aic34_dapm_widgets ) ,
. dapm_routes = audio_map ,
. num_dapm_routes = ARRAY_SIZE ( audio_map ) ,
2010-05-05 11:14:22 +03:00
} ;
2014-04-28 16:07:21 +02:00
static int rx51_soc_probe ( struct platform_device * pdev )
2010-05-05 11:14:22 +03:00
{
2014-04-28 16:07:24 +02:00
struct rx51_audio_pdata * pdata ;
2014-04-28 16:07:26 +02:00
struct device_node * np = pdev - > dev . of_node ;
2014-04-28 16:07:21 +02:00
struct snd_soc_card * card = & rx51_sound_card ;
2010-05-05 11:14:22 +03:00
int err ;
2013-07-01 23:15:04 +02:00
if ( ! machine_is_nokia_rx51 ( ) & & ! of_machine_is_compatible ( " nokia,omap3-n900 " ) )
2010-05-05 11:14:22 +03:00
return - ENODEV ;
2014-04-28 16:07:21 +02:00
card - > dev = & pdev - > dev ;
2010-05-05 11:14:22 +03:00
2014-04-28 16:07:26 +02:00
if ( np ) {
struct device_node * dai_node ;
dai_node = of_parse_phandle ( np , " nokia,cpu-dai " , 0 ) ;
if ( ! dai_node ) {
dev_err ( & pdev - > dev , " McBSP node is not provided \n " ) ;
return - EINVAL ;
}
rx51_dai [ 0 ] . cpu_dai_name = NULL ;
rx51_dai [ 0 ] . platform_name = NULL ;
rx51_dai [ 0 ] . cpu_of_node = dai_node ;
rx51_dai [ 0 ] . platform_of_node = dai_node ;
dai_node = of_parse_phandle ( np , " nokia,audio-codec " , 0 ) ;
if ( ! dai_node ) {
dev_err ( & pdev - > dev , " Codec node is not provided \n " ) ;
return - EINVAL ;
}
rx51_dai [ 0 ] . codec_name = NULL ;
rx51_dai [ 0 ] . codec_of_node = dai_node ;
dai_node = of_parse_phandle ( np , " nokia,audio-codec " , 1 ) ;
if ( ! dai_node ) {
dev_err ( & pdev - > dev , " Auxiliary Codec node is not provided \n " ) ;
return - EINVAL ;
}
rx51_aux_dev [ 0 ] . codec_name = NULL ;
rx51_aux_dev [ 0 ] . codec_of_node = dai_node ;
rx51_codec_conf [ 0 ] . dev_name = NULL ;
rx51_codec_conf [ 0 ] . of_node = dai_node ;
dai_node = of_parse_phandle ( np , " nokia,headphone-amplifier " , 0 ) ;
if ( ! dai_node ) {
dev_err ( & pdev - > dev , " Headphone amplifier node is not provided \n " ) ;
return - EINVAL ;
}
2016-06-20 14:12:29 -03:00
rx51_aux_dev [ 1 ] . codec_name = NULL ;
rx51_aux_dev [ 1 ] . codec_of_node = dai_node ;
rx51_codec_conf [ 1 ] . dev_name = NULL ;
rx51_codec_conf [ 1 ] . of_node = dai_node ;
2014-04-28 16:07:26 +02:00
}
2014-04-28 16:07:24 +02:00
pdata = devm_kzalloc ( & pdev - > dev , sizeof ( * pdata ) , GFP_KERNEL ) ;
2017-02-26 21:12:06 +02:00
if ( pdata = = NULL )
2014-04-28 16:07:24 +02:00
return - ENOMEM ;
2017-02-26 21:12:06 +02:00
2014-04-28 16:07:24 +02:00
snd_soc_card_set_drvdata ( card , pdata ) ;
pdata - > tvout_selection_gpio = devm_gpiod_get ( card - > dev ,
2015-05-19 09:48:08 +02:00
" tvout-selection " ,
GPIOD_OUT_LOW ) ;
2014-04-28 16:07:24 +02:00
if ( IS_ERR ( pdata - > tvout_selection_gpio ) ) {
dev_err ( card - > dev , " could not get tvout selection gpio \n " ) ;
return PTR_ERR ( pdata - > tvout_selection_gpio ) ;
}
pdata - > jack_detection_gpio = devm_gpiod_get ( card - > dev ,
2015-05-19 09:48:08 +02:00
" jack-detection " ,
GPIOD_ASIS ) ;
2014-04-28 16:07:24 +02:00
if ( IS_ERR ( pdata - > jack_detection_gpio ) ) {
dev_err ( card - > dev , " could not get jack detection gpio \n " ) ;
return PTR_ERR ( pdata - > jack_detection_gpio ) ;
}
2015-05-19 09:48:08 +02:00
pdata - > eci_sw_gpio = devm_gpiod_get ( card - > dev , " eci-switch " ,
GPIOD_OUT_HIGH ) ;
2014-04-28 16:07:24 +02:00
if ( IS_ERR ( pdata - > eci_sw_gpio ) ) {
dev_err ( card - > dev , " could not get eci switch gpio \n " ) ;
return PTR_ERR ( pdata - > eci_sw_gpio ) ;
}
pdata - > speaker_amp_gpio = devm_gpiod_get ( card - > dev ,
2015-05-19 09:48:08 +02:00
" speaker-amplifier " ,
GPIOD_OUT_LOW ) ;
2014-04-28 16:07:24 +02:00
if ( IS_ERR ( pdata - > speaker_amp_gpio ) ) {
dev_err ( card - > dev , " could not get speaker enable gpio \n " ) ;
return PTR_ERR ( pdata - > speaker_amp_gpio ) ;
}
2014-04-28 16:07:21 +02:00
err = devm_snd_soc_register_card ( card - > dev , card ) ;
if ( err ) {
dev_err ( & pdev - > dev , " snd_soc_register_card failed (%d) \n " , err ) ;
2014-04-28 16:07:24 +02:00
return err ;
2014-04-28 16:07:21 +02:00
}
2010-05-05 11:14:22 +03:00
return 0 ;
}
2014-04-28 16:07:26 +02:00
# if defined(CONFIG_OF)
static const struct of_device_id rx51_audio_of_match [ ] = {
{ . compatible = " nokia,n900-audio " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , rx51_audio_of_match ) ;
# endif
2014-04-28 16:07:21 +02:00
static struct platform_driver rx51_soc_driver = {
. driver = {
. name = " rx51-audio " ,
2014-04-28 16:07:26 +02:00
. of_match_table = of_match_ptr ( rx51_audio_of_match ) ,
2014-04-28 16:07:21 +02:00
} ,
. probe = rx51_soc_probe ,
} ;
module_platform_driver ( rx51_soc_driver ) ;
2010-05-05 11:14:22 +03:00
MODULE_AUTHOR ( " Nokia Corporation " ) ;
MODULE_DESCRIPTION ( " ALSA SoC Nokia RX-51 " ) ;
MODULE_LICENSE ( " GPL " ) ;
2014-04-28 16:07:20 +02:00
MODULE_ALIAS ( " platform:rx51-audio " ) ;