2 * OF helpers for ALSA SoC Layer
4 * Copyright (C) 2008, Secret Lab Technologies Ltd.
7 #include <linux/module.h>
8 #include <linux/moduleparam.h>
9 #include <linux/init.h>
10 #include <linux/delay.h>
12 #include <linux/bitops.h>
13 #include <linux/platform_device.h>
15 #include <sound/core.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include <sound/soc-of-simple.h>
20 #include <sound/initval.h>
22 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
23 MODULE_LICENSE("GPL");
24 MODULE_DESCRIPTION("ALSA SoC OpenFirmware bindings");
26 static DEFINE_MUTEX(of_snd_soc_mutex
);
27 static LIST_HEAD(of_snd_soc_device_list
);
28 static int of_snd_soc_next_index
;
30 struct of_snd_soc_device
{
32 struct list_head list
;
33 struct snd_soc_device device
;
34 struct snd_soc_card card
;
35 struct snd_soc_dai_link dai_link
;
36 struct platform_device
*pdev
;
37 struct device_node
*platform_node
;
38 struct device_node
*codec_node
;
41 static struct snd_soc_ops of_snd_soc_ops
= {
44 static struct of_snd_soc_device
*
45 of_snd_soc_get_device(struct device_node
*codec_node
)
47 struct of_snd_soc_device
*of_soc
;
49 list_for_each_entry(of_soc
, &of_snd_soc_device_list
, list
) {
50 if (of_soc
->codec_node
== codec_node
)
54 of_soc
= kzalloc(sizeof(struct of_snd_soc_device
), GFP_KERNEL
);
58 /* Initialize the structure and add it to the global list */
59 of_soc
->codec_node
= codec_node
;
60 of_soc
->id
= of_snd_soc_next_index
++;
61 of_soc
->card
.dai_link
= &of_soc
->dai_link
;
62 of_soc
->card
.num_links
= 1;
63 of_soc
->device
.card
= &of_soc
->card
;
64 of_soc
->dai_link
.ops
= &of_snd_soc_ops
;
65 list_add(&of_soc
->list
, &of_snd_soc_device_list
);
70 static void of_snd_soc_register_device(struct of_snd_soc_device
*of_soc
)
72 struct platform_device
*pdev
;
75 /* Only register the device if both the codec and platform have
77 if ((!of_soc
->device
.codec_data
) || (!of_soc
->platform_node
))
80 pr_info("platform<-->codec match achieved; registering machine\n");
82 pdev
= platform_device_alloc("soc-audio", of_soc
->id
);
84 pr_err("of_soc: platform_device_alloc() failed\n");
88 pdev
->dev
.platform_data
= of_soc
;
89 platform_set_drvdata(pdev
, &of_soc
->device
);
90 of_soc
->device
.dev
= &pdev
->dev
;
92 /* The ASoC device is complete; register it */
93 rc
= platform_device_add(pdev
);
95 pr_err("of_soc: platform_device_add() failed\n");
101 int of_snd_soc_register_codec(struct snd_soc_codec_device
*codec_dev
,
102 void *codec_data
, struct snd_soc_dai
*dai
,
103 struct device_node
*node
)
105 struct of_snd_soc_device
*of_soc
;
108 pr_info("registering ASoC codec driver: %s\n", node
->full_name
);
110 mutex_lock(&of_snd_soc_mutex
);
111 of_soc
= of_snd_soc_get_device(node
);
117 /* Store the codec data */
118 of_soc
->device
.codec_data
= codec_data
;
119 of_soc
->device
.codec_dev
= codec_dev
;
120 of_soc
->dai_link
.name
= (char *)node
->name
;
121 of_soc
->dai_link
.stream_name
= (char *)node
->name
;
122 of_soc
->dai_link
.codec_dai
= dai
;
124 /* Now try to register the SoC device */
125 of_snd_soc_register_device(of_soc
);
128 mutex_unlock(&of_snd_soc_mutex
);
131 EXPORT_SYMBOL_GPL(of_snd_soc_register_codec
);
133 int of_snd_soc_register_platform(struct snd_soc_platform
*platform
,
134 struct device_node
*node
,
135 struct snd_soc_dai
*cpu_dai
)
137 struct of_snd_soc_device
*of_soc
;
138 struct device_node
*codec_node
;
139 const phandle
*handle
;
142 pr_info("registering ASoC platform driver: %s\n", node
->full_name
);
144 handle
= of_get_property(node
, "codec-handle", &len
);
145 if (!handle
|| len
< sizeof(handle
))
147 codec_node
= of_find_node_by_phandle(*handle
);
150 pr_info("looking for codec: %s\n", codec_node
->full_name
);
152 mutex_lock(&of_snd_soc_mutex
);
153 of_soc
= of_snd_soc_get_device(codec_node
);
159 of_soc
->platform_node
= node
;
160 of_soc
->dai_link
.cpu_dai
= cpu_dai
;
161 of_soc
->card
.platform
= platform
;
162 of_soc
->card
.name
= of_soc
->dai_link
.cpu_dai
->name
;
164 /* Now try to register the SoC device */
165 of_snd_soc_register_device(of_soc
);
168 mutex_unlock(&of_snd_soc_mutex
);
171 EXPORT_SYMBOL_GPL(of_snd_soc_register_platform
);