aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2017-05-18 09:33:46 +0200
committerLinus Walleij <linus.walleij@linaro.org>2018-02-20 14:42:57 +0100
commit47f093caebf0678a277f814b2c2ac8bf00e8ce0d (patch)
tree0f4db69c03bc7508ee4a5edcecf8e604c39064ef
parent213bfad35f8cc00980f5d1f0fa550d1836f6ebfc (diff)
downloadlinux-stericsson-47f093caebf0678a277f814b2c2ac8bf00e8ce0d.tar.gz
stab
-rw-r--r--Documentation/devicetree/bindings/sound/ux500-mop500.txt22
-rw-r--r--arch/arm/boot/dts/ste-dbx5x0.dtsi5
-rw-r--r--arch/arm/boot/dts/ste-href.dtsi21
-rw-r--r--arch/arm/boot/dts/ste-snowball.dts21
-rw-r--r--sound/soc/soc-pcm.c1
-rw-r--r--sound/soc/ux500/mop500.c177
-rw-r--r--sound/soc/ux500/ux500_pcm.c76
7 files changed, 151 insertions, 172 deletions
diff --git a/Documentation/devicetree/bindings/sound/ux500-mop500.txt b/Documentation/devicetree/bindings/sound/ux500-mop500.txt
index 48e071c96b46..fab67a19b59b 100644
--- a/Documentation/devicetree/bindings/sound/ux500-mop500.txt
+++ b/Documentation/devicetree/bindings/sound/ux500-mop500.txt
@@ -6,8 +6,6 @@ Required properties:
- compatible : "stericsson,snd-soc-mop500"
Non-standard properties:
- - stericsson,cpu-dai : Phandle to the CPU-side DAI
- - stericsson,audio-codec : Phandle to the Audio CODEC
- stericsson,card-name : Over-ride default card name
Example:
@@ -15,8 +13,24 @@ Example:
sound {
compatible = "stericsson,snd-soc-mop500";
- stericsson,cpu-dai = <&msp1 &msp3>;
- stericsson,audio-codec = <&codec>;
+ ab8500-codec-playback-dai-link@0 {
+ link-name = "AB8500 codec playback";
+ cpu {
+ sound-dai = <&msp1>;
+ };
+ codec {
+ sound-dai = <&codec>;
+ };
+ };
+ ab8500-codec-record-dai-link@0 {
+ link-name = "AB8500 codec record";
+ cpu {
+ sound-dai = <&msp3>;
+ };
+ codec {
+ sound-dai = <&codec>;
+ };
+ };
};
msp1: msp@80124000 {
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index a8d60f911be7..f5efd922f0af 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -703,6 +703,7 @@
codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
+ #sound-dai-cells = <0>;
V-AUD-supply = <&ab8500_ldo_audio_reg>;
V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>;
@@ -1112,6 +1113,7 @@
reg = <0x80123000 0x1000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
v-ape-supply = <&db8500_vape_reg>;
+ #sound-dai-cells = <0>;
dmas = <&dma 31 0 0x12>, /* Logical - DevToMem - HighPrio */
<&dma 31 0 0x10>; /* Logical - MemToDev - HighPrio */
@@ -1128,6 +1130,7 @@
reg = <0x80124000 0x1000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
v-ape-supply = <&db8500_vape_reg>;
+ #sound-dai-cells = <0>;
/* This DMA channel only exist on DB8500 v1 */
dmas = <&dma 30 0 0x10>; /* Logical - MemToDev - HighPrio */
@@ -1145,6 +1148,7 @@
reg = <0x80117000 0x1000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
v-ape-supply = <&db8500_vape_reg>;
+ #sound-dai-cells = <0>;
dmas = <&dma 14 0 0x12>, /* Logical - DevToMem - HighPrio */
<&dma 14 1 0x19>; /* Physical Chan 1 - MemToDev
@@ -1162,6 +1166,7 @@
reg = <0x80125000 0x1000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
v-ape-supply = <&db8500_vape_reg>;
+ #sound-dai-cells = <0>;
/* This DMA channel only exist on DB8500 v2 */
dmas = <&dma 30 0 0x12>; /* Logical - DevToMem - HighPrio */
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 312d246b3b11..743bac93b256 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -21,10 +21,27 @@
sound {
compatible = "stericsson,snd-soc-mop500";
stericsson,card-name = "HREF500-audio";
- stericsson,cpu-dai = <&msp1>, <&msp3>;
- stericsson,audio-codec = <&codec>;
clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
clock-names = "sysclk", "ulpclk", "intclk";
+
+ ab8500-codec-playback-dai-link@0 {
+ link-name = "AB8500 codec playback";
+ cpu {
+ sound-dai = <&msp1>;
+ };
+ codec {
+ sound-dai = <&codec>;
+ };
+ };
+ ab8500-codec-record-dai-link@1 {
+ link-name = "AB8500 codec record";
+ cpu {
+ sound-dai = <&msp3>;
+ };
+ codec {
+ sound-dai = <&codec>;
+ };
+ };
};
soc {
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index 783d0ac4c64a..a4787b8c678b 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -97,10 +97,27 @@
sound {
compatible = "stericsson,snd-soc-mop500";
stericsson,card-name = "Snowball-audio";
- stericsson,cpu-dai = <&msp1>, <&msp3>;
- stericsson,audio-codec = <&codec>;
clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
clock-names = "sysclk", "ulpclk", "intclk";
+
+ ab8500-codec-playback-dai-link@0 {
+ link-name = "AB8500 codec playback";
+ cpu {
+ sound-dai = <&msp1>;
+ };
+ codec {
+ sound-dai = <&codec>;
+ };
+ };
+ ab8500-codec-record-dai-link@0 {
+ link-name = "AB8500 codec record";
+ cpu {
+ sound-dai = <&msp3>;
+ };
+ codec {
+ sound-dai = <&codec>;
+ };
+ };
};
soc {
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 084125463d10..d326c7e0cf48 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -3029,6 +3029,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
(rtd->num_codecs > 1) ?
"multicodec" : rtd->codec_dai->name, num);
+ dev_info(rtd->card->dev, "call snd_pcm_new(%d) \"%s\" playback=%d, capture=%d\n", num, new_name, playback, capture);
ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
capture, &pcm);
}
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 461fc39f4601..5a06489450c2 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -23,107 +23,104 @@
#include "ux500_pcm.h"
#include "ux500_msp_dai.h"
-
#include "mop500_ab8500.h"
-/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */
-static struct snd_soc_dai_link mop500_dai_links[] = {
- {
- .name = "ab8500_0",
- .stream_name = "ab8500_0",
- .codec_dai_name = "ab8500-codec-dai.0",
- .init = mop500_ab8500_machine_init,
- .ops = mop500_ab8500_ops,
- },
- {
- .name = "ab8500_1",
- .stream_name = "ab8500_1",
- .codec_dai_name = "ab8500-codec-dai.1",
- .ops = mop500_ab8500_ops,
- },
-};
-
-static struct snd_soc_card mop500_card = {
- .name = "MOP500-card",
- .owner = THIS_MODULE,
- .probe = NULL,
- .dai_link = mop500_dai_links,
- .num_links = ARRAY_SIZE(mop500_dai_links),
+/**
+ * struct ux500_sound_data - state container for the sound card
+ * @card: the card we're providing data for
+ * @dai_link: the digital audio interface link
+ */
+struct ux500_sound_data {
+ struct snd_soc_card *card;
+ /* This array expands downward to fit the links */
+ struct snd_soc_dai_link dai_link[];
};
-static void mop500_of_node_put(void)
-{
- int i;
-
- for (i = 0; i < 2; i++) {
- of_node_put(mop500_dai_links[i].cpu_of_node);
- of_node_put(mop500_dai_links[i].codec_of_node);
- }
-}
-
-static int mop500_of_probe(struct platform_device *pdev,
- struct device_node *np)
-{
- struct device_node *codec_np, *msp_np[2];
- int i;
-
- msp_np[0] = of_parse_phandle(np, "stericsson,cpu-dai", 0);
- msp_np[1] = of_parse_phandle(np, "stericsson,cpu-dai", 1);
- codec_np = of_parse_phandle(np, "stericsson,audio-codec", 0);
-
- if (!(msp_np[0] && msp_np[1] && codec_np)) {
- dev_err(&pdev->dev, "Phandle missing or invalid\n");
- mop500_of_node_put();
- return -EINVAL;
- }
-
- for (i = 0; i < 2; i++) {
- mop500_dai_links[i].cpu_of_node = msp_np[i];
- mop500_dai_links[i].cpu_dai_name = NULL;
- mop500_dai_links[i].platform_of_node = msp_np[i];
- mop500_dai_links[i].platform_name = NULL;
- mop500_dai_links[i].codec_of_node = codec_np;
- mop500_dai_links[i].codec_name = NULL;
- }
-
- snd_soc_of_parse_card_name(&mop500_card, "stericsson,card-name");
-
- return 0;
-}
-
static int mop500_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
- int ret;
-
- mop500_card.dev = &pdev->dev;
-
- ret = mop500_of_probe(pdev, np);
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct device_node *np, *codec, *cpu;
+ struct snd_soc_card *card;
+ struct snd_soc_dai_link *link;
+ struct ux500_sound_data *data;
+ int ret, num_links;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+ card->dev = dev;
+
+ ret = snd_soc_of_parse_card_name(card, "stericsson,card-name");
if (ret)
return ret;
- dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n",
- __func__, mop500_card.name);
-
- snd_soc_card_set_drvdata(&mop500_card, NULL);
-
- ret = snd_soc_register_card(&mop500_card);
+ /* Uses static routes for now */
+#if 0
+ ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
if (ret)
- dev_err(&pdev->dev,
- "Error: snd_soc_register_card failed (%d)!\n", ret);
-
- return ret;
-}
-
-static int mop500_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *mop500_card = platform_get_drvdata(pdev);
+ return ret;
+#endif
+
+ /* Populate DAI links */
+ num_links = of_get_child_count(node);
+
+ /* Allocate the private data and the DAI link array */
+ data = devm_kzalloc(dev, sizeof(*data) + sizeof(*link) * num_links,
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ data->card = card;
+
+ card->dai_link = &data->dai_link[0];
+ card->num_links = num_links;
+ link = data->dai_link;
+
+ for_each_child_of_node(node, np) {
+ cpu = of_get_child_by_name(np, "cpu");
+ codec = of_get_child_by_name(np, "codec");
+
+ if (!cpu || !codec) {
+ dev_err(dev, "Can't find cpu/codec DT node\n");
+ return -EINVAL;
+ }
+
+ link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
+ if (!link->cpu_of_node) {
+ dev_err(card->dev, "error getting cpu phandle\n");
+ return -EINVAL;
+ }
+
+ ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
+ if (ret) {
+ dev_err(card->dev, "error getting cpu dai name\n");
+ return ret;
+ }
+
+ ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
+ if (ret < 0) {
+ dev_err(card->dev, "error getting codec dai link\n");
+ return ret;
+ }
+
+ link->platform_of_node = link->cpu_of_node;
+ ret = of_property_read_string(np, "link-name", &link->name);
+ if (ret) {
+ dev_err(card->dev, "error getting codec DAI link name\n");
+ return ret;
+ }
+
+ link->stream_name = link->name;
+ // link->init = ux500_sound_dai_init;
+ // link->ops = &ux500_sound_ops;
+ dev_info(dev, "parsed link \"%s\"\n", link->name);
+ link++;
+ }
- snd_soc_unregister_card(mop500_card);
- mop500_ab8500_remove(mop500_card);
- mop500_of_node_put();
+ platform_set_drvdata(pdev, data);
+ snd_soc_card_set_drvdata(card, data);
- return 0;
+ return devm_snd_soc_register_card(dev, card);
}
static const struct of_device_id snd_soc_mop500_match[] = {
@@ -138,9 +135,7 @@ static struct platform_driver snd_soc_mop500_driver = {
.of_match_table = snd_soc_mop500_match,
},
.probe = mop500_probe,
- .remove = mop500_remove,
};
-
module_platform_driver(snd_soc_mop500_driver);
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 0f5ca173e930..1cecaf80da24 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -46,80 +46,10 @@ static const struct snd_pcm_hardware ux500_pcm_hw = {
.periods_max = UX500_PLATFORM_PERIODS_MAX,
};
-static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_substream *substream)
-{
- struct snd_soc_dai *dai = rtd->cpu_dai;
- u16 per_data_width, mem_data_width;
- struct stedma40_chan_cfg *dma_cfg;
- struct ux500_msp_dma_params *dma_params;
-
- dma_params = snd_soc_dai_get_dma_data(dai, substream);
- dma_cfg = dma_params->dma_cfg;
-
- mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-
- switch (dma_params->data_size) {
- case 32:
- per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- break;
- case 16:
- per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
- break;
- case 8:
- per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- break;
- default:
- per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dma_cfg->src_info.data_width = mem_data_width;
- dma_cfg->dst_info.data_width = per_data_width;
- } else {
- dma_cfg->src_info.data_width = per_data_width;
- dma_cfg->dst_info.data_width = mem_data_width;
- }
-
- return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg);
-}
-
-static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct dma_slave_config *slave_config)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_dmaengine_dai_dma_data *snd_dma_params;
- dma_addr_t dma_addr;
- int ret;
-
- snd_dma_params =
- snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- dma_addr = snd_dma_params->addr;
-
- ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
- if (ret)
- return ret;
-
- slave_config->dst_maxburst = 4;
- slave_config->src_maxburst = 4;
-
- slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
- slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- slave_config->dst_addr = dma_addr;
- else
- slave_config->src_addr = dma_addr;
-
- return 0;
-}
-
static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = {
- .pcm_hardware = &ux500_pcm_hw, /* FIXME: from devicetree?? */
- .prealloc_buffer_size = 128 * 1024, /* FIXME: from devicetree ?? */
- .compat_request_channel = ux500_pcm_request_chan,
- .prepare_slave_config = ux500_pcm_prepare_slave_config,
+ .pcm_hardware = &ux500_pcm_hw,
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .prealloc_buffer_size = UX500_PLATFORM_BUFFER_BYTES_MAX,
};
int ux500_pcm_register_platform(struct platform_device *pdev)