Commit a1cb9cd6 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'fix/asoc' into for-linus

parents 08d1e635 834eb6c5
...@@ -7,15 +7,6 @@ config SND_BF5XX_I2S ...@@ -7,15 +7,6 @@ config SND_BF5XX_I2S
mode (supports single stereo In/Out). mode (supports single stereo In/Out).
You will also need to select the audio interfaces to support below. You will also need to select the audio interfaces to support below.
config SND_BF5XX_TDM
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
depends on (BLACKFIN && SND_SOC)
help
Say Y or M if you want to add support for codecs attached to
the Blackfin SPORT (synchronous serial ports) interface in TDM
mode.
You will also need to select the audio interfaces to support below.
config SND_BF5XX_SOC_SSM2602 config SND_BF5XX_SOC_SSM2602
tristate "SoC SSM2602 Audio support for BF52x ezkit" tristate "SoC SSM2602 Audio support for BF52x ezkit"
depends on SND_BF5XX_I2S depends on SND_BF5XX_I2S
...@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE ...@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE
Enter the GPIO used to control AD73311's SE pin. Acceptable Enter the GPIO used to control AD73311's SE pin. Acceptable
values are 0 to 7 values are 0 to 7
config SND_BF5XX_TDM
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
depends on (BLACKFIN && SND_SOC)
help
Say Y or M if you want to add support for codecs attached to
the Blackfin SPORT (synchronous serial ports) interface in TDM
mode.
You will also need to select the audio interfaces to support below.
config SND_BF5XX_SOC_AD1836
tristate "SoC AD1836 Audio support for BF5xx"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1836
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_AD1938
tristate "SoC AD1938 Audio support for Blackfin"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1938
help
Say Y if you want to add support for AD1938 codec on Blackfin.
config SND_BF5XX_AC97 config SND_BF5XX_AC97
tristate "SoC AC97 Audio for the ADI BF5xx chip" tristate "SoC AC97 Audio for the ADI BF5xx chip"
depends on BLACKFIN depends on BLACKFIN
...@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT ...@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT
Say y if you want AC97 driver to support up to 5.1 channel audio. Say y if you want AC97 driver to support up to 5.1 channel audio.
this mode will consume much more memory for DMA. this mode will consume much more memory for DMA.
config SND_BF5XX_HAVE_COLD_RESET
bool "BOARD has COLD Reset GPIO"
depends on SND_BF5XX_AC97
default y if BFIN548_EZKIT
default n if !BFIN548_EZKIT
config SND_BF5XX_RESET_GPIO_NUM
int "Set a GPIO for cold reset"
depends on SND_BF5XX_HAVE_COLD_RESET
range 0 159
default 19 if BFIN548_EZKIT
default 5 if BFIN537_STAMP
default 0
help
Set the correct GPIO for RESET the sound chip.
config SND_BF5XX_SOC_AD1980
tristate "SoC AD1980/1 Audio support for BF5xx"
depends on SND_BF5XX_AC97
select SND_BF5XX_SOC_AC97
select SND_SOC_AD1980
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_SPORT config SND_BF5XX_SOC_SPORT
tristate tristate
...@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97 ...@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97
select SND_SOC_AC97_BUS select SND_SOC_AC97_BUS
select SND_BF5XX_SOC_SPORT select SND_BF5XX_SOC_SPORT
config SND_BF5XX_SOC_AD1836
tristate "SoC AD1836 Audio support for BF5xx"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1836
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_AD1980
tristate "SoC AD1980/1 Audio support for BF5xx"
depends on SND_BF5XX_AC97
select SND_BF5XX_SOC_AC97
select SND_SOC_AD1980
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_AD1938
tristate "SoC AD1938 Audio support for Blackfin"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1938
help
Say Y if you want to add support for AD1938 codec on Blackfin.
config SND_BF5XX_SPORT_NUM config SND_BF5XX_SPORT_NUM
int "Set a SPORT for Sound chip" int "Set a SPORT for Sound chip"
depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM) depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
...@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM ...@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM
default 0 default 0
help help
Set the correct SPORT for sound chip. Set the correct SPORT for sound chip.
config SND_BF5XX_HAVE_COLD_RESET
bool "BOARD has COLD Reset GPIO"
depends on SND_BF5XX_AC97
default y if BFIN548_EZKIT
default n if !BFIN548_EZKIT
config SND_BF5XX_RESET_GPIO_NUM
int "Set a GPIO for cold reset"
depends on SND_BF5XX_HAVE_COLD_RESET
range 0 159
default 19 if BFIN548_EZKIT
default 5 if BFIN537_STAMP
default 0
help
Set the correct GPIO for RESET the sound chip.
...@@ -277,7 +277,11 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai) ...@@ -277,7 +277,11 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
if (!dai->active) if (!dai->active)
return 0; return 0;
#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
ret = sport_set_multichannel(sport, 16, 0x3FF, 1);
#else
ret = sport_set_multichannel(sport, 16, 0x1F, 1); ret = sport_set_multichannel(sport, 16, 0x1F, 1);
#endif
if (ret) { if (ret) {
pr_err("SPORT is busy!\n"); pr_err("SPORT is busy!\n");
return -EBUSY; return -EBUSY;
...@@ -334,7 +338,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev, ...@@ -334,7 +338,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
goto sport_err; goto sport_err;
} }
/*SPORT works in TDM mode to simulate AC97 transfers*/ /*SPORT works in TDM mode to simulate AC97 transfers*/
#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
#else
ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
#endif
if (ret) { if (ret) {
pr_err("SPORT is busy!\n"); pr_err("SPORT is busy!\n");
ret = -EBUSY; ret = -EBUSY;
......
/* /*
* linux/sound/arm/bf5xx-ac97.h * sound/soc/blackfin/bf5xx-ac97.h
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
......
...@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = { ...@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between * TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict * the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both * by ignoring the TFS pin when Port G is selected. This allows both
* ssm2602 using Port G and EMAC concurrently. * codecs and EMAC using Port G concurrently.
*/ */
#ifdef CONFIG_BF527_SPORT0_PORTF #ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#else
#define LOCAL_SPORT0_TFS (0) #define LOCAL_SPORT0_TFS (0)
#else
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif #endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
...@@ -227,7 +227,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev, ...@@ -227,7 +227,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
return 0; return 0;
} }
static void bf5xx_i2s_remove(struct snd_soc_dai *dai) static void bf5xx_i2s_remove(struct platform_device *pdev,
struct snd_soc_dai *dai)
{ {
pr_debug("%s enter\n", __func__); pr_debug("%s enter\n", __func__);
peripheral_free_list(&sport_req[sport_num][0]); peripheral_free_list(&sport_req[sport_num][0]);
...@@ -236,36 +237,31 @@ static void bf5xx_i2s_remove(struct snd_soc_dai *dai) ...@@ -236,36 +237,31 @@ static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
{ {
struct sport_device *sport =
(struct sport_device *)dai->private_data;
pr_debug("%s : sport %d\n", __func__, dai->id); pr_debug("%s : sport %d\n", __func__, dai->id);
if (!dai->active)
return 0;
if (dai->capture.active) if (dai->capture.active)
sport_rx_stop(sport); sport_rx_stop(sport_handle);
if (dai->playback.active) if (dai->playback.active)
sport_tx_stop(sport); sport_tx_stop(sport_handle);
return 0; return 0;
} }
static int bf5xx_i2s_resume(struct snd_soc_dai *dai) static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
{ {
int ret; int ret;
struct sport_device *sport =
(struct sport_device *)dai->private_data;
pr_debug("%s : sport %d\n", __func__, dai->id); pr_debug("%s : sport %d\n", __func__, dai->id);
if (!dai->active)
return 0;
ret = sport_config_rx(sport, RFSR | RCKFE, RSFSE|0x1f, 0, 0); ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
bf5xx_i2s.rcr2, 0, 0);
if (ret) { if (ret) {
pr_err("SPORT is busy!\n"); pr_err("SPORT is busy!\n");
return -EBUSY; return -EBUSY;
} }
ret = sport_config_tx(sport, TFSR | TCKFE, TSFSE|0x1f, 0, 0); ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1,
bf5xx_i2s.tcr2, 0, 0);
if (ret) { if (ret) {
pr_err("SPORT is busy!\n"); pr_err("SPORT is busy!\n");
return -EBUSY; return -EBUSY;
......
/* /*
* linux/sound/arm/bf5xx-i2s.h * sound/soc/blackfin/bf5xx-i2s.h
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
......
...@@ -326,7 +326,7 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport) ...@@ -326,7 +326,7 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport)
int sport_tx_start(struct sport_device *sport) int sport_tx_start(struct sport_device *sport)
{ {
unsigned flags; unsigned long flags;
pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__, pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
sport->tx_run, sport->rx_run); sport->tx_run, sport->rx_run);
if (sport->tx_run) if (sport->tx_run)
......
...@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = { ...@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between * TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict * the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both * by ignoring the TFS pin when Port G is selected. This allows both
* ssm2602 using Port G and EMAC concurrently. * codecs and EMAC using Port G concurrently.
*/ */
#ifdef CONFIG_BF527_SPORT0_PORTF #ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#else
#define LOCAL_SPORT0_TFS (0) #define LOCAL_SPORT0_TFS (0)
#else
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif #endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
......
...@@ -251,8 +251,7 @@ static int __devexit ad1836_spi_remove(struct spi_device *spi) ...@@ -251,8 +251,7 @@ static int __devexit ad1836_spi_remove(struct spi_device *spi)
static struct spi_driver ad1836_spi_driver = { static struct spi_driver ad1836_spi_driver = {
.driver = { .driver = {
.name = "ad1836-spi", .name = "ad1836",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = ad1836_spi_probe, .probe = ad1836_spi_probe,
......
...@@ -456,7 +456,6 @@ static int __devexit ad1938_spi_remove(struct spi_device *spi) ...@@ -456,7 +456,6 @@ static int __devexit ad1938_spi_remove(struct spi_device *spi)
static struct spi_driver ad1938_spi_driver = { static struct spi_driver ad1938_spi_driver = {
.driver = { .driver = {
.name = "ad1938", .name = "ad1938",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = ad1938_spi_probe, .probe = ad1938_spi_probe,
...@@ -515,6 +514,7 @@ static int ad1938_register(struct ad1938_priv *ad1938) ...@@ -515,6 +514,7 @@ static int ad1938_register(struct ad1938_priv *ad1938)
codec->num_dai = 1; codec->num_dai = 1;
codec->write = ad1938_write_reg; codec->write = ad1938_write_reg;
codec->read = ad1938_read_reg_cache; codec->read = ad1938_read_reg_cache;
codec->set_bias_level = ad1938_set_bias_level;
INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths); INIT_LIST_HEAD(&codec->dapm_paths);
......
...@@ -595,6 +595,7 @@ static const struct snd_soc_dapm_route audio_map[] = { ...@@ -595,6 +595,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Mono Capture mixer-mux */ /* Mono Capture mixer-mux */
{"Capture Right Mixer", "Stereo", "Capture Right Mux"}, {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
{"Capture Left Mixer", "Stereo", "Capture Left Mux"},
{"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"}, {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
{"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"}, {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
{"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"}, {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
......
...@@ -97,22 +97,19 @@ enum { ...@@ -97,22 +97,19 @@ enum {
DAVINCI_MCBSP_WORD_32, DAVINCI_MCBSP_WORD_32,
}; };
static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
.name = "I2S PCM Stereo out",
};
static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
.name = "I2S PCM Stereo in",
};
struct davinci_mcbsp_dev { struct davinci_mcbsp_dev {
/*
* dma_params must be first because rtd->dai->cpu_dai->private_data
* is cast to a pointer of an array of struct davinci_pcm_dma_params in
* davinci_pcm_open.
*/
struct davinci_pcm_dma_params dma_params[2];
void __iomem *base; void __iomem *base;
#define MOD_DSP_A 0 #define MOD_DSP_A 0
#define MOD_DSP_B 1 #define MOD_DSP_B 1
int mode; int mode;
u32 pcr; u32 pcr;
struct clk *clk; struct clk *clk;
struct davinci_pcm_dma_params *dma_params[2];
}; };
static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
...@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback) ...@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
toggle_clock(dev, playback); toggle_clock(dev, playback);
} }
static int davinci_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
cpu_dai->dma_data = dev->dma_params[substream->stream];
return 0;
}
#define DEFAULT_BITPERSAMPLE 16 #define DEFAULT_BITPERSAMPLE 16
static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
...@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct davinci_pcm_dma_params *dma_params = dai->dma_data;
struct davinci_mcbsp_dev *dev = dai->private_data; struct davinci_mcbsp_dev *dev = dai->private_data;
struct davinci_pcm_dma_params *dma_params =
&dev->dma_params[substream->stream];
struct snd_interval *i = NULL; struct snd_interval *i = NULL;
int mcbsp_word_length; int mcbsp_word_length;
unsigned int rcr, xcr, srgr; unsigned int rcr, xcr, srgr;
...@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, ...@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
static struct snd_soc_dai_ops davinci_i2s_dai_ops = { static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
.startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown, .shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare, .prepare = davinci_i2s_prepare,
.trigger = davinci_i2s_trigger, .trigger = davinci_i2s_trigger,
...@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->base = (void __iomem *)IO_ADDRESS(mem->start); dev->base = (void __iomem *)IO_ADDRESS(mem->start);
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
/* first TX, then RX */ /* first TX, then RX */
...@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO; ret = -ENXIO;
goto err_free_mem; goto err_free_mem;
} }
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start; dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) { if (!res) {
...@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO; ret = -ENXIO;
goto err_free_mem; goto err_free_mem;
} }
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start; dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev; davinci_i2s_dai.private_data = dev;
ret = snd_soc_register_dai(&davinci_i2s_dai); ret = snd_soc_register_dai(&davinci_i2s_dai);
......
...@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) ...@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
printk(KERN_ERR "GBLCTL write error\n"); printk(KERN_ERR "GBLCTL write error\n");
} }
static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct davinci_audio_dev *dev = cpu_dai->private_data;
cpu_dai->dma_data = dev->dma_params[substream->stream];
return 0;
}
static void mcasp_start_rx(struct davinci_audio_dev *dev) static void mcasp_start_rx(struct davinci_audio_dev *dev)
{ {
mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
...@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) ...@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
{ {
if (stream == SNDRV_PCM_STREAM_PLAYBACK) if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (dev->txnumevt) /* enable FIFO */
mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
FIFO_ENABLE);
mcasp_start_tx(dev); mcasp_start_tx(dev);
else } else {
if (dev->rxnumevt) /* enable FIFO */
mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
FIFO_ENABLE);
mcasp_start_rx(dev); mcasp_start_rx(dev);
}
/* enable FIFO */
if (dev->txnumevt)
mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
if (dev->rxnumevt)
mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
} }
static void mcasp_stop_rx(struct davinci_audio_dev *dev) static void mcasp_stop_rx(struct davinci_audio_dev *dev)
...@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev) ...@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
{ {
if (stream == SNDRV_PCM_STREAM_PLAYBACK) if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (dev->txnumevt) /* disable FIFO */
mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
FIFO_ENABLE);
mcasp_stop_tx(dev); mcasp_stop_tx(dev);
else } else {
if (dev->rxnumevt) /* disable FIFO */
mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
FIFO_ENABLE);
mcasp_stop_rx(dev); mcasp_stop_rx(dev);
}
/* disable FIFO */
if (dev->txnumevt)
mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
if (dev->rxnumevt)
mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
} }
static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
...@@ -512,34 +504,49 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, ...@@ -512,34 +504,49 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
int channel_size) int channel_size)
{ {
u32 fmt = 0; u32 fmt = 0;
u32 mask, rotate;
switch (channel_size) { switch (channel_size) {
case DAVINCI_AUDIO_WORD_8: case DAVINCI_AUDIO_WORD_8:
fmt = 0x03; fmt = 0x03;
rotate = 6;
mask = 0x000000ff;
break; break;
case DAVINCI_AUDIO_WORD_12: case DAVINCI_AUDIO_WORD_12:
fmt = 0x05; fmt = 0x05;
rotate = 5;
mask = 0x00000fff;
break; break;
case DAVINCI_AUDIO_WORD_16: case DAVINCI_AUDIO_WORD_16:
fmt = 0x07; fmt = 0x07;
rotate = 4;
mask = 0x0000ffff;
break; break;
case DAVINCI_AUDIO_WORD_20: case DAVINCI_AUDIO_WORD_20:
fmt = 0x09; fmt = 0x09;
rotate = 3;
mask = 0x000fffff;
break; break;
case DAVINCI_AUDIO_WORD_24: case DAVINCI_AUDIO_WORD_24:
fmt = 0x0B; fmt = 0x0B;
rotate = 2;
mask = 0x00ffffff;
break; break;
case DAVINCI_AUDIO_WORD_28: case DAVINCI_AUDIO_WORD_28:
fmt = 0x0D; fmt = 0x0D;
rotate = 1;
mask = 0x0fffffff;
break; break;
case DAVINCI_AUDIO_WORD_32: case DAVINCI_AUDIO_WORD_32:
fmt = 0x0F; fmt = 0x0F;
rotate = 0;
mask = 0xffffffff;
break; break;
default: default:
...@@ -550,6 +557,13 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, ...@@ -550,6 +557,13 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
RXSSZ(fmt), RXSSZ(0x0F)); RXSSZ(fmt), RXSSZ(0x0F));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
TXSSZ(fmt), TXSSZ(0x0F)); TXSSZ(fmt), TXSSZ(0x0F));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate),
TXROT(7));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate),
RXROT(7));
mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask);
mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask);
return 0; return 0;
} }
...@@ -638,7 +652,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) ...@@ -638,7 +652,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
printk(KERN_ERR "playback tdm slot %d not supported\n", printk(KERN_ERR "playback tdm slot %d not supported\n",
dev->tdm_slots); dev->tdm_slots);
mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF);
mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
} else { } else {
/* bit stream is MSB first with no delay */ /* bit stream is MSB first with no delay */
...@@ -655,7 +668,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) ...@@ -655,7 +668,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
printk(KERN_ERR "capture tdm slot %d not supported\n", printk(KERN_ERR "capture tdm slot %d not supported\n",
dev->tdm_slots); dev->tdm_slots);
mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF);
mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
} }
} }
...@@ -700,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -700,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
{ {
struct davinci_audio_dev *dev = cpu_dai->private_data; struct davinci_audio_dev *dev = cpu_dai->private_data;
struct davinci_pcm_dma_params *dma_params = struct davinci_pcm_dma_params *dma_params =
dev->dma_params[substream->stream]; &dev->dma_params[substream->stream];
int word_length; int word_length;
u8 numevt; u8 numevt;
...@@ -778,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, ...@@ -778,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
} }
static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger, .trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params, .hw_params = davinci_mcasp_hw_params,
.set_fmt = davinci_mcasp_set_dai_fmt, .set_fmt = davinci_mcasp_set_dai_fmt,
...@@ -829,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -829,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
struct resource *mem, *ioarea, *res; struct resource *mem, *ioarea, *res;
struct snd_platform_data *pdata; struct snd_platform_data *pdata;
struct davinci_audio_dev *dev; struct davinci_audio_dev *dev;
int count = 0;
int ret = 0; int ret = 0;
dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
GFP_KERNEL);
if (!dma_data) {
ret = -ENOMEM;
goto err_release_dev;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) { if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n"); dev_err(&pdev->dev, "no mem resource?\n");
...@@ -877,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -877,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev->txnumevt = pdata->txnumevt; dev->txnumevt = pdata->txnumevt;
dev->rxnumevt = pdata->rxnumevt; dev->rxnumevt = pdata->rxnumevt;
dma_data[count].name = "I2S PCM Stereo out"; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
dma_data[count].eventq_no = pdata->eventq_no; dma_data->eventq_no = pdata->eventq_no;
dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset + dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
io_v2p(dev->base)); io_v2p(dev->base));
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
/* first TX, then RX */ /* first TX, then RX */
res = platform_get_resource(pdev, IORESOURCE_DMA, 0); res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
...@@ -890,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -890,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region; goto err_release_region;
} }
dma_data[count].channel = res->start; dma_data->channel = res->start;
count++;
dma_data[count].name = "I2S PCM Stereo in"; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
dma_data[count].eventq_no = pdata->eventq_no; dma_data->eventq_no = pdata->eventq_no;
dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset + dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
io_v2p(dev->base)); io_v2p(dev->base));
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) { if (!res) {
...@@ -904,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -904,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region; goto err_release_region;
} }
dma_data[count].channel = res->start; dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev; davinci_mcasp_dai[pdata->op_mode].private_data = dev;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
...@@ -916,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -916,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
err_release_region: err_release_region:
release_mem_region(mem->start, (mem->end - mem->start) + 1); release_mem_region(mem->start, (mem->end - mem->start) + 1);
err_release_data: err_release_data:
kfree(dma_data);
err_release_dev:
kfree(dev); kfree(dev);
return ret; return ret;
...@@ -926,7 +925,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -926,7 +925,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
static int davinci_mcasp_remove(struct platform_device *pdev) static int davinci_mcasp_remove(struct platform_device *pdev)
{ {
struct snd_platform_data *pdata = pdev->dev.platform_data; struct snd_platform_data *pdata = pdev->dev.platform_data;
struct davinci_pcm_dma_params *dma_data;
struct davinci_audio_dev *dev; struct davinci_audio_dev *dev;
struct resource *mem; struct resource *mem;
...@@ -939,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev) ...@@ -939,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, (mem->end - mem->start) + 1); release_mem_region(mem->start, (mem->end - mem->start) + 1);
dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
kfree(dma_data);
kfree(dev); kfree(dev);
return 0; return 0;
......
...@@ -39,10 +39,15 @@ enum { ...@@ -39,10 +39,15 @@ enum {
}; };
struct davinci_audio_dev { struct davinci_audio_dev {
/*
* dma_params must be first because rtd->dai->cpu_dai->private_data
* is cast to a pointer of an array of struct davinci_pcm_dma_params in
* davinci_pcm_open.
*/
struct davinci_pcm_dma_params dma_params[2];
void __iomem *base; void __iomem *base;
int sample_rate; int sample_rate;
struct clk *clk; struct clk *clk;
struct davinci_pcm_dma_params *dma_params[2];
unsigned int codec_fmt; unsigned int codec_fmt;
/* McASP specific data */ /* McASP specific data */
......
...@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data) ...@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
{ {
struct davinci_runtime_data *prtd = substream->runtime->private_data; struct davinci_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
struct edmacc_param p_ram; struct edmacc_param p_ram;
int ret; int ret;
if (!dma_data)
return -ENODEV;
prtd->params = dma_data;
/* Request master DMA channel */ /* Request master DMA channel */
ret = edma_alloc_channel(prtd->params->channel, ret = edma_alloc_channel(prtd->params->channel,
davinci_pcm_dma_irq, substream, davinci_pcm_dma_irq, substream,
...@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) ...@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd; struct davinci_runtime_data *prtd;
int ret = 0; int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data;
struct davinci_pcm_dma_params *params = &pa[substream->stream];
if (!params)
return -ENODEV;
snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
/* ensure that buffer size is a multiple of period size */ /* ensure that buffer size is a multiple of period size */
...@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) ...@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&prtd->lock); spin_lock_init(&prtd->lock);
prtd->params = params;
runtime->private_data = prtd; runtime->private_data = prtd;
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
struct davinci_pcm_dma_params { struct davinci_pcm_dma_params {
char *name; /* stream identifier */
int channel; /* sync dma channel ID */ int channel; /* sync dma channel ID */
unsigned short acnt; unsigned short acnt;
dma_addr_t dma_addr; /* device physical address for DMA */ dma_addr_t dma_addr; /* device physical address for DMA */
......
...@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701 ...@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701
config SND_PXA2XX_SOC_IMOTE2 config SND_PXA2XX_SOC_IMOTE2
tristate "SoC Audio support for IMote 2" tristate "SoC Audio support for IMote 2"
depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
select SND_PXA2XX_SOC_I2S select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8940 select SND_SOC_WM8940
help help
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment