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

Commit 2c66cb99 authored by Barry Song's avatar Barry Song Committed by Mark Brown
Browse files

ASoC: Blackfin: push down SPORT settings from global variables



Now that we have multi-component support, take the time to unify the
SPORT implementations a bit and make the setup dynamic.  This kills
off the global sport_handle which was shared across all the Blackfin
machine drivers.  The pin management aspect is off loaded to platform
resources, and now multiple SPORTs can be instantiated simultaneously.

Signed-off-by: default avatarBarry Song <barry.song@analog.com>
Signed-off-by: default avatarScott Jiang <scott.jiang@analog.com>
Signed-off-by: default avatarMike Frysinger <vapier@gentoo.org>
Acked-by: default avatarLiam Girdwood <lrg@ti.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent bfe4ee0a
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -243,6 +243,9 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)

static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int ret;

@@ -314,6 +317,9 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {

static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
	struct snd_dma_buffer *buf = &substream->dma_buffer;
	size_t size = bf5xx_pcm_hardware.buffer_bytes_max
@@ -377,6 +383,9 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
	struct snd_dma_buffer *buf;
	int stream;
#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
	size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
		sizeof(struct ac97_frame) / 4;
#endif
@@ -405,8 +414,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
	}
#endif
	}
	if (sport_handle)
		sport_done(sport_handle);
}

static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
+53 −113
Original line number Diff line number Diff line
@@ -41,48 +41,7 @@
 *		anomaly does not affect blackfin sound drivers.
*/

static int *cmd_count;
static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;

#define SPORT_REQ(x) \
	[x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
	       P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
static u16 sport_req[][7] = {
#ifdef SPORT0_TCR1
	SPORT_REQ(0),
#endif
#ifdef SPORT1_TCR1
	SPORT_REQ(1),
#endif
#ifdef SPORT2_TCR1
	SPORT_REQ(2),
#endif
#ifdef SPORT3_TCR1
	SPORT_REQ(3),
#endif
};

#define SPORT_PARAMS(x) \
	[x] = { \
		.dma_rx_chan = CH_SPORT##x##_RX, \
		.dma_tx_chan = CH_SPORT##x##_TX, \
		.err_irq     = IRQ_SPORT##x##_ERROR, \
		.regs        = (struct sport_register *)SPORT##x##_TCR1, \
	}
static struct sport_param sport_params[4] = {
#ifdef SPORT0_TCR1
	SPORT_PARAMS(0),
#endif
#ifdef SPORT1_TCR1
	SPORT_PARAMS(1),
#endif
#ifdef SPORT2_TCR1
	SPORT_PARAMS(2),
#endif
#ifdef SPORT3_TCR1
	SPORT_PARAMS(3),
#endif
};
static struct sport_device *ac97_sport_handle;

void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
		size_t count, unsigned int chan_mask)
@@ -140,7 +99,8 @@ static unsigned int sport_tx_curr_frag(struct sport_device *sport)

static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
{
	struct sport_device *sport = sport_handle;
	struct sport_device *sport = ac97_sport_handle;
	int *cmd_count = sport->private_data;
	int nextfrag = sport_tx_curr_frag(sport);
	struct ac97_frame *nextwrite;

@@ -161,6 +121,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
	unsigned short reg)
{
	struct sport_device *sport_handle = ac97_sport_handle;
	struct ac97_frame out_frame[2], in_frame[2];

	pr_debug("%s enter 0x%x\n", __func__, reg);
@@ -185,6 +146,8 @@ static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
	unsigned short val)
{
	struct sport_device *sport_handle = ac97_sport_handle;

	pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);

	if (sport_handle->tx_run) {
@@ -203,28 +166,19 @@ void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,

static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
{
#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \
 (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1))

#define CONCAT(a, b, c) a ## b ## c
#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS)

	u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM);
	u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM));
	struct sport_device *sport_handle = ac97_sport_handle;
	u16 gpio = P_IDENT(sport_handle->pin_req[3]);

	pr_debug("%s enter\n", __func__);

	peripheral_free(per);
	peripheral_free_list(sport_handle->pin_req);
	gpio_request(gpio, "bf5xx-ac97");
	gpio_direction_output(gpio, 1);
	udelay(2);
	gpio_set_value(gpio, 0);
	udelay(1);
	gpio_free(gpio);
	peripheral_request(per, "soc-audio");
