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