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