#else
	pr_info("%s: Not implemented\n", __func__);
#endif
	peripheral_request_list(sport_handle->pin_req, "soc-audio");
}

static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
@@ -306,18 +260,32 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
#define bf5xx_ac97_resume	NULL
#endif

static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
{
	int ret = 0;
	cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
	if (cmd_count == NULL)
		return -ENOMEM;
static struct snd_soc_dai_driver bfin_ac97_dai = {
	.ac97_control = 1,
	.suspend = bf5xx_ac97_suspend,
	.resume = bf5xx_ac97_resume,
	.playback = {
		.stream_name = "AC97 Playback",
		.channels_min = 2,
#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
		.channels_max = 6,
#else
		.channels_max = 2,
#endif
		.rates = SNDRV_PCM_RATE_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
	.capture = {
		.stream_name = "AC97 Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
};

	if (peripheral_request_list(sport_req[sport_num], "soc-audio")) {
		pr_err("Requesting Peripherals failed\n");
		ret =  -EFAULT;
		goto peripheral_err;
	}
static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev)
{
	struct sport_device *sport_handle;
	int ret;

#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
	/* Request PB3 as reset pin */
@@ -329,12 +297,14 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
	}
	gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
#endif
	sport_handle = sport_init(&sport_params[sport_num], 2, \
			sizeof(struct ac97_frame), NULL);

	sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
		PAGE_SIZE);
	if (!sport_handle) {
		ret = -ENODEV;
		goto sport_err;
	}

	/*SPORT works in TDM mode to simulate AC97 transfers*/
#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
	ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
@@ -361,67 +331,37 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
		goto sport_config_err;
	}

	ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
	if (ret) {
		pr_err("Failed to register DAI: %d\n", ret);
		goto sport_config_err;
	}

	ac97_sport_handle = sport_handle;

	return 0;

sport_config_err:
	kfree(sport_handle);
	sport_done(sport_handle);
sport_err:
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
	gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
gpio_err:
#endif
	peripheral_free_list(sport_req[sport_num]);
peripheral_err:
	free_page((unsigned long)cmd_count);
	cmd_count = NULL;

	return ret;
}

static int bf5xx_ac97_remove(struct snd_soc_dai *dai)
static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
{
	free_page((unsigned long)cmd_count);
	cmd_count = NULL;
	peripheral_free_list(sport_req[sport_num]);
	struct sport_device *sport_handle = platform_get_drvdata(pdev);

	snd_soc_unregister_dai(&pdev->dev);
	sport_done(sport_handle);
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
	gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
#endif
	return 0;
}

struct snd_soc_dai_driver bfin_ac97_dai = {
	.ac97_control = 1,
	.probe = bf5xx_ac97_probe,
	.remove = bf5xx_ac97_remove,
	.suspend = bf5xx_ac97_suspend,
	.resume = bf5xx_ac97_resume,
	.playback = {
		.stream_name = "AC97 Playback",
		.channels_min = 2,
#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
		.channels_max = 6,
#else
		.channels_max = 2,
#endif
		.rates = SNDRV_PCM_RATE_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
	.capture = {
		.stream_name = "AC97 Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
};
EXPORT_SYMBOL_GPL(bfin_ac97_dai);

static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
{
	return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
}

static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
{
	snd_soc_unregister_dai(&pdev->dev);
	return 0;
}

+20 −20
Original line number Diff line number Diff line
@@ -29,22 +29,12 @@
#include <asm/portmux.h>

#include "../codecs/ad1836.h"
#include "bf5xx-sport.h"

#include "bf5xx-tdm-pcm.h"
#include "bf5xx-tdm.h"

static struct snd_soc_card bf5xx_ad1836;

static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
	return 0;
}

static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
@@ -75,23 +65,33 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
}

static struct snd_soc_ops bf5xx_ad1836_ops = {
	.startup = bf5xx_ad1836_startup,
	.hw_params = bf5xx_ad1836_hw_params,
};

