diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2009-11-07 03:34:43 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-11-07 07:40:09 -0500 |
commit | c939e5c82142978d9d534aca34187a8489fd13f3 (patch) | |
tree | 5c0ea0815d98c71371feb25f76e852f2123e0d95 /sound/soc/fsl | |
parent | 1d8222e8df07ce4f86fb7fa80b02bdee03b57985 (diff) |
ASoC/mpc5200: fix enable/disable of AC97 slots
The MPC5200 AC97 driver is disabling the slots when a stop
trigger is received, but not reenabling them if the stream
is started again without processing the hw_params again.
This patch fixes the problem by caching the slot enable bit
settings calculated at hw_params time so that they can be
reapplied every time the start trigger is received.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.h | 4 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_psc_ac97.c | 39 |
2 files changed, 25 insertions, 18 deletions
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 956d6a5f5a8c..22208b373fb9 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h | |||
@@ -16,6 +16,7 @@ | |||
16 | * @period_end: physical address of end of DMA region | 16 | * @period_end: physical address of end of DMA region |
17 | * @period_next_pt: physical address of next DMA buffer to enqueue | 17 | * @period_next_pt: physical address of next DMA buffer to enqueue |
18 | * @period_bytes: size of DMA period in bytes | 18 | * @period_bytes: size of DMA period in bytes |
19 | * @ac97_slot_bits: Enable bits for turning on the correct AC97 slot | ||
19 | */ | 20 | */ |
20 | struct psc_dma_stream { | 21 | struct psc_dma_stream { |
21 | struct snd_pcm_runtime *runtime; | 22 | struct snd_pcm_runtime *runtime; |
@@ -28,6 +29,9 @@ struct psc_dma_stream { | |||
28 | int period_current; | 29 | int period_current; |
29 | int period_bytes; | 30 | int period_bytes; |
30 | int period_count; | 31 | int period_count; |
32 | |||
33 | /* AC97 state */ | ||
34 | u32 ac97_slot_bits; | ||
31 | }; | 35 | }; |
32 | 36 | ||
33 | /** | 37 | /** |
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index c4ae3e096bb9..3dbc7f7cd7b9 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c | |||
@@ -130,6 +130,7 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream, | |||
130 | struct snd_soc_dai *cpu_dai) | 130 | struct snd_soc_dai *cpu_dai) |
131 | { | 131 | { |
132 | struct psc_dma *psc_dma = cpu_dai->private_data; | 132 | struct psc_dma *psc_dma = cpu_dai->private_data; |
133 | struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); | ||
133 | 134 | ||
134 | dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" | 135 | dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" |
135 | " periods=%i buffer_size=%i buffer_bytes=%i channels=%i" | 136 | " periods=%i buffer_size=%i buffer_bytes=%i channels=%i" |
@@ -140,20 +141,10 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream, | |||
140 | params_channels(params), params_rate(params), | 141 | params_channels(params), params_rate(params), |
141 | params_format(params)); | 142 | params_format(params)); |
142 | 143 | ||
143 | 144 | /* Determine the set of enable bits to turn on */ | |
144 | if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { | 145 | s->ac97_slot_bits = (params_channels(params) == 1) ? 0x100 : 0x300; |
145 | if (params_channels(params) == 1) | 146 | if (substream->pstr->stream != SNDRV_PCM_STREAM_CAPTURE) |
146 | psc_dma->slots |= 0x00000100; | 147 | s->ac97_slot_bits <<= 16; |
147 | else | ||
148 | psc_dma->slots |= 0x00000300; | ||
149 | } else { | ||
150 | if (params_channels(params) == 1) | ||
151 | psc_dma->slots |= 0x01000000; | ||
152 | else | ||
153 | psc_dma->slots |= 0x03000000; | ||
154 | } | ||
155 | out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); | ||
156 | |||
157 | return 0; | 148 | return 0; |
158 | } | 149 | } |
159 | 150 | ||
@@ -163,6 +154,8 @@ static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream, | |||
163 | { | 154 | { |
164 | struct psc_dma *psc_dma = cpu_dai->private_data; | 155 | struct psc_dma *psc_dma = cpu_dai->private_data; |
165 | 156 | ||
157 | dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream); | ||
158 | |||
166 | if (params_channels(params) == 1) | 159 | if (params_channels(params) == 1) |
167 | out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000); | 160 | out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000); |
168 | else | 161 | else |
@@ -176,14 +169,24 @@ static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd, | |||
176 | { | 169 | { |
177 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 170 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
178 | struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; | 171 | struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; |
172 | struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); | ||
179 | 173 | ||
180 | switch (cmd) { | 174 | switch (cmd) { |
175 | case SNDRV_PCM_TRIGGER_START: | ||
176 | dev_dbg(psc_dma->dev, "AC97 START: stream=%i\n", | ||
177 | substream->pstr->stream); | ||
178 | |||
179 | /* Set the slot enable bits */ | ||
180 | psc_dma->slots |= s->ac97_slot_bits; | ||
181 | out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); | ||
182 | break; | ||
183 | |||
181 | case SNDRV_PCM_TRIGGER_STOP: | 184 | case SNDRV_PCM_TRIGGER_STOP: |
182 | if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) | 185 | dev_dbg(psc_dma->dev, "AC97 STOP: stream=%i\n", |
183 | psc_dma->slots &= 0xFFFF0000; | 186 | substream->pstr->stream); |
184 | else | ||
185 | psc_dma->slots &= 0x0000FFFF; | ||
186 | 187 | ||
188 | /* Clear the slot enable bits */ | ||
189 | psc_dma->slots &= ~(s->ac97_slot_bits); | ||
187 | out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); | 190 | out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); |
188 | break; | 191 | break; |
189 | } | 192 | } |