99 lines
2.4 KiB
C
99 lines
2.4 KiB
C
|
// SPDX-License-Identifier: GPL-2.0-only
|
||
|
/*
|
||
|
* Apple Onboard Audio Alsa helpers
|
||
|
*
|
||
|
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
|
||
|
*/
|
||
|
#include <linux/module.h>
|
||
|
#include "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 device *dev)
|
||
|
{
|
||
|
struct snd_card *alsa_card;
|
||
|
int err;
|
||
|
|
||
|
if (aoa_card)
|
||
|
/* cannot be EEXIST due to usage in aoa_fabric_register */
|
||
|
return -EBUSY;
|
||
|
|
||
|
err = snd_card_new(dev, index, name, mod, sizeof(struct aoa_card),
|
||
|
&alsa_card);
|
||
|
if (err < 0)
|
||
|
return err;
|
||
|
aoa_card = alsa_card->private_data;
|
||
|
aoa_card->alsa_card = alsa_card;
|
||
|
strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
|
||
|
strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
|
||
|
strscpy(alsa_card->longname, name, sizeof(alsa_card->longname));
|
||
|
strscpy(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(enum snd_device_type type,
|
||
|
void *device_data, const 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);
|