diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:13:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:13:38 -0400 |
commit | fc8a327db6c46de783b1a4276d846841b9abc24c (patch) | |
tree | bee512c142cccea93511debd98ef954581693727 /sound/isa/sscape.c | |
parent | 92d15c2ccbb3e31a3fc71ad28fdb55e1319383c0 (diff) | |
parent | 24837e6f249a2c83667552e6871c1543b4a6b934 (diff) |
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (264 commits)
[ALSA] version 1.0.15
[ALSA] Fix thinko in cs4231 mce down check
[ALSA] sun-cs4231: improved waiting after MCE down
[ALSA] sun-cs4231: use cs4231-regs.h
[ALSA] This simplifies and fixes waiting loops of the mce_down()
[ALSA] This patch adds support for a wavetable chip on
[ALSA] This patch removes open_mutex from the ad1848-lib as
[ALSA] fix bootup crash in snd_gus_interrupt()
[ALSA] hda-codec - Fix SKU ID function for realtek codecs
[ALSA] Support ASUS P701 eeepc [0x1043 0x82a1] support
[ALSA] hda-codec - Add array terminator for dmic in STAC codec
[ALSA] hdsp - Fix zero division
[ALSA] usb-audio - Fix double comment
[ALSA] hda-codec - Fix STAC922x volume knob control
[ALSA] Changed Jaroslav Kysela's e-mail from perex@suse.cz to perex@perex.cz
[ALSA] hda-codec - Fix for Fujitsu Lifebook C1410
[ALSA] mpu-401: remove MPU401_INFO_UART_ONLY flag
[ALSA] mpu-401: do not require an ACK byte for the ENTER_UART command
[ALSA] via82xx - Add DXS quirk for Shuttle AK31v2
[ALSA] hda-codec - Fix input_mux numbers for vaio stac92xx
...
Diffstat (limited to 'sound/isa/sscape.c')
-rw-r--r-- | sound/isa/sscape.c | 354 |
1 files changed, 237 insertions, 117 deletions
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index cbad2a51cbaa..1cb921d6137e 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,12 +133,21 @@ 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; |
145 | unsigned wss_base; | ||
130 | int codec_type; | 146 | int codec_type; |
131 | int ic_type; | 147 | int ic_type; |
148 | enum card_type type; | ||
132 | struct resource *io_res; | 149 | struct resource *io_res; |
150 | struct resource *wss_res; | ||
133 | struct snd_cs4231 *chip; | 151 | struct snd_cs4231 *chip; |
134 | struct snd_mpu401 *mpu; | 152 | struct snd_mpu401 *mpu; |
135 | struct snd_hwdep *hw; | 153 | struct snd_hwdep *hw; |
@@ -340,8 +358,9 @@ static inline void activate_ad1845_unsafe(unsigned io_base) | |||
340 | */ | 358 | */ |
341 | static void soundscape_free(struct snd_card *c) | 359 | static void soundscape_free(struct snd_card *c) |
342 | { | 360 | { |
343 | register struct soundscape *sscape = get_card_soundscape(c); | 361 | struct soundscape *sscape = get_card_soundscape(c); |
344 | release_and_free_resource(sscape->io_res); | 362 | release_and_free_resource(sscape->io_res); |
363 | release_and_free_resource(sscape->wss_res); | ||
345 | free_dma(sscape->chip->dma1); | 364 | free_dma(sscape->chip->dma1); |
346 | } | 365 | } |
347 | 366 | ||
@@ -382,7 +401,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout) | |||
382 | unsigned long flags; | 401 | unsigned long flags; |
383 | unsigned char x; | 402 | unsigned char x; |
384 | 403 | ||
385 | schedule_timeout(1); | 404 | schedule_timeout_uninterruptible(1); |
386 | 405 | ||
387 | spin_lock_irqsave(&s->lock, flags); | 406 | spin_lock_irqsave(&s->lock, flags); |
388 | x = inb(HOST_DATA_IO(s->io_base)); | 407 | x = inb(HOST_DATA_IO(s->io_base)); |
@@ -409,7 +428,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout) | |||
409 | unsigned long flags; | 428 | unsigned long flags; |
410 | unsigned char x; | 429 | unsigned char x; |
411 | 430 | ||
412 | schedule_timeout(1); | 431 | schedule_timeout_uninterruptible(1); |
413 | 432 | ||
414 | spin_lock_irqsave(&s->lock, flags); | 433 | spin_lock_irqsave(&s->lock, flags); |
415 | x = inb(HOST_DATA_IO(s->io_base)); | 434 | x = inb(HOST_DATA_IO(s->io_base)); |
@@ -522,7 +541,7 @@ static int upload_dma_data(struct soundscape *s, | |||
522 | ret = -EAGAIN; | 541 | ret = -EAGAIN; |
523 | } | 542 | } |
524 | 543 | ||
525 | _release_dma: | 544 | _release_dma: |
526 | /* | 545 | /* |
527 | * NOTE!!! We are NOT holding any spinlocks at this point !!! | 546 | * NOTE!!! We are NOT holding any spinlocks at this point !!! |
528 | */ | 547 | */ |
@@ -802,6 +821,7 @@ static int __devinit detect_sscape(struct soundscape *s) | |||
802 | unsigned long flags; | 821 | unsigned long flags; |
803 | unsigned d; | 822 | unsigned d; |
804 | int retval = 0; | 823 | int retval = 0; |
824 | int codec = s->wss_base; | ||
805 | 825 | ||
806 | spin_lock_irqsave(&s->lock, flags); | 826 | spin_lock_irqsave(&s->lock, flags); |
807 | 827 | ||
@@ -833,9 +853,27 @@ static int __devinit detect_sscape(struct soundscape *s) | |||
833 | outb(0xfe, ODIE_ADDR_IO(s->io_base)); | 853 | outb(0xfe, ODIE_ADDR_IO(s->io_base)); |
834 | if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0e) | 854 | if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0e) |
835 | goto _done; | 855 | goto _done; |
836 | if ((inb(ODIE_DATA_IO(s->io_base)) & 0x9f) != 0x0e) | 856 | |
857 | outb(0xfe, ODIE_ADDR_IO(s->io_base)); | ||
858 | d = inb(ODIE_DATA_IO(s->io_base)); | ||
859 | if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e) | ||
837 | goto _done; | 860 | goto _done; |
838 | 861 | ||
862 | d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; | ||
863 | sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); | ||
864 | |||
865 | if (s->type == SSCAPE_VIVO) | ||
866 | codec += 4; | ||
867 | /* wait for WSS codec */ | ||
868 | for (d = 0; d < 500; d++) { | ||
869 | if ((inb(codec) & 0x80) == 0) | ||
870 | break; | ||
871 | spin_unlock_irqrestore(&s->lock, flags); | ||
872 | msleep(1); | ||
873 | spin_lock_irqsave(&s->lock, flags); | ||
874 | } | ||
875 | snd_printd(KERN_INFO "init delay = %d ms\n", d); | ||
876 | |||
839 | /* | 877 | /* |
840 | * SoundScape successfully detected! | 878 | * SoundScape successfully detected! |
841 | */ | 879 | */ |
@@ -995,21 +1033,23 @@ 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 | 1033 | * try to support at least some of the extra bits by overriding |
996 | * some of the CS4231 callback. | 1034 | * some of the CS4231 callback. |
997 | */ | 1035 | */ |
998 | static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq, int dma1) | 1036 | static int __devinit create_ad1845(struct snd_card *card, unsigned port, |
1037 | int irq, int dma1, int dma2) | ||
999 | { | 1038 | { |
1000 | register struct soundscape *sscape = get_card_soundscape(card); | 1039 | register struct soundscape *sscape = get_card_soundscape(card); |
1001 | struct snd_cs4231 *chip; | 1040 | struct snd_cs4231 *chip; |
1002 | int err; | 1041 | int err; |
1003 | 1042 | ||
1004 | #define CS4231_SHARE_HARDWARE (CS4231_HWSHARE_DMA1 | CS4231_HWSHARE_DMA2) | 1043 | if (sscape->type == SSCAPE_VIVO) |
1005 | /* | 1044 | port += 4; |
1006 | * The AD1845 PCM device is only half-duplex, and so | 1045 | |
1007 | * we only give it one DMA channel ... | 1046 | if (dma1 == dma2) |
1008 | */ | 1047 | dma2 = -1; |
1009 | if ((err = snd_cs4231_create(card, | 1048 | |
1010 | port, -1, irq, dma1, dma1, | 1049 | err = snd_cs4231_create(card, |
1011 | CS4231_HW_DETECT, | 1050 | port, -1, irq, dma1, dma2, |
1012 | CS4231_HWSHARE_DMA1, &chip)) == 0) { | 1051 | CS4231_HW_DETECT, CS4231_HWSHARE_DMA1, &chip); |
1052 | if (!err) { | ||
1013 | unsigned long flags; | 1053 | unsigned long flags; |
1014 | struct snd_pcm *pcm; | 1054 | struct snd_pcm *pcm; |
1015 | 1055 | ||
@@ -1031,49 +1071,72 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq | |||
1031 | snd_cs4231_mce_down(chip); | 1071 | snd_cs4231_mce_down(chip); |
1032 | */ | 1072 | */ |
1033 | 1073 | ||
1034 | /* | 1074 | if (sscape->type != SSCAPE_VIVO) { |
1035 | * The input clock frequency on the SoundScape must | 1075 | int val; |
1036 | * be 14.31818 MHz, because we must set this register | 1076 | /* |
1037 | * to get the playback to sound correct ... | 1077 | * The input clock frequency on the SoundScape must |
1038 | */ | 1078 | * be 14.31818 MHz, because we must set this register |
1039 | snd_cs4231_mce_up(chip); | 1079 | * to get the playback to sound correct ... |
1040 | spin_lock_irqsave(&chip->reg_lock, flags); | 1080 | */ |
1041 | snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20); | 1081 | snd_cs4231_mce_up(chip); |
1042 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1082 | spin_lock_irqsave(&chip->reg_lock, flags); |
1043 | snd_cs4231_mce_down(chip); | 1083 | snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20); |
1084 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1085 | snd_cs4231_mce_down(chip); | ||
1044 | 1086 | ||
1045 | /* | 1087 | /* |
1046 | * More custom configuration: | 1088 | * More custom configuration: |
1047 | * a) select "mode 2", and provide a current drive of 8 mA | 1089 | * a) select "mode 2" and provide a current drive of 8mA |
1048 | * b) enable frequency selection (for capture/playback) | 1090 | * b) enable frequency selection (for capture/playback) |
1049 | */ | 1091 | */ |
1050 | spin_lock_irqsave(&chip->reg_lock, flags); | 1092 | spin_lock_irqsave(&chip->reg_lock, flags); |
1051 | snd_cs4231_out(chip, CS4231_MISC_INFO, (CS4231_MODE2 | 0x10)); | 1093 | snd_cs4231_out(chip, CS4231_MISC_INFO, |
1052 | snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL) | AD1845_FREQ_SEL_ENABLE); | 1094 | CS4231_MODE2 | 0x10); |
1053 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1095 | val = snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL); |
1096 | snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, | ||
1097 | val | AD1845_FREQ_SEL_ENABLE); | ||
1098 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1099 | } | ||
1054 | 1100 | ||
1055 | if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) { | 1101 | err = snd_cs4231_pcm(chip, 0, &pcm); |
1056 | snd_printk(KERN_ERR "sscape: No PCM device for AD1845 chip\n"); | 1102 | if (err < 0) { |
1103 | snd_printk(KERN_ERR "sscape: No PCM device " | ||
1104 | "for AD1845 chip\n"); | ||
1057 | goto _error; | 1105 | goto _error; |
1058 | } | 1106 | } |
1059 | 1107 | ||
1060 | if ((err = snd_cs4231_mixer(chip)) < 0) { | 1108 | err = snd_cs4231_mixer(chip); |
1061 | snd_printk(KERN_ERR "sscape: No mixer device for AD1845 chip\n"); | 1109 | if (err < 0) { |
1110 | snd_printk(KERN_ERR "sscape: No mixer device " | ||
1111 | "for AD1845 chip\n"); | ||
1062 | goto _error; | 1112 | goto _error; |
1063 | } | 1113 | } |
1064 | 1114 | err = snd_cs4231_timer(chip, 0, NULL); | |
1065 | if ((err = snd_ctl_add(card, snd_ctl_new1(&midi_mixer_ctl, chip))) < 0) { | 1115 | if (err < 0) { |
1066 | snd_printk(KERN_ERR "sscape: Could not create MIDI mixer control\n"); | 1116 | snd_printk(KERN_ERR "sscape: No timer device " |
1117 | "for AD1845 chip\n"); | ||
1067 | goto _error; | 1118 | goto _error; |
1068 | } | 1119 | } |
1069 | 1120 | ||
1121 | if (sscape->type != SSCAPE_VIVO) { | ||
1122 | err = snd_ctl_add(card, | ||
1123 | snd_ctl_new1(&midi_mixer_ctl, chip)); | ||
1124 | if (err < 0) { | ||
1125 | snd_printk(KERN_ERR "sscape: Could not create " | ||
1126 | "MIDI mixer control\n"); | ||
1127 | goto _error; | ||
1128 | } | ||
1129 | chip->set_playback_format = ad1845_playback_format; | ||
1130 | chip->set_capture_format = ad1845_capture_format; | ||
1131 | } | ||
1132 | |||
1070 | strcpy(card->driver, "SoundScape"); | 1133 | strcpy(card->driver, "SoundScape"); |
1071 | strcpy(card->shortname, pcm->name); | 1134 | strcpy(card->shortname, pcm->name); |
1072 | snprintf(card->longname, sizeof(card->longname), | 1135 | snprintf(card->longname, sizeof(card->longname), |
1073 | "%s at 0x%lx, IRQ %d, DMA %d\n", | 1136 | "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n", |
1074 | pcm->name, chip->port, chip->irq, chip->dma1); | 1137 | pcm->name, chip->port, chip->irq, |
1075 | chip->set_playback_format = ad1845_playback_format; | 1138 | chip->dma1, chip->dma2); |
1076 | chip->set_capture_format = ad1845_capture_format; | 1139 | |
1077 | sscape->chip = chip; | 1140 | sscape->chip = chip; |
1078 | } | 1141 | } |
1079 | 1142 | ||
@@ -1086,15 +1149,15 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq | |||
1086 | * Create an ALSA soundcard entry for the SoundScape, using | 1149 | * Create an ALSA soundcard entry for the SoundScape, using |
1087 | * the given list of port, IRQ and DMA resources. | 1150 | * the given list of port, IRQ and DMA resources. |
1088 | */ | 1151 | */ |
1089 | static int __devinit create_sscape(int dev, struct snd_card **rcardp) | 1152 | static int __devinit create_sscape(int dev, struct snd_card *card) |
1090 | { | 1153 | { |
1091 | struct snd_card *card; | 1154 | struct soundscape *sscape = get_card_soundscape(card); |
1092 | register struct soundscape *sscape; | 1155 | unsigned dma_cfg; |
1093 | register unsigned dma_cfg; | ||
1094 | unsigned irq_cfg; | 1156 | unsigned irq_cfg; |
1095 | unsigned mpu_irq_cfg; | 1157 | unsigned mpu_irq_cfg; |
1096 | unsigned xport; | 1158 | unsigned xport; |
1097 | struct resource *io_res; | 1159 | struct resource *io_res; |
1160 | struct resource *wss_res; | ||
1098 | unsigned long flags; | 1161 | unsigned long flags; |
1099 | int err; | 1162 | int err; |
1100 | 1163 | ||
@@ -1118,61 +1181,69 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1118 | * Grab IO ports that we will need to probe so that we | 1181 | * Grab IO ports that we will need to probe so that we |
1119 | * can detect and control this hardware ... | 1182 | * can detect and control this hardware ... |
1120 | */ | 1183 | */ |
1121 | if ((io_res = request_region(xport, 8, "SoundScape")) == NULL) { | 1184 | io_res = request_region(xport, 8, "SoundScape"); |
1185 | if (!io_res) { | ||
1122 | snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport); | 1186 | snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport); |
1123 | return -EBUSY; | 1187 | return -EBUSY; |
1124 | } | 1188 | } |
1189 | wss_res = NULL; | ||
1190 | if (sscape->type == SSCAPE_VIVO) { | ||
1191 | wss_res = request_region(wss_port[dev], 4, "SoundScape"); | ||
1192 | if (!wss_res) { | ||
1193 | snd_printk(KERN_ERR "sscape: can't grab port 0x%lx\n", | ||
1194 | wss_port[dev]); | ||
1195 | err = -EBUSY; | ||
1196 | goto _release_region; | ||
1197 | } | ||
1198 | } | ||
1125 | 1199 | ||
1126 | /* | 1200 | /* |
1127 | * Grab both DMA channels (OK, only one for now) ... | 1201 | * Grab one DMA channel ... |
1128 | */ | 1202 | */ |
1129 | if ((err = request_dma(dma[dev], "SoundScape")) < 0) { | 1203 | err = request_dma(dma[dev], "SoundScape"); |
1204 | if (err < 0) { | ||
1130 | snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]); | 1205 | snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]); |
1131 | goto _release_region; | 1206 | goto _release_region; |
1132 | } | 1207 | } |
1133 | 1208 | ||
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); | ||
1145 | spin_lock_init(&sscape->lock); | 1209 | spin_lock_init(&sscape->lock); |
1146 | spin_lock_init(&sscape->fwlock); | 1210 | spin_lock_init(&sscape->fwlock); |
1147 | sscape->io_res = io_res; | 1211 | sscape->io_res = io_res; |
1212 | sscape->wss_res = wss_res; | ||
1148 | sscape->io_base = xport; | 1213 | sscape->io_base = xport; |
1214 | sscape->wss_base = wss_port[dev]; | ||
1149 | 1215 | ||
1150 | if (!detect_sscape(sscape)) { | 1216 | if (!detect_sscape(sscape)) { |
1151 | printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); | 1217 | printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); |
1152 | err = -ENODEV; | 1218 | err = -ENODEV; |
1153 | goto _release_card; | 1219 | goto _release_dma; |
1154 | } | 1220 | } |
1155 | 1221 | ||
1156 | printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", | 1222 | printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", |
1157 | sscape->io_base, irq[dev], dma[dev]); | 1223 | sscape->io_base, irq[dev], dma[dev]); |
1158 | 1224 | ||
1159 | /* | 1225 | if (sscape->type != SSCAPE_VIVO) { |
1160 | * Now create the hardware-specific device so that we can | 1226 | /* |
1161 | * load the microcode into the on-board processor. | 1227 | * Now create the hardware-specific device so that we can |
1162 | * We cannot use the MPU-401 MIDI system until this firmware | 1228 | * load the microcode into the on-board processor. |
1163 | * has been loaded into the card. | 1229 | * We cannot use the MPU-401 MIDI system until this firmware |
1164 | */ | 1230 | * has been loaded into the card. |
1165 | if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) { | 1231 | */ |
1166 | printk(KERN_ERR "sscape: Failed to create firmware device\n"); | 1232 | err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw)); |
1167 | goto _release_card; | 1233 | if (err < 0) { |
1234 | printk(KERN_ERR "sscape: Failed to create " | ||
1235 | "firmware device\n"); | ||
1236 | goto _release_dma; | ||
1237 | } | ||
1238 | strlcpy(sscape->hw->name, "SoundScape M68K", | ||
1239 | sizeof(sscape->hw->name)); | ||
1240 | sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0'; | ||
1241 | sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE; | ||
1242 | sscape->hw->ops.open = sscape_hw_open; | ||
1243 | sscape->hw->ops.release = sscape_hw_release; | ||
1244 | sscape->hw->ops.ioctl = sscape_hw_ioctl; | ||
1245 | sscape->hw->private_data = sscape; | ||
1168 | } | 1246 | } |
1169 | strlcpy(sscape->hw->name, "SoundScape M68K", sizeof(sscape->hw->name)); | ||
1170 | sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0'; | ||
1171 | sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE; | ||
1172 | sscape->hw->ops.open = sscape_hw_open; | ||
1173 | sscape->hw->ops.release = sscape_hw_release; | ||
1174 | sscape->hw->ops.ioctl = sscape_hw_ioctl; | ||
1175 | sscape->hw->private_data = sscape; | ||
1176 | 1247 | ||
1177 | /* | 1248 | /* |
1178 | * Tell the on-board devices where their resources are (I think - | 1249 | * Tell the on-board devices where their resources are (I think - |
@@ -1197,7 +1268,8 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1197 | sscape_write_unsafe(sscape->io_base, | 1268 | sscape_write_unsafe(sscape->io_base, |
1198 | GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); | 1269 | GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); |
1199 | sscape_write_unsafe(sscape->io_base, | 1270 | sscape_write_unsafe(sscape->io_base, |
1200 | GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1)); | 1271 | GA_CDCFG_REG, 0x09 | DMA_8BIT |
1272 | | (dma[dev] << 4) | (irq_cfg << 1)); | ||
1201 | 1273 | ||
1202 | spin_unlock_irqrestore(&sscape->lock, flags); | 1274 | spin_unlock_irqrestore(&sscape->lock, flags); |
1203 | 1275 | ||
@@ -1205,30 +1277,37 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1205 | * We have now enabled the codec chip, and so we should | 1277 | * We have now enabled the codec chip, and so we should |
1206 | * detect the AD1845 device ... | 1278 | * detect the AD1845 device ... |
1207 | */ | 1279 | */ |
1208 | if ((err = create_ad1845(card, CODEC_IO(xport), irq[dev], dma[dev])) < 0) { | 1280 | err = create_ad1845(card, wss_port[dev], irq[dev], |
1209 | printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n", | 1281 | dma[dev], dma2[dev]); |
1210 | CODEC_IO(xport), irq[dev]); | 1282 | if (err < 0) { |
1211 | goto _release_card; | 1283 | printk(KERN_ERR "sscape: No AD1845 device at 0x%lx, IRQ %d\n", |
1284 | wss_port[dev], irq[dev]); | ||
1285 | goto _release_dma; | ||
1212 | } | 1286 | } |
1213 | #define MIDI_DEVNUM 0 | 1287 | #define MIDI_DEVNUM 0 |
1214 | if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(xport), mpu_irq[dev])) < 0) { | 1288 | if (sscape->type != SSCAPE_VIVO) { |
1215 | printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", | 1289 | err = create_mpu401(card, MIDI_DEVNUM, |
1216 | MPU401_IO(xport)); | 1290 | MPU401_IO(xport), mpu_irq[dev]); |
1217 | goto _release_card; | 1291 | if (err < 0) { |
1218 | } | 1292 | printk(KERN_ERR "sscape: Failed to create " |
1293 | "MPU-401 device at 0x%x\n", | ||
1294 | MPU401_IO(xport)); | ||
1295 | goto _release_dma; | ||
1296 | } | ||
1219 | 1297 | ||
1220 | /* | 1298 | /* |
1221 | * Enable the master IRQ ... | 1299 | * Enable the master IRQ ... |
1222 | */ | 1300 | */ |
1223 | sscape_write(sscape, GA_INTENA_REG, 0x80); | 1301 | sscape_write(sscape, GA_INTENA_REG, 0x80); |
1224 | 1302 | ||
1225 | /* | 1303 | /* |
1226 | * Initialize mixer | 1304 | * Initialize mixer |
1227 | */ | 1305 | */ |
1228 | sscape->midi_vol = 0; | 1306 | sscape->midi_vol = 0; |
1229 | host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100); | 1307 | host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100); |
1230 | host_write_ctrl_unsafe(sscape->io_base, 0, 100); | 1308 | host_write_ctrl_unsafe(sscape->io_base, 0, 100); |
1231 | host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100); | 1309 | host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100); |
1310 | } | ||
1232 | 1311 | ||
1233 | /* | 1312 | /* |
1234 | * Now that we have successfully created this sound card, | 1313 | * Now that we have successfully created this sound card, |
@@ -1237,17 +1316,14 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1237 | * function now that our "constructor" has completed. | 1316 | * function now that our "constructor" has completed. |
1238 | */ | 1317 | */ |
1239 | card->private_free = soundscape_free; | 1318 | card->private_free = soundscape_free; |
1240 | *rcardp = card; | ||
1241 | 1319 | ||
1242 | return 0; | 1320 | return 0; |
1243 | 1321 | ||
1244 | _release_card: | 1322 | _release_dma: |
1245 | snd_card_free(card); | ||
1246 | |||
1247 | _release_dma: | ||
1248 | free_dma(dma[dev]); | 1323 | free_dma(dma[dev]); |
1249 | 1324 | ||
1250 | _release_region: | 1325 | _release_region: |
1326 | release_and_free_resource(wss_res); | ||
1251 | release_and_free_resource(io_res); | 1327 | release_and_free_resource(io_res); |
1252 | 1328 | ||
1253 | return err; | 1329 | return err; |
@@ -1276,19 +1352,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) | 1352 | static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) |
1277 | { | 1353 | { |
1278 | struct snd_card *card; | 1354 | struct snd_card *card; |
1355 | struct soundscape *sscape; | ||
1279 | int ret; | 1356 | int ret; |
1280 | 1357 | ||
1358 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
1359 | sizeof(struct soundscape)); | ||
1360 | if (!card) | ||
1361 | return -ENOMEM; | ||
1362 | |||
1363 | sscape = get_card_soundscape(card); | ||
1364 | sscape->type = SSCAPE; | ||
1365 | |||
1281 | dma[dev] &= 0x03; | 1366 | dma[dev] &= 0x03; |
1282 | ret = create_sscape(dev, &card); | 1367 | ret = create_sscape(dev, card); |
1283 | if (ret < 0) | 1368 | if (ret < 0) |
1284 | return ret; | 1369 | goto _release_card; |
1370 | |||
1285 | snd_card_set_dev(card, pdev); | 1371 | snd_card_set_dev(card, pdev); |
1286 | if ((ret = snd_card_register(card)) < 0) { | 1372 | if ((ret = snd_card_register(card)) < 0) { |
1287 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | 1373 | printk(KERN_ERR "sscape: Failed to register sound card\n"); |
1288 | return ret; | 1374 | goto _release_card; |
1289 | } | 1375 | } |
1290 | dev_set_drvdata(pdev, card); | 1376 | dev_set_drvdata(pdev, card); |
1291 | return 0; | 1377 | return 0; |
1378 | |||
1379 | _release_card: | ||
1380 | snd_card_free(card); | ||
1381 | return ret; | ||
1292 | } | 1382 | } |
1293 | 1383 | ||
1294 | static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) | 1384 | static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) |
@@ -1325,6 +1415,7 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1325 | static int idx = 0; | 1415 | static int idx = 0; |
1326 | struct pnp_dev *dev; | 1416 | struct pnp_dev *dev; |
1327 | struct snd_card *card; | 1417 | struct snd_card *card; |
1418 | struct soundscape *sscape; | ||
1328 | int ret; | 1419 | int ret; |
1329 | 1420 | ||
1330 | /* | 1421 | /* |
@@ -1366,26 +1457,55 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1366 | } | 1457 | } |
1367 | 1458 | ||
1368 | /* | 1459 | /* |
1460 | * Create a new ALSA sound card entry, in anticipation | ||
1461 | * of detecting our hardware ... | ||
1462 | */ | ||
1463 | card = snd_card_new(index[idx], id[idx], THIS_MODULE, | ||
1464 | sizeof(struct soundscape)); | ||
1465 | if (!card) | ||
1466 | return -ENOMEM; | ||
1467 | |||
1468 | sscape = get_card_soundscape(card); | ||
1469 | |||
1470 | /* | ||
1471 | * Identify card model ... | ||
1472 | */ | ||
1473 | if (!strncmp("ENS4081", pid->id, 7)) | ||
1474 | sscape->type = SSCAPE_VIVO; | ||
1475 | else | ||
1476 | sscape->type = SSCAPE_PNP; | ||
1477 | |||
1478 | /* | ||
1369 | * Read the correct parameters off the ISA PnP bus ... | 1479 | * Read the correct parameters off the ISA PnP bus ... |
1370 | */ | 1480 | */ |
1371 | port[idx] = pnp_port_start(dev, 0); | 1481 | port[idx] = pnp_port_start(dev, 0); |
1372 | irq[idx] = pnp_irq(dev, 0); | 1482 | irq[idx] = pnp_irq(dev, 0); |
1373 | mpu_irq[idx] = pnp_irq(dev, 1); | 1483 | mpu_irq[idx] = pnp_irq(dev, 1); |
1374 | dma[idx] = pnp_dma(dev, 0) & 0x03; | 1484 | dma[idx] = pnp_dma(dev, 0) & 0x03; |
1485 | if (sscape->type == SSCAPE_PNP) { | ||
1486 | dma2[idx] = dma[idx]; | ||
1487 | wss_port[idx] = CODEC_IO(port[idx]); | ||
1488 | } else { | ||
1489 | wss_port[idx] = pnp_port_start(dev, 1); | ||
1490 | dma2[idx] = pnp_dma(dev, 1); | ||
1491 | } | ||
1375 | 1492 | ||
1376 | ret = create_sscape(idx, &card); | 1493 | ret = create_sscape(idx, card); |
1377 | if (ret < 0) | 1494 | if (ret < 0) |
1378 | return ret; | 1495 | goto _release_card; |
1496 | |||
1379 | snd_card_set_dev(card, &pcard->card->dev); | 1497 | snd_card_set_dev(card, &pcard->card->dev); |
1380 | if ((ret = snd_card_register(card)) < 0) { | 1498 | if ((ret = snd_card_register(card)) < 0) { |
1381 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | 1499 | printk(KERN_ERR "sscape: Failed to register sound card\n"); |
1382 | snd_card_free(card); | 1500 | goto _release_card; |
1383 | return ret; | ||
1384 | } | 1501 | } |
1385 | 1502 | ||
1386 | pnp_set_card_drvdata(pcard, card); | 1503 | pnp_set_card_drvdata(pcard, card); |
1387 | ++idx; | 1504 | ++idx; |
1505 | return 0; | ||
1388 | 1506 | ||
1507 | _release_card: | ||
1508 | snd_card_free(card); | ||
1389 | return ret; | 1509 | return ret; |
1390 | } | 1510 | } |
1391 | 1511 | ||