2019-05-27 08:55:06 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-01-23 04:01:15 +03:00
/*
* SoC audio for EDB93xx
*
* Copyright ( c ) 2010 Alexander Sverdlin < subaparts @ yandex . ru >
*
* This driver support CS4271 codec being master or slave , working
* in control port mode , connected either via SPI or I2C .
* The data format accepted is I2S or left - justified .
* DAPM support not implemented .
*/
# include <linux/platform_device.h>
# include <linux/gpio.h>
2011-07-15 12:38:28 -04:00
# include <linux/module.h>
2019-04-15 22:17:11 +02:00
# include <linux/soc/cirrus/ep93xx.h>
2011-01-23 04:01:15 +03:00
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/soc.h>
# include <asm/mach-types.h>
static int edb93xx_hw_params ( struct snd_pcm_substream * substream ,
struct snd_pcm_hw_params * params )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
struct snd_soc_dai * codec_dai = rtd - > codec_dai ;
struct snd_soc_dai * cpu_dai = rtd - > cpu_dai ;
int err ;
2011-03-07 20:29:53 +03:00
unsigned int mclk_rate ;
2011-01-23 04:01:15 +03:00
unsigned int rate = params_rate ( params ) ;
2011-03-07 20:29:53 +03:00
2011-01-23 04:01:15 +03:00
/*
2011-03-07 20:29:53 +03:00
* According to CS4271 datasheet we use MCLK / LRCK = 256 for
* rates below 50 kHz and 128 for higher sample rates
2011-01-23 04:01:15 +03:00
*/
2011-03-07 20:29:53 +03:00
if ( rate < 50000 )
mclk_rate = rate * 64 * 4 ;
else
mclk_rate = rate * 64 * 2 ;
2011-01-23 04:01:15 +03:00
err = snd_soc_dai_set_sysclk ( codec_dai , 0 , mclk_rate ,
SND_SOC_CLOCK_IN ) ;
if ( err )
return err ;
return snd_soc_dai_set_sysclk ( cpu_dai , 0 , mclk_rate ,
SND_SOC_CLOCK_OUT ) ;
}
2017-08-16 22:29:25 +05:30
static const struct snd_soc_ops edb93xx_ops = {
2011-01-23 04:01:15 +03:00
. hw_params = edb93xx_hw_params ,
} ;
2019-06-06 13:14:18 +09:00
SND_SOC_DAILINK_DEFS ( hifi ,
DAILINK_COMP_ARRAY ( COMP_CPU ( " ep93xx-i2s " ) ) ,
DAILINK_COMP_ARRAY ( COMP_CODEC ( " spi0.0 " , " cs4271-hifi " ) ) ,
DAILINK_COMP_ARRAY ( COMP_PLATFORM ( " ep93xx-i2s " ) ) ) ;
2011-01-23 04:01:15 +03:00
static struct snd_soc_dai_link edb93xx_dai = {
. name = " CS4271 " ,
. stream_name = " CS4271 HiFi " ,
2018-04-28 22:51:38 +02:00
. dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
2011-12-17 15:36:52 +08:00
SND_SOC_DAIFMT_CBS_CFS ,
2011-01-23 04:01:15 +03:00
. ops = & edb93xx_ops ,
2019-06-06 13:14:18 +09:00
SND_SOC_DAILINK_REG ( hifi ) ,
2011-01-23 04:01:15 +03:00
} ;
static struct snd_soc_card snd_soc_edb93xx = {
. name = " EDB93XX " ,
2011-12-22 21:21:37 +08:00
. owner = THIS_MODULE ,
2011-01-23 04:01:15 +03:00
. dai_link = & edb93xx_dai ,
. num_links = 1 ,
} ;
2012-12-07 09:26:23 -05:00
static int edb93xx_probe ( struct platform_device * pdev )
2011-01-23 04:01:15 +03:00
{
2011-09-11 12:28:51 +03:00
struct snd_soc_card * card = & snd_soc_edb93xx ;
2011-01-23 04:01:15 +03:00
int ret ;
2012-01-11 14:14:31 +11:00
ret = ep93xx_i2s_acquire ( ) ;
2011-01-23 04:01:15 +03:00
if ( ret )
return ret ;
2011-09-11 12:28:51 +03:00
card - > dev = & pdev - > dev ;
ret = snd_soc_register_card ( card ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " snd_soc_register_card() failed: %d \n " ,
ret ) ;
ep93xx_i2s_release ( ) ;
2011-01-23 04:01:15 +03:00
}
2011-09-11 12:28:51 +03:00
return ret ;
}
2011-01-23 04:01:15 +03:00
2012-12-07 09:26:23 -05:00
static int edb93xx_remove ( struct platform_device * pdev )
2011-09-11 12:28:51 +03:00
{
struct snd_soc_card * card = platform_get_drvdata ( pdev ) ;
2011-01-23 04:01:15 +03:00
2011-09-11 12:28:51 +03:00
snd_soc_unregister_card ( card ) ;
2011-01-23 04:01:15 +03:00
ep93xx_i2s_release ( ) ;
2011-09-11 12:28:51 +03:00
return 0 ;
}
static struct platform_driver edb93xx_driver = {
. driver = {
. name = " edb93xx-audio " ,
} ,
. probe = edb93xx_probe ,
2012-12-07 09:26:23 -05:00
. remove = edb93xx_remove ,
2011-09-11 12:28:51 +03:00
} ;
2011-11-24 12:07:55 +08:00
module_platform_driver ( edb93xx_driver ) ;
2011-01-23 04:01:15 +03:00
MODULE_AUTHOR ( " Alexander Sverdlin <subaparts@yandex.ru> " ) ;
MODULE_DESCRIPTION ( " ALSA SoC EDB93xx " ) ;
MODULE_LICENSE ( " GPL " ) ;
2011-09-11 12:28:51 +03:00
MODULE_ALIAS ( " platform:edb93xx-audio " ) ;