Merge branch 'topic/davinci' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-omap

This commit is contained in:
Mark Brown 2014-05-26 15:31:40 +01:00
commit 35bcc3c20d
7 changed files with 175 additions and 114 deletions

View File

@ -18,7 +18,7 @@ config SND_DAVINCI_SOC_GENERIC_EVM
config SND_AM33XX_SOC_EVM config SND_AM33XX_SOC_EVM
tristate "SoC Audio for the AM33XX chip based boards" tristate "SoC Audio for the AM33XX chip based boards"
depends on SND_DAVINCI_SOC && SOC_AM33XX depends on SND_DAVINCI_SOC && SOC_AM33XX && I2C
select SND_DAVINCI_SOC_GENERIC_EVM select SND_DAVINCI_SOC_GENERIC_EVM
help help
Say Y or M if you want to add support for SoC audio on AM33XX Say Y or M if you want to add support for SoC audio on AM33XX
@ -28,7 +28,7 @@ config SND_AM33XX_SOC_EVM
config SND_DAVINCI_SOC_EVM config SND_DAVINCI_SOC_EVM
tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
depends on SND_DAVINCI_SOC depends on SND_DAVINCI_SOC && I2C
depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
select SND_DAVINCI_SOC_GENERIC_EVM select SND_DAVINCI_SOC_GENERIC_EVM
help help
@ -56,7 +56,7 @@ endchoice
config SND_DM6467_SOC_EVM config SND_DM6467_SOC_EVM
tristate "SoC Audio support for DaVinci DM6467 EVM" tristate "SoC Audio support for DaVinci DM6467 EVM"
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM && I2C
select SND_DAVINCI_SOC_GENERIC_EVM select SND_DAVINCI_SOC_GENERIC_EVM
select SND_SOC_SPDIF select SND_SOC_SPDIF
@ -65,7 +65,7 @@ config SND_DM6467_SOC_EVM
config SND_DA830_SOC_EVM config SND_DA830_SOC_EVM
tristate "SoC Audio support for DA830/OMAP-L137 EVM" tristate "SoC Audio support for DA830/OMAP-L137 EVM"
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM && I2C
select SND_DAVINCI_SOC_GENERIC_EVM select SND_DAVINCI_SOC_GENERIC_EVM
help help
@ -74,7 +74,7 @@ config SND_DA830_SOC_EVM
config SND_DA850_SOC_EVM config SND_DA850_SOC_EVM
tristate "SoC Audio support for DA850/OMAP-L138 EVM" tristate "SoC Audio support for DA850/OMAP-L138 EVM"
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM && I2C
select SND_DAVINCI_SOC_GENERIC_EVM select SND_DAVINCI_SOC_GENERIC_EVM
help help
Say Y if you want to add support for SoC audio on TI Say Y if you want to add support for SoC audio on TI

View File

@ -757,7 +757,6 @@ static int davinci_i2s_remove(struct platform_device *pdev)
struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
davinci_soc_platform_unregister(&pdev->dev);
clk_disable(dev->clk); clk_disable(dev->clk);
clk_put(dev->clk); clk_put(dev->clk);

View File

