aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/gus/gusclassic.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/gus/gusclassic.c')
-rw-r--r--sound/isa/gus/gusclassic.c116
1 files changed, 70 insertions, 46 deletions
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 6db484f71367..57beb74f5b9d 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -20,14 +20,15 @@
20 */ 20 */
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <asm/dma.h>
24#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/err.h>
25#include <linux/platform_device.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/time.h> 27#include <linux/time.h>
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <asm/dma.h>
28#include <sound/core.h> 30#include <sound/core.h>
29#include <sound/gus.h> 31#include <sound/gus.h>
30#define SNDRV_LEGACY_AUTO_PROBE
31#define SNDRV_LEGACY_FIND_FREE_IRQ 32#define SNDRV_LEGACY_FIND_FREE_IRQ
32#define SNDRV_LEGACY_FIND_FREE_DMA 33#define SNDRV_LEGACY_FIND_FREE_DMA
33#include <sound/initval.h> 34#include <sound/initval.h>
@@ -70,7 +71,6 @@ MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver.");
70module_param_array(pcm_channels, int, NULL, 0444); 71module_param_array(pcm_channels, int, NULL, 0444);
71MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver."); 72MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
72 73
73static struct snd_card *snd_gusclassic_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
74 74
75#define PFX "gusclassic: " 75#define PFX "gusclassic: "
76 76
@@ -101,20 +101,19 @@ static void __init snd_gusclassic_init(int dev, struct snd_gus_card * gus)
101 gus->joystick_dac = joystick_dac[dev]; 101 gus->joystick_dac = joystick_dac[dev];
102} 102}
103 103
104static int __init snd_gusclassic_probe(int dev) 104static int __init snd_gusclassic_probe(struct platform_device *pdev)
105{ 105{
106 int dev = pdev->id;
106 static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; 107 static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
107 static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; 108 static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
108 int xirq, xdma1, xdma2; 109 int xirq, xdma1, xdma2;
109 struct snd_card *card; 110 struct snd_card *card;
110 struct snd_gusclassic *guscard;
111 struct snd_gus_card *gus = NULL; 111 struct snd_gus_card *gus = NULL;
112 int err; 112 int err;
113 113
114 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); 114 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
115 if (card == NULL) 115 if (card == NULL)
116 return -ENOMEM; 116 return -ENOMEM;
117 guscard = (struct snd_gusclassic *)card->private_data;
118 if (pcm_channels[dev] < 2) 117 if (pcm_channels[dev] < 2)
119 pcm_channels[dev] = 2; 118 pcm_channels[dev] = 2;
120 119
@@ -143,12 +142,31 @@ static int __init snd_gusclassic_probe(int dev)
143 } 142 }
144 } 143 }
145 144
146 145 if (port[dev] != SNDRV_AUTO_PORT) {
147 if ((err = snd_gus_create(card, 146 err = snd_gus_create(card,
148 port[dev], 147 port[dev],
149 xirq, xdma1, xdma2, 148 xirq, xdma1, xdma2,
150 0, channels[dev], pcm_channels[dev], 149 0, channels[dev], pcm_channels[dev],
151 0, &gus)) < 0) 150 0, &gus);
151 } else {
152 /* auto-probe legacy ports */
153 static unsigned long possible_ports[] = {
154 0x220, 0x230, 0x240, 0x250, 0x260,
155 };
156 int i;
157 for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
158 err = snd_gus_create(card,
159 possible_ports[i],
160 xirq, xdma1, xdma2,
161 0, channels[dev], pcm_channels[dev],
162 0, &gus);
163 if (err >= 0) {
164 port[dev] = possible_ports[i];
165 break;
166 }
167 }
168 }
169 if (err < 0)
152 goto _err; 170 goto _err;
153 171
154 if ((err = snd_gusclassic_detect(gus)) < 0) 172 if ((err = snd_gusclassic_detect(gus)) < 0)
@@ -178,13 +196,12 @@ static int __init snd_gusclassic_probe(int dev)
178 if (dma2 >= 0) 196 if (dma2 >= 0)
179 sprintf(card->longname + strlen(card->longname), "&%d", xdma2); 197 sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
180 198
181 if ((err = snd_card_set_generic_dev(card)) < 0) 199 snd_card_set_dev(card, &pdev->dev);
182 goto _err;
183 200
184 if ((err = snd_card_register(card)) < 0) 201 if ((err = snd_card_register(card)) < 0)
185 goto _err; 202 goto _err;
186 203
187 snd_gusclassic_cards[dev] = card; 204 platform_set_drvdata(pdev, card);
188 return 0; 205 return 0;
189 206
190 _err: 207 _err:
@@ -192,53 +209,60 @@ static int __init snd_gusclassic_probe(int dev)
192 return err; 209 return err;
193} 210}
194 211
195static int __init snd_gusclassic_legacy_auto_probe(unsigned long xport) 212static int snd_gusclassic_remove(struct platform_device *devptr)
196{ 213{
197 static int dev; 214 snd_card_free(platform_get_drvdata(devptr));
198 int res; 215 platform_set_drvdata(devptr, NULL);
199 216 return 0;
200 for ( ; dev < SNDRV_CARDS; dev++) {
201 if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
202 continue;
203 port[dev] = xport;
204 res = snd_gusclassic_probe(dev);
205 if (res < 0)
206 port[dev] = SNDRV_AUTO_PORT;
207 return res;
208 }
209 return -ENODEV;
210} 217}
211 218
219#define GUSCLASSIC_DRIVER "snd_gusclassic"
220
221static struct platform_driver snd_gusclassic_driver = {
222 .probe = snd_gusclassic_probe,
223 .remove = snd_gusclassic_remove,
224 /* FIXME: suspend/resume */
225 .driver = {
226 .name = GUSCLASSIC_DRIVER
227 },
228};
229
212static int __init alsa_card_gusclassic_init(void) 230static int __init alsa_card_gusclassic_init(void)
213{ 231{
214 static unsigned long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260, -1}; 232 int i, cards, err;
215 int dev, cards, i; 233
216 234 err = platform_driver_register(&snd_gusclassic_driver);
217 for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) { 235 if (err < 0)
218 if (port[dev] == SNDRV_AUTO_PORT) 236 return err;
219 continue;
220 if (snd_gusclassic_probe(dev) >= 0)
221 cards++;
222 }
223 i = snd_legacy_auto_probe(possible_ports, snd_gusclassic_legacy_auto_probe);
224 if (i > 0)
225 cards += i;
226 237
238 cards = 0;
239 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
240 struct platform_device *device;
241 device = platform_device_register_simple(GUSCLASSIC_DRIVER,
242 i, NULL, 0);
243 if (IS_ERR(device)) {
244 err = PTR_ERR(device);
245 goto errout;
246 }
247 cards++;
248 }
227 if (!cards) { 249 if (!cards) {
228#ifdef MODULE 250#ifdef MODULE
229 printk(KERN_ERR "GUS Classic soundcard not found or device busy\n"); 251 printk(KERN_ERR "GUS Classic soundcard not found or device busy\n");
230#endif 252#endif
231 return -ENODEV; 253 err = -ENODEV;
254 goto errout;
232 } 255 }
233 return 0; 256 return 0;
257
258 errout:
259 platform_driver_unregister(&snd_gusclassic_driver);
260 return err;
234} 261}
235 262
236static void __exit alsa_card_gusclassic_exit(void) 263static void __exit alsa_card_gusclassic_exit(void)
237{ 264{
238 int idx; 265 platform_driver_unregister(&snd_gusclassic_driver);
239
240 for (idx = 0; idx < SNDRV_CARDS; idx++)
241 snd_card_free(snd_gusclassic_cards[idx]);
242} 266}
243 267
244module_init(alsa_card_gusclassic_init) 268module_init(alsa_card_gusclassic_init)