Merge branch 'fix/davinci' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into HEAD

This commit is contained in:
Mark Brown 2014-01-31 16:38:20 +00:00
commit 61d384aed4
2 changed files with 37 additions and 43 deletions

View file

@ -453,6 +453,7 @@ static struct platform_driver davinci_evm_driver = {
.driver = { .driver = {
.name = "davinci_evm", .name = "davinci_evm",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
.of_match_table = of_match_ptr(davinci_evm_dt_ids), .of_match_table = of_match_ptr(davinci_evm_dt_ids),
}, },
}; };

View file

@ -266,7 +266,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt) unsigned int fmt)
{ {
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;
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_B: case SND_SOC_DAIFMT_DSP_B:
case SND_SOC_DAIFMT_AC97: case SND_SOC_DAIFMT_AC97:
@ -323,7 +325,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
goto out;
} }
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@ -360,10 +363,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
break;
} }
out:
return 0; pm_runtime_put_sync(mcasp->dev);
return ret;
} }
static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
@ -456,7 +461,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
return 0; return 0;
} }
static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
int channels) int channels)
{ {
int i; int i;
@ -532,12 +537,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream,
return 0; return 0;
} }
static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
{ {
int i, active_slots; int i, active_slots;
u32 mask = 0; u32 mask = 0;
u32 busel = 0; u32 busel = 0;
if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) {
dev_err(mcasp->dev, "tdm slot %d not supported\n",
mcasp->tdm_slots);
return -EINVAL;
}
active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots;
for (i = 0; i < active_slots; i++) for (i = 0; i < active_slots; i++)
mask |= (1 << i); mask |= (1 << i);
@ -547,35 +558,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream)
if (!mcasp->dat_port) if (!mcasp->dat_port)
busel = TXSEL; busel = TXSEL;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
/* bit stream is MSB first with no delay */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
/* DSP_B mode */ mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF));
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
else FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF));
printk(KERN_ERR "playback tdm slot %d not supported\n",
mcasp->tdm_slots);
} else {
/* bit stream is MSB first with no delay */
/* DSP_B mode */
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) return 0;
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF));
else
printk(KERN_ERR "capture tdm slot %d not supported\n",
mcasp->tdm_slots);
}
} }
/* S/PDIF */ /* S/PDIF */
static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
{ {
/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
and LSB first */ and LSB first */
@ -597,6 +594,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp)
/* Enable the DIT */ /* Enable the DIT */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
return 0;
} }
static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
@ -613,6 +612,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
u8 slots = mcasp->tdm_slots; u8 slots = mcasp->tdm_slots;
u8 active_serializers; u8 active_serializers;
int channels; int channels;
int ret;
struct snd_interval *pcm_channels = hw_param_interval(params, struct snd_interval *pcm_channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS); SNDRV_PCM_HW_PARAM_CHANNELS);
@ -631,7 +631,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
active_serializers = (channels + slots - 1) / slots; active_serializers = (channels + slots - 1) / slots;
if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL)
return -EINVAL; return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
fifo_level = mcasp->txnumevt * active_serializers; fifo_level = mcasp->txnumevt * active_serializers;
@ -639,9 +639,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
fifo_level = mcasp->rxnumevt * active_serializers; fifo_level = mcasp->rxnumevt * active_serializers;
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
davinci_hw_dit_param(mcasp); ret = mcasp_dit_hw_param(mcasp);
else else
davinci_hw_param(mcasp, substream->stream); ret = mcasp_i2s_hw_param(mcasp, substream->stream);
if (ret)
return ret;
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_U8: case SNDRV_PCM_FORMAT_U8:
@ -698,19 +701,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
ret = pm_runtime_get_sync(mcasp->dev);
if (IS_ERR_VALUE(ret))
dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n");
davinci_mcasp_start(mcasp, substream->stream); davinci_mcasp_start(mcasp, substream->stream);
break; break;
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
davinci_mcasp_stop(mcasp, substream->stream);
ret = pm_runtime_put_sync(mcasp->dev);
if (IS_ERR_VALUE(ret))
dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n");
break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
davinci_mcasp_stop(mcasp, substream->stream); davinci_mcasp_stop(mcasp, substream->stream);