@ -36,6 +36,9 @@
#include "davinci-pcm.h" #include "davinci-pcm.h"
#include "davinci-mcasp.h" #include "davinci-mcasp.h"
#include "../omap/omap-pcm.h"
#define MCASP_MAX_AFIFO_DEPTH 64
struct davinci_mcasp_context { struct davinci_mcasp_context {
u32 txfmtctl; u32 txfmtctl;
@ -269,25 +272,51 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
{ {
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
int ret = 0; int ret = 0;
u32 data_delay;
bool fs_pol_rising;
bool inv_fs = false;
pm_runtime_get_sync(mcasp->dev); pm_runtime_get_sync(mcasp->dev);
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A:
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
/* 1st data bit occur one ACLK cycle after the frame sync */
data_delay = 1;
break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
case SND_SOC_DAIFMT_AC97: case SND_SOC_DAIFMT_AC97:
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
/* No delay after FS */
data_delay = 0;
break; break;
default: case SND_SOC_DAIFMT_I2S:
/* configure a full-word SYNC pulse (LRCLK) */ /* configure a full-word SYNC pulse (LRCLK) */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
/* 1st data bit occur one ACLK cycle after the frame sync */
/* make 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1;
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); /* FS need to be inverted */
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); inv_fs = true;
break; break;
case SND_SOC_DAIFMT_LEFT_J:
/* configure a full-word SYNC pulse (LRCLK) */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
/* No delay after FS */
data_delay = 0;
break;
default:
ret = -EINVAL;
goto out;
} }
mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay),
FSXDLY(3));
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay),
FSRDLY(3));
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFS:
/* codec is clock and frame slave */ /* codec is clock and frame slave */
@ -325,7 +354,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
mcasp->bclk_master = 0; mcasp->bclk_master = 0;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
@ -334,39 +362,38 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_IB_NF: case SND_SOC_DAIFMT_IB_NF:
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); fs_pol_rising = true;
break; break;
case SND_SOC_DAIFMT_NB_IF: case SND_SOC_DAIFMT_NB_IF:
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); fs_pol_rising = false;
break; break;
case SND_SOC_DAIFMT_IB_IF: case SND_SOC_DAIFMT_IB_IF:
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); fs_pol_rising = false;
break; break;
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_NB_NF:
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); fs_pol_rising = true;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
break; goto out;
}
if (inv_fs)
fs_pol_rising = !fs_pol_rising;
if (fs_pol_rising) {
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
} else {
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
} }
out: out:
pm_runtime_put_sync(mcasp->dev); pm_runtime_put_sync(mcasp->dev);
@ -464,17 +491,19 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
} }
static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
int channels) int period_words, int channels)
{ {
struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream];
struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream];
int i; int i;
u8 tx_ser = 0; u8 tx_ser = 0;
u8 rx_ser = 0; u8 rx_ser = 0;
u8 ser;
u8 slots = mcasp->tdm_slots; u8 slots = mcasp->tdm_slots;
u8 max_active_serializers = (channels + slots - 1) / slots; u8 max_active_serializers = (channels + slots - 1) / slots;
int active_serializers, numevt, n;
u32 reg; u32 reg;
/* Default configuration */ /* Default configuration */
if (mcasp->version != MCASP_VERSION_4) if (mcasp->version < MCASP_VERSION_3)
mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
/* All PINS as McASP */ /* All PINS as McASP */
@ -505,37 +534,71 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
} }
} }
if (stream == SNDRV_PCM_STREAM_PLAYBACK) if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
ser = tx_ser; active_serializers = tx_ser;
else numevt = mcasp->txnumevt;
ser = rx_ser; reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
} else {
active_serializers = rx_ser;
numevt = mcasp->rxnumevt;
reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
}
if (ser < max_active_serializers) { if (active_serializers < max_active_serializers) {
dev_warn(mcasp->dev, "stream has more channels (%d) than are " dev_warn(mcasp->dev, "stream has more channels (%d) than are "
"enabled in mcasp (%d)\n", channels, ser * slots); "enabled in mcasp (%d)\n", channels,
active_serializers * slots);
return -EINVAL; return -EINVAL;
} }
if (mcasp->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { /* AFIFO is not in use */
if (mcasp->txnumevt * tx_ser > 64) if (!numevt) {
mcasp->txnumevt = 1; /* Configure the burst size for platform drivers */
if (active_serializers > 1) {
reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; /*
mcasp_mod_bits(mcasp, reg, tx_ser, NUMDMA_MASK); * If more than one serializers are in use we have one
mcasp_mod_bits(mcasp, reg, ((mcasp->txnumevt * tx_ser) << 8), * DMA request to provide data for all serializers.
NUMEVT_MASK); * For example if three serializers are enabled the DMA
* need to transfer three words per DMA request.
*/
dma_params->fifo_level = active_serializers;
dma_data->maxburst = active_serializers;
} else {
dma_params->fifo_level = 0;
dma_data->maxburst = 0;
}
return 0;
} }
if (mcasp->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { if (period_words % active_serializers) {
if (mcasp->rxnumevt * rx_ser > 64) dev_err(mcasp->dev, "Invalid combination of period words and "
mcasp->rxnumevt = 1; "active serializers: %d, %d\n", period_words,
active_serializers);
reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; return -EINVAL;
mcasp_mod_bits(mcasp, reg, rx_ser, NUMDMA_MASK);
mcasp_mod_bits(mcasp, reg, ((mcasp->rxnumevt * rx_ser) << 8),
NUMEVT_MASK);
} }
/*
* Calculate the optimal AFIFO depth for platform side:
* The number of words for numevt need to be in steps of active
* serializers.
*/
n = numevt % active_serializers;
if (n)
numevt += (active_serializers - n);
while (period_words % numevt && numevt > 0)
numevt -= active_serializers;
if (numevt <= 0)
numevt = active_serializers;
mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK);
mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK);
/* Configure the burst size for platform drivers */
if (numevt == 1)
numevt = 0;
dma_params->fifo_level = numevt;
dma_data->maxburst = numevt;
return 0; return 0;
} }
@ -607,27 +670,24 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
struct davinci_pcm_dma_params *dma_params = struct davinci_pcm_dma_params *dma_params =
&mcasp->dma_params[substream->stream]; &mcasp->dma_params[substream->stream];
struct snd_dmaengine_dai_dma_data *dma_data =
&mcasp->dma_data[substream->stream];
int word_length; int word_length;
u8 fifo_level;
u8 slots = mcasp->tdm_slots;
u8 active_serializers;
int channels = params_channels(params); int channels = params_channels(params);
int period_size = params_period_size(params);
int ret; int ret;
/* If mcasp is BCLK master we need to set BCLK divider */ /* If mcasp is BCLK master we need to set BCLK divider */
if (mcasp->bclk_master) { if (mcasp->bclk_master) {
unsigned int bclk_freq = snd_soc_params_to_bclk(params); unsigned int bclk_freq = snd_soc_params_to_bclk(params);
if (mcasp->sysclk_freq % bclk_freq != 0) { if (mcasp->sysclk_freq % bclk_freq != 0) {
dev_err(mcasp->dev, "Can't produce requred BCLK\n"); dev_err(mcasp->dev, "Can't produce required BCLK\n");
return -EINVAL; return -EINVAL;
} }
davinci_mcasp_set_clkdiv( davinci_mcasp_set_clkdiv(
cpu_dai, 1, mcasp->sysclk_freq / bclk_freq); cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
} }
ret = mcasp_common_hw_param(mcasp, substream->stream, channels); ret = mcasp_common_hw_param(mcasp, substream->stream,
period_size * channels, channels);
if (ret) if (ret)
return ret; return ret;
@ -671,21 +731,11 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
} }
/* Calculate FIFO level */ if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level)
active_serializers = (channels + slots - 1) / slots;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
fifo_level = mcasp->txnumevt * active_serializers;
else
fifo_level = mcasp->rxnumevt * active_serializers;
if (mcasp->version == MCASP_VERSION_2 && !fifo_level)
dma_params->acnt = 4; dma_params->acnt = 4;
else else
dma_params->acnt = dma_params->data_type; dma_params->acnt = dma_params->data_type;
dma_params->fifo_level = fifo_level;
dma_data->maxburst = fifo_level;
davinci_config_channel_size(mcasp, word_length); davinci_config_channel_size(mcasp, word_length);
return 0; return 0;
@ -716,22 +766,7 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
return ret; return ret;
} }
static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
if (mcasp->version == MCASP_VERSION_4)
snd_soc_dai_set_dma_data(dai, substream,
&mcasp->dma_data[substream->stream]);
else
snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params);
return 0;
}
static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { static const 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,
@ -739,6 +774,25 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.set_sysclk = davinci_mcasp_set_sysclk, .set_sysclk = davinci_mcasp_set_sysclk,
}; };
static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
if (mcasp->version == MCASP_VERSION_4) {
/* Using dmaengine PCM */
dai->playback_dma_data =
&mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
dai->capture_dma_data =
&mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
} else {
/* Using davinci-pcm */
dai->playback_dma_data = mcasp->dma_params;
dai->capture_dma_data = mcasp->dma_params;
}
return 0;
}
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int davinci_mcasp_suspend(struct snd_soc_dai *dai) static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
{ {
@ -792,6 +846,7 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
static struct snd_soc_dai_driver davinci_mcasp_dai[] = { static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
{ {
.name = "davinci-mcasp.0", .name = "davinci-mcasp.0",
.probe = davinci_mcasp_dai_probe,
.suspend = davinci_mcasp_suspend, .suspend = davinci_mcasp_suspend,
.resume = davinci_mcasp_resume, .resume = davinci_mcasp_resume,
.playback = { .playback = {
@ -811,6 +866,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
}, },
{ {
.name = "davinci-mcasp.1", .name = "davinci-mcasp.1",
.probe = davinci_mcasp_dai_probe,
.playback = { .playback = {
.channels_min = 1, .channels_min = 1,
.channels_max = 384, .channels_max = 384,
@ -1078,7 +1134,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
if (!mcasp->base) { if (!mcasp->base) {
dev_err(&pdev->dev, "ioremap failed\n"); dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_release_clk; goto err;
} }
mcasp->op_mode = pdata->op_mode; mcasp->op_mode = pdata->op_mode;
@ -1159,25 +1215,37 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
mcasp_reparent_fck(pdev); mcasp_reparent_fck(pdev);
ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, ret = devm_snd_soc_register_component(&pdev->dev,
&davinci_mcasp_dai[pdata->op_mode], 1); &davinci_mcasp_component,
&davinci_mcasp_dai[pdata->op_mode], 1);
if (ret != 0) if (ret != 0)
goto err_release_clk; goto err;
if (mcasp->version != MCASP_VERSION_4) { switch (mcasp->version) {
case MCASP_VERSION_1:
case MCASP_VERSION_2:
case MCASP_VERSION_3:
ret = davinci_soc_platform_register(&pdev->dev); ret = davinci_soc_platform_register(&pdev->dev);
if (ret) { break;
dev_err(&pdev->dev, "register PCM failed: %d\n", ret); case MCASP_VERSION_4:
goto err_unregister_component; ret = omap_pcm_platform_register(&pdev->dev);
} break;
default:
dev_err(&pdev->dev, "Invalid McASP version: %d\n",
mcasp->version);
ret = -EINVAL;
break;
}
if (ret) {
dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
goto err;
} }
return 0; return 0;
err_unregister_component: err:
snd_soc_unregister_component(&pdev->dev);
err_release_clk:
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return ret; return ret;
@ -1185,12 +1253,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 davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
if (mcasp->version != MCASP_VERSION_4)
davinci_soc_platform_unregister(&pdev->dev);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);

View File

@ -283,6 +283,7 @@
*/ */
#define FIFO_ENABLE BIT(16) #define FIFO_ENABLE BIT(16)
#define NUMEVT_MASK (0xFF << 8) #define NUMEVT_MASK (0xFF << 8)
#define NUMEVT(x) (((x) & 0xFF) << 8)
#define NUMDMA_MASK (0xFF) #define NUMDMA_MASK (0xFF)
#endif /* DAVINCI_MCASP_H */ #endif /* DAVINCI_MCASP_H */

View File

@ -852,16 +852,10 @@ static struct snd_soc_platform_driver davinci_soc_platform = {
int davinci_soc_platform_register(struct device *dev) int davinci_soc_platform_register(struct device *dev)
{ {
return snd_soc_register_platform(dev, &davinci_soc_platform); return devm_snd_soc_register_platform(dev, &davinci_soc_platform);
} }
EXPORT_SYMBOL_GPL(davinci_soc_platform_register); EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
void davinci_soc_platform_unregister(struct device *dev)
{
snd_soc_unregister_platform(dev);
}
EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister);
MODULE_AUTHOR("Vladimir Barinov"); MODULE_AUTHOR("Vladimir Barinov");
MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -29,7 +29,13 @@ struct davinci_pcm_dma_params {
unsigned int fifo_level; unsigned int fifo_level;
}; };
#if IS_ENABLED(CONFIG_SND_DAVINCI_SOC)
int davinci_soc_platform_register(struct device *dev); int davinci_soc_platform_register(struct device *dev);
void davinci_soc_platform_unregister(struct device *dev); #else
static inline int davinci_soc_platform_register(struct device *dev)
{
return 0;
}
#endif /* CONFIG_SND_DAVINCI_SOC */
#endif #endif

View File

@ -258,7 +258,6 @@ static int davinci_vcif_probe(struct platform_device *pdev)
static int davinci_vcif_remove(struct platform_device *pdev) static int davinci_vcif_remove(struct platform_device *pdev)
{ {
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
davinci_soc_platform_unregister(&pdev->dev);
return 0; return 0;
} }