diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-09-17 10:23:13 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 10:50:47 -0400 |
commit | 4996bca9850c0d6a1dd6c541efda3738ba2305ae (patch) | |
tree | aba88bfbfe2ca0122a9fd2ea09d0f1e448cff666 /sound/isa/sscape.c | |
parent | ad1e34b5653f86cbff2ea45dd166e2e58949d9bb (diff) |
[ALSA] sscape: driver extension to 2nd DMA and WSS port
This patch adds second DMA channel and WSS port settings
to the sscape driver. Also, it adds internal card type setting.
The Ensoniq SoundScape VIVO PnP id is added but not handled
yet.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/isa/sscape.c')
-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 | ||