static struct snd_soc_dai_link bf5xx_ad1836_dai = {
static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
	{
		.name = "ad1836",
		.stream_name = "AD1836",
		.cpu_dai_name = "bfin-tdm.0",
		.codec_dai_name = "ad1836-hifi",
		.platform_name = "bfin-tdm-pcm-audio",
		.codec_name = "ad1836.0",
		.ops = &bf5xx_ad1836_ops,
	},
	{
		.name = "ad1836",
		.stream_name = "AD1836",
	.cpu_dai_name = "bfin-tdm",
		.cpu_dai_name = "bfin-tdm.1",
		.codec_dai_name = "ad1836-hifi",
		.platform_name = "bfin-tdm-pcm-audio",
		.codec_name = "ad1836.0",
		.ops = &bf5xx_ad1836_ops,
	},
};

static struct snd_soc_card bf5xx_ad1836 = {
	.name = "bfin-ad1836",
	.dai_link = &bf5xx_ad1836_dai,
	.dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
	.num_links = 1,
};

+20 −20
Original line number Diff line number Diff line
@@ -38,22 +38,12 @@
#include <asm/portmux.h>

#include "../codecs/ad193x.h"
#include "bf5xx-sport.h"

#include "bf5xx-tdm-pcm.h"
#include "bf5xx-tdm.h"

static struct snd_soc_card bf5xx_ad193x;

static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
	return 0;
}

static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
@@ -103,23 +93,33 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
}

static struct snd_soc_ops bf5xx_ad193x_ops = {
	.startup = bf5xx_ad193x_startup,
	.hw_params = bf5xx_ad193x_hw_params,
};

static struct snd_soc_dai_link bf5xx_ad193x_dai = {
static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
	{
		.name = "ad193x",
		.stream_name = "AD193X",
		.cpu_dai_name = "bfin-tdm.0",
		.codec_dai_name ="ad193x-hifi",
		.platform_name = "bfin-tdm-pcm-audio",
		.codec_name = "ad193x.5",
		.ops = &bf5xx_ad193x_ops,
	},
	{
		.name = "ad193x",
		.stream_name = "AD193X",
	.cpu_dai_name = "bfin-tdm",
		.cpu_dai_name = "bfin-tdm.1",
		.codec_dai_name ="ad193x-hifi",
		.platform_name = "bfin-tdm-pcm-audio",
		.codec_name = "ad193x.5",
		.ops = &bf5xx_ad193x_ops,
	},
};

static struct snd_soc_card bf5xx_ad193x = {
	.name = "bfin-ad193x",
	.dai_link = &bf5xx_ad193x_dai,
	.dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
	.num_links = 1,
};

+19 −24
Original line number Diff line number Diff line
@@ -47,39 +47,34 @@
#include <asm/portmux.h>

#include "../codecs/ad1980.h"
#include "bf5xx-sport.h"

#include "bf5xx-ac97-pcm.h"
#include "bf5xx-ac97.h"

static struct snd_soc_card bf5xx_board;

static int bf5xx_board_startup(struct snd_pcm_substream *substream)
static struct snd_soc_dai_link bf5xx_board_dai[] = {
	{
		.name = "AC97",
		.stream_name = "AC97 HiFi",
		.cpu_dai_name = "bfin-ac97.0",
		.codec_dai_name = "ad1980-hifi",
		.platform_name = "bfin-ac97-pcm-audio",
		.codec_name = "ad1980",
	},
	{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	pr_debug("%s enter\n", __func__);
	snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
	return 0;
}

static struct snd_soc_ops bf5xx_board_ops = {
	.startup = bf5xx_board_startup,
};

static struct snd_soc_dai_link bf5xx_board_dai = {
		.name = "AC97",
		.stream_name = "AC97 HiFi",
	.cpu_dai_name = "bfin-ac97",
		.cpu_dai_name = "bfin-ac97.1",
		.codec_dai_name = "ad1980-hifi",
		.platform_name = "bfin-ac97-pcm-audio",
		.codec_name = "ad1980",
	.ops = &bf5xx_board_ops,
	},
};

static struct snd_soc_card bf5xx_board = {
	.name = "bfin-ad1980",
	.dai_link = &bf5xx_board_dai,
	.dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
	.num_links = 1,
};

Loading