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

Commit b87704ce authored by Rongjun Ying's avatar Rongjun Ying Committed by Mark Brown
Browse files

ASoC: sirf: Move the tx rx enable from port to codec, that will not need register sharing



The port driver only used to register component and dmaengine pcm.

Signed-off-by: default avatarRongjun Ying <rongjun.ying@csr.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent c9eaa447
Loading
Loading
Loading
Loading
+66 −8
Original line number Diff line number Diff line
@@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = {
	{"Mic input mode mux", "Differential", "MICIN1"},
};

static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec)
{
	regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
		AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
	regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
		AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
	regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
	regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
	regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
		AUDIO_FIFO_START, AUDIO_FIFO_START);
	regmap_update_bits(sirf_audio_codec->regmap,
		AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE);
}

static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec)
{
	regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
	regmap_update_bits(sirf_audio_codec->regmap,
		AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE);
}

static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec,
	int channels)
{
	regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
		AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
	regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
		AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
	regmap_write(sirf_audio_codec->regmap,
		AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
	regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
	regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
		AUDIO_FIFO_START, AUDIO_FIFO_START);
	if (channels == 1)
		regmap_update_bits(sirf_audio_codec->regmap,
			AUDIO_PORT_IC_CODEC_RX_CTRL,
			IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
	else
		regmap_update_bits(sirf_audio_codec->regmap,
			AUDIO_PORT_IC_CODEC_RX_CTRL,
			IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
}

static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec)
{
	regmap_update_bits(sirf_audio_codec->regmap,
			AUDIO_PORT_IC_CODEC_RX_CTRL,
			IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
}

static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
		int cmd,
		struct snd_soc_dai *dai)
{
	int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
	struct snd_soc_codec *codec = dai->codec;
	u32 val = 0;
	struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
	int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;

	/*
	 * This is a workaround, When stop playback,
@@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if (playback) {
			snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
				IC_HSLEN | IC_HSREN, 0);
			sirf_audio_codec_tx_disable(sirf_audio_codec);
		} else
			sirf_audio_codec_rx_disable(sirf_audio_codec);
		break;
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (playback)
			val = IC_HSLEN | IC_HSREN;
		if (playback) {
			sirf_audio_codec_tx_enable(sirf_audio_codec);
			snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
				IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
		} else
			sirf_audio_codec_rx_enable(sirf_audio_codec,
				substream->runtime->channels);
		break;
	default:
		return -EINVAL;
	}

	if (playback)
		snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
			IC_HSLEN | IC_HSREN, val);
	return 0;
}

@@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.max_register = AUDIO_IC_CODEC_CTRL3,
	.max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
	.cache_type = REGCACHE_NONE,
};

+50 −0
Original line number Diff line number Diff line
@@ -72,4 +72,54 @@
#define IC_RXPGAR		0x7B
#define IC_RXPGAL		0x7B

#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK     0x3F
#define AUDIO_PORT_TX_FIFO_SC_OFFSET    0
#define AUDIO_PORT_TX_FIFO_LC_OFFSET    10
#define AUDIO_PORT_TX_FIFO_HC_OFFSET    20

#define TX_FIFO_SC(x)           (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_TX_FIFO_SC_OFFSET)
#define TX_FIFO_LC(x)           (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_TX_FIFO_LC_OFFSET)
#define TX_FIFO_HC(x)           (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_TX_FIFO_HC_OFFSET)

#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK     0x0F
#define AUDIO_PORT_RX_FIFO_SC_OFFSET    0
#define AUDIO_PORT_RX_FIFO_LC_OFFSET    10
#define AUDIO_PORT_RX_FIFO_HC_OFFSET    20

#define RX_FIFO_SC(x)           (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_RX_FIFO_SC_OFFSET)
#define RX_FIFO_LC(x)           (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_RX_FIFO_LC_OFFSET)
#define RX_FIFO_HC(x)           (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_RX_FIFO_HC_OFFSET)
#define AUDIO_PORT_IC_CODEC_TX_CTRL		(0x00F4)
#define AUDIO_PORT_IC_CODEC_RX_CTRL		(0x00F8)

#define AUDIO_PORT_IC_TXFIFO_OP			(0x00FC)
#define AUDIO_PORT_IC_TXFIFO_LEV_CHK		(0x0100)
#define AUDIO_PORT_IC_TXFIFO_STS		(0x0104)
#define AUDIO_PORT_IC_TXFIFO_INT		(0x0108)
#define AUDIO_PORT_IC_TXFIFO_INT_MSK		(0x010C)

#define AUDIO_PORT_IC_RXFIFO_OP			(0x0110)
#define AUDIO_PORT_IC_RXFIFO_LEV_CHK		(0x0114)
#define AUDIO_PORT_IC_RXFIFO_STS		(0x0118)
#define AUDIO_PORT_IC_RXFIFO_INT		(0x011C)
#define AUDIO_PORT_IC_RXFIFO_INT_MSK		(0x0120)

#define AUDIO_FIFO_START		(1 << 0)
#define AUDIO_FIFO_RESET		(1 << 1)

#define AUDIO_FIFO_FULL			(1 << 0)
#define AUDIO_FIFO_EMPTY		(1 << 1)
#define AUDIO_FIFO_OFLOW		(1 << 2)
#define AUDIO_FIFO_UFLOW		(1 << 3)

#define IC_TX_ENABLE		(0x03)
#define IC_RX_ENABLE_MONO	(0x01)
#define IC_RX_ENABLE_STEREO	(0x03)

#endif /*__SIRF_AUDIO_CODEC_H*/
+0 −107
Original line number Diff line number Diff line
@@ -6,60 +6,15 @@
 * Licensed under GPLv2 or later.
 */
#include <linux/module.h>
#include <linux/io.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>

#include "sirf-audio-port.h"

struct sirf_audio_port {
	struct regmap *regmap;
	struct snd_dmaengine_dai_dma_data playback_dma_data;
	struct snd_dmaengine_dai_dma_data capture_dma_data;
};

static void sirf_audio_port_tx_enable(struct sirf_audio_port *port)
{
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP,
		AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
	regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
	regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP,
		AUDIO_FIFO_START, AUDIO_FIFO_START);
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL,
		IC_TX_ENABLE, IC_TX_ENABLE);
}

