1d6869352SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2888dcb7cSJohannes Berg /*
3888dcb7cSJohannes Berg * Apple Onboard Audio Alsa helpers
4888dcb7cSJohannes Berg *
5888dcb7cSJohannes Berg * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6888dcb7cSJohannes Berg */
7888dcb7cSJohannes Berg #include <linux/module.h>
8888dcb7cSJohannes Berg #include "alsa.h"
9888dcb7cSJohannes Berg
10888dcb7cSJohannes Berg static int index = -1;
11888dcb7cSJohannes Berg module_param(index, int, 0444);
12888dcb7cSJohannes Berg MODULE_PARM_DESC(index, "index for AOA sound card.");
13888dcb7cSJohannes Berg
14888dcb7cSJohannes Berg static struct aoa_card *aoa_card;
15888dcb7cSJohannes Berg
aoa_alsa_init(char * name,struct module * mod,struct device * dev)16888dcb7cSJohannes Berg int aoa_alsa_init(char *name, struct module *mod, struct device *dev)
17888dcb7cSJohannes Berg {
18888dcb7cSJohannes Berg struct snd_card *alsa_card;
19888dcb7cSJohannes Berg int err;
20888dcb7cSJohannes Berg
21888dcb7cSJohannes Berg if (aoa_card)
22888dcb7cSJohannes Berg /* cannot be EEXIST due to usage in aoa_fabric_register */
23888dcb7cSJohannes Berg return -EBUSY;
24888dcb7cSJohannes Berg
2510768797STakashi Iwai err = snd_card_new(dev, index, name, mod, sizeof(struct aoa_card),
26bd7dd77cSTakashi Iwai &alsa_card);
27bd7dd77cSTakashi Iwai if (err < 0)
28bd7dd77cSTakashi Iwai return err;
29888dcb7cSJohannes Berg aoa_card = alsa_card->private_data;
30888dcb7cSJohannes Berg aoa_card->alsa_card = alsa_card;
31*75b1a8f9SJoe Perches strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
32*75b1a8f9SJoe Perches strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
33*75b1a8f9SJoe Perches strscpy(alsa_card->longname, name, sizeof(alsa_card->longname));
34*75b1a8f9SJoe Perches strscpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
35888dcb7cSJohannes Berg err = snd_card_register(aoa_card->alsa_card);
36888dcb7cSJohannes Berg if (err < 0) {
37888dcb7cSJohannes Berg printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
38888dcb7cSJohannes Berg snd_card_free(aoa_card->alsa_card);
39888dcb7cSJohannes Berg aoa_card = NULL;
40888dcb7cSJohannes Berg return err;
41888dcb7cSJohannes Berg }
42888dcb7cSJohannes Berg return 0;
43888dcb7cSJohannes Berg }
44888dcb7cSJohannes Berg
aoa_get_card(void)45888dcb7cSJohannes Berg struct snd_card *aoa_get_card(void)
46888dcb7cSJohannes Berg {
47888dcb7cSJohannes Berg if (aoa_card)
48888dcb7cSJohannes Berg return aoa_card->alsa_card;
49888dcb7cSJohannes Berg return NULL;
50888dcb7cSJohannes Berg }
51888dcb7cSJohannes Berg EXPORT_SYMBOL_GPL(aoa_get_card);
52888dcb7cSJohannes Berg
aoa_alsa_cleanup(void)53888dcb7cSJohannes Berg void aoa_alsa_cleanup(void)
54888dcb7cSJohannes Berg {
55888dcb7cSJohannes Berg if (aoa_card) {
56888dcb7cSJohannes Berg snd_card_free(aoa_card->alsa_card);
57888dcb7cSJohannes Berg aoa_card = NULL;
58888dcb7cSJohannes Berg }
59888dcb7cSJohannes Berg }
60888dcb7cSJohannes Berg
aoa_snd_device_new(enum snd_device_type type,void * device_data,const struct snd_device_ops * ops)619ce50543STakashi Iwai int aoa_snd_device_new(enum snd_device_type type,
62e6f2a617STakashi Iwai void *device_data, const struct snd_device_ops *ops)
63888dcb7cSJohannes Berg {
64888dcb7cSJohannes Berg struct snd_card *card = aoa_get_card();
65888dcb7cSJohannes Berg int err;
66888dcb7cSJohannes Berg
67888dcb7cSJohannes Berg if (!card) return -ENOMEM;
68888dcb7cSJohannes Berg
69888dcb7cSJohannes Berg err = snd_device_new(card, type, device_data, ops);
70888dcb7cSJohannes Berg if (err) {
71888dcb7cSJohannes Berg printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
72888dcb7cSJohannes Berg return err;
73888dcb7cSJohannes Berg }
74888dcb7cSJohannes Berg err = snd_device_register(card, device_data);
75888dcb7cSJohannes Berg if (err) {
76888dcb7cSJohannes Berg printk(KERN_ERR "snd-aoa: failed to register "
77888dcb7cSJohannes Berg "snd device (%d)\n", err);
78888dcb7cSJohannes Berg printk(KERN_ERR "snd-aoa: have you forgotten the "
79888dcb7cSJohannes Berg "dev_register callback?\n");
80888dcb7cSJohannes Berg snd_device_free(card, device_data);
81888dcb7cSJohannes Berg }
82888dcb7cSJohannes Berg return err;
83888dcb7cSJohannes Berg }
84888dcb7cSJohannes Berg EXPORT_SYMBOL_GPL(aoa_snd_device_new);
85888dcb7cSJohannes Berg
aoa_snd_ctl_add(struct snd_kcontrol * control)86888dcb7cSJohannes Berg int aoa_snd_ctl_add(struct snd_kcontrol* control)
87888dcb7cSJohannes Berg {
88888dcb7cSJohannes Berg int err;
89888dcb7cSJohannes Berg
90888dcb7cSJohannes Berg if (!aoa_card) return -ENODEV;
91888dcb7cSJohannes Berg
92888dcb7cSJohannes Berg err = snd_ctl_add(aoa_card->alsa_card, control);
93888dcb7cSJohannes Berg if (err)
94888dcb7cSJohannes Berg printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n",
95888dcb7cSJohannes Berg err);
96888dcb7cSJohannes Berg return err;
97888dcb7cSJohannes Berg }
98888dcb7cSJohannes Berg EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
99