aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/es1688/es1688.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/es1688/es1688.c')
-rw-r--r--sound/isa/es1688/es1688.c112
1 files changed, 69 insertions, 43 deletions
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 278511bd0950..68bd40a76f01 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -20,16 +20,17 @@
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/time.h> 26#include <linux/time.h>
26#include <linux/wait.h> 27#include <linux/wait.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/es1688.h> 31#include <sound/es1688.h>
30#include <sound/mpu401.h> 32#include <sound/mpu401.h>
31#include <sound/opl3.h> 33#include <sound/opl3.h>
32#define SNDRV_LEGACY_AUTO_PROBE
33#define SNDRV_LEGACY_FIND_FREE_IRQ 34#define SNDRV_LEGACY_FIND_FREE_IRQ
34#define SNDRV_LEGACY_FIND_FREE_DMA 35#define SNDRV_LEGACY_FIND_FREE_DMA
35#include <sound/initval.h> 36#include <sound/initval.h>
@@ -68,12 +69,11 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver.");
68module_param_array(dma8, int, NULL, 0444); 69module_param_array(dma8, int, NULL, 0444);
69MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); 70MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
70 71
71static struct snd_card *snd_audiodrive_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
72
73#define PFX "es1688: " 72#define PFX "es1688: "
74 73
75static int __init snd_audiodrive_probe(int dev) 74static int __init snd_es1688_probe(struct platform_device *pdev)
76{ 75{
76 int dev = pdev->id;
77 static int possible_irqs[] = {5, 9, 10, 7, -1}; 77 static int possible_irqs[] = {5, 9, 10, 7, -1};
78 static int possible_dmas[] = {1, 3, 0, -1}; 78 static int possible_dmas[] = {1, 3, 0, -1};
79 int xirq, xdma, xmpu_irq; 79 int xirq, xdma, xmpu_irq;
@@ -105,10 +105,30 @@ static int __init snd_audiodrive_probe(int dev)
105 } 105 }
106 } 106 }
107 107
108 if ((err = snd_es1688_create(card, port[dev], mpu_port[dev], 108 if (port[dev] != SNDRV_AUTO_PORT) {
109 xirq, xmpu_irq, xdma, 109 if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
110 ES1688_HW_AUTO, &chip)) < 0) 110 xirq, xmpu_irq, xdma,
111 goto _err; 111 ES1688_HW_AUTO, &chip)) < 0)
112 goto _err;
113 } else {
114 /* auto-probe legacy ports */
115 static unsigned long possible_ports[] = {
116 0x220, 0x240, 0x260,
117 };
118 int i;
119 for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
120 err = snd_es1688_create(card, possible_ports[i],
121 mpu_port[dev],
122 xirq, xmpu_irq, xdma,
123 ES1688_HW_AUTO, &chip);
124 if (err >= 0) {
125 port[dev] = possible_ports[i];
126 break;
127 }
128 }
129 if (i >= ARRAY_SIZE(possible_ports))
130 goto _err;
131 }
112 132
113 if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) 133 if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
114 goto _err; 134 goto _err;
@@ -136,13 +156,12 @@ static int __init snd_audiodrive_probe(int dev)
136 goto _err; 156 goto _err;
137 } 157 }
138 158
139 if ((err = snd_card_set_generic_dev(card)) < 0) 159 snd_card_set_dev(card, &pdev->dev);
140 goto _err;
141 160
142 if ((err = snd_card_register(card)) < 0) 161 if ((err = snd_card_register(card)) < 0)
143 goto _err; 162 goto _err;
144 163
145 snd_audiodrive_cards[dev] = card; 164 platform_set_drvdata(pdev, card);
146 return 0; 165 return 0;
147 166
148 _err: 167 _err:
@@ -150,53 +169,60 @@ static int __init snd_audiodrive_probe(int dev)
150 return err; 169 return err;
151} 170}
152 171
153static int __init snd_audiodrive_legacy_auto_probe(unsigned long xport) 172static int snd_es1688_remove(struct platform_device *devptr)
154{ 173{
155 static int dev; 174 snd_card_free(platform_get_drvdata(devptr));
156 int res; 175 platform_set_drvdata(devptr, NULL);
157 176 return 0;
158 for ( ; dev < SNDRV_CARDS; dev++) {
159 if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
160 continue;
161 port[dev] = xport;
162 res = snd_audiodrive_probe(dev);
163 if (res < 0)
164 port[dev] = SNDRV_AUTO_PORT;
165 return res;
166 }
167 return -ENODEV;
168} 177}
169 178
179#define ES1688_DRIVER "snd_es1688"
180
181static struct platform_driver snd_es1688_driver = {
182 .probe = snd_es1688_probe,
183 .remove = snd_es1688_remove,
184 /* FIXME: suspend/resume */
185 .driver = {
186 .name = ES1688_DRIVER
187 },
188};
189
170static int __init alsa_card_es1688_init(void) 190static int __init alsa_card_es1688_init(void)
171{ 191{
172 static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1}; 192 int i, cards, err;
173 int dev, cards = 0, i; 193
174 194 err = platform_driver_register(&snd_es1688_driver);
175 for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) { 195 if (err < 0)
176 if (port[dev] == SNDRV_AUTO_PORT) 196 return err;
177 continue; 197
178 if (snd_audiodrive_probe(dev) >= 0) 198 cards = 0;
179 cards++; 199 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
200 struct platform_device *device;
201 device = platform_device_register_simple(ES1688_DRIVER,
202 i, NULL, 0);
203 if (IS_ERR(device)) {
204 err = PTR_ERR(device);
205 goto errout;
206 }
207 cards++;
180 } 208 }
181 i = snd_legacy_auto_probe(possible_ports, snd_audiodrive_legacy_auto_probe);
182 if (i > 0)
183 cards += i;
184
185 if (!cards) { 209 if (!cards) {
186#ifdef MODULE 210#ifdef MODULE
187 printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n"); 211 printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
188#endif 212#endif
189 return -ENODEV; 213 err = -ENODEV;
214 goto errout;
190 } 215 }
191 return 0; 216 return 0;
217
218 errout:
219 platform_driver_unregister(&snd_es1688_driver);
220 return err;
192} 221}
193 222
194static void __exit alsa_card_es1688_exit(void) 223static void __exit alsa_card_es1688_exit(void)
195{ 224{
196 int idx; 225 platform_driver_unregister(&snd_es1688_driver);
197
198 for (idx = 0; idx < SNDRV_CARDS; idx++)
199 snd_card_free(snd_audiodrive_cards[idx]);
200} 226}
201 227
202module_init(alsa_card_es1688_init) 228module_init(alsa_card_es1688_init)