static void sirf_audio_port_tx_disable(struct sirf_audio_port *port)
{
	regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL,
		IC_TX_ENABLE, ~IC_TX_ENABLE);
}

static void sirf_audio_port_rx_enable(struct sirf_audio_port *port,
	int channels)
{
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP,
		AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
	regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
	regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP,
		AUDIO_FIFO_START, AUDIO_FIFO_START);
	if (channels == 1)
		regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
			IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
	else
		regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
			IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
}

static void sirf_audio_port_rx_disable(struct sirf_audio_port *port)
{
	regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
			IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
}

static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
{
@@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
	return 0;
}

static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd,
	struct snd_soc_dai *dai)
{
	struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai);
	int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if (playback)
			sirf_audio_port_tx_disable(port);
		else
			sirf_audio_port_rx_disable(port);
		break;
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (playback)
			sirf_audio_port_tx_enable(port);
		else
			sirf_audio_port_rx_enable(port,
				substream->runtime->channels);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = {
	.trigger = sirf_audio_port_trigger,
};

static struct snd_soc_dai_driver sirf_audio_port_dai = {
	.probe = sirf_audio_port_dai_probe,
	.name = "sirf-audio-port",
@@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = {
		.rates = SNDRV_PCM_RATE_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,
	},
	.ops = &sirf_audio_port_dai_ops,
};

static const struct snd_soc_component_driver sirf_audio_port_component = {
	.name       = "sirf-audio-port",
};

static const struct regmap_config sirf_audio_port_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
	.cache_type = REGCACHE_NONE,
};

