aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/gus/gusextreme.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/gus/gusextreme.c')
-rw-r--r--sound/isa/gus/gusextreme.c116
1 files changed, 67 insertions, 49 deletions
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 9be59d501333..6fad9734a853 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -20,11 +20,13 @@
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#include <sound/es1688.h> 32#include <sound/es1688.h>
@@ -85,7 +87,6 @@ MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver.");
85module_param_array(pcm_channels, int, NULL, 0444); 87module_param_array(pcm_channels, int, NULL, 0444);
86MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver."); 88MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
87 89
88static struct snd_card *snd_gusextreme_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
89 90
90#define PFX "gusextreme: " 91#define PFX "gusextreme: "
91 92
@@ -166,15 +167,15 @@ static int __init snd_gusextreme_mixer(struct snd_es1688 *chip)
166 return 0; 167 return 0;
167} 168}
168 169
169static int __init snd_gusextreme_probe(int dev) 170static int __init snd_gusextreme_probe(struct platform_device *pdev)
170{ 171{
172 int dev = pdev->id;
171 static int possible_ess_irqs[] = {5, 9, 10, 7, -1}; 173 static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
172 static int possible_ess_dmas[] = {1, 3, 0, -1}; 174 static int possible_ess_dmas[] = {1, 3, 0, -1};
173 static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; 175 static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
174 static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1}; 176 static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
175 int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma; 177 int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
176 struct snd_card *card; 178 struct snd_card *card;
177 struct snd_gusextreme *acard;
178 struct snd_gus_card *gus; 179 struct snd_gus_card *gus;
179 struct snd_es1688 *es1688; 180 struct snd_es1688 *es1688;
180 struct snd_opl3 *opl3; 181 struct snd_opl3 *opl3;
@@ -183,7 +184,6 @@ static int __init snd_gusextreme_probe(int dev)
183 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); 184 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
184 if (card == NULL) 185 if (card == NULL)
185 return -ENOMEM; 186 return -ENOMEM;
186 acard = (struct snd_gusextreme *)card->private_data;
187 187
188 xgf1_irq = gf1_irq[dev]; 188 xgf1_irq = gf1_irq[dev];
189 if (xgf1_irq == SNDRV_AUTO_IRQ) { 189 if (xgf1_irq == SNDRV_AUTO_IRQ) {
@@ -223,10 +223,29 @@ static int __init snd_gusextreme_probe(int dev)
223 } 223 }
224 } 224 }
225 225
226 if ((err = snd_es1688_create(card, port[dev], mpu_port[dev], 226 if (port[dev] != SNDRV_AUTO_PORT) {
227 xess_irq, xmpu_irq, xess_dma, 227 err = snd_es1688_create(card, port[dev], mpu_port[dev],
228 ES1688_HW_1688, &es1688)) < 0) 228 xess_irq, xmpu_irq, xess_dma,
229 ES1688_HW_1688, &es1688);
230 } else {
231 /* auto-probe legacy ports */
232 static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
233 int i;
234 for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
235 err = snd_es1688_create(card,
236 possible_ports[i],
237 mpu_port[dev],
238 xess_irq, xmpu_irq, xess_dma,
239 ES1688_HW_1688, &es1688);
240 if (err >= 0) {
241 port[dev] = possible_ports[i];
242 break;
243 }
244 }
245 }
246 if (err < 0)
229 goto out; 247 goto out;
248
230 if (gf1_port[dev] < 0) 249 if (gf1_port[dev] < 0)
231 gf1_port[dev] = port[dev] + 0x20; 250 gf1_port[dev] = port[dev] + 0x20;
232 if ((err = snd_gus_create(card, 251 if ((err = snd_gus_create(card,
@@ -287,13 +306,12 @@ static int __init snd_gusextreme_probe(int dev)
287 sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i", 306 sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
288 es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma); 307 es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
289 308
290 if ((err = snd_card_set_generic_dev(card)) < 0) 309 snd_card_set_dev(card, &pdev->dev);
291 goto out;
292 310
293 if ((err = snd_card_register(card)) < 0) 311 if ((err = snd_card_register(card)) < 0)
294 goto out; 312 goto out;
295 313
296 snd_gusextreme_cards[dev] = card; 314 platform_set_drvdata(pdev, card);
297 return 0; 315 return 0;
298 316
299 out: 317 out:
@@ -301,60 +319,60 @@ static int __init snd_gusextreme_probe(int dev)
301 return err; 319 return err;
302} 320}
303 321
304static int __init snd_gusextreme_legacy_auto_probe(unsigned long xport) 322static int snd_gusextreme_remove(struct platform_device *devptr)
305{ 323{
306 static int dev; 324 snd_card_free(platform_get_drvdata(devptr));
307 int res; 325 platform_set_drvdata(devptr, NULL);
308 326 return 0;
309 for ( ; dev < SNDRV_CARDS; dev++) {
310 if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
311 continue;
312 port[dev] = xport;
313 res = snd_gusextreme_probe(dev);
314 if (res < 0)
315 port[dev] = SNDRV_AUTO_PORT;
316 return res;
317 }
318 return -ENODEV;
319} 327}
320 328
329#define GUSEXTREME_DRIVER "snd_gusextreme"
330
331static struct platform_driver snd_gusextreme_driver = {
332 .probe = snd_gusextreme_probe,
333 .remove = snd_gusextreme_remove,
334 /* FIXME: suspend/resume */
335 .driver = {
336 .name = GUSEXTREME_DRIVER
337 },
338};
339
321static int __init alsa_card_gusextreme_init(void) 340static int __init alsa_card_gusextreme_init(void)
322{ 341{
323 static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1}; 342 int i, cards, err;
324 int dev, cards, i; 343
325 344 err = platform_driver_register(&snd_gusextreme_driver);
326 for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev] > 0; dev++) { 345 if (err < 0)
327 if (port[dev] == SNDRV_AUTO_PORT) 346 return err;
328 continue;
329 if (snd_gusextreme_probe(dev) >= 0)
330 cards++;
331 }
332 i = snd_legacy_auto_probe(possible_ports, snd_gusextreme_legacy_auto_probe);
333 if (i > 0)
334 cards += i;
335 347
348 cards = 0;
349 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
350 struct platform_device *device;
351 device = platform_device_register_simple(GUSEXTREME_DRIVER,
352 i, NULL, 0);
353 if (IS_ERR(device)) {
354 err = PTR_ERR(device);
355 goto errout;
356 }
357 cards++;
358 }
336 if (!cards) { 359 if (!cards) {
337#ifdef MODULE 360#ifdef MODULE
338 printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n"); 361 printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n");
339#endif 362#endif
340 return -ENODEV; 363 err = -ENODEV;
364 goto errout;
341 } 365 }
342 return 0; 366 return 0;
367
368 errout:
369 platform_driver_unregister(&snd_gusextreme_driver);
370 return err;
343} 371}
344 372
345static void __exit alsa_card_gusextreme_exit(void) 373static void __exit alsa_card_gusextreme_exit(void)
346{ 374{
347 int idx; 375 platform_driver_unregister(&snd_gusextreme_driver);
348 struct snd_card *card;
349 struct snd_gusextreme *acard;
350
351 for (idx = 0; idx < SNDRV_CARDS; idx++) {
352 card = snd_gusextreme_cards[idx];
353 if (card == NULL)
354 continue;
355 acard = (struct snd_gusextreme *)card->private_data;
356 snd_card_free(snd_gusextreme_cards[idx]);
357 }
358} 376}
359 377
360module_init(alsa_card_gusextreme_init) 378module_init(alsa_card_gusextreme_init)