aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/ux500/mop500.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/ux500/mop500.c')
-rw-r--r--sound/soc/ux500/mop500.c177
1 files changed, 86 insertions, 91 deletions
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");