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