1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Driver for PowerMac AWACS
4*4882a593Smuzhiyun * Copyright (c) 2001 by Takashi Iwai <tiwai@suse.de>
5*4882a593Smuzhiyun * based on dmasound.c.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/platform_device.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <sound/core.h>
13*4882a593Smuzhiyun #include <sound/initval.h>
14*4882a593Smuzhiyun #include "pmac.h"
15*4882a593Smuzhiyun #include "awacs.h"
16*4882a593Smuzhiyun #include "burgundy.h"
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #define CHIP_NAME "PMac"
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun MODULE_DESCRIPTION("PowerMac");
21*4882a593Smuzhiyun MODULE_SUPPORTED_DEVICE("{{Apple,PowerMac}}");
22*4882a593Smuzhiyun MODULE_LICENSE("GPL");
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
25*4882a593Smuzhiyun static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
26*4882a593Smuzhiyun static bool enable_beep = 1;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun module_param(index, int, 0444);
29*4882a593Smuzhiyun MODULE_PARM_DESC(index, "Index value for " CHIP_NAME " soundchip.");
30*4882a593Smuzhiyun module_param(id, charp, 0444);
31*4882a593Smuzhiyun MODULE_PARM_DESC(id, "ID string for " CHIP_NAME " soundchip.");
32*4882a593Smuzhiyun module_param(enable_beep, bool, 0444);
33*4882a593Smuzhiyun MODULE_PARM_DESC(enable_beep, "Enable beep using PCM.");
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun static struct platform_device *device;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun */
40*4882a593Smuzhiyun
snd_pmac_probe(struct platform_device * devptr)41*4882a593Smuzhiyun static int snd_pmac_probe(struct platform_device *devptr)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun struct snd_card *card;
44*4882a593Smuzhiyun struct snd_pmac *chip;
45*4882a593Smuzhiyun char *name_ext;
46*4882a593Smuzhiyun int err;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun err = snd_card_new(&devptr->dev, index, id, THIS_MODULE, 0, &card);
49*4882a593Smuzhiyun if (err < 0)
50*4882a593Smuzhiyun return err;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun if ((err = snd_pmac_new(card, &chip)) < 0)
53*4882a593Smuzhiyun goto __error;
54*4882a593Smuzhiyun card->private_data = chip;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun switch (chip->model) {
57*4882a593Smuzhiyun case PMAC_BURGUNDY:
58*4882a593Smuzhiyun strcpy(card->driver, "PMac Burgundy");
59*4882a593Smuzhiyun strcpy(card->shortname, "PowerMac Burgundy");
60*4882a593Smuzhiyun sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
61*4882a593Smuzhiyun card->shortname, chip->device_id, chip->subframe);
62*4882a593Smuzhiyun if ((err = snd_pmac_burgundy_init(chip)) < 0)
63*4882a593Smuzhiyun goto __error;
64*4882a593Smuzhiyun break;
65*4882a593Smuzhiyun case PMAC_DACA:
66*4882a593Smuzhiyun strcpy(card->driver, "PMac DACA");
67*4882a593Smuzhiyun strcpy(card->shortname, "PowerMac DACA");
68*4882a593Smuzhiyun sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
69*4882a593Smuzhiyun card->shortname, chip->device_id, chip->subframe);
70*4882a593Smuzhiyun if ((err = snd_pmac_daca_init(chip)) < 0)
71*4882a593Smuzhiyun goto __error;
72*4882a593Smuzhiyun break;
73*4882a593Smuzhiyun case PMAC_TUMBLER:
74*4882a593Smuzhiyun case PMAC_SNAPPER:
75*4882a593Smuzhiyun name_ext = chip->model == PMAC_TUMBLER ? "Tumbler" : "Snapper";
76*4882a593Smuzhiyun sprintf(card->driver, "PMac %s", name_ext);
77*4882a593Smuzhiyun sprintf(card->shortname, "PowerMac %s", name_ext);
78*4882a593Smuzhiyun sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
79*4882a593Smuzhiyun card->shortname, chip->device_id, chip->subframe);
80*4882a593Smuzhiyun err = snd_pmac_tumbler_init(chip);
81*4882a593Smuzhiyun if (err < 0)
82*4882a593Smuzhiyun goto __error;
83*4882a593Smuzhiyun err = snd_pmac_tumbler_post_init();
84*4882a593Smuzhiyun if (err < 0)
85*4882a593Smuzhiyun goto __error;
86*4882a593Smuzhiyun break;
87*4882a593Smuzhiyun case PMAC_AWACS:
88*4882a593Smuzhiyun case PMAC_SCREAMER:
89*4882a593Smuzhiyun name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS";
90*4882a593Smuzhiyun sprintf(card->driver, "PMac %s", name_ext);
91*4882a593Smuzhiyun sprintf(card->shortname, "PowerMac %s", name_ext);
92*4882a593Smuzhiyun if (chip->is_pbook_3400)
93*4882a593Smuzhiyun name_ext = " [PB3400]";
94*4882a593Smuzhiyun else if (chip->is_pbook_G3)
95*4882a593Smuzhiyun name_ext = " [PBG3]";
96*4882a593Smuzhiyun else
97*4882a593Smuzhiyun name_ext = "";
98*4882a593Smuzhiyun sprintf(card->longname, "%s%s Rev %d",
99*4882a593Smuzhiyun card->shortname, name_ext, chip->revision);
100*4882a593Smuzhiyun if ((err = snd_pmac_awacs_init(chip)) < 0)
101*4882a593Smuzhiyun goto __error;
102*4882a593Smuzhiyun break;
103*4882a593Smuzhiyun default:
104*4882a593Smuzhiyun snd_printk(KERN_ERR "unsupported hardware %d\n", chip->model);
105*4882a593Smuzhiyun err = -EINVAL;
106*4882a593Smuzhiyun goto __error;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun if ((err = snd_pmac_pcm_new(chip)) < 0)
110*4882a593Smuzhiyun goto __error;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun chip->initialized = 1;
113*4882a593Smuzhiyun if (enable_beep)
114*4882a593Smuzhiyun snd_pmac_attach_beep(chip);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if ((err = snd_card_register(card)) < 0)
117*4882a593Smuzhiyun goto __error;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun platform_set_drvdata(devptr, card);
120*4882a593Smuzhiyun return 0;
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun __error:
123*4882a593Smuzhiyun snd_card_free(card);
124*4882a593Smuzhiyun return err;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun
snd_pmac_remove(struct platform_device * devptr)128*4882a593Smuzhiyun static int snd_pmac_remove(struct platform_device *devptr)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun snd_card_free(platform_get_drvdata(devptr));
131*4882a593Smuzhiyun return 0;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
snd_pmac_driver_suspend(struct device * dev)135*4882a593Smuzhiyun static int snd_pmac_driver_suspend(struct device *dev)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct snd_card *card = dev_get_drvdata(dev);
138*4882a593Smuzhiyun snd_pmac_suspend(card->private_data);
139*4882a593Smuzhiyun return 0;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
snd_pmac_driver_resume(struct device * dev)142*4882a593Smuzhiyun static int snd_pmac_driver_resume(struct device *dev)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun struct snd_card *card = dev_get_drvdata(dev);
145*4882a593Smuzhiyun snd_pmac_resume(card->private_data);
146*4882a593Smuzhiyun return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(snd_pmac_pm, snd_pmac_driver_suspend, snd_pmac_driver_resume);
150*4882a593Smuzhiyun #define SND_PMAC_PM_OPS &snd_pmac_pm
151*4882a593Smuzhiyun #else
152*4882a593Smuzhiyun #define SND_PMAC_PM_OPS NULL
153*4882a593Smuzhiyun #endif
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun #define SND_PMAC_DRIVER "snd_powermac"
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun static struct platform_driver snd_pmac_driver = {
158*4882a593Smuzhiyun .probe = snd_pmac_probe,
159*4882a593Smuzhiyun .remove = snd_pmac_remove,
160*4882a593Smuzhiyun .driver = {
161*4882a593Smuzhiyun .name = SND_PMAC_DRIVER,
162*4882a593Smuzhiyun .pm = SND_PMAC_PM_OPS,
163*4882a593Smuzhiyun },
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun
alsa_card_pmac_init(void)166*4882a593Smuzhiyun static int __init alsa_card_pmac_init(void)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun int err;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
171*4882a593Smuzhiyun return err;
172*4882a593Smuzhiyun device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
173*4882a593Smuzhiyun return 0;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
alsa_card_pmac_exit(void)177*4882a593Smuzhiyun static void __exit alsa_card_pmac_exit(void)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun if (!IS_ERR(device))
180*4882a593Smuzhiyun platform_device_unregister(device);
181*4882a593Smuzhiyun platform_driver_unregister(&snd_pmac_driver);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun module_init(alsa_card_pmac_init)
185*4882a593Smuzhiyun module_exit(alsa_card_pmac_exit)
186