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.c130
1 files changed, 84 insertions, 46 deletions
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 26a7d335ed8e..50d23cf3d7cc 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,19 +69,20 @@ 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 snd_card_t *snd_audiodrive_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; 72static struct platform_device *devices[SNDRV_CARDS];
72 73
73#define PFX "es1688: " 74#define PFX "es1688: "
74 75
75static int __init snd_audiodrive_probe(int dev) 76static int __init snd_es1688_probe(struct platform_device *pdev)
76{ 77{
78 int dev = pdev->id;
77 static int possible_irqs[] = {5, 9, 10, 7, -1}; 79 static int possible_irqs[] = {5, 9, 10, 7, -1};
78 static int possible_dmas[] = {1, 3, 0, -1}; 80 static int possible_dmas[] = {1, 3, 0, -1};
79 int xirq, xdma, xmpu_irq; 81 int xirq, xdma, xmpu_irq;
80 snd_card_t *card; 82 struct snd_card *card;
81 es1688_t *chip; 83 struct snd_es1688 *chip;
82 opl3_t *opl3; 84 struct snd_opl3 *opl3;
83 snd_pcm_t *pcm; 85 struct snd_pcm *pcm;
84 int err; 86 int err;
85 87
86 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); 88 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -105,10 +107,30 @@ static int __init snd_audiodrive_probe(int dev)
105 } 107 }
106 } 108 }
107 109
108 if ((err = snd_es1688_create(card, port[dev], mpu_port[dev], 110 if (port[dev] != SNDRV_AUTO_PORT) {
109 xirq, xmpu_irq, xdma, 111 if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
110 ES1688_HW_AUTO, &chip)) < 0) 112 xirq, xmpu_irq, xdma,
111 goto _err; 113 ES1688_HW_AUTO, &chip)) < 0)
114 goto _err;
115 } else {
116 /* auto-probe legacy ports */
117 static unsigned long possible_ports[] = {
118 0x220, 0x240, 0x260,
119 };
120 int i;
121 for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
122 err = snd_es1688_create(card, possible_ports[i],
123 mpu_port[dev],
124 xirq, xmpu_irq, xdma,
125 ES1688_HW_AUTO, &chip);
126 if (err >= 0) {
127 port[dev] = possible_ports[i];
128 break;
129 }
130 }
131 if (i >= ARRAY_SIZE(possible_ports))
132 goto _err;
133 }
112 134
113 if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) 135 if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
114 goto _err; 136 goto _err;
@@ -136,13 +158,12 @@ static int __init snd_audiodrive_probe(int dev)
136 goto _err; 158 goto _err;
137 } 159 }
138 160
139 if ((err = snd_card_set_generic_dev(card)) < 0) 161 snd_card_set_dev(card, &pdev->dev);
140 goto _err;
141 162
142 if ((err = snd_card_register(card)) < 0) 163 if ((err = snd_card_register(card)) < 0)
143 goto _err; 164 goto _err;
144 165
145 snd_audiodrive_cards[dev] = card; 166 platform_set_drvdata(pdev, card);
146 return 0; 167 return 0;
147 168
148 _err: 169 _err:
@@ -150,53 +171,70 @@ static int __init snd_audiodrive_probe(int dev)
150 return err; 171 return err;
151} 172}
152 173
153static int __init snd_audiodrive_legacy_auto_probe(unsigned long xport) 174static int snd_es1688_remove(struct platform_device *devptr)
154{ 175{
155 static int dev; 176 snd_card_free(platform_get_drvdata(devptr));
156 int res; 177 platform_set_drvdata(devptr, NULL);
157 178 return 0;
158 for ( ; dev < SNDRV_CARDS; dev++) { 179}
159 if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT) 180
160 continue; 181#define ES1688_DRIVER "snd_es1688"
161 port[dev] = xport; 182
162 res = snd_audiodrive_probe(dev); 183static struct platform_driver snd_es1688_driver = {
163 if (res < 0) 184 .probe = snd_es1688_probe,
164 port[dev] = SNDRV_AUTO_PORT; 185 .remove = snd_es1688_remove,
165 return res; 186 /* FIXME: suspend/resume */
166 } 187 .driver = {
167 return -ENODEV; 188 .name = ES1688_DRIVER
189 },
190};
191
192static void __init_or_module snd_es1688_unregister_all(void)
193{
194 int i;
195
196 for (i = 0; i < ARRAY_SIZE(devices); ++i)
197 platform_device_unregister(devices[i]);
198 platform_driver_unregister(&snd_es1688_driver);
168} 199}
169 200
170static int __init alsa_card_es1688_init(void) 201static int __init alsa_card_es1688_init(void)
171{ 202{
172 static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1}; 203 int i, cards, err;
173 int dev, cards = 0, i; 204
174 205 err = platform_driver_register(&snd_es1688_driver);
175 for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) { 206 if (err < 0)
176 if (port[dev] == SNDRV_AUTO_PORT) 207 return err;
177 continue; 208
178 if (snd_audiodrive_probe(dev) >= 0) 209 cards = 0;
179 cards++; 210 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
211 struct platform_device *device;
212 device = platform_device_register_simple(ES1688_DRIVER,
213 i, NULL, 0);
214 if (IS_ERR(device)) {
215 err = PTR_ERR(device);
216 goto errout;
217 }
218 devices[i] = device;
219 cards++;
180 } 220 }
181 i = snd_legacy_auto_probe(possible_ports, snd_audiodrive_legacy_auto_probe);
182 if (i > 0)
183 cards += i;
184
185 if (!cards) { 221 if (!cards) {
186#ifdef MODULE 222#ifdef MODULE
187 printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n"); 223 printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
188#endif 224#endif
189 return -ENODEV; 225 err = -ENODEV;
226 goto errout;
190 } 227 }
191 return 0; 228 return 0;
229
230 errout:
231 snd_es1688_unregister_all();
232 return err;
192} 233}
193 234
194static void __exit alsa_card_es1688_exit(void) 235static void __exit alsa_card_es1688_exit(void)
195{ 236{
196 int idx; 237 snd_es1688_unregister_all();
197
198 for (idx = 0; idx < SNDRV_CARDS; idx++)
199 snd_card_free(snd_audiodrive_cards[idx]);
200} 238}
201 239
202module_init(alsa_card_es1688_init) 240module_init(alsa_card_es1688_init)