2009-02-07 16:01:58 +03:00
/*
* Handles the Mitac mioa701 SoC system
*
* Copyright ( C ) 2008 Robert Jarzmik
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation in version 2 of the License .
*
* 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 . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* This is a little schema of the sound interconnections :
*
* Sagem X200 Wolfson WM9713
* + - - - - - - - - + + - - - - - - - - - - - - - - - - - - - + Rear Speaker
* | | | | / - +
* | + - - - > - - - - - > - - - + MONOIN SPKL + - - - > - - - - + - + |
* | GSM | | | | | |
* | + - - - > - - - - - > - - - + PCBEEP SPKR + - - - > - - - - + - + |
* | CHIP | | | \ - +
* | + - - - < - - - - - < - - - + MONO |
* | | | | Front Speaker
* + - - - - - - - - + | | / - +
* | HPL + - - - > - - - - + - + |
* | | | | |
* | OUT3 + - - - > - - - - + - + |
* | | \ - +
* | |
* | | Front Micro
* | | +
* | MIC1 + - - - - - < - - + o +
* | | +
* + - - - - - - - - - - - - - - - - - - - + - - -
*/
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/platform_device.h>
# include <asm/mach-types.h>
# include <mach/audio.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/soc.h>
# include <sound/initval.h>
# include <sound/ac97_codec.h>
# include "../codecs/wm9713.h"
# define AC97_GPIO_PULL 0x58
/* Use GPIO8 for rear speaker amplifier */
2018-01-29 07:46:53 +03:00
static int rear_amp_power ( struct snd_soc_component * component , int power )
2009-02-07 16:01:58 +03:00
{
unsigned short reg ;
if ( power ) {
2018-01-29 07:46:53 +03:00
reg = snd_soc_component_read32 ( component , AC97_GPIO_CFG ) ;
snd_soc_component_write ( component , AC97_GPIO_CFG , reg | 0x0100 ) ;
reg = snd_soc_component_read32 ( component , AC97_GPIO_PULL ) ;
snd_soc_component_write ( component , AC97_GPIO_PULL , reg | ( 1 < < 15 ) ) ;
2009-02-07 16:01:58 +03:00
} else {
2018-01-29 07:46:53 +03:00
reg = snd_soc_component_read32 ( component , AC97_GPIO_CFG ) ;
snd_soc_component_write ( component , AC97_GPIO_CFG , reg & ~ 0x0100 ) ;
reg = snd_soc_component_read32 ( component , AC97_GPIO_PULL ) ;
snd_soc_component_write ( component , AC97_GPIO_PULL , reg & ~ ( 1 < < 15 ) ) ;
2009-02-07 16:01:58 +03:00
}
return 0 ;
}
static int rear_amp_event ( struct snd_soc_dapm_widget * widget ,
struct snd_kcontrol * kctl , int event )
{
2015-11-18 10:34:01 +03:00
struct snd_soc_card * card = widget - > dapm - > card ;
struct snd_soc_pcm_runtime * rtd ;
2018-01-29 07:46:53 +03:00
struct snd_soc_component * component ;
2009-02-07 16:01:58 +03:00
2015-11-18 10:34:01 +03:00
rtd = snd_soc_get_pcm_runtime ( card , card - > dai_link [ 0 ] . name ) ;
2018-01-29 07:46:53 +03:00
component = rtd - > codec_dai - > component ;
return rear_amp_power ( component , SND_SOC_DAPM_EVENT_ON ( event ) ) ;
2009-02-07 16:01:58 +03:00
}
/* mioa701 machine dapm widgets */
static const struct snd_soc_dapm_widget mioa701_dapm_widgets [ ] = {
SND_SOC_DAPM_SPK ( " Front Speaker " , NULL ) ,
SND_SOC_DAPM_SPK ( " Rear Speaker " , rear_amp_event ) ,
SND_SOC_DAPM_MIC ( " Headset " , NULL ) ,
SND_SOC_DAPM_LINE ( " GSM Line Out " , NULL ) ,
SND_SOC_DAPM_LINE ( " GSM Line In " , NULL ) ,
SND_SOC_DAPM_MIC ( " Headset Mic " , NULL ) ,
SND_SOC_DAPM_MIC ( " Front Mic " , NULL ) ,
} ;
static const struct snd_soc_dapm_route audio_map [ ] = {
/* Call Mic */
{ " Mic Bias " , NULL , " Front Mic " } ,
{ " MIC1 " , NULL , " Mic Bias " } ,
/* Headset Mic */
{ " LINEL " , NULL , " Headset Mic " } ,
{ " LINER " , NULL , " Headset Mic " } ,
/* GSM Module */
{ " MONOIN " , NULL , " GSM Line Out " } ,
{ " PCBEEP " , NULL , " GSM Line Out " } ,
{ " GSM Line In " , NULL , " MONO " } ,
/* headphone connected to HPL, HPR */
{ " Headset " , NULL , " HPL " } ,
{ " Headset " , NULL , " HPR " } ,
/* front speaker connected to HPL, OUT3 */
{ " Front Speaker " , NULL , " HPL " } ,
{ " Front Speaker " , NULL , " OUT3 " } ,
/* rear speaker connected to SPKL, SPKR */
{ " Rear Speaker " , NULL , " SPKL " } ,
{ " Rear Speaker " , NULL , " SPKR " } ,
} ;
2010-03-17 23:15:21 +03:00
static int mioa701_wm9713_init ( struct snd_soc_pcm_runtime * rtd )
2009-02-07 16:01:58 +03:00
{
2018-01-29 07:46:53 +03:00
struct snd_soc_component * component = rtd - > codec_dai - > component ;
2009-02-07 16:01:58 +03:00
/* Prepare GPIO8 for rear speaker amplifier */
2018-01-29 07:46:53 +03:00
snd_soc_component_update_bits ( component , AC97_GPIO_CFG , 0x100 , 0x100 ) ;
2009-02-07 16:01:58 +03:00
/* Prepare MIC input */
2018-01-29 07:46:53 +03:00
snd_soc_component_update_bits ( component , AC97_3D_CONTROL , 0xc000 , 0xc000 ) ;
2009-02-07 16:01:58 +03:00
return 0 ;
}
static struct snd_soc_ops mioa701_ops ;
static struct snd_soc_dai_link mioa701_dai [ ] = {
{
. name = " AC97 " ,
. stream_name = " AC97 HiFi " ,
2011-02-23 02:29:11 +03:00
. cpu_dai_name = " pxa2xx-ac97 " ,
2010-03-17 23:15:21 +03:00
. codec_dai_name = " wm9713-hifi " ,
. codec_name = " wm9713-codec " ,
2009-02-07 16:01:58 +03:00
. init = mioa701_wm9713_init ,
2010-03-17 23:15:21 +03:00
. platform_name = " pxa-pcm-audio " ,
2009-02-07 16:01:58 +03:00
. ops = & mioa701_ops ,
} ,
{
. name = " AC97 Aux " ,
. stream_name = " AC97 Aux " ,
2011-02-23 02:29:11 +03:00
. cpu_dai_name = " pxa2xx-ac97-aux " ,
2017-02-25 23:25:23 +03:00
. codec_dai_name = " wm9713-aux " ,
2010-03-17 23:15:21 +03:00
. codec_name = " wm9713-codec " ,
. platform_name = " pxa-pcm-audio " ,
2009-02-07 16:01:58 +03:00
. ops = & mioa701_ops ,
} ,
} ;
static struct snd_soc_card mioa701 = {
. name = " MioA701 " ,
2011-12-22 05:44:43 +04:00
. owner = THIS_MODULE ,
2009-02-07 16:01:58 +03:00
. dai_link = mioa701_dai ,
. num_links = ARRAY_SIZE ( mioa701_dai ) ,
2014-03-01 18:48:18 +04:00
. dapm_widgets = mioa701_dapm_widgets ,
. num_dapm_widgets = ARRAY_SIZE ( mioa701_dapm_widgets ) ,
. dapm_routes = audio_map ,
. num_dapm_routes = ARRAY_SIZE ( audio_map ) ,
2009-02-07 16:01:58 +03:00
} ;
2012-12-07 18:26:17 +04:00
static int mioa701_wm9713_probe ( struct platform_device * pdev )
2009-02-07 16:01:58 +03:00
{
2012-06-30 21:25:08 +04:00
int rc ;
2009-02-07 16:01:58 +03:00
if ( ! machine_is_mioa701 ( ) )
return - ENODEV ;
2012-06-30 21:25:08 +04:00
mioa701 . dev = & pdev - > dev ;
2015-09-01 05:32:59 +03:00
rc = devm_snd_soc_register_card ( & pdev - > dev , & mioa701 ) ;
2012-06-30 21:25:08 +04:00
if ( ! rc )
2016-11-12 19:30:25 +03:00
dev_warn ( & pdev - > dev , " Be warned that incorrect mixers/muxes setup will "
2012-06-30 21:25:08 +04:00
" lead to overheating and possible destruction of your device. "
" Do not use without a good knowledge of mio's board design! \n " ) ;
return rc ;
2009-02-07 16:01:58 +03:00
}
static struct platform_driver mioa701_wm9713_driver = {
. probe = mioa701_wm9713_probe ,
. driver = {
. name = " mioa701-wm9713 " ,
2013-10-17 14:01:37 +04:00
. pm = & snd_soc_pm_ops ,
2009-02-07 16:01:58 +03:00
} ,
} ;
2011-11-25 06:13:37 +04:00
module_platform_driver ( mioa701_wm9713_driver ) ;
2009-02-07 16:01:58 +03:00
/* Module information */
MODULE_AUTHOR ( " Robert Jarzmik (rjarzmik@free.fr) " ) ;
MODULE_DESCRIPTION ( " ALSA SoC WM9713 MIO A701 " ) ;
MODULE_LICENSE ( " GPL " ) ;
2016-05-06 18:27:34 +03:00
MODULE_ALIAS ( " platform:mioa701-wm9713 " ) ;