f3d9478b2c
This large patch adds all of snd-aoa. Consisting of many modules, it currently replaces snd-powermac for all layout-id based machines and handles many more (for example new powerbooks and powermacs with digital output that previously couldn't be used at all). It also has support for all layout-IDs that Apple has (judging from their Info.plist file) but not all are tested. The driver currently has 2 known regressions over snd-powermac: * it doesn't handle powermac 7,2 and 7,3 * it doesn't have a DRC control on snapper-based machines I will fix those during the 2.6.18 development cycle. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Takashi Iwai <tiwai@suse.de>
98 lines
2.3 KiB
C
98 lines
2.3 KiB
C
/*
|
|
* Apple Onboard Audio Alsa helpers
|
|
*
|
|
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
|
|
*
|
|
* GPL v2, can be found in COPYING.
|
|
*/
|
|
#include <linux/module.h>
|
|
#include "snd-aoa-alsa.h"
|
|
|
|
static int index = -1;
|
|
module_param(index, int, 0444);
|
|
MODULE_PARM_DESC(index, "index for AOA sound card.");
|
|
|
|
static struct aoa_card *aoa_card;
|
|
|
|
int aoa_alsa_init(char *name, struct module *mod)
|
|
{
|
|
struct snd_card *alsa_card;
|
|
int err;
|
|
|
|
if (aoa_card)
|
|
/* cannot be EEXIST due to usage in aoa_fabric_register */
|
|
return -EBUSY;
|
|
|
|
alsa_card = snd_card_new(index, name, mod, sizeof(struct aoa_card));
|
|
if (!alsa_card)
|
|
return -ENOMEM;
|
|
aoa_card = alsa_card->private_data;
|
|
aoa_card->alsa_card = alsa_card;
|
|
strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
|
|
strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
|
|
strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
|
|
strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
|
|
err = snd_card_register(aoa_card->alsa_card);
|
|
if (err < 0) {
|
|
printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
|
|
snd_card_free(aoa_card->alsa_card);
|
|
aoa_card = NULL;
|
|
return err;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct snd_card *aoa_get_card(void)
|
|
{
|
|
if (aoa_card)
|
|
return aoa_card->alsa_card;
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL_GPL(aoa_get_card);
|
|
|
|
void aoa_alsa_cleanup(void)
|
|
{
|
|
if (aoa_card) {
|
|
snd_card_free(aoa_card->alsa_card);
|
|
aoa_card = NULL;
|
|
}
|
|
}
|
|
|
|
int aoa_snd_device_new(snd_device_type_t type,
|
|
void * device_data, struct snd_device_ops * ops)
|
|
{
|
|
struct snd_card *card = aoa_get_card();
|
|
int err;
|
|
|
|
if (!card) return -ENOMEM;
|
|
|
|
err = snd_device_new(card, type, device_data, ops);
|
|
if (err) {
|
|
printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
|
|
return err;
|
|
}
|
|
err = snd_device_register(card, device_data);
|
|
if (err) {
|
|
printk(KERN_ERR "snd-aoa: failed to register "
|
|
"snd device (%d)\n", err);
|
|
printk(KERN_ERR "snd-aoa: have you forgotten the "
|
|
"dev_register callback?\n");
|
|
snd_device_free(card, device_data);
|
|
}
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL_GPL(aoa_snd_device_new);
|
|
|
|
int aoa_snd_ctl_add(struct snd_kcontrol* control)
|
|
{
|
|
int err;
|
|
|
|
if (!aoa_card) return -ENODEV;
|
|
|
|
err = snd_ctl_add(aoa_card->alsa_card, control);
|
|
if (err)
|
|
printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n",
|
|
err);
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
|