2019-05-31 01:09:53 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2009-02-07 14:01:58 +01:00
/*
* Handles the Mitac mioa701 SoC system
*
* Copyright ( C ) 2008 Robert Jarzmik
*
* 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 04:46:53 +00:00
static int rear_amp_power ( struct snd_soc_component * component , int power )
2009-02-07 14:01:58 +01:00
{
unsigned short reg ;
if ( power ) {
2018-01-29 04:46:53 +00: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 14:01:58 +01:00
} else {
2018-01-29 04:46:53 +00: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 14:01:58 +01:00
}
return 0 ;
}
static int rear_amp_event ( struct snd_soc_dapm_widget * widget ,
struct snd_kcontrol * kctl , int event )
{
2015-11-18 02:34:01 -05:00
struct snd_soc_card * card = widget - > dapm - > card ;
struct snd_soc_pcm_runtime * rtd ;
2018-01-29 04:46:53 +00:00
struct snd_soc_component * component ;
2009-02-07 14:01:58 +01:00
2019-12-10 09:34:08 +09:00
rtd = snd_soc_get_pcm_runtime ( card , & card - > dai_link [ 0 ] ) ;
2020-03-23 14:19:49 +09:00
component = asoc_rtd_to_codec ( rtd , 0 ) - > component ;
2018-01-29 04:46:53 +00:00
return rear_amp_power ( component , SND_SOC_DAPM_EVENT_ON ( event ) ) ;
2009-02-07 14:01:58 +01: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 20:15:21 +00:00
static int mioa701_wm9713_init ( struct snd_soc_pcm_runtime * rtd )
2009-02-07 14:01:58 +01:00
{
2020-03-23 14:19:49 +09:00
struct snd_soc_component * component = asoc_rtd_to_codec ( rtd , 0 ) - > component ;
2009-02-07 14:01:58 +01:00
/* Prepare GPIO8 for rear speaker amplifier */
2018-01-29 04:46:53 +00:00
snd_soc_component_update_bits ( component , AC97_GPIO_CFG , 0x100 , 0x100 ) ;
2009-02-07 14:01:58 +01:00
/* Prepare MIC input */
2018-01-29 04:46:53 +00:00
snd_soc_component_update_bits ( component , AC97_3D_CONTROL , 0xc000 , 0xc000 ) ;
2009-02-07 14:01:58 +01:00
return 0 ;
}
static struct snd_soc_ops mioa701_ops ;
2019-06-06 13:11:56 +09:00
SND_SOC_DAILINK_DEFS ( ac97 ,
DAILINK_COMP_ARRAY ( COMP_CPU ( " pxa2xx-ac97 " ) ) ,
DAILINK_COMP_ARRAY ( COMP_CODEC ( " wm9713-codec " , " wm9713-hifi " ) ) ,
DAILINK_COMP_ARRAY ( COMP_PLATFORM ( " pxa-pcm-audio " ) ) ) ;
SND_SOC_DAILINK_DEFS ( ac97_aux ,
DAILINK_COMP_ARRAY ( COMP_CPU ( " pxa2xx-ac97-aux " ) ) ,
DAILINK_COMP_ARRAY ( COMP_CODEC ( " wm9713-codec " , " wm9713-aux " ) ) ,
DAILINK_COMP_ARRAY ( COMP_PLATFORM ( " pxa-pcm-audio " ) ) ) ;
2009-02-07 14:01:58 +01:00
static struct snd_soc_dai_link mioa701_dai [ ] = {
{
. name = " AC97 " ,
. stream_name = " AC97 HiFi " ,
. init = mioa701_wm9713_init ,
. ops = & mioa701_ops ,
2019-06-06 13:11:56 +09:00
SND_SOC_DAILINK_REG ( ac97 ) ,
2009-02-07 14:01:58 +01:00
} ,
{
. name = " AC97 Aux " ,
. stream_name = " AC97 Aux " ,
. ops = & mioa701_ops ,
2019-06-06 13:11:56 +09:00
SND_SOC_DAILINK_REG ( ac97_aux ) ,
2009-02-07 14:01:58 +01:00
} ,
} ;
static struct snd_soc_card mioa701 = {
. name = " MioA701 " ,
2011-12-22 09:44:43 +08:00
. owner = THIS_MODULE ,
2009-02-07 14:01:58 +01:00
. dai_link = mioa701_dai ,
. num_links = ARRAY_SIZE ( mioa701_dai ) ,
2014-03-01 15:48:18 +01: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 14:01:58 +01:00
} ;
2012-12-07 09:26:17 -05:00
static int mioa701_wm9713_probe ( struct platform_device * pdev )
2009-02-07 14:01:58 +01:00
{
2012-06-30 19:25:08 +02:00
int rc ;
2009-02-07 14:01:58 +01:00
if ( ! machine_is_mioa701 ( ) )
return - ENODEV ;
2012-06-30 19:25:08 +02:00
mioa701 . dev = & pdev - > dev ;
2015-09-01 10:32:59 +08:00
rc = devm_snd_soc_register_card ( & pdev - > dev , & mioa701 ) ;
2012-06-30 19:25:08 +02:00
if ( ! rc )
2016-11-12 16:30:25 +00:00
dev_warn ( & pdev - > dev , " Be warned that incorrect mixers/muxes setup will "
2012-06-30 19:25:08 +02: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 14:01:58 +01: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 14:01:58 +01:00
} ,
} ;
2011-11-25 10:13:37 +08:00
module_platform_driver ( mioa701_wm9713_driver ) ;
2009-02-07 14:01:58 +01:00
/* Module information */
MODULE_AUTHOR ( " Robert Jarzmik (rjarzmik@free.fr) " ) ;
MODULE_DESCRIPTION ( " ALSA SoC WM9713 MIO A701 " ) ;
MODULE_LICENSE ( " GPL " ) ;
2016-05-06 17:27:34 +02:00
MODULE_ALIAS ( " platform:mioa701-wm9713 " ) ;