aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/opti9xx/miro.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-11-30 01:45:47 -0500
committerTakashi Iwai <tiwai@suse.de>2009-11-30 05:26:22 -0500
commit70a5f1187bcb3fac93a7d5c5fcfc5fc76b9c3f55 (patch)
tree18e91a2cd17770d51634ceb053f014b6b1c9092b /sound/isa/opti9xx/miro.c
parentabe6becb7c603991b925c0d2dd908e31dd6611f5 (diff)
ALSA: opti-miro: separate comon probing code
Separate common probing code in order to use it for PnP probing. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa/opti9xx/miro.c')
-rw-r--r--sound/isa/opti9xx/miro.c273
1 files changed, 147 insertions, 126 deletions
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index e374869e3e21..c67bc3cd2c65 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1142,28 +1142,39 @@ __skip_mpu:
1142 return 0; 1142 return 0;
1143} 1143}
1144 1144
1145static int __devinit snd_miro_opti_check(struct snd_miro *chip)
1146{
1147 unsigned char value;
1148
1149 chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
1150 "OPTi9xx MC");
1151 if (chip->res_mc_base == NULL)
1152 return -ENOMEM;
1153
1154 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1155 if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
1156 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1157 return 0;
1158
1159 release_and_free_resource(chip->res_mc_base);
1160 chip->res_mc_base = NULL;
1161
1162 return -ENODEV;
1163}
1164
1145static int __devinit snd_card_miro_detect(struct snd_card *card, 1165static int __devinit snd_card_miro_detect(struct snd_card *card,
1146 struct snd_miro *chip) 1166 struct snd_miro *chip)
1147{ 1167{
1148 int i, err; 1168 int i, err;
1149 unsigned char value;
1150 1169
1151 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) { 1170 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
1152 1171
1153 if ((err = snd_miro_init(chip, i)) < 0) 1172 if ((err = snd_miro_init(chip, i)) < 0)
1154 return err; 1173 return err;
1155 1174
1156 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 1175 err = snd_miro_opti_check(chip);
1157 continue; 1176 if (err == 0)
1158 1177 return 1;
1159 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1160 if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
1161 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1162 return 1;
1163
1164 release_and_free_resource(chip->res_mc_base);
1165 chip->res_mc_base = NULL;
1166
1167 } 1178 }
1168 1179
1169 return -ENODEV; 1180 return -ENODEV;
@@ -1234,151 +1245,69 @@ static void snd_card_miro_free(struct snd_card *card)
1234 release_and_free_resource(miro->res_mc_base); 1245 release_and_free_resource(miro->res_mc_base);
1235} 1246}
1236 1247
1237static int __devinit snd_miro_match(struct device *devptr, unsigned int n) 1248static int __devinit snd_miro_probe(struct snd_card *card)
1238{
1239 return 1;
1240}
1241
1242static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1243{ 1249{
1244 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1245 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1246 static int possible_irqs[] = {11, 9, 10, 7, -1};
1247 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1248 static int possible_dma1s[] = {3, 1, 0, -1};
1249 static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
1250
1251 int error; 1250 int error;
1252 struct snd_miro *miro; 1251 struct snd_miro *miro = card->private_data;
1253 struct snd_wss *codec; 1252 struct snd_wss *codec;
1254 struct snd_timer *timer; 1253 struct snd_timer *timer;
1255 struct snd_card *card;
1256 struct snd_pcm *pcm; 1254 struct snd_pcm *pcm;
1257 struct snd_rawmidi *rmidi; 1255 struct snd_rawmidi *rmidi;
1258 1256
1259 error = snd_card_create(index, id, THIS_MODULE, 1257 if (!miro->res_mc_base) {
1260 sizeof(struct snd_miro), &card); 1258 miro->res_mc_base = request_region(miro->mc_base,
1261 if (error < 0) 1259 miro->mc_base_size,
1262 return error; 1260 "miro (OPTi9xx MC)");
1263 1261 if (miro->res_mc_base == NULL) {
1264 card->private_free = snd_card_miro_free; 1262 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1265 miro = card->private_data; 1263 return -ENOMEM;
1266 1264 }
1267 error = snd_card_miro_detect(card, miro);
1268 if (error < 0) {
1269 snd_card_free(card);
1270 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
1271 return -ENODEV;
1272 } 1265 }
1273 1266
1274 if ((error = snd_card_miro_aci_detect(card, miro)) < 0) { 1267 error = snd_card_miro_aci_detect(card, miro);
1268 if (error < 0) {
1275 snd_card_free(card); 1269 snd_card_free(card);
1276 snd_printk(KERN_ERR "unable to detect aci chip\n"); 1270 snd_printk(KERN_ERR "unable to detect aci chip\n");
1277 return -ENODEV; 1271 return -ENODEV;
1278 } 1272 }
1279 1273
1280 /* init proc interface */
1281 snd_miro_proc_init(card, miro);
1282
1283
1284 if (! miro->res_mc_base &&
1285 (miro->res_mc_base = request_region(miro->mc_base, miro->mc_base_size,
1286 "miro (OPTi9xx MC)")) == NULL) {
1287 snd_card_free(card);
1288 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1289 return -ENOMEM;
1290 }
1291
1292 miro->wss_base = port; 1274 miro->wss_base = port;
1275 miro->mpu_port = mpu_port;
1293 miro->irq = irq; 1276 miro->irq = irq;
1294 miro->mpu_irq = mpu_irq; 1277 miro->mpu_irq = mpu_irq;
1295 miro->dma1 = dma1; 1278 miro->dma1 = dma1;
1296 miro->dma2 = dma2; 1279 miro->dma2 = dma2;
1297 1280
1298 if (miro->wss_base == SNDRV_AUTO_PORT) { 1281 /* init proc interface */
1299 if ((miro->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) { 1282 snd_miro_proc_init(card, miro);
1300 snd_card_free(card);
1301 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1302 return -EBUSY;
1303 }
1304 }
1305
1306 if (mpu_port == SNDRV_AUTO_PORT) {
1307 mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
1308 if (mpu_port < 0) {
1309 snd_card_free(card);
1310 snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
1311 return -EBUSY;
1312 }
1313 }
1314 miro->mpu_port = mpu_port;
1315
1316 if (miro->irq == SNDRV_AUTO_IRQ) {
1317 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
1318 snd_card_free(card);
1319 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1320 return -EBUSY;
1321 }
1322 }
1323 if (miro->mpu_irq == SNDRV_AUTO_IRQ) {
1324 if ((miro->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
1325 snd_card_free(card);
1326 snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
1327 return -EBUSY;
1328 }
1329 }
1330 if (miro->dma1 == SNDRV_AUTO_DMA) {
1331 if ((miro->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
1332 snd_card_free(card);
1333 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1334 return -EBUSY;
1335 }
1336 }
1337 if (miro->dma2 == SNDRV_AUTO_DMA) {
1338 if ((miro->dma2 = snd_legacy_find_free_dma(possible_dma2s[miro->dma1 % 4])) < 0) {
1339 snd_card_free(card);
1340 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1341 return -EBUSY;
1342 }
1343 }
1344 1283
1345 error = snd_miro_configure(miro); 1284 error = snd_miro_configure(miro);
1346 if (error) { 1285 if (error)
1347 snd_card_free(card);
1348 return error; 1286 return error;
1349 }
1350 1287
1351 error = snd_wss_create(card, miro->wss_base + 4, -1, 1288 error = snd_wss_create(card, miro->wss_base + 4, -1,
1352 miro->irq, miro->dma1, miro->dma2, 1289 miro->irq, miro->dma1, miro->dma2,
1353 WSS_HW_AD1845, 0, &codec); 1290 WSS_HW_DETECT, 0, &codec);
1354 if (error < 0) { 1291 if (error < 0)
1355 snd_card_free(card);
1356 return error; 1292 return error;
1357 }
1358 1293
1359 error = snd_wss_pcm(codec, 0, &pcm); 1294 error = snd_wss_pcm(codec, 0, &pcm);
1360 if (error < 0) { 1295 if (error < 0)
1361 snd_card_free(card);
1362 return error; 1296 return error;
1363 } 1297
1364 error = snd_wss_mixer(codec); 1298 error = snd_wss_mixer(codec);
1365 if (error < 0) { 1299 if (error < 0)
1366 snd_card_free(card);
1367 return error; 1300 return error;
1368 } 1301
1369 error = snd_wss_timer(codec, 0, &timer); 1302 error = snd_wss_timer(codec, 0, &timer);
1370 if (error < 0) { 1303 if (error < 0)
1371 snd_card_free(card);
1372 return error; 1304 return error;
1373 }
1374 1305
1375 miro->pcm = pcm; 1306 miro->pcm = pcm;
1376 1307
1377 error = snd_miro_mixer(card, miro); 1308 error = snd_miro_mixer(card, miro);
1378 if (error < 0) { 1309 if (error < 0)
1379 snd_card_free(card);
1380 return error; 1310 return error;
1381 }
1382 1311
1383 if (miro->aci->aci_vendor == 'm') { 1312 if (miro->aci->aci_vendor == 'm') {
1384 /* It looks like a miro sound card. */ 1313 /* It looks like a miro sound card. */
@@ -1425,20 +1354,111 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1425 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) { 1354 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
1426 struct snd_opl3 *opl3 = NULL; 1355 struct snd_opl3 *opl3 = NULL;
1427 struct snd_opl4 *opl4; 1356 struct snd_opl4 *opl4;
1357
1428 if (snd_opl4_create(card, fm_port, fm_port - 8, 1358 if (snd_opl4_create(card, fm_port, fm_port - 8,
1429 2, &opl3, &opl4) < 0) 1359 2, &opl3, &opl4) < 0)
1430 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n", 1360 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n",
1431 fm_port); 1361 fm_port);
1432 } 1362 }
1433 1363
1434 if ((error = snd_set_aci_init_values(miro)) < 0) { 1364 error = snd_set_aci_init_values(miro);
1435 snd_card_free(card); 1365 if (error < 0)
1436 return error; 1366 return error;
1367
1368 return snd_card_register(card);
1369}
1370
1371static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n)
1372{
1373 return 1;
1374}
1375
1376static int __devinit snd_miro_isa_probe(struct device *devptr, unsigned int n)
1377{
1378 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1379 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1380 static int possible_irqs[] = {11, 9, 10, 7, -1};
1381 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1382 static int possible_dma1s[] = {3, 1, 0, -1};
1383 static int possible_dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1},
1384 {0, -1} };
1385
1386 int error;
1387 struct snd_miro *miro;
1388 struct snd_card *card;
1389
1390 error = snd_card_create(index, id, THIS_MODULE,
1391 sizeof(struct snd_miro), &card);
1392 if (error < 0)
1393 return error;
1394
1395 card->private_free = snd_card_miro_free;
1396 miro = card->private_data;
1397
1398 error = snd_card_miro_detect(card, miro);
1399 if (error < 0) {
1400 snd_card_free(card);
1401 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
1402 return -ENODEV;
1403 }
1404
1405 if (port == SNDRV_AUTO_PORT) {
1406 port = snd_legacy_find_free_ioport(possible_ports, 4);
1407 if (port < 0) {
1408 snd_card_free(card);
1409 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1410 return -EBUSY;
1411 }
1412 }
1413
1414 if (mpu_port == SNDRV_AUTO_PORT) {
1415 mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
1416 if (mpu_port < 0) {
1417 snd_card_free(card);
1418 snd_printk(KERN_ERR
1419 "unable to find a free MPU401 port\n");
1420 return -EBUSY;
1421 }
1422 }
1423
1424 if (irq == SNDRV_AUTO_IRQ) {
1425 irq = snd_legacy_find_free_irq(possible_irqs);
1426 if (irq < 0) {
1427 snd_card_free(card);
1428 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1429 return -EBUSY;
1430 }
1431 }
1432 if (mpu_irq == SNDRV_AUTO_IRQ) {
1433 mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
1434 if (mpu_irq < 0) {
1435 snd_card_free(card);
1436 snd_printk(KERN_ERR
1437 "unable to find a free MPU401 IRQ\n");
1438 return -EBUSY;
1439 }
1440 }
1441 if (dma1 == SNDRV_AUTO_DMA) {
1442 dma1 = snd_legacy_find_free_dma(possible_dma1s);
1443 if (dma1 < 0) {
1444 snd_card_free(card);
1445 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1446 return -EBUSY;
1447 }
1448 }
1449 if (dma2 == SNDRV_AUTO_DMA) {
1450 dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
1451 if (dma2 < 0) {
1452 snd_card_free(card);
1453 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1454 return -EBUSY;
1455 }
1437 } 1456 }
1438 1457
1439 snd_card_set_dev(card, devptr); 1458 snd_card_set_dev(card, devptr);
1440 1459
1441 if ((error = snd_card_register(card))) { 1460 error = snd_miro_probe(card);
1461 if (error < 0) {
1442 snd_card_free(card); 1462 snd_card_free(card);
1443 return error; 1463 return error;
1444 } 1464 }
@@ -1447,7 +1467,8 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1447 return 0; 1467 return 0;
1448} 1468}
1449 1469
1450static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) 1470static int __devexit snd_miro_isa_remove(struct device *devptr,
1471 unsigned int dev)
1451{ 1472{
1452 snd_card_free(dev_get_drvdata(devptr)); 1473 snd_card_free(dev_get_drvdata(devptr));
1453 dev_set_drvdata(devptr, NULL); 1474 dev_set_drvdata(devptr, NULL);
@@ -1457,9 +1478,9 @@ static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
1457#define DEV_NAME "miro" 1478#define DEV_NAME "miro"
1458 1479
1459static struct isa_driver snd_miro_driver = { 1480static struct isa_driver snd_miro_driver = {
1460 .match = snd_miro_match, 1481 .match = snd_miro_isa_match,
1461 .probe = snd_miro_probe, 1482 .probe = snd_miro_isa_probe,
1462 .remove = __devexit_p(snd_miro_remove), 1483 .remove = __devexit_p(snd_miro_isa_remove),
1463 /* FIXME: suspend/resume */ 1484 /* FIXME: suspend/resume */
1464 .driver = { 1485 .driver = {
1465 .name = DEV_NAME 1486 .name = DEV_NAME