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

Commit b047e1cc authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: ac97: Support multi-platform AC'97



Currently we can only have a single platform built in with AC'97 support
due to the use of a global variable to provide the bus operations. Fix
this by making that variable a pointer and having the bus drivers set the
operations prior to registering.

This is not a particularly good or nice approach but it avoids blocking
multiplatform and a real fix involves fixing the fairly deep problems
with AC'97 support - we should be converting it to a real bus.

Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent b49dff8c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -340,7 +340,7 @@ struct snd_soc_jack_gpio;

typedef int (*hw_write_t)(void *,const char* ,int);

extern struct snd_ac97_bus_ops soc_ac97_ops;
extern struct snd_ac97_bus_ops *soc_ac97_ops;

enum snd_soc_control_type {
	SND_SOC_I2C = 1,
@@ -467,6 +467,8 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
	struct snd_ac97_bus_ops *ops, int num);
void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);

int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);

/*
 *Controls
 */
+5 −2
Original line number Diff line number Diff line
@@ -179,13 +179,12 @@ static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
}

/* AC97 controller operations */
struct snd_ac97_bus_ops soc_ac97_ops = {
static struct snd_ac97_bus_ops ac97c_bus_ops = {
	.read		= au1xac97c_ac97_read,
	.write		= au1xac97c_ac97_write,
	.reset		= au1xac97c_ac97_cold_reset,
	.warm_reset	= au1xac97c_ac97_warm_reset,
};
EXPORT_SYMBOL_GPL(soc_ac97_ops);	/* globals be gone! */

static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *dai)
@@ -272,6 +271,10 @@ static int au1xac97c_drvprobe(struct platform_device *pdev)

	platform_set_drvdata(pdev, ctx);

	ret = snd_soc_set_ac97_ops(&ac97c_bus_ops);
	if (ret)
		return ret;

	ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,
					 &au1xac97c_dai_driver, 1);
	if (ret)
+5 −2
Original line number Diff line number Diff line
@@ -201,13 +201,12 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
}

/* AC97 controller operations */
struct snd_ac97_bus_ops soc_ac97_ops = {
static struct snd_ac97_bus_ops psc_ac97_ops = {
	.read		= au1xpsc_ac97_read,
	.write		= au1xpsc_ac97_write,
	.reset		= au1xpsc_ac97_cold_reset,
	.warm_reset	= au1xpsc_ac97_warm_reset,
};
EXPORT_SYMBOL_GPL(soc_ac97_ops);

static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *params,
@@ -417,6 +416,10 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)

	platform_set_drvdata(pdev, wd);

	ret = snd_soc_set_ac97_ops(&psc_ac97_ops);
	if (ret)
		return ret;

	ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
					 &wd->dai_drv, 1);
	if (ret)
+9 −2
Original line number Diff line number Diff line
@@ -198,13 +198,12 @@ static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
#endif
}

struct snd_ac97_bus_ops soc_ac97_ops = {
static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
	.read	= bf5xx_ac97_read,
	.write	= bf5xx_ac97_write,
	.warm_reset	= bf5xx_ac97_warm_reset,
	.reset	= bf5xx_ac97_cold_reset,
};
EXPORT_SYMBOL_GPL(soc_ac97_ops);

#ifdef CONFIG_PM
static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
@@ -336,6 +335,12 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
		goto sport_config_err;
	}

	ret = snd_soc_set_ac97_ops(&bf5xx_ac97_ops);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
		goto sport_config_err;
	}

	ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
					 &bfin_ac97_dai, 1);
	if (ret) {
@@ -350,6 +355,7 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
sport_config_err:
	sport_done(sport_handle);
sport_err:
	snd_soc_set_ac97_ops(NULL);

	return ret;
}
@@ -360,6 +366,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev)

	snd_soc_unregister_component(&pdev->dev);
	sport_done(sport_handle);
	snd_soc_set_ac97_ops(NULL);

	return 0;
}
+8 −2
Original line number Diff line number Diff line
@@ -237,13 +237,12 @@ static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)
	return IRQ_HANDLED;
}

struct snd_ac97_bus_ops soc_ac97_ops = {
static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
	.read		= ep93xx_ac97_read,
	.write		= ep93xx_ac97_write,
	.reset		= ep93xx_ac97_cold_reset,
	.warm_reset	= ep93xx_ac97_warm_reset,
};
EXPORT_SYMBOL_GPL(soc_ac97_ops);

static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
			       int cmd, struct snd_soc_dai *dai)
@@ -395,6 +394,10 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
	ep93xx_ac97_info = info;
	platform_set_drvdata(pdev, info);

	ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
	if (ret)
		goto fail;

	ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
					 &ep93xx_ac97_dai, 1);
	if (ret)
@@ -405,6 +408,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
fail:
	platform_set_drvdata(pdev, NULL);
	ep93xx_ac97_info = NULL;
	snd_soc_set_ac97_ops(NULL);
	return ret;
}

@@ -420,6 +424,8 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
	platform_set_drvdata(pdev, NULL);
	ep93xx_ac97_info = NULL;

	snd_soc_set_ac97_ops(NULL);

	return 0;
}

Loading