diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 11:13:12 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:28:31 -0500 |
commit | 277e926c9b2722317a6bf89ed921d97f6784e0cc (patch) | |
tree | a8f5ae3307e26fecd61f11ac60205c34ebe587ac | |
parent | feb158e6ada20b7871f625e1edd429216ac00d3c (diff) |
[ALSA] sscape - Use platform_device
Modules: Sound Scape driver
Rewrite the probe/remove with platform_device.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/isa/sscape.c | 282 |
1 files changed, 112 insertions, 170 deletions
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index d07963eddb3f..6271efe689df 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/err.h> | ||
27 | #include <linux/platform_device.h> | ||
26 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
27 | #include <linux/pnp.h> | 29 | #include <linux/pnp.h> |
28 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
@@ -75,8 +77,6 @@ static struct pnp_card_device_id sscape_pnpids[] = { | |||
75 | MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids); | 77 | MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids); |
76 | #endif | 78 | #endif |
77 | 79 | ||
78 | static struct snd_card *sscape_card[SNDRV_CARDS]; | ||
79 | |||
80 | 80 | ||
81 | #define MPU401_IO(i) ((i) + 0) | 81 | #define MPU401_IO(i) ((i) + 0) |
82 | #define MIDI_DATA_IO(i) ((i) + 0) | 82 | #define MIDI_DATA_IO(i) ((i) + 0) |
@@ -1080,48 +1080,18 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq | |||
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | 1082 | ||
1083 | struct params | ||
1084 | { | ||
1085 | int index; | ||
1086 | const char *id; | ||
1087 | unsigned port; | ||
1088 | int irq; | ||
1089 | int mpu_irq; | ||
1090 | int dma1; | ||
1091 | }; | ||
1092 | |||
1093 | |||
1094 | static inline struct params* | ||
1095 | init_params(struct params *params, | ||
1096 | int index, | ||
1097 | const char *id, | ||
1098 | unsigned port, | ||
1099 | int irq, | ||
1100 | int mpu_irq, | ||
1101 | int dma1) | ||
1102 | { | ||
1103 | params->index = index; | ||
1104 | params->id = id; | ||
1105 | params->port = port; | ||
1106 | params->irq = irq; | ||
1107 | params->mpu_irq = mpu_irq; | ||
1108 | params->dma1 = (dma1 & 0x03); | ||
1109 | |||
1110 | return params; | ||
1111 | } | ||
1112 | |||
1113 | |||
1114 | /* | 1083 | /* |
1115 | * Create an ALSA soundcard entry for the SoundScape, using | 1084 | * Create an ALSA soundcard entry for the SoundScape, using |
1116 | * the given list of port, IRQ and DMA resources. | 1085 | * the given list of port, IRQ and DMA resources. |
1117 | */ | 1086 | */ |
1118 | static int __devinit create_sscape(const struct params *params, struct snd_card **rcardp) | 1087 | static int __devinit create_sscape(int dev, struct snd_card **rcardp) |
1119 | { | 1088 | { |
1120 | struct snd_card *card; | 1089 | struct snd_card *card; |
1121 | register struct soundscape *sscape; | 1090 | register struct soundscape *sscape; |
1122 | register unsigned dma_cfg; | 1091 | register unsigned dma_cfg; |
1123 | unsigned irq_cfg; | 1092 | unsigned irq_cfg; |
1124 | unsigned mpu_irq_cfg; | 1093 | unsigned mpu_irq_cfg; |
1094 | unsigned xport; | ||
1125 | struct resource *io_res; | 1095 | struct resource *io_res; |
1126 | unsigned long flags; | 1096 | unsigned long flags; |
1127 | int err; | 1097 | int err; |
@@ -1129,32 +1099,33 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1129 | /* | 1099 | /* |
1130 | * Check that the user didn't pass us garbage data ... | 1100 | * Check that the user didn't pass us garbage data ... |
1131 | */ | 1101 | */ |
1132 | irq_cfg = get_irq_config(params->irq); | 1102 | irq_cfg = get_irq_config(irq[dev]); |
1133 | if (irq_cfg == INVALID_IRQ) { | 1103 | if (irq_cfg == INVALID_IRQ) { |
1134 | snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->irq); | 1104 | snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); |
1135 | return -ENXIO; | 1105 | return -ENXIO; |
1136 | } | 1106 | } |
1137 | 1107 | ||
1138 | mpu_irq_cfg = get_irq_config(params->mpu_irq); | 1108 | mpu_irq_cfg = get_irq_config(mpu_irq[dev]); |
1139 | if (mpu_irq_cfg == INVALID_IRQ) { | 1109 | if (mpu_irq_cfg == INVALID_IRQ) { |
1140 | printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->mpu_irq); | 1110 | printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); |
1141 | return -ENXIO; | 1111 | return -ENXIO; |
1142 | } | 1112 | } |
1113 | xport = port[dev]; | ||
1143 | 1114 | ||
1144 | /* | 1115 | /* |
1145 | * Grab IO ports that we will need to probe so that we | 1116 | * Grab IO ports that we will need to probe so that we |
1146 | * can detect and control this hardware ... | 1117 | * can detect and control this hardware ... |
1147 | */ | 1118 | */ |
1148 | if ((io_res = request_region(params->port, 8, "SoundScape")) == NULL) { | 1119 | if ((io_res = request_region(xport, 8, "SoundScape")) == NULL) { |
1149 | snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", params->port); | 1120 | snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport); |
1150 | return -EBUSY; | 1121 | return -EBUSY; |
1151 | } | 1122 | } |
1152 | 1123 | ||
1153 | /* | 1124 | /* |
1154 | * Grab both DMA channels (OK, only one for now) ... | 1125 | * Grab both DMA channels (OK, only one for now) ... |
1155 | */ | 1126 | */ |
1156 | if ((err = request_dma(params->dma1, "SoundScape")) < 0) { | 1127 | if ((err = request_dma(dma[dev], "SoundScape")) < 0) { |
1157 | snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", params->dma1); | 1128 | snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]); |
1158 | goto _release_region; | 1129 | goto _release_region; |
1159 | } | 1130 | } |
1160 | 1131 | ||
@@ -1162,7 +1133,8 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1162 | * Create a new ALSA sound card entry, in anticipation | 1133 | * Create a new ALSA sound card entry, in anticipation |
1163 | * of detecting our hardware ... | 1134 | * of detecting our hardware ... |
1164 | */ | 1135 | */ |
1165 | if ((card = snd_card_new(params->index, params->id, THIS_MODULE, sizeof(struct soundscape))) == NULL) { | 1136 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, |
1137 | sizeof(struct soundscape))) == NULL) { | ||
1166 | err = -ENOMEM; | 1138 | err = -ENOMEM; |
1167 | goto _release_dma; | 1139 | goto _release_dma; |
1168 | } | 1140 | } |
@@ -1171,7 +1143,7 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1171 | spin_lock_init(&sscape->lock); | 1143 | spin_lock_init(&sscape->lock); |
1172 | spin_lock_init(&sscape->fwlock); | 1144 | spin_lock_init(&sscape->fwlock); |
1173 | sscape->io_res = io_res; | 1145 | sscape->io_res = io_res; |
1174 | sscape->io_base = params->port; | 1146 | sscape->io_base = xport; |
1175 | 1147 | ||
1176 | if (!detect_sscape(sscape)) { | 1148 | if (!detect_sscape(sscape)) { |
1177 | printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); | 1149 | printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); |
@@ -1180,7 +1152,7 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1180 | } | 1152 | } |
1181 | 1153 | ||
1182 | printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", | 1154 | printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", |
1183 | sscape->io_base, params->irq, params->dma1); | 1155 | sscape->io_base, irq[dev], dma[dev]); |
1184 | 1156 | ||
1185 | /* | 1157 | /* |
1186 | * Now create the hardware-specific device so that we can | 1158 | * Now create the hardware-specific device so that we can |
@@ -1223,7 +1195,7 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1223 | sscape_write_unsafe(sscape->io_base, | 1195 | sscape_write_unsafe(sscape->io_base, |
1224 | GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); | 1196 | GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); |
1225 | sscape_write_unsafe(sscape->io_base, | 1197 | sscape_write_unsafe(sscape->io_base, |
1226 | GA_CDCFG_REG, 0x09 | DMA_8BIT | (params->dma1 << 4) | (irq_cfg << 1)); | 1198 | GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1)); |
1227 | 1199 | ||
1228 | spin_unlock_irqrestore(&sscape->lock, flags); | 1200 | spin_unlock_irqrestore(&sscape->lock, flags); |
1229 | 1201 | ||
@@ -1231,15 +1203,15 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1231 | * We have now enabled the codec chip, and so we should | 1203 | * We have now enabled the codec chip, and so we should |
1232 | * detect the AD1845 device ... | 1204 | * detect the AD1845 device ... |
1233 | */ | 1205 | */ |
1234 | if ((err = create_ad1845(card, CODEC_IO(params->port), params->irq, params->dma1)) < 0) { | 1206 | if ((err = create_ad1845(card, CODEC_IO(xport), irq[dev], dma[dev])) < 0) { |
1235 | printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n", | 1207 | printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n", |
1236 | CODEC_IO(params->port), params->irq); | 1208 | CODEC_IO(xport), irq[dev]); |
1237 | goto _release_card; | 1209 | goto _release_card; |
1238 | } | 1210 | } |
1239 | #define MIDI_DEVNUM 0 | 1211 | #define MIDI_DEVNUM 0 |
1240 | if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(params->port), params->mpu_irq)) < 0) { | 1212 | if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(xport), mpu_irq[dev])) < 0) { |
1241 | printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", | 1213 | printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", |
1242 | MPU401_IO(params->port)); | 1214 | MPU401_IO(xport)); |
1243 | goto _release_card; | 1215 | goto _release_card; |
1244 | } | 1216 | } |
1245 | 1217 | ||
@@ -1271,7 +1243,7 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1271 | snd_card_free(card); | 1243 | snd_card_free(card); |
1272 | 1244 | ||
1273 | _release_dma: | 1245 | _release_dma: |
1274 | free_dma(params->dma1); | 1246 | free_dma(dma[dev]); |
1275 | 1247 | ||
1276 | _release_region: | 1248 | _release_region: |
1277 | release_and_free_resource(io_res); | 1249 | release_and_free_resource(io_res); |
@@ -1280,44 +1252,66 @@ static int __devinit create_sscape(const struct params *params, struct snd_card | |||
1280 | } | 1252 | } |
1281 | 1253 | ||
1282 | 1254 | ||
1283 | static int sscape_cards __devinitdata; | 1255 | static int __init snd_sscape_probe(struct platform_device *pdev) |
1284 | static struct params sscape_params[SNDRV_CARDS] __devinitdata; | 1256 | { |
1257 | int dev = pdev->id; | ||
1258 | struct snd_card *card; | ||
1259 | int ret; | ||
1260 | |||
1261 | dma[dev] &= 0x03; | ||
1262 | ret = create_sscape(dev, &card); | ||
1263 | if (ret < 0) | ||
1264 | return ret; | ||
1265 | snd_card_set_dev(card, &pdev->dev); | ||
1266 | if ((ret = snd_card_register(card)) < 0) { | ||
1267 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | ||
1268 | return ret; | ||
1269 | } | ||
1270 | platform_set_drvdata(pdev, card); | ||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1274 | static int __devexit snd_sscape_remove(struct platform_device *devptr) | ||
1275 | { | ||
1276 | snd_card_free(platform_get_drvdata(devptr)); | ||
1277 | platform_set_drvdata(devptr, NULL); | ||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1281 | #define SSCAPE_DRIVER "snd_sscape" | ||
1282 | |||
1283 | static struct platform_driver snd_sscape_driver = { | ||
1284 | .probe = snd_sscape_probe, | ||
1285 | .remove = __devexit_p(snd_sscape_remove), | ||
1286 | /* FIXME: suspend/resume */ | ||
1287 | .driver = { | ||
1288 | .name = SSCAPE_DRIVER | ||
1289 | }, | ||
1290 | }; | ||
1285 | 1291 | ||
1286 | #ifdef CONFIG_PNP | 1292 | #ifdef CONFIG_PNP |
1287 | static inline int __devinit get_next_autoindex(int i) | 1293 | static inline int __devinit get_next_autoindex(int i) |
1288 | { | 1294 | { |
1289 | while ((i < SNDRV_CARDS) && (port[i] != SNDRV_AUTO_PORT)) { | 1295 | while (i < SNDRV_CARDS && port[i] != SNDRV_AUTO_PORT) |
1290 | ++i; | 1296 | ++i; |
1291 | } /* while */ | ||
1292 | |||
1293 | return i; | 1297 | return i; |
1294 | } | 1298 | } |
1295 | 1299 | ||
1296 | 1300 | ||
1297 | static inline int __devinit is_port_known(unsigned io, struct params *params, int cards) | ||
1298 | { | ||
1299 | while (--cards >= 0) { | ||
1300 | if (params[cards].port == io) | ||
1301 | return 1; | ||
1302 | } /* while */ | ||
1303 | |||
1304 | return 0; | ||
1305 | } | ||
1306 | |||
1307 | static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | 1301 | static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, |
1308 | const struct pnp_card_device_id *pid) | 1302 | const struct pnp_card_device_id *pid) |
1309 | { | 1303 | { |
1310 | struct pnp_dev *dev; | ||
1311 | static int idx = 0; | 1304 | static int idx = 0; |
1305 | struct pnp_dev *dev; | ||
1306 | struct snd_card *card; | ||
1312 | int ret; | 1307 | int ret; |
1313 | 1308 | ||
1314 | /* | 1309 | /* |
1315 | * Allow this function to fail *quietly* if all the ISA PnP | 1310 | * Allow this function to fail *quietly* if all the ISA PnP |
1316 | * devices were configured using module parameters instead. | 1311 | * devices were configured using module parameters instead. |
1317 | */ | 1312 | */ |
1318 | if ((idx = get_next_autoindex(idx)) >= SNDRV_CARDS) { | 1313 | if ((idx = get_next_autoindex(idx)) >= SNDRV_CARDS) |
1319 | return -ENOSPC; | 1314 | return -ENOSPC; |
1320 | } | ||
1321 | 1315 | ||
1322 | /* | 1316 | /* |
1323 | * We have found a candidate ISA PnP card. Now we | 1317 | * We have found a candidate ISA PnP card. Now we |
@@ -1339,66 +1333,45 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1339 | /* | 1333 | /* |
1340 | * Check that we still have room for another sound card ... | 1334 | * Check that we still have room for another sound card ... |
1341 | */ | 1335 | */ |
1342 | if (sscape_cards >= SNDRV_CARDS) { | ||
1343 | printk(KERN_ERR "sscape: No room for another ALSA device\n"); | ||
1344 | return -ENOSPC; | ||
1345 | } | ||
1346 | |||
1347 | ret = -ENODEV; | ||
1348 | |||
1349 | dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); | 1336 | dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); |
1350 | if (dev) { | 1337 | if (! dev) |
1351 | struct params *this; | 1338 | return -ENODEV; |
1352 | if (!pnp_is_active(dev)) { | ||
1353 | if (pnp_activate_dev(dev) < 0) { | ||
1354 | printk(KERN_INFO "sscape: device is inactive\n"); | ||
1355 | return -EBUSY; | ||
1356 | } | ||
1357 | } | ||
1358 | /* | ||
1359 | * Read the correct parameters off the ISA PnP bus ... | ||
1360 | */ | ||
1361 | this = init_params(&sscape_params[sscape_cards], | ||
1362 | index[idx], | ||
1363 | id[idx], | ||
1364 | pnp_port_start(dev, 0), | ||
1365 | pnp_irq(dev, 0), | ||
1366 | pnp_irq(dev, 1), | ||
1367 | pnp_dma(dev, 0)); | ||
1368 | 1339 | ||
1369 | /* | 1340 | if (!pnp_is_active(dev)) { |
1370 | * Do we know about this sound card already? | 1341 | if (pnp_activate_dev(dev) < 0) { |
1371 | */ | 1342 | printk(KERN_INFO "sscape: device is inactive\n"); |
1372 | if ( !is_port_known(this->port, sscape_params, sscape_cards) ) { | 1343 | return -EBUSY; |
1373 | struct snd_card *card; | ||
1374 | |||
1375 | ret = create_sscape(this, &card); | ||
1376 | if (ret < 0) | ||
1377 | return ret; | ||
1378 | snd_card_set_dev(card, &pcard->card->dev); | ||
1379 | |||
1380 | if ((ret = snd_card_register(card)) < 0) { | ||
1381 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | ||
1382 | snd_card_free(card); | ||
1383 | return ret; | ||
1384 | } | ||
1385 | |||
1386 | pnp_set_card_drvdata(pcard, card); | ||
1387 | ++sscape_cards; | ||
1388 | ++idx; | ||
1389 | } | 1344 | } |
1390 | } | 1345 | } |
1391 | 1346 | ||
1347 | /* | ||
1348 | * Read the correct parameters off the ISA PnP bus ... | ||
1349 | */ | ||
1350 | port[idx] = pnp_port_start(dev, 0); | ||
1351 | irq[idx] = pnp_irq(dev, 0); | ||
1352 | mpu_irq[idx] = pnp_irq(dev, 1); | ||
1353 | dma[idx] = pnp_dma(dev, 0) & 0x03; | ||
1354 | |||
1355 | ret = create_sscape(idx, &card); | ||
1356 | if (ret < 0) | ||
1357 | return ret; | ||
1358 | snd_card_set_dev(card, &pcard->card->dev); | ||
1359 | if ((ret = snd_card_register(card)) < 0) { | ||
1360 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | ||
1361 | snd_card_free(card); | ||
1362 | return ret; | ||
1363 | } | ||
1364 | |||
1365 | pnp_set_card_drvdata(pcard, card); | ||
1366 | ++idx; | ||
1367 | |||
1392 | return ret; | 1368 | return ret; |
1393 | } | 1369 | } |
1394 | 1370 | ||
1395 | static void __devexit sscape_pnp_remove(struct pnp_card_link * pcard) | 1371 | static void __devexit sscape_pnp_remove(struct pnp_card_link * pcard) |
1396 | { | 1372 | { |
1397 | struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard); | 1373 | snd_card_free(pnp_get_card_drvdata(pcard)); |
1398 | |||
1399 | pnp_set_card_drvdata(pcard, NULL); | 1374 | pnp_set_card_drvdata(pcard, NULL); |
1400 | snd_card_disconnect(card); | ||
1401 | snd_card_free_in_thread(card); | ||
1402 | } | 1375 | } |
1403 | 1376 | ||
1404 | static struct pnp_card_driver sscape_pnpc_driver = { | 1377 | static struct pnp_card_driver sscape_pnpc_driver = { |
@@ -1411,11 +1384,14 @@ static struct pnp_card_driver sscape_pnpc_driver = { | |||
1411 | 1384 | ||
1412 | #endif /* CONFIG_PNP */ | 1385 | #endif /* CONFIG_PNP */ |
1413 | 1386 | ||
1414 | static int __init sscape_manual_probe(struct params *params) | 1387 | static int __init sscape_manual_probe(void) |
1415 | { | 1388 | { |
1416 | int ret; | 1389 | struct platform_device *device; |
1417 | unsigned i; | 1390 | int i, ret; |
1418 | struct snd_card *card; | 1391 | |
1392 | ret = platform_driver_register(&snd_sscape_driver); | ||
1393 | if (ret < 0) | ||
1394 | return ret; | ||
1419 | 1395 | ||
1420 | for (i = 0; i < SNDRV_CARDS; ++i) { | 1396 | for (i = 0; i < SNDRV_CARDS; ++i) { |
1421 | /* | 1397 | /* |
@@ -1430,52 +1406,32 @@ static int __init sscape_manual_probe(struct params *params) | |||
1430 | /* | 1406 | /* |
1431 | * Make sure we were given ALL of the other parameters. | 1407 | * Make sure we were given ALL of the other parameters. |
1432 | */ | 1408 | */ |
1433 | if ( (irq[i] == SNDRV_AUTO_IRQ) || | 1409 | if (irq[i] == SNDRV_AUTO_IRQ || |
1434 | (mpu_irq[i] == SNDRV_AUTO_IRQ) || | 1410 | mpu_irq[i] == SNDRV_AUTO_IRQ || |
1435 | (dma[i] == SNDRV_AUTO_DMA) ) { | 1411 | dma[i] == SNDRV_AUTO_DMA) { |
1436 | printk(KERN_INFO | 1412 | printk(KERN_INFO |
1437 | "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); | 1413 | "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); |
1414 | platform_driver_unregister(&snd_sscape_driver); | ||
1438 | return -ENXIO; | 1415 | return -ENXIO; |
1439 | } | 1416 | } |
1440 | 1417 | ||
1441 | /* | 1418 | /* |
1442 | * This cards looks OK ... | 1419 | * This cards looks OK ... |
1443 | */ | 1420 | */ |
1444 | init_params(params, index[i], id[i], port[i], irq[i], mpu_irq[i], dma[i]); | 1421 | device = platform_device_register_simple(SSCAPE_DRIVER, |
1445 | 1422 | i, NULL, 0); | |
1446 | ret = create_sscape(params, &card); | 1423 | if (IS_ERR(device)) { |
1447 | if (ret < 0) | 1424 | platform_driver_unregister(&snd_sscape_driver); |
1448 | return ret; | 1425 | return PTR_ERR(device); |
1449 | |||
1450 | if ((ret = snd_card_set_generic_dev(card)) < 0) { | ||
1451 | snd_card_free(card); | ||
1452 | return ret; | ||
1453 | } | ||
1454 | if ((ret = snd_card_register(card)) < 0) { | ||
1455 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | ||
1456 | snd_card_free(card); | ||
1457 | return ret; | ||
1458 | } | 1426 | } |
1459 | 1427 | } | |
1460 | sscape_card[sscape_cards] = card; | ||
1461 | params++; | ||
1462 | sscape_cards++; | ||
1463 | } /* for */ | ||
1464 | |||
1465 | return 0; | 1428 | return 0; |
1466 | } | 1429 | } |
1467 | 1430 | ||
1468 | |||
1469 | static void sscape_exit(void) | 1431 | static void sscape_exit(void) |
1470 | { | 1432 | { |
1471 | unsigned i; | ||
1472 | |||
1473 | #ifdef CONFIG_PNP | ||
1474 | pnp_unregister_card_driver(&sscape_pnpc_driver); | 1433 | pnp_unregister_card_driver(&sscape_pnpc_driver); |
1475 | #endif | 1434 | platform_driver_unregister(&snd_sscape_driver); |
1476 | for (i = 0; i < ARRAY_SIZE(sscape_card); ++i) { | ||
1477 | snd_card_free(sscape_card[i]); | ||
1478 | } /* for */ | ||
1479 | } | 1435 | } |
1480 | 1436 | ||
1481 | 1437 | ||
@@ -1489,24 +1445,10 @@ static int __init sscape_init(void) | |||
1489 | * of allocating cards, because the operator is | 1445 | * of allocating cards, because the operator is |
1490 | * S-P-E-L-L-I-N-G it out for us... | 1446 | * S-P-E-L-L-I-N-G it out for us... |
1491 | */ | 1447 | */ |
1492 | ret = sscape_manual_probe(sscape_params); | 1448 | ret = sscape_manual_probe(); |
1493 | if (ret < 0) { | 1449 | if (ret < 0) |
1494 | int i; | ||
1495 | for (i = 0; i < sscape_cards; ++i) | ||
1496 | snd_card_free(sscape_card[i]); | ||
1497 | return ret; | 1450 | return ret; |
1498 | } | 1451 | pnp_register_card_driver(&sscape_pnpc_driver); |
1499 | |||
1500 | #ifdef CONFIG_PNP | ||
1501 | if (sscape_cards < SNDRV_CARDS) { | ||
1502 | ret = pnp_register_card_driver(&sscape_pnpc_driver); | ||
1503 | if (ret < 0) { | ||
1504 | sscape_exit(); | ||
1505 | return ret; | ||
1506 | } | ||
1507 | } | ||
1508 | #endif | ||
1509 | |||
1510 | return 0; | 1452 | return 0; |
1511 | } | 1453 | } |
1512 | 1454 | ||