1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright 2011 Broadcom Corporation. All rights reserved. */ 3 4 #include <linux/platform_device.h> 5 6 #include <linux/init.h> 7 #include <linux/slab.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 11 #include "bcm2835.h" 12 13 static bool enable_hdmi; 14 static bool enable_headphones; 15 static bool enable_compat_alsa = true; 16 17 module_param(enable_hdmi, bool, 0444); 18 MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); 19 module_param(enable_headphones, bool, 0444); 20 MODULE_PARM_DESC(enable_headphones, "Enables Headphones virtual audio device"); 21 module_param(enable_compat_alsa, bool, 0444); 22 MODULE_PARM_DESC(enable_compat_alsa, 23 "Enables ALSA compatibility virtual audio device"); 24 25 static void snd_devm_unregister_child(struct device *dev, void *res) 26 { 27 struct device *childdev = *(struct device **)res; 28 29 device_unregister(childdev); 30 } 31 32 static int snd_devm_add_child(struct device *dev, struct device *child) 33 { 34 struct device **dr; 35 int ret; 36 37 dr = devres_alloc(snd_devm_unregister_child, sizeof(*dr), GFP_KERNEL); 38 if (!dr) 39 return -ENOMEM; 40 41 ret = device_add(child); 42 if (ret) { 43 devres_free(dr); 44 return ret; 45 } 46 47 *dr = child; 48 devres_add(dev, dr); 49 50 return 0; 51 } 52 53 static struct device * 54 snd_create_device(struct device *parent, 55 struct device_driver *driver, 56 const char *name) 57 { 58 struct device *device; 59 int ret; 60 61 device = devm_kzalloc(parent, sizeof(*device), GFP_KERNEL); 62 if (!device) 63 return ERR_PTR(-ENOMEM); 64 65 device_initialize(device); 66 device->parent = parent; 67 device->driver = driver; 68 69 dev_set_name(device, "%s", name); 70 71 ret = snd_devm_add_child(parent, device); 72 if (ret) 73 return ERR_PTR(ret); 74 75 return device; 76 } 77 78 static int snd_bcm2835_free(struct bcm2835_chip *chip) 79 { 80 kfree(chip); 81 return 0; 82 } 83 84 /* component-destructor 85 * (see "Management of Cards and Components") 86 */ 87 static int snd_bcm2835_dev_free(struct snd_device *device) 88 { 89 return snd_bcm2835_free(device->device_data); 90 } 91 92 /* chip-specific constructor 93 * (see "Management of Cards and Components") 94 */ 95 static int snd_bcm2835_create(struct snd_card *card, 96 struct bcm2835_chip **rchip) 97 { 98 struct bcm2835_chip *chip; 99 int err; 100 static struct snd_device_ops ops = { 101 .dev_free = snd_bcm2835_dev_free, 102 }; 103 104 *rchip = NULL; 105 106 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 107 if (!chip) 108 return -ENOMEM; 109 110 chip->card = card; 111 112 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 113 if (err) { 114 snd_bcm2835_free(chip); 115 return err; 116 } 117 118 *rchip = chip; 119 return 0; 120 } 121 122 static void snd_devm_card_free(struct device *dev, void *res) 123 { 124 struct snd_card *snd_card = *(struct snd_card **)res; 125 126 snd_card_free(snd_card); 127 } 128 129 static struct snd_card *snd_devm_card_new(struct device *dev) 130 { 131 struct snd_card **dr; 132 struct snd_card *card; 133 int ret; 134 135 dr = devres_alloc(snd_devm_card_free, sizeof(*dr), GFP_KERNEL); 136 if (!dr) 137 return ERR_PTR(-ENOMEM); 138 139 ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card); 140 if (ret) { 141 devres_free(dr); 142 return ERR_PTR(ret); 143 } 144 145 *dr = card; 146 devres_add(dev, dr); 147 148 return card; 149 } 150 151 typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip, 152 const char *name, 153 enum snd_bcm2835_route route, 154 u32 numchannels); 155 156 typedef int (*bcm2835_audio_newctl_func)(struct bcm2835_chip *chip); 157 158 struct bcm2835_audio_driver { 159 struct device_driver driver; 160 const char *shortname; 161 const char *longname; 162 int minchannels; 163 bcm2835_audio_newpcm_func newpcm; 164 bcm2835_audio_newctl_func newctl; 165 enum snd_bcm2835_route route; 166 }; 167 168 static int bcm2835_audio_alsa_newpcm(struct bcm2835_chip *chip, 169 const char *name, 170 enum snd_bcm2835_route route, 171 u32 numchannels) 172 { 173 int err; 174 175 err = snd_bcm2835_new_pcm(chip, numchannels - 1); 176 if (err) 177 return err; 178 179 err = snd_bcm2835_new_spdif_pcm(chip); 180 if (err) 181 return err; 182 183 return 0; 184 } 185 186 static struct bcm2835_audio_driver bcm2835_audio_alsa = { 187 .driver = { 188 .name = "bcm2835_alsa", 189 .owner = THIS_MODULE, 190 }, 191 .shortname = "bcm2835 ALSA", 192 .longname = "bcm2835 ALSA", 193 .minchannels = 2, 194 .newpcm = bcm2835_audio_alsa_newpcm, 195 .newctl = snd_bcm2835_new_ctl, 196 }; 197 198 static struct bcm2835_audio_driver bcm2835_audio_hdmi = { 199 .driver = { 200 .name = "bcm2835_hdmi", 201 .owner = THIS_MODULE, 202 }, 203 .shortname = "bcm2835 HDMI", 204 .longname = "bcm2835 HDMI", 205 .minchannels = 1, 206 .newpcm = snd_bcm2835_new_simple_pcm, 207 .newctl = snd_bcm2835_new_hdmi_ctl, 208 .route = AUDIO_DEST_HDMI 209 }; 210 211 static struct bcm2835_audio_driver bcm2835_audio_headphones = { 212 .driver = { 213 .name = "bcm2835_headphones", 214 .owner = THIS_MODULE, 215 }, 216 .shortname = "bcm2835 Headphones", 217 .longname = "bcm2835 Headphones", 218 .minchannels = 1, 219 .newpcm = snd_bcm2835_new_simple_pcm, 220 .newctl = snd_bcm2835_new_headphones_ctl, 221 .route = AUDIO_DEST_HEADPHONES 222 }; 223 224 struct bcm2835_audio_drivers { 225 struct bcm2835_audio_driver *audio_driver; 226 const bool *is_enabled; 227 }; 228 229 static struct bcm2835_audio_drivers children_devices[] = { 230 { 231 .audio_driver = &bcm2835_audio_alsa, 232 .is_enabled = &enable_compat_alsa, 233 }, 234 { 235 .audio_driver = &bcm2835_audio_hdmi, 236 .is_enabled = &enable_hdmi, 237 }, 238 { 239 .audio_driver = &bcm2835_audio_headphones, 240 .is_enabled = &enable_headphones, 241 }, 242 }; 243 244 static int snd_add_child_device(struct device *device, 245 struct bcm2835_audio_driver *audio_driver, 246 u32 numchans) 247 { 248 struct snd_card *card; 249 struct device *child; 250 struct bcm2835_chip *chip; 251 int err, i; 252 253 child = snd_create_device(device, &audio_driver->driver, 254 audio_driver->driver.name); 255 if (IS_ERR(child)) { 256 dev_err(device, 257 "Unable to create child device %p, error %ld", 258 audio_driver->driver.name, 259 PTR_ERR(child)); 260 return PTR_ERR(child); 261 } 262 263 card = snd_devm_card_new(child); 264 if (IS_ERR(card)) { 265 dev_err(child, "Failed to create card"); 266 return PTR_ERR(card); 267 } 268 269 snd_card_set_dev(card, child); 270 strcpy(card->driver, audio_driver->driver.name); 271 strcpy(card->shortname, audio_driver->shortname); 272 strcpy(card->longname, audio_driver->longname); 273 274 err = snd_bcm2835_create(card, &chip); 275 if (err) { 276 dev_err(child, "Failed to create chip, error %d\n", err); 277 return err; 278 } 279 280 chip->dev = child; 281 282 err = audio_driver->newpcm(chip, audio_driver->shortname, 283 audio_driver->route, 284 numchans); 285 if (err) { 286 dev_err(child, "Failed to create pcm, error %d\n", err); 287 return err; 288 } 289 290 err = audio_driver->newctl(chip); 291 if (err) { 292 dev_err(child, "Failed to create controls, error %d\n", err); 293 return err; 294 } 295 296 for (i = 0; i < numchans; i++) 297 chip->avail_substreams |= (1 << i); 298 299 err = snd_card_register(card); 300 if (err) { 301 dev_err(child, "Failed to register card, error %d\n", err); 302 return err; 303 } 304 305 dev_set_drvdata(child, card); 306 dev_info(child, "card created with %d channels\n", numchans); 307 308 return 0; 309 } 310 311 static int snd_add_child_devices(struct device *device, u32 numchans) 312 { 313 int i; 314 int count_devices = 0; 315 int minchannels = 0; 316 int extrachannels = 0; 317 int extrachannels_per_driver = 0; 318 int extrachannels_remainder = 0; 319 320 for (i = 0; i < ARRAY_SIZE(children_devices); i++) 321 if (*children_devices[i].is_enabled) 322 count_devices++; 323 324 if (!count_devices) 325 return 0; 326 327 for (i = 0; i < ARRAY_SIZE(children_devices); i++) 328 if (*children_devices[i].is_enabled) 329 minchannels += 330 children_devices[i].audio_driver->minchannels; 331 332 if (minchannels < numchans) { 333 extrachannels = numchans - minchannels; 334 extrachannels_per_driver = extrachannels / count_devices; 335 extrachannels_remainder = extrachannels % count_devices; 336 } 337 338 dev_dbg(device, "minchannels %d\n", minchannels); 339 dev_dbg(device, "extrachannels %d\n", extrachannels); 340 dev_dbg(device, "extrachannels_per_driver %d\n", 341 extrachannels_per_driver); 342 dev_dbg(device, "extrachannels_remainder %d\n", 343 extrachannels_remainder); 344 345 for (i = 0; i < ARRAY_SIZE(children_devices); i++) { 346 int err; 347 int numchannels_this_device; 348 struct bcm2835_audio_driver *audio_driver; 349 350 if (!*children_devices[i].is_enabled) 351 continue; 352 353 audio_driver = children_devices[i].audio_driver; 354 355 if (audio_driver->minchannels > numchans) { 356 dev_err(device, 357 "Out of channels, needed %d but only %d left\n", 358 audio_driver->minchannels, 359 numchans); 360 continue; 361 } 362 363 numchannels_this_device = 364 audio_driver->minchannels + extrachannels_per_driver + 365 extrachannels_remainder; 366 extrachannels_remainder = 0; 367 368 numchans -= numchannels_this_device; 369 370 err = snd_add_child_device(device, audio_driver, 371 numchannels_this_device); 372 if (err) 373 return err; 374 } 375 376 return 0; 377 } 378 379 static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) 380 { 381 struct device *dev = &pdev->dev; 382 u32 numchans; 383 int err; 384 385 err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", 386 &numchans); 387 if (err) { 388 dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); 389 return err; 390 } 391 392 if (numchans == 0 || numchans > MAX_SUBSTREAMS) { 393 numchans = MAX_SUBSTREAMS; 394 dev_warn(dev, 395 "Illegal 'brcm,pwm-channels' value, will use %u\n", 396 numchans); 397 } 398 399 err = snd_add_child_devices(dev, numchans); 400 if (err) 401 return err; 402 403 return 0; 404 } 405 406 #ifdef CONFIG_PM 407 408 static int snd_bcm2835_alsa_suspend(struct platform_device *pdev, 409 pm_message_t state) 410 { 411 return 0; 412 } 413 414 static int snd_bcm2835_alsa_resume(struct platform_device *pdev) 415 { 416 return 0; 417 } 418 419 #endif 420 421 static const struct of_device_id snd_bcm2835_of_match_table[] = { 422 { .compatible = "brcm,bcm2835-audio",}, 423 {}, 424 }; 425 MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); 426 427 static struct platform_driver bcm2835_alsa0_driver = { 428 .probe = snd_bcm2835_alsa_probe_dt, 429 #ifdef CONFIG_PM 430 .suspend = snd_bcm2835_alsa_suspend, 431 .resume = snd_bcm2835_alsa_resume, 432 #endif 433 .driver = { 434 .name = "bcm2835_audio", 435 .of_match_table = snd_bcm2835_of_match_table, 436 }, 437 }; 438 439 static int bcm2835_alsa_device_init(void) 440 { 441 int retval; 442 443 retval = platform_driver_register(&bcm2835_alsa0_driver); 444 if (retval) 445 pr_err("Error registering bcm2835_audio driver %d .\n", retval); 446 447 return retval; 448 } 449 450 static void bcm2835_alsa_device_exit(void) 451 { 452 platform_driver_unregister(&bcm2835_alsa0_driver); 453 } 454 455 late_initcall(bcm2835_alsa_device_init); 456 module_exit(bcm2835_alsa_device_exit); 457 458 MODULE_AUTHOR("Dom Cobley"); 459 MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); 460 MODULE_LICENSE("GPL"); 461