Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c939e5c8 authored by Grant Likely's avatar Grant Likely Committed by Mark Brown
Browse files

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: default avatarGrant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 1d8222e8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
 * @period_end:		physical address of end of DMA region
 * @period_next_pt:	physical address of next DMA buffer to enqueue
 * @period_bytes:	size of DMA period in bytes
 * @ac97_slot_bits:	Enable bits for turning on the correct AC97 slot
 */
struct psc_dma_stream {
	struct snd_pcm_runtime *runtime;
@@ -28,6 +29,9 @@ struct psc_dma_stream {
	int period_current;
	int period_bytes;
	int period_count;

	/* AC97 state */
	u32 ac97_slot_bits;
};

/**
+21 −18
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *cpu_dai)
{
	struct psc_dma *psc_dma = cpu_dai->private_data;
	struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);

	dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
		" 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,
		params_channels(params), params_rate(params),
		params_format(params));


	if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
		if (params_channels(params) == 1)
			psc_dma->slots |= 0x00000100;
		else
			psc_dma->slots |= 0x00000300;
	} else {
		if (params_channels(params) == 1)
			psc_dma->slots |= 0x01000000;
		else
			psc_dma->slots |= 0x03000000;
	}
	out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);

	/* Determine the set of enable bits to turn on */
	s->ac97_slot_bits = (params_channels(params) == 1) ? 0x100 : 0x300;
	if (substream->pstr->stream != SNDRV_PCM_STREAM_CAPTURE)
		s->ac97_slot_bits <<= 16;
	return 0;
}

@@ -163,6 +154,8 @@ static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
{
	struct psc_dma *psc_dma = cpu_dai->private_data;

	dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream);

	if (params_channels(params) == 1)
		out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000);
	else
@@ -176,14 +169,24 @@ static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
	struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		dev_dbg(psc_dma->dev, "AC97 START: stream=%i\n",
			substream->pstr->stream);

		/* Set the slot enable bits */
		psc_dma->slots |= s->ac97_slot_bits;
		out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
		if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
			psc_dma->slots &= 0xFFFF0000;
		else
			psc_dma->slots &= 0x0000FFFF;
		dev_dbg(psc_dma->dev, "AC97 STOP: stream=%i\n",
			substream->pstr->stream);

		/* Clear the slot enable bits */
		psc_dma->slots &= ~(s->ac97_slot_bits);
		out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
		break;
	}