diff options
Diffstat (limited to 'kernel/sound/ppc/powermac.c')
-rw-r--r-- | kernel/sound/ppc/powermac.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/kernel/sound/ppc/powermac.c b/kernel/sound/ppc/powermac.c new file mode 100644 index 000000000..33c6be9fb --- /dev/null +++ b/kernel/sound/ppc/powermac.c @@ -0,0 +1,194 @@ +/* + * Driver for PowerMac AWACS + * Copyright (c) 2001 by Takashi Iwai <tiwai@suse.de> + * based on dmasound.c. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <sound/core.h> +#include <sound/initval.h> +#include "pmac.h" +#include "awacs.h" +#include "burgundy.h" + +#define CHIP_NAME "PMac" + +MODULE_DESCRIPTION("PowerMac"); +MODULE_SUPPORTED_DEVICE("{{Apple,PowerMac}}"); +MODULE_LICENSE("GPL"); + +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ +static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ +static bool enable_beep = 1; + +module_param(index, int, 0444); +MODULE_PARM_DESC(index, "Index value for " CHIP_NAME " soundchip."); +module_param(id, charp, 0444); +MODULE_PARM_DESC(id, "ID string for " CHIP_NAME " soundchip."); +module_param(enable_beep, bool, 0444); +MODULE_PARM_DESC(enable_beep, "Enable beep using PCM."); + +static struct platform_device *device; + + +/* + */ + +static int snd_pmac_probe(struct platform_device *devptr) +{ + struct snd_card *card; + struct snd_pmac *chip; + char *name_ext; + int err; + + err = snd_card_new(&devptr->dev, index, id, THIS_MODULE, 0, &card); + if (err < 0) + return err; + + if ((err = snd_pmac_new(card, &chip)) < 0) + goto __error; + card->private_data = chip; + + switch (chip->model) { + case PMAC_BURGUNDY: + strcpy(card->driver, "PMac Burgundy"); + strcpy(card->shortname, "PowerMac Burgundy"); + sprintf(card->longname, "%s (Dev %d) Sub-frame %d", + card->shortname, chip->device_id, chip->subframe); + if ((err = snd_pmac_burgundy_init(chip)) < 0) + goto __error; + break; + case PMAC_DACA: + strcpy(card->driver, "PMac DACA"); + strcpy(card->shortname, "PowerMac DACA"); + sprintf(card->longname, "%s (Dev %d) Sub-frame %d", + card->shortname, chip->device_id, chip->subframe); + if ((err = snd_pmac_daca_init(chip)) < 0) + goto __error; + break; + case PMAC_TUMBLER: + case PMAC_SNAPPER: + name_ext = chip->model == PMAC_TUMBLER ? "Tumbler" : "Snapper"; + sprintf(card->driver, "PMac %s", name_ext); + sprintf(card->shortname, "PowerMac %s", name_ext); + sprintf(card->longname, "%s (Dev %d) Sub-frame %d", + card->shortname, chip->device_id, chip->subframe); + if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0) + goto __error; + break; + case PMAC_AWACS: + case PMAC_SCREAMER: + name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS"; + sprintf(card->driver, "PMac %s", name_ext); + sprintf(card->shortname, "PowerMac %s", name_ext); + if (chip->is_pbook_3400) + name_ext = " [PB3400]"; + else if (chip->is_pbook_G3) + name_ext = " [PBG3]"; + else + name_ext = ""; + sprintf(card->longname, "%s%s Rev %d", + card->shortname, name_ext, chip->revision); + if ((err = snd_pmac_awacs_init(chip)) < 0) + goto __error; + break; + default: + snd_printk(KERN_ERR "unsupported hardware %d\n", chip->model); + err = -EINVAL; + goto __error; + } + + if ((err = snd_pmac_pcm_new(chip)) < 0) + goto __error; + + chip->initialized = 1; + if (enable_beep) + snd_pmac_attach_beep(chip); + + if ((err = snd_card_register(card)) < 0) + goto __error; + + platform_set_drvdata(devptr, card); + return 0; + +__error: + snd_card_free(card); + return err; +} + + +static int snd_pmac_remove(struct platform_device *devptr) +{ + snd_card_free(platform_get_drvdata(devptr)); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int snd_pmac_driver_suspend(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + snd_pmac_suspend(card->private_data); + return 0; +} + +static int snd_pmac_driver_resume(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + snd_pmac_resume(card->private_data); + return 0; +} + +static SIMPLE_DEV_PM_OPS(snd_pmac_pm, snd_pmac_driver_suspend, snd_pmac_driver_resume); +#define SND_PMAC_PM_OPS &snd_pmac_pm +#else +#define SND_PMAC_PM_OPS NULL +#endif + +#define SND_PMAC_DRIVER "snd_powermac" + +static struct platform_driver snd_pmac_driver = { + .probe = snd_pmac_probe, + .remove = snd_pmac_remove, + .driver = { + .name = SND_PMAC_DRIVER, + .pm = SND_PMAC_PM_OPS, + }, +}; + +static int __init alsa_card_pmac_init(void) +{ + int err; + + if ((err = platform_driver_register(&snd_pmac_driver)) < 0) + return err; + device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0); + return 0; + +} + +static void __exit alsa_card_pmac_exit(void) +{ + if (!IS_ERR(device)) + platform_device_unregister(device); + platform_driver_unregister(&snd_pmac_driver); +} + +module_init(alsa_card_pmac_init) +module_exit(alsa_card_pmac_exit) |