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