2010-05-05 12:14:22 +04:00
/*
* rx51 . c - - SoC audio for Nokia RX - 51
*
* Copyright ( C ) 2008 - 2009 Nokia Corporation
*
2011-05-03 19:15:10 +04:00
* Contact : Peter Ujfalusi < peter . ujfalusi @ ti . com >
2010-05-05 12:14:22 +04:00
* Eduardo Valentin < eduardo . valentin @ nokia . com >
2011-08-11 16:44:57 +04:00
* Jarkko Nikula < jarkko . nikula @ bitmer . com >
2010-05-05 12:14:22 +04: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 18:07:24 +04:00
# include <linux/gpio/consumer.h>
2011-07-15 20:38:28 +04:00
# include <linux/module.h>
2010-05-05 12:14:22 +04:00
# include <sound/core.h>
2010-06-21 15:15:00 +04:00
# include <sound/jack.h>
2010-05-05 12:14:22 +04:00
# include <sound/pcm.h>
# include <sound/soc.h>
2012-08-24 17:21:06 +04:00
# include <linux/platform_data/asoc-ti-mcbsp.h>
2011-01-27 17:47:11 +03:00
# include "../codecs/tpa6130a2.h"
2010-05-05 12:14:22 +04:00
# include <asm/mach-types.h>
# include "omap-mcbsp.h"
2010-06-21 15:14:59 +04:00
enum {
RX51_JACK_DISABLED ,
2011-01-27 17:47:11 +03:00
RX51_JACK_TVOUT , /* tv-out with stereo output */
RX51_JACK_HP , /* headphone: stereo output, no mic */
2011-02-14 18:20:21 +03:00
RX51_JACK_HS , /* headset: stereo output with mic */
2010-06-21 15:14:59 +04:00
} ;
2014-04-28 18:07:24 +04: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 12:14:22 +04:00
static int rx51_spk_func ;
static int rx51_dmic_func ;
2010-06-21 15:14:59 +04:00
static int rx51_jack_func ;
2010-05-05 12:14:22 +04:00
2012-02-03 21:43:09 +04:00
static void rx51_ext_control ( struct snd_soc_dapm_context * dapm )
2010-05-05 12:14:22 +04:00
{
2014-04-28 18:07:24 +04:00
struct snd_soc_card * card = dapm - > card ;
struct rx51_audio_pdata * pdata = snd_soc_card_get_drvdata ( card ) ;
2011-02-14 18:20:21 +03:00
int hp = 0 , hs = 0 , tvout = 0 ;
2011-01-27 17:47:11 +03:00
switch ( rx51_jack_func ) {
case RX51_JACK_TVOUT :
tvout = 1 ;
2011-02-14 18:20:21 +03:00
hp = 1 ;
break ;
case RX51_JACK_HS :
hs = 1 ;
2011-01-27 17:47:11 +03:00
case RX51_JACK_HP :
hp = 1 ;
break ;
}
2010-11-05 16:53:46 +03:00
2014-02-18 19:22:24 +04:00
snd_soc_dapm_mutex_lock ( dapm ) ;
2010-05-05 12:14:22 +04:00
if ( rx51_spk_func )
2014-02-18 19:22:24 +04:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " Ext Spk " ) ;
2010-05-05 12:14:22 +04:00
else
2014-02-18 19:22:24 +04:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " Ext Spk " ) ;
2010-05-05 12:14:22 +04:00
if ( rx51_dmic_func )
2014-02-18 19:22:24 +04:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " DMic " ) ;
2010-05-05 12:14:22 +04:00
else
2014-02-18 19:22:24 +04:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " DMic " ) ;
2011-01-27 17:47:11 +03:00
if ( hp )
2014-02-18 19:22:24 +04:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " Headphone Jack " ) ;
2011-01-27 17:47:11 +03:00
else
2014-02-18 19:22:24 +04:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " Headphone Jack " ) ;
2011-02-14 18:20:21 +03:00
if ( hs )
2014-02-18 19:22:24 +04:00
snd_soc_dapm_enable_pin_unlocked ( dapm , " HS Mic " ) ;
2011-02-14 18:20:21 +03:00
else
2014-02-18 19:22:24 +04:00
snd_soc_dapm_disable_pin_unlocked ( dapm , " HS Mic " ) ;
2010-05-05 12:14:22 +04:00
2014-04-28 18:07:24 +04:00
gpiod_set_value ( pdata - > tvout_selection_gpio , tvout ) ;
2010-06-21 15:14:59 +04:00
2014-02-18 19:22:24 +04:00
snd_soc_dapm_sync_unlocked ( dapm ) ;
snd_soc_dapm_mutex_unlock ( dapm ) ;
2010-05-05 12:14:22 +04: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 21:43:09 +04:00
struct snd_soc_card * card = rtd - > card ;
2010-05-05 12:14:22 +04:00
snd_pcm_hw_constraint_minmax ( runtime ,
SNDRV_PCM_HW_PARAM_CHANNELS , 2 , 2 ) ;
2012-02-03 21:43:09 +04:00
rx51_ext_control ( & card - > dapm ) ;
2010-05-05 12:14:22 +04: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 23:15:21 +03:00
struct snd_soc_dai * codec_dai = rtd - > codec_dai ;
2010-05-05 12:14:22 +04:00
/* Set the codec system clock for DAC and ADC */
return snd_soc_dai_set_sysclk ( codec_dai , 0 , 19200000 ,
SND_SOC_CLOCK_IN ) ;
}
static struct snd_soc_ops rx51_ops = {
. startup = rx51_startup ,
. hw_params = rx51_hw_params ,
} ;
static int rx51_get_spk ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
ucontrol - > value . integer . value [ 0 ] = rx51_spk_func ;
return 0 ;
}
static int rx51_set_spk ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2012-02-03 21:43:09 +04:00
struct snd_soc_card * card = snd_kcontrol_chip ( kcontrol ) ;
2010-05-05 12:14:22 +04:00
if ( rx51_spk_func = = ucontrol - > value . integer . value [ 0 ] )
return 0 ;
rx51_spk_func = ucontrol - > value . integer . value [ 0 ] ;
2012-02-03 21:43:09 +04:00
rx51_ext_control ( & card - > dapm ) ;
2010-05-05 12:14:22 +04:00
return 1 ;
}
static int rx51_spk_event ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * k , int event )
{
2014-04-28 18:07:24 +04: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 12:14:22 +04:00
return 0 ;
}
2011-01-27 17:47:11 +03:00
static int rx51_hp_event ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * k , int event )
{
struct snd_soc_codec * codec = w - > dapm - > codec ;
if ( SND_SOC_DAPM_EVENT_ON ( event ) )
tpa6130a2_stereo_enable ( codec , 1 ) ;
else
tpa6130a2_stereo_enable ( codec , 0 ) ;
return 0 ;
}
2010-05-05 12:14:22 +04:00
static int rx51_get_input ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
ucontrol - > value . integer . value [ 0 ] = rx51_dmic_func ;
return 0 ;
}
static int rx51_set_input ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2012-02-03 21:43:09 +04:00
struct snd_soc_card * card = snd_kcontrol_chip ( kcontrol ) ;
2010-05-05 12:14:22 +04:00
if ( rx51_dmic_func = = ucontrol - > value . integer . value [ 0 ] )
return 0 ;
rx51_dmic_func = ucontrol - > value . integer . value [ 0 ] ;
2012-02-03 21:43:09 +04:00
rx51_ext_control ( & card - > dapm ) ;
2010-05-05 12:14:22 +04:00
return 1 ;
}
2010-06-21 15:14:59 +04:00
static int rx51_get_jack ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
ucontrol - > value . integer . value [ 0 ] = rx51_jack_func ;
return 0 ;
}
static int rx51_set_jack ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2012-02-03 21:43:09 +04:00
struct snd_soc_card * card = snd_kcontrol_chip ( kcontrol ) ;
2010-06-21 15:14:59 +04:00
if ( rx51_jack_func = = ucontrol - > value . integer . value [ 0 ] )
return 0 ;
rx51_jack_func = ucontrol - > value . integer . value [ 0 ] ;
2012-02-03 21:43:09 +04:00
rx51_ext_control ( & card - > dapm ) ;
2010-06-21 15:14:59 +04:00
return 1 ;
}
2010-06-21 15:15:00 +04: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 18:20:22 +03:00
. report = SND_JACK_HEADSET ,
2010-06-21 15:15:00 +04:00
. invert = 1 ,
. debounce_time = 200 ,
} ,
} ;
2010-05-05 12:14:22 +04: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 ) ,
2011-01-27 17:47:11 +03:00
SND_SOC_DAPM_HP ( " Headphone Jack " , rx51_hp_event ) ,
2011-02-14 18:20:21 +03:00
SND_SOC_DAPM_MIC ( " HS Mic " , NULL ) ,
2011-02-21 15:57:22 +03:00
SND_SOC_DAPM_LINE ( " FM Transmitter " , NULL ) ,
2011-01-31 15:43:48 +03:00
SND_SOC_DAPM_SPK ( " Earphone " , NULL ) ,
} ;
2010-05-05 12:14:22 +04:00
static const struct snd_soc_dapm_route audio_map [ ] = {
{ " Ext Spk " , NULL , " HPLOUT " } ,
{ " Ext Spk " , NULL , " HPROUT " } ,
2011-01-27 17:47:11 +03:00
{ " Headphone Jack " , NULL , " LLOUT " } ,
{ " Headphone Jack " , NULL , " RLOUT " } ,
2011-02-21 15:57:22 +03:00
{ " FM Transmitter " , NULL , " LLOUT " } ,
{ " FM Transmitter " , NULL , " RLOUT " } ,
2010-05-05 12:14:22 +04:00
2013-01-31 16:53:04 +04:00
{ " DMic Rate 64 " , NULL , " Mic Bias " } ,
{ " Mic Bias " , NULL , " DMic " } ,
2010-05-05 12:14:22 +04:00
2011-01-31 15:43:48 +03:00
{ " b LINE2R " , NULL , " MONO_LOUT " } ,
{ " Earphone " , NULL , " b HPLOUT " } ,
2011-02-14 18:20:21 +03:00
2013-01-31 16:53:04 +04:00
{ " LINE1L " , NULL , " b Mic Bias " } ,
{ " b Mic Bias " , NULL , " HS Mic " }
2011-01-31 15:43:48 +03:00
} ;
2014-04-28 18:07:19 +04: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 12:14:22 +04: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 15:14:59 +04:00
SOC_ENUM_SINGLE_EXT ( ARRAY_SIZE ( jack_function ) , jack_function ) ,
2010-05-05 12:14:22 +04: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 15:14:59 +04:00
SOC_ENUM_EXT ( " Jack Function " , rx51_enum [ 2 ] ,
rx51_get_jack , rx51_set_jack ) ,
2011-02-21 15:57:22 +03:00
SOC_DAPM_PIN_SWITCH ( " FM Transmitter " ) ,
2011-01-31 15:43:48 +03:00
SOC_DAPM_PIN_SWITCH ( " Earphone " ) ,
} ;
2010-03-17 23:15:21 +03:00
static int rx51_aic34_init ( struct snd_soc_pcm_runtime * rtd )
2010-05-05 12:14:22 +04:00
{
2010-03-17 23:15:21 +03:00
struct snd_soc_codec * codec = rtd - > codec ;
2014-04-28 18:07:24 +04:00
struct snd_soc_card * card = codec - > card ;
struct rx51_audio_pdata * pdata = snd_soc_card_get_drvdata ( card ) ;
2010-11-05 16:53:46 +03:00
struct snd_soc_dapm_context * dapm = & codec - > dapm ;
2010-05-05 12:14:22 +04:00
int err ;
/* Set up NC codec pins */
2010-11-05 16:53:46 +03:00
snd_soc_dapm_nc_pin ( dapm , " MIC3L " ) ;
snd_soc_dapm_nc_pin ( dapm , " MIC3R " ) ;
snd_soc_dapm_nc_pin ( dapm , " LINE1R " ) ;
2010-05-05 12:14:22 +04:00
2011-01-27 17:47:11 +03:00
err = tpa6130a2_add_controls ( codec ) ;
2014-04-28 18:07:25 +04:00
if ( err < 0 ) {
dev_err ( card - > dev , " Failed to add TPA6130A2 controls \n " ) ;
2011-01-27 17:47:11 +03:00
return err ;
2014-04-28 18:07:25 +04:00
}
2011-01-27 17:47:11 +03:00
snd_soc_limit_volume ( codec , " TPA6130A2 Headphone Playback Volume " , 42 ) ;
2014-04-28 18:07:23 +04:00
err = omap_mcbsp_st_add_controls ( rtd , 2 ) ;
2014-04-28 18:07:25 +04:00
if ( err < 0 ) {
dev_err ( card - > dev , " Failed to add MCBSP controls \n " ) ;
2011-03-09 12:25:00 +03:00
return err ;
2014-04-28 18:07:25 +04:00
}
2011-03-09 12:25:00 +03:00
2010-06-21 15:15:00 +04:00
/* AV jack detection */
2010-03-17 23:15:21 +03:00
err = snd_soc_jack_new ( codec , " AV Jack " ,
2011-02-14 18:20:22 +03:00
SND_JACK_HEADSET | SND_JACK_VIDEOOUT ,
& rx51_av_jack ) ;
2014-04-28 18:07:25 +04:00
if ( err ) {
dev_err ( card - > dev , " Failed to add AV Jack \n " ) ;
2010-06-21 15:15:00 +04:00
return err ;
2014-04-28 18:07:25 +04:00
}
2014-04-28 18:07:24 +04: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 15:15:00 +04:00
err = snd_soc_jack_add_gpios ( & rx51_av_jack ,
ARRAY_SIZE ( rx51_av_jack_gpios ) ,
rx51_av_jack_gpios ) ;
2014-04-28 18:07:25 +04:00
if ( err ) {
dev_err ( card - > dev , " Failed to add GPIOs \n " ) ;
return err ;
}
2010-06-21 15:15:00 +04:00
return err ;
2010-05-05 12:14:22 +04:00
}
/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link rx51_dai [ ] = {
{
. name = " TLV320AIC34 " ,
. stream_name = " AIC34 " ,
2012-02-14 20:20:58 +04:00
. cpu_dai_name = " omap-mcbsp.2 " ,
2010-03-17 23:15:21 +03:00
. codec_dai_name = " tlv320aic3x-hifi " ,
2014-04-16 16:46:28 +04:00
. platform_name = " omap-mcbsp.2 " ,
2010-03-17 23:15:21 +03:00
. codec_name = " tlv320aic3x-codec.2-0018 " ,
2011-09-30 17:07:45 +04:00
. dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
SND_SOC_DAIFMT_CBM_CFM ,
2010-05-05 12:14:22 +04:00
. init = rx51_aic34_init ,
. ops = & rx51_ops ,
} ,
} ;
2011-12-13 06:13:13 +04:00
static struct snd_soc_aux_dev rx51_aux_dev [ ] = {
2011-01-31 15:43:48 +03:00
{
. name = " TLV320AIC34b " ,
. codec_name = " tlv320aic3x-codec.2-0019 " ,
} ,
} ;
static struct snd_soc_codec_conf rx51_codec_conf [ ] = {
{
. dev_name = " tlv320aic3x-codec.2-0019 " ,
. name_prefix = " b " ,
} ,
} ;
2010-05-05 12:14:22 +04:00
/* Audio card */
static struct snd_soc_card rx51_sound_card = {
. name = " RX-51 " ,
2011-12-22 07:08:59 +04:00
. owner = THIS_MODULE ,
2010-05-05 12:14:22 +04:00
. dai_link = rx51_dai ,
. num_links = ARRAY_SIZE ( rx51_dai ) ,
2011-01-31 15:43:48 +03: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 ) ,
2014-03-12 18:27:33 +04: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 12:14:22 +04:00
} ;
2014-04-28 18:07:21 +04:00
static int rx51_soc_probe ( struct platform_device * pdev )
2010-05-05 12:14:22 +04:00
{
2014-04-28 18:07:24 +04:00
struct rx51_audio_pdata * pdata ;
2014-04-28 18:07:21 +04:00
struct snd_soc_card * card = & rx51_sound_card ;
2010-05-05 12:14:22 +04:00
int err ;
2013-07-02 01:15:04 +04:00
if ( ! machine_is_nokia_rx51 ( ) & & ! of_machine_is_compatible ( " nokia,omap3-n900 " ) )
2010-05-05 12:14:22 +04:00
return - ENODEV ;
2014-04-28 18:07:21 +04:00
card - > dev = & pdev - > dev ;
2010-05-05 12:14:22 +04:00
2014-04-28 18:07:24 +04:00
pdata = devm_kzalloc ( & pdev - > dev , sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( pdata = = NULL ) {
dev_err ( card - > dev , " failed to create private data \n " ) ;
return - ENOMEM ;
}
snd_soc_card_set_drvdata ( card , pdata ) ;
pdata - > tvout_selection_gpio = devm_gpiod_get ( card - > dev ,
" tvout-selection " ) ;
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 ) ;
}
err = gpiod_direction_output ( pdata - > tvout_selection_gpio , 0 ) ;
if ( err ) {
dev_err ( card - > dev , " could not setup tvout selection gpio \n " ) ;
return err ;
}
pdata - > jack_detection_gpio = devm_gpiod_get ( card - > dev ,
" jack-detection " ) ;
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 ) ;
}
pdata - > eci_sw_gpio = devm_gpiod_get ( card - > dev , " eci-switch " ) ;
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 ) ;
}
err = gpiod_direction_output ( pdata - > eci_sw_gpio , 1 ) ;
if ( err ) {
dev_err ( card - > dev , " could not setup eci switch gpio \n " ) ;
return err ;
}
pdata - > speaker_amp_gpio = devm_gpiod_get ( card - > dev ,
" speaker-amplifier " ) ;
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 ) ;
}
err = gpiod_direction_output ( pdata - > speaker_amp_gpio , 0 ) ;
if ( err ) {
dev_err ( card - > dev , " could not setup speaker enable gpio \n " ) ;
return err ;
}
2014-04-28 18:07:21 +04: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 18:07:24 +04:00
return err ;
2014-04-28 18:07:21 +04:00
}
2010-05-05 12:14:22 +04:00
return 0 ;
}
2014-04-28 18:07:21 +04:00
static int rx51_soc_remove ( struct platform_device * pdev )
2010-05-05 12:14:22 +04:00
{
2010-06-21 15:15:00 +04:00
snd_soc_jack_free_gpios ( & rx51_av_jack , ARRAY_SIZE ( rx51_av_jack_gpios ) ,
rx51_av_jack_gpios ) ;
2014-04-28 18:07:21 +04:00
return 0 ;
2010-05-05 12:14:22 +04:00
}
2014-04-28 18:07:21 +04:00
static struct platform_driver rx51_soc_driver = {
. driver = {
. name = " rx51-audio " ,
. owner = THIS_MODULE ,
} ,
. probe = rx51_soc_probe ,
. remove = rx51_soc_remove ,
} ;
module_platform_driver ( rx51_soc_driver ) ;
2010-05-05 12:14:22 +04:00
MODULE_AUTHOR ( " Nokia Corporation " ) ;
MODULE_DESCRIPTION ( " ALSA SoC Nokia RX-51 " ) ;
MODULE_LICENSE ( " GPL " ) ;
2014-04-28 18:07:20 +04:00
MODULE_ALIAS ( " platform:rx51-audio " ) ;