static int sirf_audio_port_probe(struct platform_device *pdev)
{
	int ret;
	struct sirf_audio_port *port;
	void __iomem *base;
	struct resource *mem_res;

	port = devm_kzalloc(&pdev->dev,
			sizeof(struct sirf_audio_port), GFP_KERNEL);
	if (!port)
		return -ENOMEM;

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem_res) {
		dev_err(&pdev->dev, "no mem resource?\n");
		return -ENODEV;
	}

	base = devm_ioremap(&pdev->dev, mem_res->start,
			resource_size(mem_res));
	if (base == NULL)
		return -ENOMEM;

	port->regmap = devm_regmap_init_mmio(&pdev->dev, base,
					    &sirf_audio_port_regmap_config);
	if (IS_ERR(port->regmap))
		return PTR_ERR(port->regmap);

	ret = devm_snd_soc_register_component(&pdev->dev,
			&sirf_audio_port_component, &sirf_audio_port_dai, 1);
	if (ret)

sound/soc/sirf/sirf-audio-port.h

deleted100644 → 0
+0 −62
Original line number Diff line number Diff line
/*
 * SiRF Audio port controllers define
 *
 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
 *
 * Licensed under GPLv2 or later.
 */

#ifndef _SIRF_AUDIO_PORT_H
#define _SIRF_AUDIO_PORT_H

#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK     0x3F
#define AUDIO_PORT_TX_FIFO_SC_OFFSET    0
#define AUDIO_PORT_TX_FIFO_LC_OFFSET    10
#define AUDIO_PORT_TX_FIFO_HC_OFFSET    20

#define TX_FIFO_SC(x)           (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_TX_FIFO_SC_OFFSET)
#define TX_FIFO_LC(x)           (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_TX_FIFO_LC_OFFSET)
#define TX_FIFO_HC(x)           (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_TX_FIFO_HC_OFFSET)

#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK     0x0F
#define AUDIO_PORT_RX_FIFO_SC_OFFSET    0
#define AUDIO_PORT_RX_FIFO_LC_OFFSET    10
#define AUDIO_PORT_RX_FIFO_HC_OFFSET    20

#define RX_FIFO_SC(x)           (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_RX_FIFO_SC_OFFSET)
#define RX_FIFO_LC(x)           (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_RX_FIFO_LC_OFFSET)
#define RX_FIFO_HC(x)           (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
				<< AUDIO_PORT_RX_FIFO_HC_OFFSET)
#define AUDIO_PORT_IC_CODEC_TX_CTRL		(0x00F4)
#define AUDIO_PORT_IC_CODEC_RX_CTRL		(0x00F8)

#define AUDIO_PORT_IC_TXFIFO_OP			(0x00FC)
#define AUDIO_PORT_IC_TXFIFO_LEV_CHK		(0x0100)
#define AUDIO_PORT_IC_TXFIFO_STS		(0x0104)
#define AUDIO_PORT_IC_TXFIFO_INT		(0x0108)
#define AUDIO_PORT_IC_TXFIFO_INT_MSK		(0x010C)

#define AUDIO_PORT_IC_RXFIFO_OP			(0x0110)
#define AUDIO_PORT_IC_RXFIFO_LEV_CHK		(0x0114)
#define AUDIO_PORT_IC_RXFIFO_STS		(0x0118)
#define AUDIO_PORT_IC_RXFIFO_INT		(0x011C)
#define AUDIO_PORT_IC_RXFIFO_INT_MSK		(0x0120)

#define AUDIO_FIFO_START		(1 << 0)
#define AUDIO_FIFO_RESET		(1 << 1)

#define AUDIO_FIFO_FULL			(1 << 0)
#define AUDIO_FIFO_EMPTY		(1 << 1)
#define AUDIO_FIFO_OFLOW		(1 << 2)
#define AUDIO_FIFO_UFLOW		(1 << 3)

#define IC_TX_ENABLE		(0x03)
#define IC_RX_ENABLE_MONO	(0x01)
#define IC_RX_ENABLE_STEREO	(0x03)

#endif /*__SIRF_AUDIO_PORT_H*/