diff options
Diffstat (limited to 'sound/isa/es1688/es1688.c')
-rw-r--r-- | sound/isa/es1688/es1688.c | 112 |
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."); | |||
68 | module_param_array(dma8, int, NULL, 0444); | 69 | module_param_array(dma8, int, NULL, 0444); |
69 | MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); | 70 | MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); |
70 | 71 | ||
71 | static struct snd_card *snd_audiodrive_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
72 | |||
73 | #define PFX "es1688: " | 72 | #define PFX "es1688: " |
74 | 73 | ||
75 | static int __init snd_audiodrive_probe(int dev) | 74 | static 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 | ||
153 | static int __init snd_audiodrive_legacy_auto_probe(unsigned long xport) | 172 | static 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 | |||
181 | static 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 | |||
170 | static int __init alsa_card_es1688_init(void) | 190 | static 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 | ||
194 | static void __exit alsa_card_es1688_exit(void) | 223 | static 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 | ||
202 | module_init(alsa_card_es1688_init) | 228 | module_init(alsa_card_es1688_init) |