diff options
author | Leon Romanovsky <leon@leon.nu> | 2012-01-31 02:26:59 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-31 14:34:48 -0500 |
commit | b4dc0a75afb93f317eb3ad0a4d91f7ccfd01cd15 (patch) | |
tree | 5f9897e19d141da5d42caf57bc39de7f05aea177 /sound/soc/tegra/tegra_alc5632.c | |
parent | f959dee9c7b5e36a139e1e8fcfedbddfea65d00d (diff) |
ASoC: Tegra+ALC5632: Implement device tree support in board file
This patch implements device tree support for Tegra boards with ALC5632
codec.
Signed-off-by: Leon Romanovsky <leon@leon.nu>
Acked-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/tegra/tegra_alc5632.c')
-rw-r--r-- | sound/soc/tegra/tegra_alc5632.c | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 4a0e805c4edd..c0ba1e420192 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | struct tegra_alc5632 { | 37 | struct tegra_alc5632 { |
38 | struct tegra_asoc_utils_data util_data; | 38 | struct tegra_asoc_utils_data util_data; |
39 | struct platform_device *pcm_dev; | ||
39 | }; | 40 | }; |
40 | 41 | ||
41 | static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, | 42 | static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, |
@@ -128,9 +129,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
128 | static struct snd_soc_dai_link tegra_alc5632_dai = { | 129 | static struct snd_soc_dai_link tegra_alc5632_dai = { |
129 | .name = "ALC5632", | 130 | .name = "ALC5632", |
130 | .stream_name = "ALC5632 PCM", | 131 | .stream_name = "ALC5632 PCM", |
131 | .codec_name = "alc5632.0-001e", | ||
132 | .platform_name = "tegra-pcm-audio", | 132 | .platform_name = "tegra-pcm-audio", |
133 | .cpu_dai_name = "tegra-i2s.0", | ||
134 | .codec_dai_name = "alc5632-hifi", | 133 | .codec_dai_name = "alc5632-hifi", |
135 | .init = tegra_alc5632_asoc_init, | 134 | .init = tegra_alc5632_asoc_init, |
136 | .ops = &tegra_alc5632_asoc_ops, | 135 | .ops = &tegra_alc5632_asoc_ops, |
@@ -163,26 +162,78 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | |||
163 | sizeof(struct tegra_alc5632), GFP_KERNEL); | 162 | sizeof(struct tegra_alc5632), GFP_KERNEL); |
164 | if (!alc5632) { | 163 | if (!alc5632) { |
165 | dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); | 164 | dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); |
166 | return -ENOMEM; | 165 | ret = -ENOMEM; |
166 | goto err; | ||
167 | } | 167 | } |
168 | 168 | ||
169 | ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); | ||
170 | if (ret) | ||
171 | return ret; | ||
172 | |||
173 | card->dev = &pdev->dev; | 169 | card->dev = &pdev->dev; |
174 | platform_set_drvdata(pdev, card); | 170 | platform_set_drvdata(pdev, card); |
175 | snd_soc_card_set_drvdata(card, alc5632); | 171 | snd_soc_card_set_drvdata(card, alc5632); |
176 | 172 | ||
173 | alc5632->pcm_dev = ERR_PTR(-EINVAL); | ||
174 | |||
175 | if (!(pdev->dev.of_node)) { | ||
176 | dev_err(&pdev->dev, "Must be instantiated using device tree\n"); | ||
177 | ret = -EINVAL; | ||
178 | goto err; | ||
179 | } | ||
180 | |||
181 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
182 | if (ret) | ||
183 | goto err; | ||
184 | |||
185 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
186 | if (ret) | ||
187 | goto err; | ||
188 | |||
189 | tegra_alc5632_dai.codec_of_node = of_parse_phandle( | ||
190 | pdev->dev.of_node, "nvidia,audio-codec", 0); | ||
191 | |||
192 | if (!tegra_alc5632_dai.codec_of_node) { | ||
193 | dev_err(&pdev->dev, | ||
194 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
195 | ret = -EINVAL; | ||
196 | goto err; | ||
197 | } | ||
198 | |||
199 | tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( | ||
200 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | ||
201 | if (!tegra_alc5632_dai.cpu_dai_of_node) { | ||
202 | dev_err(&pdev->dev, | ||
203 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
204 | ret = -EINVAL; | ||
205 | goto err; | ||
206 | } | ||
207 | |||
208 | alc5632->pcm_dev = platform_device_register_simple( | ||
209 | "tegra-pcm-audio", -1, NULL, 0); | ||
210 | if (IS_ERR(alc5632->pcm_dev)) { | ||
211 | dev_err(&pdev->dev, | ||
212 | "Can't instantiate tegra-pcm-audio\n"); | ||
213 | ret = PTR_ERR(alc5632->pcm_dev); | ||
214 | goto err; | ||
215 | } | ||
216 | |||
217 | ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); | ||
218 | if (ret) | ||
219 | goto err_unregister; | ||
220 | |||
177 | ret = snd_soc_register_card(card); | 221 | ret = snd_soc_register_card(card); |
178 | if (ret) { | 222 | if (ret) { |
179 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | 223 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", |
180 | ret); | 224 | ret); |
181 | tegra_asoc_utils_fini(&alc5632->util_data); | 225 | goto err_fini_utils; |
182 | return ret; | ||
183 | } | 226 | } |
184 | 227 | ||
185 | return 0; | 228 | return 0; |
229 | |||
230 | err_fini_utils: | ||
231 | tegra_asoc_utils_fini(&alc5632->util_data); | ||
232 | err_unregister: | ||
233 | if (!IS_ERR(alc5632->pcm_dev)) | ||
234 | platform_device_unregister(alc5632->pcm_dev); | ||
235 | err: | ||
236 | return ret; | ||
186 | } | 237 | } |
187 | 238 | ||
188 | static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | 239 | static int __devexit tegra_alc5632_remove(struct platform_device *pdev) |
@@ -193,15 +244,23 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | |||
193 | snd_soc_unregister_card(card); | 244 | snd_soc_unregister_card(card); |
194 | 245 | ||
195 | tegra_asoc_utils_fini(&alc5632->util_data); | 246 | tegra_asoc_utils_fini(&alc5632->util_data); |
247 | if (!IS_ERR(alc5632->pcm_dev)) | ||
248 | platform_device_unregister(alc5632->pcm_dev); | ||
196 | 249 | ||
197 | return 0; | 250 | return 0; |
198 | } | 251 | } |
199 | 252 | ||
253 | static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = { | ||
254 | { .compatible = "nvidia,tegra-audio-alc5632", }, | ||
255 | {}, | ||
256 | }; | ||
257 | |||
200 | static struct platform_driver tegra_alc5632_driver = { | 258 | static struct platform_driver tegra_alc5632_driver = { |
201 | .driver = { | 259 | .driver = { |
202 | .name = DRV_NAME, | 260 | .name = DRV_NAME, |
203 | .owner = THIS_MODULE, | 261 | .owner = THIS_MODULE, |
204 | .pm = &snd_soc_pm_ops, | 262 | .pm = &snd_soc_pm_ops, |
263 | .of_match_table = tegra_alc5632_of_match, | ||
205 | }, | 264 | }, |
206 | .probe = tegra_alc5632_probe, | 265 | .probe = tegra_alc5632_probe, |
207 | .remove = __devexit_p(tegra_alc5632_remove), | 266 | .remove = __devexit_p(tegra_alc5632_remove), |
@@ -212,3 +271,4 @@ MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>"); | |||
212 | MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); | 271 | MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); |
213 | MODULE_LICENSE("GPL"); | 272 | MODULE_LICENSE("GPL"); |
214 | MODULE_ALIAS("platform:" DRV_NAME); | 273 | MODULE_ALIAS("platform:" DRV_NAME); |
274 | MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match); | ||