2010-05-17 19:53:10 -05:00
/*
* sdp4430 . c - - SoC audio for TI OMAP4430 SDP
*
* Author : Misael Lopez Cruz < x0052729 @ ti . com >
*
* 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/clk.h>
# include <linux/platform_device.h>
2011-05-01 21:27:00 -05:00
# include <linux/mfd/twl6040.h>
2011-07-15 12:38:28 -04:00
# include <linux/module.h>
2011-05-01 21:27:00 -05:00
2010-05-17 19:53:10 -05:00
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/soc.h>
2010-12-10 20:45:19 -06:00
# include <sound/jack.h>
2010-05-17 19:53:10 -05:00
# include <asm/mach-types.h>
# include <plat/hardware.h>
# include <plat/mux.h>
2011-07-05 19:50:45 +03:00
# include "omap-mcpdm.h"
2010-05-17 19:53:10 -05:00
# include "omap-pcm.h"
# include "../codecs/twl6040.h"
static int sdp4430_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-17 19:53:10 -05:00
int clk_id , freq ;
int ret ;
2011-06-27 17:03:14 +03:00
clk_id = twl6040_get_clk_id ( rtd - > codec ) ;
if ( clk_id = = TWL6040_SYSCLK_SEL_HPPLL )
2010-05-17 19:53:10 -05:00
freq = 38400000 ;
2011-06-27 17:03:14 +03:00
else if ( clk_id = = TWL6040_SYSCLK_SEL_LPPLL )
2010-05-17 19:53:10 -05:00
freq = 32768 ;
2011-06-27 17:03:14 +03:00
else
return - EINVAL ;
2010-05-17 19:53:10 -05:00
/* set the codec mclk */
ret = snd_soc_dai_set_sysclk ( codec_dai , clk_id , freq ,
SND_SOC_CLOCK_IN ) ;
if ( ret ) {
printk ( KERN_ERR " can't set codec system clock \n " ) ;
return ret ;
}
2010-03-17 20:15:21 +00:00
return ret ;
2010-05-17 19:53:10 -05:00
}
static struct snd_soc_ops sdp4430_ops = {
. hw_params = sdp4430_hw_params ,
} ;
2010-12-10 20:45:19 -06:00
/* Headset jack */
static struct snd_soc_jack hs_jack ;
/*Headset jack detection DAPM pins */
static struct snd_soc_jack_pin hs_jack_pins [ ] = {
{
. pin = " Headset Mic " ,
. mask = SND_JACK_MICROPHONE ,
} ,
{
. pin = " Headset Stereophone " ,
. mask = SND_JACK_HEADPHONE ,
} ,
} ;
2010-05-17 19:53:10 -05:00
/* SDP4430 machine DAPM */
static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets [ ] = {
SND_SOC_DAPM_MIC ( " Ext Mic " , NULL ) ,
SND_SOC_DAPM_SPK ( " Ext Spk " , NULL ) ,
SND_SOC_DAPM_MIC ( " Headset Mic " , NULL ) ,
SND_SOC_DAPM_HP ( " Headset Stereophone " , NULL ) ,
2010-05-18 12:44:17 -05:00
SND_SOC_DAPM_SPK ( " Earphone Spk " , NULL ) ,
2011-09-30 11:39:50 +03:00
SND_SOC_DAPM_INPUT ( " FM Stereo In " ) ,
2010-05-17 19:53:10 -05:00
} ;
static const struct snd_soc_dapm_route audio_map [ ] = {
/* External Mics: MAINMIC, SUBMIC with bias*/
{ " MAINMIC " , NULL , " Main Mic Bias " } ,
{ " SUBMIC " , NULL , " Main Mic Bias " } ,
{ " Main Mic Bias " , NULL , " Ext Mic " } ,
/* External Speakers: HFL, HFR */
{ " Ext Spk " , NULL , " HFL " } ,
{ " Ext Spk " , NULL , " HFR " } ,
/* Headset Mic: HSMIC with bias */
{ " HSMIC " , NULL , " Headset Mic Bias " } ,
{ " Headset Mic Bias " , NULL , " Headset Mic " } ,
/* Headset Stereophone (Headphone): HSOL, HSOR */
{ " Headset Stereophone " , NULL , " HSOL " } ,
{ " Headset Stereophone " , NULL , " HSOR " } ,
2010-05-18 12:44:17 -05:00
/* Earphone speaker */
{ " Earphone Spk " , NULL , " EP " } ,
2010-12-08 10:55:05 -06:00
/* Aux/FM Stereo In: AFML, AFMR */
2011-09-30 11:39:50 +03:00
{ " AFML " , NULL , " FM Stereo In " } ,
{ " AFMR " , NULL , " FM Stereo In " } ,
2010-05-17 19:53:10 -05:00
} ;
2010-03-17 20:15:21 +00:00
static int sdp4430_twl6040_init ( struct snd_soc_pcm_runtime * rtd )
2010-05-17 19:53:10 -05:00
{
2010-03-17 20:15:21 +00:00
struct snd_soc_codec * codec = rtd - > codec ;
2011-09-26 16:05:59 +03:00
int ret , hs_trim ;
2010-05-17 19:53:10 -05:00
2011-09-26 16:05:59 +03:00
/*
* Configure McPDM offset cancellation based on the HSOTRIM value from
* twl6040 .
*/
hs_trim = twl6040_get_trim_value ( codec , TWL6040_TRIM_HSOTRIM ) ;
omap_mcpdm_configure_dn_offsets ( rtd , TWL6040_HSF_TRIM_LEFT ( hs_trim ) ,
TWL6040_HSF_TRIM_RIGHT ( hs_trim ) ) ;
2010-12-10 20:45:19 -06:00
/* Headset jack detection */
ret = snd_soc_jack_new ( codec , " Headset Jack " ,
SND_JACK_HEADSET , & hs_jack ) ;
if ( ret )
return ret ;
ret = snd_soc_jack_add_pins ( & hs_jack , ARRAY_SIZE ( hs_jack_pins ) ,
hs_jack_pins ) ;
if ( machine_is_omap_4430sdp ( ) )
twl6040_hs_jack_detect ( codec , & hs_jack , SND_JACK_HEADSET ) ;
else
snd_soc_jack_report ( & hs_jack , SND_JACK_HEADSET , SND_JACK_HEADSET ) ;
2010-05-17 19:53:10 -05:00
return ret ;
}
/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link sdp4430_dai = {
. name = " TWL6040 " ,
. stream_name = " TWL6040 " ,
2011-08-02 14:04:26 +03:00
. cpu_dai_name = " omap-mcpdm " ,
2011-09-22 11:05:53 +03:00
. codec_dai_name = " twl6040-legacy " ,
2010-03-17 20:15:21 +00:00
. platform_name = " omap-pcm-audio " ,
. codec_name = " twl6040-codec " ,
2010-05-17 19:53:10 -05:00
. init = sdp4430_twl6040_init ,
2010-05-19 14:14:51 +01:00
. ops = & sdp4430_ops ,
2010-05-17 19:53:10 -05:00
} ;
/* Audio machine driver */
static struct snd_soc_card snd_soc_sdp4430 = {
. name = " SDP4430 " ,
. dai_link = & sdp4430_dai ,
. num_links = 1 ,
2011-10-10 15:34:15 +03:00
. dapm_widgets = sdp4430_twl6040_dapm_widgets ,
. num_dapm_widgets = ARRAY_SIZE ( sdp4430_twl6040_dapm_widgets ) ,
. dapm_routes = audio_map ,
. num_dapm_routes = ARRAY_SIZE ( audio_map ) ,
2010-05-17 19:53:10 -05:00
} ;
static struct platform_device * sdp4430_snd_device ;
static int __init sdp4430_soc_init ( void )
{
int ret ;
2010-10-06 16:47:26 +03:00
if ( ! machine_is_omap_4430sdp ( ) )
2010-05-17 19:53:10 -05:00
return - ENODEV ;
printk ( KERN_INFO " SDP4430 SoC init \n " ) ;
sdp4430_snd_device = platform_device_alloc ( " soc-audio " , - 1 ) ;
if ( ! sdp4430_snd_device ) {
printk ( KERN_ERR " Platform device allocation failed \n " ) ;
return - ENOMEM ;
}
2010-03-17 20:15:21 +00:00
platform_set_drvdata ( sdp4430_snd_device , & snd_soc_sdp4430 ) ;
2010-05-17 19:53:10 -05:00
ret = platform_device_add ( sdp4430_snd_device ) ;
if ( ret )
goto err ;
return 0 ;
err :
printk ( KERN_ERR " Unable to add platform device \n " ) ;
platform_device_put ( sdp4430_snd_device ) ;
return ret ;
}
module_init ( sdp4430_soc_init ) ;
static void __exit sdp4430_soc_exit ( void )
{
platform_device_unregister ( sdp4430_snd_device ) ;
}
module_exit ( sdp4430_soc_exit ) ;
MODULE_AUTHOR ( " Misael Lopez Cruz <x0052729@ti.com> " ) ;
MODULE_DESCRIPTION ( " ALSA SoC SDP4430 " ) ;
MODULE_LICENSE ( " GPL " ) ;