diff options
Diffstat (limited to 'sound/isa')
-rw-r--r-- | sound/isa/sscape.c | 150 |
1 files changed, 100 insertions, 50 deletions
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index cbad2a51cbaa..53daa8bd9b78 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -45,10 +45,12 @@ MODULE_LICENSE("GPL"); | |||
45 | 45 | ||
46 | static int index[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IDX; | 46 | static int index[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IDX; |
47 | static char* id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_STR; | 47 | static char* id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_STR; |
48 | static long port[SNDRV_CARDS] __devinitdata = { [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_PORT }; | 48 | static long port[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PORT; |
49 | static long wss_port[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PORT; | ||
49 | static int irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ; | 50 | static int irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ; |
50 | static int mpu_irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ; | 51 | static int mpu_irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ; |
51 | static int dma[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA; | 52 | static int dma[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA; |
53 | static int dma2[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA; | ||
52 | 54 | ||
53 | module_param_array(index, int, NULL, 0444); | 55 | module_param_array(index, int, NULL, 0444); |
54 | MODULE_PARM_DESC(index, "Index number for SoundScape soundcard"); | 56 | MODULE_PARM_DESC(index, "Index number for SoundScape soundcard"); |
@@ -59,6 +61,9 @@ MODULE_PARM_DESC(id, "Description for SoundScape card"); | |||
59 | module_param_array(port, long, NULL, 0444); | 61 | module_param_array(port, long, NULL, 0444); |
60 | MODULE_PARM_DESC(port, "Port # for SoundScape driver."); | 62 | MODULE_PARM_DESC(port, "Port # for SoundScape driver."); |
61 | 63 | ||
64 | module_param_array(wss_port, long, NULL, 0444); | ||
65 | MODULE_PARM_DESC(wss_port, "WSS Port # for SoundScape driver."); | ||
66 | |||
62 | module_param_array(irq, int, NULL, 0444); | 67 | module_param_array(irq, int, NULL, 0444); |
63 | MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver."); | 68 | MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver."); |
64 | 69 | ||
@@ -68,12 +73,16 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver."); | |||
68 | module_param_array(dma, int, NULL, 0444); | 73 | module_param_array(dma, int, NULL, 0444); |
69 | MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); | 74 | MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); |
70 | 75 | ||
76 | module_param_array(dma2, int, NULL, 0444); | ||
77 | MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver."); | ||
78 | |||
71 | #ifdef CONFIG_PNP | 79 | #ifdef CONFIG_PNP |
72 | static int isa_registered; | 80 | static int isa_registered; |
73 | static int pnp_registered; | 81 | static int pnp_registered; |
74 | 82 | ||
75 | static struct pnp_card_device_id sscape_pnpids[] = { | 83 | static struct pnp_card_device_id sscape_pnpids[] = { |
76 | { .id = "ENS3081", .devs = { { "ENS0000" } } }, | 84 | { .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */ |
85 | { .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */ | ||
77 | { .id = "" } /* end */ | 86 | { .id = "" } /* end */ |
78 | }; | 87 | }; |
79 | 88 | ||
@@ -124,11 +133,18 @@ enum GA_REG { | |||
124 | #define AD1845_FREQ_SEL_MSB 0x16 | 133 | #define AD1845_FREQ_SEL_MSB 0x16 |
125 | #define AD1845_FREQ_SEL_LSB 0x17 | 134 | #define AD1845_FREQ_SEL_LSB 0x17 |
126 | 135 | ||
136 | enum card_type { | ||
137 | SSCAPE, | ||
138 | SSCAPE_PNP, | ||
139 | SSCAPE_VIVO, | ||
140 | }; | ||
141 | |||
127 | struct soundscape { | 142 | struct soundscape { |
128 | spinlock_t lock; | 143 | spinlock_t lock; |
129 | unsigned io_base; | 144 | unsigned io_base; |
130 | int codec_type; | 145 | int codec_type; |
131 | int ic_type; | 146 | int ic_type; |
147 | enum card_type type; | ||
132 | struct resource *io_res; | 148 | struct resource *io_res; |
133 | struct snd_cs4231 *chip; | 149 | struct snd_cs4231 *chip; |
134 | struct snd_mpu401 *mpu; | 150 | struct snd_mpu401 *mpu; |
@@ -522,7 +538,7 @@ static int upload_dma_data(struct soundscape *s, | |||
522 | ret = -EAGAIN; | 538 | ret = -EAGAIN; |
523 | } | 539 | } |
524 | 540 | ||
525 | _release_dma: | 541 | _release_dma: |
526 | /* | 542 | /* |
527 | * NOTE!!! We are NOT holding any spinlocks at this point !!! | 543 | * NOTE!!! We are NOT holding any spinlocks at this point !!! |
528 | */ | 544 | */ |
@@ -995,21 +1011,20 @@ static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_pa | |||
995 | * try to support at least some of the extra bits by overriding | 1011 | * try to support at least some of the extra bits by overriding |
996 | * some of the CS4231 callback. | 1012 | * some of the CS4231 callback. |
997 | */ | 1013 | */ |
998 | static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq, int dma1) | 1014 | static int __devinit create_ad1845(struct snd_card *card, unsigned port, |
1015 | int irq, int dma1, int dma2) | ||
999 | { | 1016 | { |
1000 | register struct soundscape *sscape = get_card_soundscape(card); | 1017 | register struct soundscape *sscape = get_card_soundscape(card); |
1001 | struct snd_cs4231 *chip; | 1018 | struct snd_cs4231 *chip; |
1002 | int err; | 1019 | int err; |
1003 | 1020 | ||
1004 | #define CS4231_SHARE_HARDWARE (CS4231_HWSHARE_DMA1 | CS4231_HWSHARE_DMA2) | 1021 | if (dma1 == dma2) |
1005 | /* | 1022 | dma2 = -1; |
1006 | * The AD1845 PCM device is only half-duplex, and so | 1023 | |
1007 | * we only give it one DMA channel ... | 1024 | err = snd_cs4231_create(card, |
1008 | */ | 1025 | port, -1, irq, dma1, dma2, |
1009 | if ((err = snd_cs4231_create(card, | 1026 | CS4231_HW_DETECT, CS4231_HWSHARE_DMA1, &chip); |
1010 | port, -1, irq, dma1, dma1, | 1027 | if (!err) { |
1011 | CS4231_HW_DETECT, | ||
1012 | CS4231_HWSHARE_DMA1, &chip)) == 0) { | ||
1013 | unsigned long flags; | 1028 | unsigned long flags; |
1014 | struct snd_pcm *pcm; | 1029 | struct snd_pcm *pcm; |
1015 | 1030 | ||
@@ -1070,8 +1085,9 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq | |||
1070 | strcpy(card->driver, "SoundScape"); | 1085 | strcpy(card->driver, "SoundScape"); |
1071 | strcpy(card->shortname, pcm->name); | 1086 | strcpy(card->shortname, pcm->name); |
1072 | snprintf(card->longname, sizeof(card->longname), | 1087 | snprintf(card->longname, sizeof(card->longname), |
1073 | "%s at 0x%lx, IRQ %d, DMA %d\n", | 1088 | "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n", |
1074 | pcm->name, chip->port, chip->irq, chip->dma1); | 1089 | pcm->name, chip->port, chip->irq, |
1090 | chip->dma1, chip->dma2); | ||
1075 | chip->set_playback_format = ad1845_playback_format; | 1091 | chip->set_playback_format = ad1845_playback_format; |
1076 | chip->set_capture_format = ad1845_capture_format; | 1092 | chip->set_capture_format = ad1845_capture_format; |
1077 | sscape->chip = chip; | 1093 | sscape->chip = chip; |
@@ -1086,9 +1102,8 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq | |||
1086 | * Create an ALSA soundcard entry for the SoundScape, using | 1102 | * Create an ALSA soundcard entry for the SoundScape, using |
1087 | * the given list of port, IRQ and DMA resources. | 1103 | * the given list of port, IRQ and DMA resources. |
1088 | */ | 1104 | */ |
1089 | static int __devinit create_sscape(int dev, struct snd_card **rcardp) | 1105 | static int __devinit create_sscape(int dev, struct snd_card *card) |
1090 | { | 1106 | { |
1091 | struct snd_card *card; | ||
1092 | register struct soundscape *sscape; | 1107 | register struct soundscape *sscape; |
1093 | register unsigned dma_cfg; | 1108 | register unsigned dma_cfg; |
1094 | unsigned irq_cfg; | 1109 | unsigned irq_cfg; |
@@ -1126,21 +1141,12 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1126 | /* | 1141 | /* |
1127 | * Grab both DMA channels (OK, only one for now) ... | 1142 | * Grab both DMA channels (OK, only one for now) ... |
1128 | */ | 1143 | */ |
1129 | if ((err = request_dma(dma[dev], "SoundScape")) < 0) { | 1144 | err = request_dma(dma[dev], "SoundScape"); |
1145 | if (err < 0) { | ||
1130 | snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]); | 1146 | snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]); |
1131 | goto _release_region; | 1147 | goto _release_region; |
1132 | } | 1148 | } |
1133 | 1149 | ||
1134 | /* | ||
1135 | * Create a new ALSA sound card entry, in anticipation | ||
1136 | * of detecting our hardware ... | ||
1137 | */ | ||
1138 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
1139 | sizeof(struct soundscape))) == NULL) { | ||
1140 | err = -ENOMEM; | ||
1141 | goto _release_dma; | ||
1142 | } | ||
1143 | |||
1144 | sscape = get_card_soundscape(card); | 1150 | sscape = get_card_soundscape(card); |
1145 | spin_lock_init(&sscape->lock); | 1151 | spin_lock_init(&sscape->lock); |
1146 | spin_lock_init(&sscape->fwlock); | 1152 | spin_lock_init(&sscape->fwlock); |
@@ -1150,11 +1156,11 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1150 | if (!detect_sscape(sscape)) { | 1156 | if (!detect_sscape(sscape)) { |
1151 | printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); | 1157 | printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); |
1152 | err = -ENODEV; | 1158 | err = -ENODEV; |
1153 | goto _release_card; | 1159 | goto _release_dma; |
1154 | } | 1160 | } |
1155 | 1161 | ||
1156 | printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", | 1162 | printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", |
1157 | sscape->io_base, irq[dev], dma[dev]); | 1163 | sscape->io_base, irq[dev], dma[dev]); |
1158 | 1164 | ||
1159 | /* | 1165 | /* |
1160 | * Now create the hardware-specific device so that we can | 1166 | * Now create the hardware-specific device so that we can |
@@ -1164,7 +1170,7 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1164 | */ | 1170 | */ |
1165 | if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) { | 1171 | if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) { |
1166 | printk(KERN_ERR "sscape: Failed to create firmware device\n"); | 1172 | printk(KERN_ERR "sscape: Failed to create firmware device\n"); |
1167 | goto _release_card; | 1173 | goto _release_dma; |
1168 | } | 1174 | } |
1169 | strlcpy(sscape->hw->name, "SoundScape M68K", sizeof(sscape->hw->name)); | 1175 | strlcpy(sscape->hw->name, "SoundScape M68K", sizeof(sscape->hw->name)); |
1170 | sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0'; | 1176 | sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0'; |
@@ -1197,7 +1203,8 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1197 | sscape_write_unsafe(sscape->io_base, | 1203 | sscape_write_unsafe(sscape->io_base, |
1198 | GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); | 1204 | GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); |
1199 | sscape_write_unsafe(sscape->io_base, | 1205 | sscape_write_unsafe(sscape->io_base, |
1200 | GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1)); | 1206 | GA_CDCFG_REG, 0x09 | DMA_8BIT |
1207 | | (dma[dev] << 4) | (irq_cfg << 1)); | ||
1201 | 1208 | ||
1202 | spin_unlock_irqrestore(&sscape->lock, flags); | 1209 | spin_unlock_irqrestore(&sscape->lock, flags); |
1203 | 1210 | ||
@@ -1205,16 +1212,18 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1205 | * We have now enabled the codec chip, and so we should | 1212 | * We have now enabled the codec chip, and so we should |
1206 | * detect the AD1845 device ... | 1213 | * detect the AD1845 device ... |
1207 | */ | 1214 | */ |
1208 | if ((err = create_ad1845(card, CODEC_IO(xport), irq[dev], dma[dev])) < 0) { | 1215 | err = create_ad1845(card, wss_port[dev], irq[dev], |
1209 | printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n", | 1216 | dma[dev], dma2[dev]); |
1210 | CODEC_IO(xport), irq[dev]); | 1217 | if (err < 0) { |
1211 | goto _release_card; | 1218 | printk(KERN_ERR "sscape: No AD1845 device at 0x%lx, IRQ %d\n", |
1219 | wss_port[dev], irq[dev]); | ||
1220 | goto _release_dma; | ||
1212 | } | 1221 | } |
1213 | #define MIDI_DEVNUM 0 | 1222 | #define MIDI_DEVNUM 0 |
1214 | if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(xport), mpu_irq[dev])) < 0) { | 1223 | if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(xport), mpu_irq[dev])) < 0) { |
1215 | printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", | 1224 | printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", |
1216 | MPU401_IO(xport)); | 1225 | MPU401_IO(xport)); |
1217 | goto _release_card; | 1226 | goto _release_dma; |
1218 | } | 1227 | } |
1219 | 1228 | ||
1220 | /* | 1229 | /* |
@@ -1237,17 +1246,13 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1237 | * function now that our "constructor" has completed. | 1246 | * function now that our "constructor" has completed. |
1238 | */ | 1247 | */ |
1239 | card->private_free = soundscape_free; | 1248 | card->private_free = soundscape_free; |
1240 | *rcardp = card; | ||
1241 | 1249 | ||
1242 | return 0; | 1250 | return 0; |
1243 | 1251 | ||
1244 | _release_card: | 1252 | _release_dma: |
1245 | snd_card_free(card); | ||
1246 | |||
1247 | _release_dma: | ||
1248 | free_dma(dma[dev]); | 1253 | free_dma(dma[dev]); |
1249 | 1254 | ||
1250 | _release_region: | 1255 | _release_region: |
1251 | release_and_free_resource(io_res); | 1256 | release_and_free_resource(io_res); |
1252 | 1257 | ||
1253 | return err; | 1258 | return err; |
@@ -1276,19 +1281,33 @@ static int __devinit snd_sscape_match(struct device *pdev, unsigned int i) | |||
1276 | static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) | 1281 | static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) |
1277 | { | 1282 | { |
1278 | struct snd_card *card; | 1283 | struct snd_card *card; |
1284 | struct soundscape *sscape; | ||
1279 | int ret; | 1285 | int ret; |
1280 | 1286 | ||
1287 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
1288 | sizeof(struct soundscape)); | ||
1289 | if (!card) | ||
1290 | return -ENOMEM; | ||
1291 | |||
1292 | sscape = get_card_soundscape(card); | ||
1293 | sscape->type = SSCAPE; | ||
1294 | |||
1281 | dma[dev] &= 0x03; | 1295 | dma[dev] &= 0x03; |
1282 | ret = create_sscape(dev, &card); | 1296 | ret = create_sscape(dev, card); |
1283 | if (ret < 0) | 1297 | if (ret < 0) |
1284 | return ret; | 1298 | goto _release_card; |
1299 | |||
1285 | snd_card_set_dev(card, pdev); | 1300 | snd_card_set_dev(card, pdev); |
1286 | if ((ret = snd_card_register(card)) < 0) { | 1301 | if ((ret = snd_card_register(card)) < 0) { |
1287 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | 1302 | printk(KERN_ERR "sscape: Failed to register sound card\n"); |
1288 | return ret; | 1303 | goto _release_card; |
1289 | } | 1304 | } |
1290 | dev_set_drvdata(pdev, card); | 1305 | dev_set_drvdata(pdev, card); |
1291 | return 0; | 1306 | return 0; |
1307 | |||
1308 | _release_card: | ||
1309 | snd_card_free(card); | ||
1310 | return ret; | ||
1292 | } | 1311 | } |
1293 | 1312 | ||
1294 | static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) | 1313 | static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) |
@@ -1325,6 +1344,7 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1325 | static int idx = 0; | 1344 | static int idx = 0; |
1326 | struct pnp_dev *dev; | 1345 | struct pnp_dev *dev; |
1327 | struct snd_card *card; | 1346 | struct snd_card *card; |
1347 | struct soundscape *sscape; | ||
1328 | int ret; | 1348 | int ret; |
1329 | 1349 | ||
1330 | /* | 1350 | /* |
@@ -1366,26 +1386,56 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1366 | } | 1386 | } |
1367 | 1387 | ||
1368 | /* | 1388 | /* |
1389 | * Create a new ALSA sound card entry, in anticipation | ||
1390 | * of detecting our hardware ... | ||
1391 | */ | ||
1392 | card = snd_card_new(index[idx], id[idx], THIS_MODULE, | ||
1393 | sizeof(struct soundscape)); | ||
1394 | if (!card) | ||
1395 | return -ENOMEM; | ||
1396 | |||
1397 | sscape = get_card_soundscape(card); | ||
1398 | |||
1399 | /* | ||
1400 | * Identify card model ... | ||
1401 | */ | ||
1402 | if (!strncmp("ENS4081", pid->id, 7)) | ||
1403 | sscape->type = SSCAPE_VIVO; | ||
1404 | else | ||
1405 | sscape->type = SSCAPE_PNP; | ||
1406 | |||
1407 | /* VIVO fails for now */ | ||
1408 | if (sscape->type == SSCAPE_VIVO) { | ||
1409 | ret = -ENODEV; | ||
1410 | goto _release_card; | ||
1411 | } | ||
1412 | |||
1413 | /* | ||
1369 | * Read the correct parameters off the ISA PnP bus ... | 1414 | * Read the correct parameters off the ISA PnP bus ... |
1370 | */ | 1415 | */ |
1371 | port[idx] = pnp_port_start(dev, 0); | 1416 | port[idx] = pnp_port_start(dev, 0); |
1372 | irq[idx] = pnp_irq(dev, 0); | 1417 | irq[idx] = pnp_irq(dev, 0); |
1373 | mpu_irq[idx] = pnp_irq(dev, 1); | 1418 | mpu_irq[idx] = pnp_irq(dev, 1); |
1374 | dma[idx] = pnp_dma(dev, 0) & 0x03; | 1419 | dma[idx] = pnp_dma(dev, 0) & 0x03; |
1420 | dma2[idx] = dma[idx]; | ||
1421 | wss_port[idx] = CODEC_IO(port[idx]); | ||
1375 | 1422 | ||
1376 | ret = create_sscape(idx, &card); | 1423 | ret = create_sscape(idx, card); |
1377 | if (ret < 0) | 1424 | if (ret < 0) |
1378 | return ret; | 1425 | goto _release_card; |
1426 | |||
1379 | snd_card_set_dev(card, &pcard->card->dev); | 1427 | snd_card_set_dev(card, &pcard->card->dev); |
1380 | if ((ret = snd_card_register(card)) < 0) { | 1428 | if ((ret = snd_card_register(card)) < 0) { |
1381 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | 1429 | printk(KERN_ERR "sscape: Failed to register sound card\n"); |
1382 | snd_card_free(card); | 1430 | goto _release_card; |
1383 | return ret; | ||
1384 | } | 1431 | } |
1385 | 1432 | ||
1386 | pnp_set_card_drvdata(pcard, card); | 1433 | pnp_set_card_drvdata(pcard, card); |
1387 | ++idx; | 1434 | ++idx; |
1435 | return 0; | ||
1388 | 1436 | ||
1437 | _release_card: | ||
1438 | snd_card_free(card); | ||
1389 | return ret; | 1439 | return ret; |
1390 | } | 1440 | } |
1391 | 1441 | ||