GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / staging / vc04_services / bcm2835-audio / bcm2835.c
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");