2008-11-03 12:02:12 +00:00
/*
* linux / sound / soc / pxa / palm27x . c
*
* SoC Audio driver for Palm T | X , T5 and LifeDrive
*
* based on tosa . c
*
* Copyright ( C ) 2008 Marek Vasut < marek . vasut @ gmail . 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 .
*
*/
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/device.h>
# include <linux/gpio.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/soc.h>
2009-07-23 22:16:56 +02:00
# include <sound/jack.h>
2008-11-03 12:02:12 +00:00
# include <asm/mach-types.h>
# include <mach/audio.h>
2012-08-24 15:16:48 +02:00
# include <linux/platform_data/asoc-palm27x.h>
2008-11-03 12:02:12 +00:00
# include "../codecs/wm9712.h"
# include "pxa2xx-ac97.h"
2009-07-23 22:16:56 +02:00
static struct snd_soc_jack hs_jack ;
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
/* Headphones jack detection DAPM pins */
static struct snd_soc_jack_pin hs_jack_pins [ ] = {
{
. pin = " Headphone Jack " ,
. mask = SND_JACK_HEADPHONE ,
} ,
2008-11-03 12:02:12 +00:00
} ;
2009-07-23 22:16:56 +02:00
/* Headphones jack detection gpios */
static struct snd_soc_jack_gpio hs_jack_gpios [ ] = {
[ 0 ] = {
/* gpio is set on per-platform basis */
. name = " hp-gpio " ,
. report = SND_JACK_HEADPHONE ,
. debounce_time = 200 ,
} ,
} ;
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
/* Palm27x machine dapm widgets */
2008-11-03 12:02:12 +00:00
static const struct snd_soc_dapm_widget palm27x_dapm_widgets [ ] = {
SND_SOC_DAPM_HP ( " Headphone Jack " , NULL ) ,
2009-07-23 22:16:56 +02:00
SND_SOC_DAPM_SPK ( " Ext. Speaker " , NULL ) ,
SND_SOC_DAPM_MIC ( " Ext. Microphone " , NULL ) ,
2008-11-03 12:02:12 +00:00
} ;
/* PalmTX audio map */
static const struct snd_soc_dapm_route audio_map [ ] = {
/* headphone connected to HPOUTL, HPOUTR */
{ " Headphone Jack " , NULL , " HPOUTL " } ,
{ " Headphone Jack " , NULL , " HPOUTR " } ,
/* ext speaker connected to ROUT2, LOUT2 */
2009-07-23 22:16:56 +02:00
{ " Ext. Speaker " , NULL , " LOUT2 " } ,
{ " Ext. Speaker " , NULL , " ROUT2 " } ,
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
/* mic connected to MIC1 */
{ " Ext. Microphone " , NULL , " MIC1 " } ,
2008-11-03 12:02:12 +00:00
} ;
2009-07-23 22:16:56 +02:00
static struct snd_soc_card palm27x_asoc ;
2008-11-03 12:02:12 +00:00
2010-03-17 20:15:21 +00:00
static int palm27x_ac97_init ( struct snd_soc_pcm_runtime * rtd )
2008-11-03 12:02:12 +00:00
{
2010-03-17 20:15:21 +00:00
struct snd_soc_codec * codec = rtd - > codec ;
2010-11-05 15:53:46 +02:00
struct snd_soc_dapm_context * dapm = & codec - > dapm ;
2009-03-12 11:07:54 +01:00
int err ;
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
/* add palm27x specific widgets */
2010-11-05 15:53:46 +02:00
err = snd_soc_dapm_new_controls ( dapm , palm27x_dapm_widgets ,
2009-07-23 22:16:56 +02:00
ARRAY_SIZE ( palm27x_dapm_widgets ) ) ;
if ( err )
return err ;
/* set up palm27x specific audio path audio_map */
2010-11-05 15:53:46 +02:00
err = snd_soc_dapm_add_routes ( dapm , audio_map , ARRAY_SIZE ( audio_map ) ) ;
2009-07-23 22:16:56 +02:00
if ( err )
return err ;
/* connected pins */
if ( machine_is_palmld ( ) )
2010-11-05 15:53:46 +02:00
snd_soc_dapm_enable_pin ( dapm , " MIC1 " ) ;
snd_soc_dapm_enable_pin ( dapm , " HPOUTL " ) ;
snd_soc_dapm_enable_pin ( dapm , " HPOUTR " ) ;
snd_soc_dapm_enable_pin ( dapm , " LOUT2 " ) ;
snd_soc_dapm_enable_pin ( dapm , " ROUT2 " ) ;
2009-07-23 22:16:56 +02:00
/* not connected pins */
2010-11-05 15:53:46 +02:00
snd_soc_dapm_nc_pin ( dapm , " OUT3 " ) ;
snd_soc_dapm_nc_pin ( dapm , " MONOOUT " ) ;
snd_soc_dapm_nc_pin ( dapm , " LINEINL " ) ;
snd_soc_dapm_nc_pin ( dapm , " LINEINR " ) ;
snd_soc_dapm_nc_pin ( dapm , " PCBEEP " ) ;
snd_soc_dapm_nc_pin ( dapm , " PHONE " ) ;
snd_soc_dapm_nc_pin ( dapm , " MIC2 " ) ;
2009-07-23 22:16:56 +02:00
/* Jack detection API stuff */
2010-03-17 20:15:21 +00:00
err = snd_soc_jack_new ( codec , " Headphone Jack " ,
2009-07-23 22:16:56 +02:00
SND_JACK_HEADPHONE , & hs_jack ) ;
if ( err )
2009-03-12 11:07:54 +01:00
return err ;
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
err = snd_soc_jack_add_pins ( & hs_jack , ARRAY_SIZE ( hs_jack_pins ) ,
hs_jack_pins ) ;
if ( err )
return err ;
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
err = snd_soc_jack_add_gpios ( & hs_jack , ARRAY_SIZE ( hs_jack_gpios ) ,
hs_jack_gpios ) ;
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
return err ;
2008-11-03 12:02:12 +00:00
}
static struct snd_soc_dai_link palm27x_dai [ ] = {
{
. name = " AC97 HiFi " ,
. stream_name = " AC97 HiFi " ,
2011-02-23 02:29:11 +03:00
. cpu_dai_name = " pxa2xx-ac97 " ,
2010-03-17 20:15:21 +00:00
. codec_dai_name = " wm9712-hifi " ,
. codec_name = " wm9712-codec " ,
. platform_name = " pxa-pcm-audio " ,
2008-11-03 12:02:12 +00:00
. init = palm27x_ac97_init ,
} ,
{
. name = " AC97 Aux " ,
. stream_name = " AC97 Aux " ,
2011-02-23 02:29:11 +03:00
. cpu_dai_name = " pxa2xx-ac97-aux " ,
2010-03-17 20:15:21 +00:00
. codec_dai_name = " wm9712-aux " ,
. codec_name = " wm9712-codec " ,
. platform_name = " pxa-pcm-audio " ,
2008-11-03 12:02:12 +00:00
} ,
} ;
2008-11-18 20:50:34 +00:00
static struct snd_soc_card palm27x_asoc = {
2008-11-03 12:02:12 +00:00
. name = " Palm/PXA27x " ,
2011-12-22 09:44:43 +08:00
. owner = THIS_MODULE ,
2008-11-03 12:02:12 +00:00
. dai_link = palm27x_dai ,
. num_links = ARRAY_SIZE ( palm27x_dai ) ,
} ;
static struct platform_device * palm27x_snd_device ;
2009-04-17 11:37:35 +02:00
static int palm27x_asoc_probe ( struct platform_device * pdev )
2008-11-03 12:02:12 +00:00
{
int ret ;
if ( ! ( machine_is_palmtx ( ) | | machine_is_palmt5 ( ) | |
2009-04-23 11:27:11 +02:00
machine_is_palmld ( ) | | machine_is_palmte2 ( ) ) )
2008-11-03 12:02:12 +00:00
return - ENODEV ;
2009-07-23 22:16:56 +02:00
if ( ! pdev - > dev . platform_data ) {
dev_err ( & pdev - > dev , " please supply platform_data \n " ) ;
return - ENODEV ;
}
2008-11-03 12:02:12 +00:00
2009-07-23 22:16:56 +02:00
hs_jack_gpios [ 0 ] . gpio = ( ( struct palm27x_asoc_info * )
( pdev - > dev . platform_data ) ) - > jack_gpio ;
2008-11-03 12:02:12 +00:00
palm27x_snd_device = platform_device_alloc ( " soc-audio " , - 1 ) ;
2009-07-23 22:16:56 +02:00
if ( ! palm27x_snd_device )
return - ENOMEM ;
2008-11-03 12:02:12 +00:00
2010-03-17 20:15:21 +00:00
platform_set_drvdata ( palm27x_snd_device , & palm27x_asoc ) ;
2008-11-03 12:02:12 +00:00
ret = platform_device_add ( palm27x_snd_device ) ;
if ( ret ! = 0 )
goto put_device ;
return 0 ;
put_device :
platform_device_put ( palm27x_snd_device ) ;
return ret ;
}
2009-04-17 11:37:35 +02:00
static int __devexit palm27x_asoc_remove ( struct platform_device * pdev )
2008-11-03 12:02:12 +00:00
{
platform_device_unregister ( palm27x_snd_device ) ;
2009-04-17 11:37:35 +02:00
return 0 ;
2008-11-03 12:02:12 +00:00
}
2009-04-17 11:37:35 +02:00
static struct platform_driver palm27x_wm9712_driver = {
. probe = palm27x_asoc_probe ,
. remove = __devexit_p ( palm27x_asoc_remove ) ,
. driver = {
. name = " palm27x-asoc " ,
. owner = THIS_MODULE ,
} ,
} ;
2011-11-25 10:13:37 +08:00
module_platform_driver ( palm27x_wm9712_driver ) ;
2008-11-03 12:02:12 +00:00
/* Module information */
MODULE_AUTHOR ( " Marek Vasut <marek.vasut@gmail.com> " ) ;
MODULE_DESCRIPTION ( " ALSA SoC Palm T|X, T5 and LifeDrive " ) ;
MODULE_LICENSE ( " GPL " ) ;