@@ -283,9 +283,10 @@ 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;
+ if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ return 0;
/*
* This is a workaround, When stop playback,
@@ -299,15 +300,13 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (playback)
- val = IC_HSLEN | IC_HSREN;
+ val = IC_HSLEN | IC_HSREN;
break;
default:
return -EINVAL;
}
- if (playback)
- snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
+ snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
IC_HSLEN | IC_HSREN, val);
return 0;
}
@@ -397,23 +396,10 @@ static const struct of_device_id sirf_audio_codec_of_match[] = {
};
MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match);
-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,
- .cache_type = REGCACHE_NONE,
-};
-
static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
{
int ret;
struct sirf_audio_codec *sirf_audio_codec;
- void __iomem *base;
- struct resource *mem_res;
- const struct of_device_id *match;
-
- match = of_match_node(sirf_audio_codec_of_match, pdev->dev.of_node);
sirf_audio_codec = devm_kzalloc(&pdev->dev,
sizeof(struct sirf_audio_codec), GFP_KERNEL);
@@ -422,15 +408,7 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sirf_audio_codec);
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, mem_res);
- if (base == NULL)
- return -ENOMEM;
-
- sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
- &sirf_audio_codec_regmap_config);
- if (IS_ERR(sirf_audio_codec->regmap))
- return PTR_ERR(sirf_audio_codec->regmap);
+ sirf_audio_codec->regmap = dev_get_drvdata(pdev->dev.parent);
sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(sirf_audio_codec->clk)) {
@@ -8,6 +8,11 @@ config SND_SOC_SIRF_AUDIO
depends on SND_SOC_SIRF
select SND_SOC_SIRF_AUDIO_CODEC
select SND_SOC_SIRF_AUDIO_PORT
+ select SND_SOC_SIRF_AUDIO_HUB
+
+config SND_SOC_SIRF_AUDIO_HUB
+ depends on SND_SOC_SIRF
+ tristate
config SND_SOC_SIRF_AUDIO_PORT
select REGMAP_MMIO
@@ -1,5 +1,7 @@
snd-soc-sirf-audio-objs := sirf-audio.o
+snd-soc-sirf-audio-hub-objs := sirf-audio-hub.o
snd-soc-sirf-audio-port-objs := sirf-audio-port.o
obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o
+obj-$(CONFIG_SND_SOC_SIRF_AUDIO_HUB) += snd-soc-sirf-audio-hub.o
obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o
new file mode 100644
@@ -0,0 +1,66 @@
+/*
+ * sirf-audio-hub.c - SiRF Audio hub driver purpose is sharing regmap.
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* This regmap is shared all child audio drivers */
+struct regmap *regmap;
+
+static const struct regmap_config sirf_audio_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int sirf_audio_probe(struct platform_device *pdev)
+{
+ struct resource *mem_res;
+ void __iomem *base;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, mem_res);
+ if (base == NULL)
+ return -ENOMEM;
+
+ regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &sirf_audio_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ platform_set_drvdata(pdev, regmap);
+
+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+}
+
+static const struct of_device_id sirf_audio_of_match[] = {
+ { .compatible = "sirf,audio-hub", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sirf_audio_of_match);
+
+static struct platform_driver sirf_audio_driver = {
+ .driver = {
+ .name = "sirf-audio-hub",
+ .owner = THIS_MODULE,
+ .of_match_table = sirf_audio_of_match,
+ },
+ .probe = sirf_audio_probe,
+};
+
+module_platform_driver(sirf_audio_driver);
+
+MODULE_DESCRIPTION("SiRF Audio hub driver");
+MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
+MODULE_LICENSE("GPL v2");
@@ -127,41 +127,17 @@ 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);
+ port->regmap = dev_get_drvdata(pdev->dev.parent);
ret = devm_snd_soc_register_component(&pdev->dev,
&sirf_audio_port_component, &sirf_audio_port_dai, 1);