1 /*****************************************************************************
2 * Copyright 2011 Broadcom Corporation. All rights reserved.
4 * Unless you and Broadcom execute a separate written software license
5 * agreement governing use of this software, this software is licensed to you
6 * under the terms of the GNU General Public License version 2, available at
7 * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
9 * Notwithstanding the above, under no circumstances may you combine this
10 * software in any way with any other Broadcom software provided under a
11 * license other than the GPL, without Broadcom's express prior written
13 *****************************************************************************/
15 #include <linux/platform_device.h>
17 #include <linux/init.h>
18 #include <linux/slab.h>
19 #include <linux/module.h>
24 static bool enable_hdmi;
25 static bool enable_headphones;
26 static bool enable_compat_alsa = true;
28 module_param(enable_hdmi, bool, 0444);
29 MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device");
30 module_param(enable_headphones, bool, 0444);
31 MODULE_PARM_DESC(enable_headphones, "Enables Headphones virtual audio device");
32 module_param(enable_compat_alsa, bool, 0444);
33 MODULE_PARM_DESC(enable_compat_alsa,
34 "Enables ALSA compatibility virtual audio device");
36 static void snd_devm_unregister_child(struct device *dev, void *res)
38 struct device *childdev = *(struct device **)res;
39 struct bcm2835_chip *chip = dev_get_drvdata(childdev);
40 struct snd_card *card = chip->card;
44 device_unregister(childdev);
47 static int snd_devm_add_child(struct device *dev, struct device *child)
52 dr = devres_alloc(snd_devm_unregister_child, sizeof(*dr), GFP_KERNEL);
56 ret = device_add(child);
68 static void snd_bcm2835_release(struct device *dev)
70 struct bcm2835_chip *chip = dev_get_drvdata(dev);
75 static struct device *
76 snd_create_device(struct device *parent,
77 struct device_driver *driver,
80 struct device *device;
83 device = devm_kzalloc(parent, sizeof(*device), GFP_KERNEL);
85 return ERR_PTR(-ENOMEM);
87 device_initialize(device);
88 device->parent = parent;
89 device->driver = driver;
90 device->release = snd_bcm2835_release;
92 dev_set_name(device, "%s", name);
94 ret = snd_devm_add_child(parent, device);
101 /* component-destructor
102 * (see "Management of Cards and Components")
104 static int snd_bcm2835_dev_free(struct snd_device *device)
106 struct bcm2835_chip *chip = device->device_data;
107 struct snd_card *card = chip->card;
109 /* TODO: free pcm, ctl */
111 snd_device_free(card, chip);
116 /* chip-specific constructor
117 * (see "Management of Cards and Components")
119 static int snd_bcm2835_create(struct snd_card *card,
120 struct bcm2835_chip **rchip)
122 struct bcm2835_chip *chip;
124 static struct snd_device_ops ops = {
125 .dev_free = snd_bcm2835_dev_free,
130 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
136 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
146 static struct snd_card *snd_bcm2835_card_new(struct device *dev)
148 struct snd_card *card;
151 ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card);
158 typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip,
160 enum snd_bcm2835_route route,
163 typedef int (*bcm2835_audio_newctl_func)(struct bcm2835_chip *chip);
165 struct bcm2835_audio_driver {
166 struct device_driver driver;
167 const char *shortname;
168 const char *longname;
170 bcm2835_audio_newpcm_func newpcm;
171 bcm2835_audio_newctl_func newctl;
172 enum snd_bcm2835_route route;
175 static int bcm2835_audio_alsa_newpcm(struct bcm2835_chip *chip,
177 enum snd_bcm2835_route route,
182 err = snd_bcm2835_new_pcm(chip, numchannels - 1);
186 err = snd_bcm2835_new_spdif_pcm(chip);
193 static struct bcm2835_audio_driver bcm2835_audio_alsa = {
195 .name = "bcm2835_alsa",
196 .owner = THIS_MODULE,
198 .shortname = "bcm2835 ALSA",
199 .longname = "bcm2835 ALSA",
201 .newpcm = bcm2835_audio_alsa_newpcm,
202 .newctl = snd_bcm2835_new_ctl,
205 static struct bcm2835_audio_driver bcm2835_audio_hdmi = {
207 .name = "bcm2835_hdmi",
208 .owner = THIS_MODULE,
210 .shortname = "bcm2835 HDMI",
211 .longname = "bcm2835 HDMI",
213 .newpcm = snd_bcm2835_new_simple_pcm,
214 .newctl = snd_bcm2835_new_hdmi_ctl,
215 .route = AUDIO_DEST_HDMI
218 static struct bcm2835_audio_driver bcm2835_audio_headphones = {
220 .name = "bcm2835_headphones",
221 .owner = THIS_MODULE,
223 .shortname = "bcm2835 Headphones",
224 .longname = "bcm2835 Headphones",
226 .newpcm = snd_bcm2835_new_simple_pcm,
227 .newctl = snd_bcm2835_new_headphones_ctl,
228 .route = AUDIO_DEST_HEADPHONES
231 struct bcm2835_audio_drivers {
232 struct bcm2835_audio_driver *audio_driver;
233 const bool *is_enabled;
236 static struct bcm2835_audio_drivers children_devices[] = {
238 .audio_driver = &bcm2835_audio_alsa,
239 .is_enabled = &enable_compat_alsa,
242 .audio_driver = &bcm2835_audio_hdmi,
243 .is_enabled = &enable_hdmi,
246 .audio_driver = &bcm2835_audio_headphones,
247 .is_enabled = &enable_headphones,
251 static int snd_add_child_device(struct device *device,
252 struct bcm2835_audio_driver *audio_driver,
255 struct snd_card *card;
256 struct device *child;
257 struct bcm2835_chip *chip;
260 child = snd_create_device(device, &audio_driver->driver,
261 audio_driver->driver.name);
264 "Unable to create child device %p, error %ld",
265 audio_driver->driver.name,
267 return PTR_ERR(child);
270 card = snd_bcm2835_card_new(child);
272 dev_err(child, "Failed to create card");
273 return PTR_ERR(card);
276 snd_card_set_dev(card, child);
277 strcpy(card->driver, audio_driver->driver.name);
278 strcpy(card->shortname, audio_driver->shortname);
279 strcpy(card->longname, audio_driver->longname);
281 err = snd_bcm2835_create(card, &chip);
283 dev_err(child, "Failed to create chip, error %d\n", err);
289 err = audio_driver->newpcm(chip, audio_driver->shortname,
293 dev_err(child, "Failed to create pcm, error %d\n", err);
297 err = audio_driver->newctl(chip);
299 dev_err(child, "Failed to create controls, error %d\n", err);
303 for (i = 0; i < numchans; i++)
304 chip->avail_substreams |= (1 << i);
306 err = snd_card_register(card);
308 dev_err(child, "Failed to register card, error %d\n", err);
312 dev_set_drvdata(child, chip);
313 dev_info(child, "card created with %d channels\n", numchans);
318 static int snd_add_child_devices(struct device *device, u32 numchans)
321 int count_devices = 0;
323 int extrachannels = 0;
324 int extrachannels_per_driver = 0;
325 int extrachannels_remainder = 0;
327 for (i = 0; i < ARRAY_SIZE(children_devices); i++)
328 if (*children_devices[i].is_enabled)
334 for (i = 0; i < ARRAY_SIZE(children_devices); i++)
335 if (*children_devices[i].is_enabled)
337 children_devices[i].audio_driver->minchannels;
339 if (minchannels < numchans) {
340 extrachannels = numchans - minchannels;
341 extrachannels_per_driver = extrachannels / count_devices;
342 extrachannels_remainder = extrachannels % count_devices;
345 dev_dbg(device, "minchannels %d\n", minchannels);
346 dev_dbg(device, "extrachannels %d\n", extrachannels);
347 dev_dbg(device, "extrachannels_per_driver %d\n",
348 extrachannels_per_driver);
349 dev_dbg(device, "extrachannels_remainder %d\n",
350 extrachannels_remainder);
352 for (i = 0; i < ARRAY_SIZE(children_devices); i++) {
354 int numchannels_this_device;
355 struct bcm2835_audio_driver *audio_driver;
357 if (!*children_devices[i].is_enabled)
360 audio_driver = children_devices[i].audio_driver;
362 if (audio_driver->minchannels > numchans) {
364 "Out of channels, needed %d but only %d left\n",
365 audio_driver->minchannels,
370 numchannels_this_device =
371 audio_driver->minchannels + extrachannels_per_driver +
372 extrachannels_remainder;
373 extrachannels_remainder = 0;
375 numchans -= numchannels_this_device;
377 err = snd_add_child_device(device, audio_driver,
378 numchannels_this_device);
386 static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev)
388 struct device *dev = &pdev->dev;
392 err = of_property_read_u32(dev->of_node, "brcm,pwm-channels",
395 dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'");
399 if (numchans == 0 || numchans > MAX_SUBSTREAMS) {
400 numchans = MAX_SUBSTREAMS;
402 "Illegal 'brcm,pwm-channels' value, will use %u\n",
406 err = snd_add_child_devices(dev, numchans);
415 static int snd_bcm2835_alsa_suspend(struct platform_device *pdev,
421 static int snd_bcm2835_alsa_resume(struct platform_device *pdev)
428 static const struct of_device_id snd_bcm2835_of_match_table[] = {
429 { .compatible = "brcm,bcm2835-audio",},
432 MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table);
434 static struct platform_driver bcm2835_alsa0_driver = {
435 .probe = snd_bcm2835_alsa_probe_dt,
437 .suspend = snd_bcm2835_alsa_suspend,
438 .resume = snd_bcm2835_alsa_resume,
441 .name = "bcm2835_audio",
442 .owner = THIS_MODULE,
443 .of_match_table = snd_bcm2835_of_match_table,
447 static int bcm2835_alsa_device_init(void)
451 retval = platform_driver_register(&bcm2835_alsa0_driver);
453 pr_err("Error registering bcm2835_audio driver %d .\n", retval);
458 static void bcm2835_alsa_device_exit(void)
460 platform_driver_unregister(&bcm2835_alsa0_driver);
463 late_initcall(bcm2835_alsa_device_init);
464 module_exit(bcm2835_alsa_device_exit);
466 MODULE_AUTHOR("Dom Cobley");
467 MODULE_DESCRIPTION("Alsa driver for BCM2835 chip");
468 MODULE_LICENSE("GPL");