diff options
Diffstat (limited to 'sound/isa')
48 files changed, 3781 insertions, 462 deletions
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 542c1ead14bd..c5c9a9218ff6 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -56,8 +56,8 @@ config SND_AD1848 | |||
56 | Say Y here to include support for AD1848 (Analog Devices) or | 56 | Say Y here to include support for AD1848 (Analog Devices) or |
57 | CS4248 (Cirrus Logic - Crystal Semiconductors) chips. | 57 | CS4248 (Cirrus Logic - Crystal Semiconductors) chips. |
58 | 58 | ||
59 | For newer chips from Cirrus Logic, use the CS4231, CS4232 or | 59 | For newer chips from Cirrus Logic, use the CS4231 or CS4232+ |
60 | CS4236+ drivers. | 60 | drivers. |
61 | 61 | ||
62 | To compile this driver as a module, choose M here: the module | 62 | To compile this driver as a module, choose M here: the module |
63 | will be called snd-ad1848. | 63 | will be called snd-ad1848. |
@@ -94,6 +94,8 @@ config SND_CMI8330 | |||
94 | tristate "C-Media CMI8330" | 94 | tristate "C-Media CMI8330" |
95 | select SND_WSS_LIB | 95 | select SND_WSS_LIB |
96 | select SND_SB16_DSP | 96 | select SND_SB16_DSP |
97 | select SND_OPL3_LIB | ||
98 | select SND_MPU401_UART | ||
97 | help | 99 | help |
98 | Say Y here to include support for soundcards based on the | 100 | Say Y here to include support for soundcards based on the |
99 | C-Media CMI8330 chip. | 101 | C-Media CMI8330 chip. |
@@ -112,26 +114,15 @@ config SND_CS4231 | |||
112 | To compile this driver as a module, choose M here: the module | 114 | To compile this driver as a module, choose M here: the module |
113 | will be called snd-cs4231. | 115 | will be called snd-cs4231. |
114 | 116 | ||
115 | config SND_CS4232 | ||
116 | tristate "Generic Cirrus Logic CS4232 driver" | ||
117 | select SND_OPL3_LIB | ||
118 | select SND_MPU401_UART | ||
119 | select SND_WSS_LIB | ||
120 | help | ||
121 | Say Y here to include support for CS4232 chips from Cirrus | ||
122 | Logic - Crystal Semiconductors. | ||
123 | |||
124 | To compile this driver as a module, choose M here: the module | ||
125 | will be called snd-cs4232. | ||
126 | |||
127 | config SND_CS4236 | 117 | config SND_CS4236 |
128 | tristate "Generic Cirrus Logic CS4236+ driver" | 118 | tristate "Generic Cirrus Logic CS4232/CS4236+ driver" |
129 | select SND_OPL3_LIB | 119 | select SND_OPL3_LIB |
130 | select SND_MPU401_UART | 120 | select SND_MPU401_UART |
131 | select SND_WSS_LIB | 121 | select SND_WSS_LIB |
132 | help | 122 | help |
133 | Say Y to include support for CS4235,CS4236,CS4237B,CS4238B, | 123 | Say Y to include support for CS4232,CS4235,CS4236,CS4237B, |
134 | CS4239 chips from Cirrus Logic - Crystal Semiconductors. | 124 | CS4238B,CS4239 chips from Cirrus Logic - Crystal |
125 | Semiconductors. | ||
135 | 126 | ||
136 | To compile this driver as a module, choose M here: the module | 127 | To compile this driver as a module, choose M here: the module |
137 | will be called snd-cs4236. | 128 | will be called snd-cs4236. |
@@ -414,5 +405,36 @@ config SND_WAVEFRONT_FIRMWARE_IN_KERNEL | |||
414 | you need to install the firmware files from the | 405 | you need to install the firmware files from the |
415 | alsa-firmware package. | 406 | alsa-firmware package. |
416 | 407 | ||
408 | config SND_MSND_PINNACLE | ||
409 | tristate "Turtle Beach MultiSound Pinnacle/Fiji driver" | ||
410 | depends on X86 && EXPERIMENTAL | ||
411 | select FW_LOADER | ||
412 | select SND_MPU401_UART | ||
413 | select SND_PCM | ||
414 | help | ||
415 | Say Y to include support for Turtle Beach MultiSound Pinnacle/ | ||
416 | Fiji soundcards. | ||
417 | |||
418 | To compile this driver as a module, choose M here: the module | ||
419 | will be called snd-msnd-pinnacle. | ||
420 | |||
421 | config SND_MSND_CLASSIC | ||
422 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" | ||
423 | depends on X86 && EXPERIMENTAL | ||
424 | select FW_LOADER | ||
425 | select SND_MPU401_UART | ||
426 | select SND_PCM | ||
427 | help | ||
428 | Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or | ||
429 | Monterey (not for the Pinnacle or Fiji). | ||
430 | |||
431 | See <file:Documentation/sound/oss/MultiSound> for important information | ||
432 | about this driver. Note that it has been discontinued, but the | ||
433 | Voyetra Turtle Beach knowledge base entry for it is still available | ||
434 | at <http://www.turtlebeach.com/site/kb_ftp/790.asp>. | ||
435 | |||
436 | To compile this driver as a module, choose M here: the module | ||
437 | will be called snd-msnd-classic. | ||
438 | |||
417 | endif # SND_ISA | 439 | endif # SND_ISA |
418 | 440 | ||
diff --git a/sound/isa/Makefile b/sound/isa/Makefile index 63af13d901a5..b906b9a1a81e 100644 --- a/sound/isa/Makefile +++ b/sound/isa/Makefile | |||
@@ -26,5 +26,5 @@ obj-$(CONFIG_SND_SC6000) += snd-sc6000.o | |||
26 | obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o | 26 | obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o |
27 | obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o | 27 | obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o |
28 | 28 | ||
29 | obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ opti9xx/ \ | 29 | obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ msnd/ opti9xx/ \ |
30 | sb/ wavefront/ wss/ | 30 | sb/ wavefront/ wss/ |
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 77524244a846..bbcbf92a8ebe 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
@@ -156,10 +156,12 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard | |||
156 | struct snd_card_ad1816a *acard; | 156 | struct snd_card_ad1816a *acard; |
157 | struct snd_ad1816a *chip; | 157 | struct snd_ad1816a *chip; |
158 | struct snd_opl3 *opl3; | 158 | struct snd_opl3 *opl3; |
159 | struct snd_timer *timer; | ||
159 | 160 | ||
160 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 161 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
161 | sizeof(struct snd_card_ad1816a))) == NULL) | 162 | sizeof(struct snd_card_ad1816a), &card); |
162 | return -ENOMEM; | 163 | if (error < 0) |
164 | return error; | ||
163 | acard = (struct snd_card_ad1816a *)card->private_data; | 165 | acard = (struct snd_card_ad1816a *)card->private_data; |
164 | 166 | ||
165 | if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { | 167 | if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { |
@@ -194,6 +196,12 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard | |||
194 | return error; | 196 | return error; |
195 | } | 197 | } |
196 | 198 | ||
199 | error = snd_ad1816a_timer(chip, 0, &timer); | ||
200 | if (error < 0) { | ||
201 | snd_card_free(card); | ||
202 | return error; | ||
203 | } | ||
204 | |||
197 | if (mpu_port[dev] > 0) { | 205 | if (mpu_port[dev] > 0) { |
198 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 206 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
199 | mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED, | 207 | mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED, |
@@ -207,11 +215,8 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard | |||
207 | OPL3_HW_AUTO, 0, &opl3) < 0) { | 215 | OPL3_HW_AUTO, 0, &opl3) < 0) { |
208 | printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2); | 216 | printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2); |
209 | } else { | 217 | } else { |
210 | if ((error = snd_opl3_timer_new(opl3, 1, 2)) < 0) { | 218 | error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); |
211 | snd_card_free(card); | 219 | if (error < 0) { |
212 | return error; | ||
213 | } | ||
214 | if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { | ||
215 | snd_card_free(card); | 220 | snd_card_free(card); |
216 | return error; | 221 | return error; |
217 | } | 222 | } |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 3bfca7c59baf..05aef8b97e96 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
@@ -37,7 +37,7 @@ static inline int snd_ad1816a_busy_wait(struct snd_ad1816a *chip) | |||
37 | if (inb(AD1816A_REG(AD1816A_CHIP_STATUS)) & AD1816A_READY) | 37 | if (inb(AD1816A_REG(AD1816A_CHIP_STATUS)) & AD1816A_READY) |
38 | return 0; | 38 | return 0; |
39 | 39 | ||
40 | snd_printk("chip busy.\n"); | 40 | snd_printk(KERN_WARNING "chip busy.\n"); |
41 | return -EBUSY; | 41 | return -EBUSY; |
42 | } | 42 | } |
43 | 43 | ||
@@ -196,7 +196,7 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, | |||
196 | spin_unlock(&chip->lock); | 196 | spin_unlock(&chip->lock); |
197 | break; | 197 | break; |
198 | default: | 198 | default: |
199 | snd_printk("invalid trigger mode 0x%x.\n", what); | 199 | snd_printk(KERN_WARNING "invalid trigger mode 0x%x.\n", what); |
200 | error = -EINVAL; | 200 | error = -EINVAL; |
201 | } | 201 | } |
202 | 202 | ||
@@ -377,7 +377,6 @@ static struct snd_pcm_hardware snd_ad1816a_capture = { | |||
377 | .fifo_size = 0, | 377 | .fifo_size = 0, |
378 | }; | 378 | }; |
379 | 379 | ||
380 | #if 0 /* not used now */ | ||
381 | static int snd_ad1816a_timer_close(struct snd_timer *timer) | 380 | static int snd_ad1816a_timer_close(struct snd_timer *timer) |
382 | { | 381 | { |
383 | struct snd_ad1816a *chip = snd_timer_chip(timer); | 382 | struct snd_ad1816a *chip = snd_timer_chip(timer); |
@@ -442,8 +441,6 @@ static struct snd_timer_hardware snd_ad1816a_timer_table = { | |||
442 | .start = snd_ad1816a_timer_start, | 441 | .start = snd_ad1816a_timer_start, |
443 | .stop = snd_ad1816a_timer_stop, | 442 | .stop = snd_ad1816a_timer_stop, |
444 | }; | 443 | }; |
445 | #endif /* not used now */ | ||
446 | |||
447 | 444 | ||
448 | static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream) | 445 | static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream) |
449 | { | 446 | { |
@@ -568,7 +565,7 @@ static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip) | |||
568 | case AD1816A_HW_AD1815: return "AD1815"; | 565 | case AD1816A_HW_AD1815: return "AD1815"; |
569 | case AD1816A_HW_AD18MAX10: return "AD18max10"; | 566 | case AD1816A_HW_AD18MAX10: return "AD18max10"; |
570 | default: | 567 | default: |
571 | snd_printk("Unknown chip version %d:%d.\n", | 568 | snd_printk(KERN_WARNING "Unknown chip version %d:%d.\n", |
572 | chip->version, chip->hardware); | 569 | chip->version, chip->hardware); |
573 | return "AD1816A - unknown"; | 570 | return "AD1816A - unknown"; |
574 | } | 571 | } |
@@ -687,7 +684,6 @@ int __devinit snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_p | |||
687 | return 0; | 684 | return 0; |
688 | } | 685 | } |
689 | 686 | ||
690 | #if 0 /* not used now */ | ||
691 | int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer) | 687 | int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer) |
692 | { | 688 | { |
693 | struct snd_timer *timer; | 689 | struct snd_timer *timer; |
@@ -709,7 +705,6 @@ int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd | |||
709 | *rtimer = timer; | 705 | *rtimer = timer; |
710 | return 0; | 706 | return 0; |
711 | } | 707 | } |
712 | #endif /* not used now */ | ||
713 | 708 | ||
714 | /* | 709 | /* |
715 | * | 710 | * |
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 223a6c038819..4beeb6f98e0e 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c | |||
@@ -91,9 +91,9 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) | |||
91 | struct snd_pcm *pcm; | 91 | struct snd_pcm *pcm; |
92 | int error; | 92 | int error; |
93 | 93 | ||
94 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 94 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
95 | if (!card) | 95 | if (error < 0) |
96 | return -EINVAL; | 96 | return error; |
97 | 97 | ||
98 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1, | 98 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1, |
99 | thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, | 99 | thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, |
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c index 374b7177e111..7465ae036e0b 100644 --- a/sound/isa/adlib.c +++ b/sound/isa/adlib.c | |||
@@ -53,10 +53,10 @@ static int __devinit snd_adlib_probe(struct device *dev, unsigned int n) | |||
53 | struct snd_opl3 *opl3; | 53 | struct snd_opl3 *opl3; |
54 | int error; | 54 | int error; |
55 | 55 | ||
56 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 56 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
57 | if (!card) { | 57 | if (error < 0) { |
58 | dev_err(dev, "could not create card\n"); | 58 | dev_err(dev, "could not create card\n"); |
59 | return -EINVAL; | 59 | return error; |
60 | } | 60 | } |
61 | 61 | ||
62 | card->private_data = request_region(port[n], 4, CRD_NAME); | 62 | card->private_data = request_region(port[n], 4, CRD_NAME); |
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index f1ce30f379c9..5fd52e4d7079 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
@@ -163,9 +163,10 @@ static int __devinit snd_card_als100_probe(int dev, | |||
163 | struct snd_card_als100 *acard; | 163 | struct snd_card_als100 *acard; |
164 | struct snd_opl3 *opl3; | 164 | struct snd_opl3 *opl3; |
165 | 165 | ||
166 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 166 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
167 | sizeof(struct snd_card_als100))) == NULL) | 167 | sizeof(struct snd_card_als100), &card); |
168 | return -ENOMEM; | 168 | if (error < 0) |
169 | return error; | ||
169 | acard = card->private_data; | 170 | acard = card->private_data; |
170 | 171 | ||
171 | if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) { | 172 | if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) { |
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index 3e74d1a3928e..f7aa637b0d18 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c | |||
@@ -184,9 +184,10 @@ static int __devinit snd_card_azt2320_probe(int dev, | |||
184 | struct snd_wss *chip; | 184 | struct snd_wss *chip; |
185 | struct snd_opl3 *opl3; | 185 | struct snd_opl3 *opl3; |
186 | 186 | ||
187 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 187 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
188 | sizeof(struct snd_card_azt2320))) == NULL) | 188 | sizeof(struct snd_card_azt2320), &card); |
189 | return -ENOMEM; | 189 | if (error < 0) |
190 | return error; | ||
190 | acard = (struct snd_card_azt2320 *)card->private_data; | 191 | acard = (struct snd_card_azt2320 *)card->private_data; |
191 | 192 | ||
192 | if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { | 193 | if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { |
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index e49aec700a55..de83608719ea 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c | |||
@@ -31,11 +31,11 @@ | |||
31 | * To quickly load the module, | 31 | * To quickly load the module, |
32 | * | 32 | * |
33 | * modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1 | 33 | * modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1 |
34 | * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 | 34 | * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 fmport=0x388 |
35 | * | 35 | * |
36 | * This card has two mixers and two PCM devices. I've cheesed it such | 36 | * This card has two mixers and two PCM devices. I've cheesed it such |
37 | * that recording and playback can be done through the same device. | 37 | * that recording and playback can be done through the same device. |
38 | * The driver "magically" routes the capturing to the AD1848 codec, | 38 | * The driver "magically" routes the capturing to the CMI8330 codec, |
39 | * and playback to the SB16 codec. This allows for full-duplex mode | 39 | * and playback to the SB16 codec. This allows for full-duplex mode |
40 | * to some extent. | 40 | * to some extent. |
41 | * The utilities in alsa-utils are aware of both devices, so passing | 41 | * The utilities in alsa-utils are aware of both devices, so passing |
@@ -51,6 +51,8 @@ | |||
51 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
52 | #include <sound/core.h> | 52 | #include <sound/core.h> |
53 | #include <sound/wss.h> | 53 | #include <sound/wss.h> |
54 | #include <sound/opl3.h> | ||
55 | #include <sound/mpu401.h> | ||
54 | #include <sound/sb.h> | 56 | #include <sound/sb.h> |
55 | #include <sound/initval.h> | 57 | #include <sound/initval.h> |
56 | 58 | ||
@@ -79,6 +81,9 @@ static int sbdma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; | |||
79 | static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | 81 | static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; |
80 | static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | 82 | static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; |
81 | static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; | 83 | static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; |
84 | static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
85 | static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
86 | static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | ||
82 | 87 | ||
83 | module_param_array(index, int, NULL, 0444); | 88 | module_param_array(index, int, NULL, 0444); |
84 | MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); | 89 | MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); |
@@ -107,6 +112,12 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); | |||
107 | module_param_array(wssdma, int, NULL, 0444); | 112 | module_param_array(wssdma, int, NULL, 0444); |
108 | MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); | 113 | MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); |
109 | 114 | ||
115 | module_param_array(fmport, long, NULL, 0444); | ||
116 | MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver."); | ||
117 | module_param_array(mpuport, long, NULL, 0444); | ||
118 | MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver."); | ||
119 | module_param_array(mpuirq, int, NULL, 0444); | ||
120 | MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port."); | ||
110 | #ifdef CONFIG_PNP | 121 | #ifdef CONFIG_PNP |
111 | static int isa_registered; | 122 | static int isa_registered; |
112 | static int pnp_registered; | 123 | static int pnp_registered; |
@@ -149,6 +160,7 @@ struct snd_cmi8330 { | |||
149 | #ifdef CONFIG_PNP | 160 | #ifdef CONFIG_PNP |
150 | struct pnp_dev *cap; | 161 | struct pnp_dev *cap; |
151 | struct pnp_dev *play; | 162 | struct pnp_dev *play; |
163 | struct pnp_dev *mpu; | ||
152 | #endif | 164 | #endif |
153 | struct snd_card *card; | 165 | struct snd_card *card; |
154 | struct snd_wss *wss; | 166 | struct snd_wss *wss; |
@@ -165,7 +177,7 @@ struct snd_cmi8330 { | |||
165 | #ifdef CONFIG_PNP | 177 | #ifdef CONFIG_PNP |
166 | 178 | ||
167 | static struct pnp_card_device_id snd_cmi8330_pnpids[] = { | 179 | static struct pnp_card_device_id snd_cmi8330_pnpids[] = { |
168 | { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" } } }, | 180 | { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, |
169 | { .id = "" } | 181 | { .id = "" } |
170 | }; | 182 | }; |
171 | 183 | ||
@@ -219,8 +231,10 @@ WSS_SINGLE("3D Control - Switch", 0, | |||
219 | CMI8330_RMUX3D, 5, 1, 1), | 231 | CMI8330_RMUX3D, 5, 1, 1), |
220 | WSS_SINGLE("PC Speaker Playback Volume", 0, | 232 | WSS_SINGLE("PC Speaker Playback Volume", 0, |
221 | CMI8330_OUTPUTVOL, 3, 3, 0), | 233 | CMI8330_OUTPUTVOL, 3, 3, 0), |
222 | WSS_SINGLE("FM Playback Switch", 0, | 234 | WSS_DOUBLE("FM Playback Switch", 0, |
223 | CMI8330_RECMUX, 3, 1, 1), | 235 | CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), |
236 | WSS_DOUBLE("FM Playback Volume", 0, | ||
237 | CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), | ||
224 | WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0, | 238 | WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0, |
225 | CMI8330_RMUX3D, 7, 1, 1), | 239 | CMI8330_RMUX3D, 7, 1, 1), |
226 | WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0, | 240 | WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0, |
@@ -323,16 +337,21 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, | |||
323 | if (acard->play == NULL) | 337 | if (acard->play == NULL) |
324 | return -EBUSY; | 338 | return -EBUSY; |
325 | 339 | ||
340 | acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL); | ||
341 | if (acard->play == NULL) | ||
342 | return -EBUSY; | ||
343 | |||
326 | pdev = acard->cap; | 344 | pdev = acard->cap; |
327 | 345 | ||
328 | err = pnp_activate_dev(pdev); | 346 | err = pnp_activate_dev(pdev); |
329 | if (err < 0) { | 347 | if (err < 0) { |
330 | snd_printk(KERN_ERR "CMI8330/C3D (AD1848) PnP configure failure\n"); | 348 | snd_printk(KERN_ERR "CMI8330/C3D PnP configure failure\n"); |
331 | return -EBUSY; | 349 | return -EBUSY; |
332 | } | 350 | } |
333 | wssport[dev] = pnp_port_start(pdev, 0); | 351 | wssport[dev] = pnp_port_start(pdev, 0); |
334 | wssdma[dev] = pnp_dma(pdev, 0); | 352 | wssdma[dev] = pnp_dma(pdev, 0); |
335 | wssirq[dev] = pnp_irq(pdev, 0); | 353 | wssirq[dev] = pnp_irq(pdev, 0); |
354 | fmport[dev] = pnp_port_start(pdev, 1); | ||
336 | 355 | ||
337 | /* allocate SB16 resources */ | 356 | /* allocate SB16 resources */ |
338 | pdev = acard->play; | 357 | pdev = acard->play; |
@@ -347,6 +366,17 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, | |||
347 | sbdma16[dev] = pnp_dma(pdev, 1); | 366 | sbdma16[dev] = pnp_dma(pdev, 1); |
348 | sbirq[dev] = pnp_irq(pdev, 0); | 367 | sbirq[dev] = pnp_irq(pdev, 0); |
349 | 368 | ||
369 | /* allocate MPU-401 resources */ | ||
370 | pdev = acard->mpu; | ||
371 | |||
372 | err = pnp_activate_dev(pdev); | ||
373 | if (err < 0) { | ||
374 | snd_printk(KERN_ERR | ||
375 | "CMI8330/C3D (MPU-401) PnP configure failure\n"); | ||
376 | return -EBUSY; | ||
377 | } | ||
378 | mpuport[dev] = pnp_port_start(pdev, 0); | ||
379 | mpuirq[dev] = pnp_irq(pdev, 0); | ||
350 | return 0; | 380 | return 0; |
351 | } | 381 | } |
352 | #endif | 382 | #endif |
@@ -467,26 +497,29 @@ static int snd_cmi8330_resume(struct snd_card *card) | |||
467 | 497 | ||
468 | #define PFX "cmi8330: " | 498 | #define PFX "cmi8330: " |
469 | 499 | ||
470 | static struct snd_card *snd_cmi8330_card_new(int dev) | 500 | static int snd_cmi8330_card_new(int dev, struct snd_card **cardp) |
471 | { | 501 | { |
472 | struct snd_card *card; | 502 | struct snd_card *card; |
473 | struct snd_cmi8330 *acard; | 503 | struct snd_cmi8330 *acard; |
504 | int err; | ||
474 | 505 | ||
475 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 506 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
476 | sizeof(struct snd_cmi8330)); | 507 | sizeof(struct snd_cmi8330), &card); |
477 | if (card == NULL) { | 508 | if (err < 0) { |
478 | snd_printk(KERN_ERR PFX "could not get a new card\n"); | 509 | snd_printk(KERN_ERR PFX "could not get a new card\n"); |
479 | return NULL; | 510 | return err; |
480 | } | 511 | } |
481 | acard = card->private_data; | 512 | acard = card->private_data; |
482 | acard->card = card; | 513 | acard->card = card; |
483 | return card; | 514 | *cardp = card; |
515 | return 0; | ||
484 | } | 516 | } |
485 | 517 | ||
486 | static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) | 518 | static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) |
487 | { | 519 | { |
488 | struct snd_cmi8330 *acard; | 520 | struct snd_cmi8330 *acard; |
489 | int i, err; | 521 | int i, err; |
522 | struct snd_opl3 *opl3; | ||
490 | 523 | ||
491 | acard = card->private_data; | 524 | acard = card->private_data; |
492 | err = snd_wss_create(card, wssport[dev] + 4, -1, | 525 | err = snd_wss_create(card, wssport[dev] + 4, -1, |
@@ -494,11 +527,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) | |||
494 | wssdma[dev], -1, | 527 | wssdma[dev], -1, |
495 | WSS_HW_DETECT, 0, &acard->wss); | 528 | WSS_HW_DETECT, 0, &acard->wss); |
496 | if (err < 0) { | 529 | if (err < 0) { |
497 | snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); | 530 | snd_printk(KERN_ERR PFX "(CMI8330) device busy??\n"); |
498 | return err; | 531 | return err; |
499 | } | 532 | } |
500 | if (acard->wss->hardware != WSS_HW_CMI8330) { | 533 | if (acard->wss->hardware != WSS_HW_CMI8330) { |
501 | snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n"); | 534 | snd_printk(KERN_ERR PFX "(CMI8330) not found during probe\n"); |
502 | return -ENODEV; | 535 | return -ENODEV; |
503 | } | 536 | } |
504 | 537 | ||
@@ -530,6 +563,27 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) | |||
530 | snd_printk(KERN_ERR PFX "failed to create pcms\n"); | 563 | snd_printk(KERN_ERR PFX "failed to create pcms\n"); |
531 | return err; | 564 | return err; |
532 | } | 565 | } |
566 | if (fmport[dev] != SNDRV_AUTO_PORT) { | ||
567 | if (snd_opl3_create(card, | ||
568 | fmport[dev], fmport[dev] + 2, | ||
569 | OPL3_HW_AUTO, 0, &opl3) < 0) { | ||
570 | snd_printk(KERN_ERR PFX | ||
571 | "no OPL device at 0x%lx-0x%lx ?\n", | ||
572 | fmport[dev], fmport[dev] + 2); | ||
573 | } else { | ||
574 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | ||
575 | if (err < 0) | ||
576 | return err; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | if (mpuport[dev] != SNDRV_AUTO_PORT) { | ||
581 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | ||
582 | mpuport[dev], 0, mpuirq[dev], | ||
583 | IRQF_DISABLED, NULL) < 0) | ||
584 | printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", | ||
585 | mpuport[dev]); | ||
586 | } | ||
533 | 587 | ||
534 | strcpy(card->driver, "CMI8330/C3D"); | 588 | strcpy(card->driver, "CMI8330/C3D"); |
535 | strcpy(card->shortname, "C-Media CMI8330/C3D"); | 589 | strcpy(card->shortname, "C-Media CMI8330/C3D"); |
@@ -564,9 +618,9 @@ static int __devinit snd_cmi8330_isa_probe(struct device *pdev, | |||
564 | struct snd_card *card; | 618 | struct snd_card *card; |
565 | int err; | 619 | int err; |
566 | 620 | ||
567 | card = snd_cmi8330_card_new(dev); | 621 | err = snd_cmi8330_card_new(dev, &card); |
568 | if (! card) | 622 | if (err < 0) |
569 | return -ENOMEM; | 623 | return err; |
570 | snd_card_set_dev(card, pdev); | 624 | snd_card_set_dev(card, pdev); |
571 | if ((err = snd_cmi8330_probe(card, dev)) < 0) { | 625 | if ((err = snd_cmi8330_probe(card, dev)) < 0) { |
572 | snd_card_free(card); | 626 | snd_card_free(card); |
@@ -628,9 +682,9 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, | |||
628 | if (dev >= SNDRV_CARDS) | 682 | if (dev >= SNDRV_CARDS) |
629 | return -ENODEV; | 683 | return -ENODEV; |
630 | 684 | ||
631 | card = snd_cmi8330_card_new(dev); | 685 | res = snd_cmi8330_card_new(dev, &card); |
632 | if (! card) | 686 | if (res < 0) |
633 | return -ENOMEM; | 687 | return res; |
634 | if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) { | 688 | if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) { |
635 | snd_printk(KERN_ERR PFX "PnP detection failed\n"); | 689 | snd_printk(KERN_ERR PFX "PnP detection failed\n"); |
636 | snd_card_free(card); | 690 | snd_card_free(card); |
diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile index 5870ca21ab59..6d397e8d54ac 100644 --- a/sound/isa/cs423x/Makefile +++ b/sound/isa/cs423x/Makefile | |||
@@ -3,13 +3,11 @@ | |||
3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> | 3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | snd-cs4236-lib-objs := cs4236_lib.o | ||
7 | snd-cs4231-objs := cs4231.o | 6 | snd-cs4231-objs := cs4231.o |
8 | snd-cs4232-objs := cs4232.o | 7 | snd-cs4236-objs := cs4236.o cs4236_lib.o |
9 | snd-cs4236-objs := cs4236.o | ||
10 | 8 | ||
11 | # Toplevel Module Dependency | 9 | # Toplevel Module Dependency |
12 | obj-$(CONFIG_SND_CS4231) += snd-cs4231.o | 10 | obj-$(CONFIG_SND_CS4231) += snd-cs4231.o |
13 | obj-$(CONFIG_SND_CS4232) += snd-cs4232.o | 11 | obj-$(CONFIG_SND_CS4236) += snd-cs4236.o |
14 | obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o | 12 | |
15 | 13 | ||
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index f019d449e2d6..cb9153e75b82 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
@@ -95,9 +95,9 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) | |||
95 | struct snd_pcm *pcm; | 95 | struct snd_pcm *pcm; |
96 | int error; | 96 | int error; |
97 | 97 | ||
98 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 98 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
99 | if (!card) | 99 | if (error < 0) |
100 | return -EINVAL; | 100 | return error; |
101 | 101 | ||
102 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n], | 102 | error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n], |
103 | WSS_HW_DETECT, 0, &chip); | 103 | WSS_HW_DETECT, 0, &chip); |
diff --git a/sound/isa/cs423x/cs4232.c b/sound/isa/cs423x/cs4232.c deleted file mode 100644 index 9fad2e6c0c2c..000000000000 --- a/sound/isa/cs423x/cs4232.c +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | #define CS4232 | ||
2 | #include "cs4236.c" | ||
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 019c9401663e..a076a6ce8071 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
@@ -33,17 +33,14 @@ | |||
33 | 33 | ||
34 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 34 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | #ifdef CS4232 | 36 | MODULE_DESCRIPTION("Cirrus Logic CS4232-9"); |
37 | MODULE_DESCRIPTION("Cirrus Logic CS4232"); | ||
38 | MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," | 37 | MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," |
39 | "{Turtle Beach,Tropez Plus}," | 38 | "{Turtle Beach,Tropez Plus}," |
40 | "{SIC CrystalWave 32}," | 39 | "{SIC CrystalWave 32}," |
41 | "{Hewlett Packard,Omnibook 5500}," | 40 | "{Hewlett Packard,Omnibook 5500}," |
42 | "{TerraTec,Maestro 32/96}," | 41 | "{TerraTec,Maestro 32/96}," |
43 | "{Philips,PCA70PS}}"); | 42 | "{Philips,PCA70PS}}," |
44 | #else | 43 | "{{Crystal Semiconductors,CS4235}," |
45 | MODULE_DESCRIPTION("Cirrus Logic CS4235-9"); | ||
46 | MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," | ||
47 | "{Crystal Semiconductors,CS4236}," | 44 | "{Crystal Semiconductors,CS4236}," |
48 | "{Crystal Semiconductors,CS4237}," | 45 | "{Crystal Semiconductors,CS4237}," |
49 | "{Crystal Semiconductors,CS4238}," | 46 | "{Crystal Semiconductors,CS4238}," |
@@ -70,15 +67,11 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," | |||
70 | "{Typhoon Soundsystem,CS4236B}," | 67 | "{Typhoon Soundsystem,CS4236B}," |
71 | "{Turtle Beach,Malibu}," | 68 | "{Turtle Beach,Malibu}," |
72 | "{Unknown,Digital PC 5000 Onboard}}"); | 69 | "{Unknown,Digital PC 5000 Onboard}}"); |
73 | #endif | ||
74 | 70 | ||
75 | #ifdef CS4232 | 71 | MODULE_ALIAS("snd_cs4232"); |
76 | #define IDENT "CS4232" | 72 | |
77 | #define DEV_NAME "cs4232" | 73 | #define IDENT "CS4232+" |
78 | #else | 74 | #define DEV_NAME "cs4232+" |
79 | #define IDENT "CS4236+" | ||
80 | #define DEV_NAME "cs4236" | ||
81 | #endif | ||
82 | 75 | ||
83 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 76 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
84 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 77 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
@@ -128,9 +121,7 @@ MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); | |||
128 | #ifdef CONFIG_PNP | 121 | #ifdef CONFIG_PNP |
129 | static int isa_registered; | 122 | static int isa_registered; |
130 | static int pnpc_registered; | 123 | static int pnpc_registered; |
131 | #ifdef CS4232 | ||
132 | static int pnp_registered; | 124 | static int pnp_registered; |
133 | #endif | ||
134 | #endif /* CONFIG_PNP */ | 125 | #endif /* CONFIG_PNP */ |
135 | 126 | ||
136 | struct snd_card_cs4236 { | 127 | struct snd_card_cs4236 { |
@@ -145,11 +136,10 @@ struct snd_card_cs4236 { | |||
145 | 136 | ||
146 | #ifdef CONFIG_PNP | 137 | #ifdef CONFIG_PNP |
147 | 138 | ||
148 | #ifdef CS4232 | ||
149 | /* | 139 | /* |
150 | * PNP BIOS | 140 | * PNP BIOS |
151 | */ | 141 | */ |
152 | static const struct pnp_device_id snd_cs4232_pnpbiosids[] = { | 142 | static const struct pnp_device_id snd_cs423x_pnpbiosids[] = { |
153 | { .id = "CSC0100" }, | 143 | { .id = "CSC0100" }, |
154 | { .id = "CSC0000" }, | 144 | { .id = "CSC0000" }, |
155 | /* Guillemot Turtlebeach something appears to be cs4232 compatible | 145 | /* Guillemot Turtlebeach something appears to be cs4232 compatible |
@@ -157,10 +147,8 @@ static const struct pnp_device_id snd_cs4232_pnpbiosids[] = { | |||
157 | { .id = "GIM0100" }, | 147 | { .id = "GIM0100" }, |
158 | { .id = "" } | 148 | { .id = "" } |
159 | }; | 149 | }; |
160 | MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids); | 150 | MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids); |
161 | #endif /* CS4232 */ | ||
162 | 151 | ||
163 | #ifdef CS4232 | ||
164 | #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" | 152 | #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" |
165 | static struct pnp_card_device_id snd_cs423x_pnpids[] = { | 153 | static struct pnp_card_device_id snd_cs423x_pnpids[] = { |
166 | /* Philips PCA70PS */ | 154 | /* Philips PCA70PS */ |
@@ -179,12 +167,6 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { | |||
179 | { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, | 167 | { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, |
180 | /* Netfinity 3000 on-board soundcard */ | 168 | /* Netfinity 3000 on-board soundcard */ |
181 | { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } }, | 169 | { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } }, |
182 | /* --- */ | ||
183 | { .id = "" } /* end */ | ||
184 | }; | ||
185 | #else /* CS4236 */ | ||
186 | #define CS423X_ISAPNP_DRIVER "cs4236_isapnp" | ||
187 | static struct pnp_card_device_id snd_cs423x_pnpids[] = { | ||
188 | /* Intel Marlin Spike Motherboard - CS4235 */ | 170 | /* Intel Marlin Spike Motherboard - CS4235 */ |
189 | { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, | 171 | { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, |
190 | /* Intel Marlin Spike Motherboard (#2) - CS4235 */ | 172 | /* Intel Marlin Spike Motherboard (#2) - CS4235 */ |
@@ -266,7 +248,6 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { | |||
266 | /* --- */ | 248 | /* --- */ |
267 | { .id = "" } /* end */ | 249 | { .id = "" } /* end */ |
268 | }; | 250 | }; |
269 | #endif | ||
270 | 251 | ||
271 | MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); | 252 | MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); |
272 | 253 | ||
@@ -323,17 +304,19 @@ static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev) | |||
323 | return 0; | 304 | return 0; |
324 | } | 305 | } |
325 | 306 | ||
326 | #ifdef CS4232 | 307 | static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard, |
327 | static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, | 308 | struct pnp_dev *pdev, |
328 | struct pnp_dev *pdev) | 309 | struct pnp_dev *cdev) |
329 | { | 310 | { |
330 | acard->wss = pdev; | 311 | acard->wss = pdev; |
331 | if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) | 312 | if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) |
332 | return -EBUSY; | 313 | return -EBUSY; |
333 | cport[dev] = -1; | 314 | if (cdev) |
315 | cport[dev] = pnp_port_start(cdev, 0); | ||
316 | else | ||
317 | cport[dev] = -1; | ||
334 | return 0; | 318 | return 0; |
335 | } | 319 | } |
336 | #endif | ||
337 | 320 | ||
338 | static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard, | 321 | static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard, |
339 | struct pnp_card_link *card, | 322 | struct pnp_card_link *card, |
@@ -382,16 +365,18 @@ static void snd_card_cs4236_free(struct snd_card *card) | |||
382 | release_and_free_resource(acard->res_sb_port); | 365 | release_and_free_resource(acard->res_sb_port); |
383 | } | 366 | } |
384 | 367 | ||
385 | static struct snd_card *snd_cs423x_card_new(int dev) | 368 | static int snd_cs423x_card_new(int dev, struct snd_card **cardp) |
386 | { | 369 | { |
387 | struct snd_card *card; | 370 | struct snd_card *card; |
371 | int err; | ||
388 | 372 | ||
389 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 373 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
390 | sizeof(struct snd_card_cs4236)); | 374 | sizeof(struct snd_card_cs4236), &card); |
391 | if (card == NULL) | 375 | if (err < 0) |
392 | return NULL; | 376 | return err; |
393 | card->private_free = snd_card_cs4236_free; | 377 | card->private_free = snd_card_cs4236_free; |
394 | return card; | 378 | *cardp = card; |
379 | return 0; | ||
395 | } | 380 | } |
396 | 381 | ||
397 | static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | 382 | static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) |
@@ -409,40 +394,39 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | |||
409 | return -EBUSY; | 394 | return -EBUSY; |
410 | } | 395 | } |
411 | 396 | ||
412 | #ifdef CS4232 | ||
413 | err = snd_wss_create(card, port[dev], cport[dev], | 397 | err = snd_wss_create(card, port[dev], cport[dev], |
414 | irq[dev], | 398 | irq[dev], |
415 | dma1[dev], dma2[dev], | 399 | dma1[dev], dma2[dev], |
416 | WSS_HW_DETECT, 0, &chip); | 400 | WSS_HW_DETECT3, 0, &chip); |
417 | if (err < 0) | ||
418 | return err; | ||
419 | acard->chip = chip; | ||
420 | |||
421 | err = snd_wss_pcm(chip, 0, &pcm); | ||
422 | if (err < 0) | ||
423 | return err; | ||
424 | |||
425 | err = snd_wss_mixer(chip); | ||
426 | if (err < 0) | 401 | if (err < 0) |
427 | return err; | 402 | return err; |
428 | 403 | if (chip->hardware & WSS_HW_CS4236B_MASK) { | |
429 | #else /* CS4236 */ | 404 | snd_wss_free(chip); |
430 | err = snd_cs4236_create(card, | 405 | err = snd_cs4236_create(card, |
431 | port[dev], cport[dev], | 406 | port[dev], cport[dev], |
432 | irq[dev], dma1[dev], dma2[dev], | 407 | irq[dev], dma1[dev], dma2[dev], |
433 | WSS_HW_DETECT, 0, &chip); | 408 | WSS_HW_DETECT, 0, &chip); |
434 | if (err < 0) | 409 | if (err < 0) |
435 | return err; | 410 | return err; |
436 | acard->chip = chip; | 411 | acard->chip = chip; |
437 | 412 | ||
438 | err = snd_cs4236_pcm(chip, 0, &pcm); | 413 | err = snd_cs4236_pcm(chip, 0, &pcm); |
439 | if (err < 0) | 414 | if (err < 0) |
440 | return err; | 415 | return err; |
441 | 416 | ||
442 | err = snd_cs4236_mixer(chip); | 417 | err = snd_cs4236_mixer(chip); |
443 | if (err < 0) | 418 | if (err < 0) |
444 | return err; | 419 | return err; |
445 | #endif | 420 | } else { |
421 | acard->chip = chip; | ||
422 | err = snd_wss_pcm(chip, 0, &pcm); | ||
423 | if (err < 0) | ||
424 | return err; | ||
425 | |||
426 | err = snd_wss_mixer(chip); | ||
427 | if (err < 0) | ||
428 | return err; | ||
429 | } | ||
446 | strcpy(card->driver, pcm->name); | 430 | strcpy(card->driver, pcm->name); |
447 | strcpy(card->shortname, pcm->name); | 431 | strcpy(card->shortname, pcm->name); |
448 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", | 432 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", |
@@ -512,9 +496,9 @@ static int __devinit snd_cs423x_isa_probe(struct device *pdev, | |||
512 | struct snd_card *card; | 496 | struct snd_card *card; |
513 | int err; | 497 | int err; |
514 | 498 | ||
515 | card = snd_cs423x_card_new(dev); | 499 | err = snd_cs423x_card_new(dev, &card); |
516 | if (! card) | 500 | if (err < 0) |
517 | return -ENOMEM; | 501 | return err; |
518 | snd_card_set_dev(card, pdev); | 502 | snd_card_set_dev(card, pdev); |
519 | if ((err = snd_cs423x_probe(card, dev)) < 0) { | 503 | if ((err = snd_cs423x_probe(card, dev)) < 0) { |
520 | snd_card_free(card); | 504 | snd_card_free(card); |
@@ -577,13 +561,14 @@ static struct isa_driver cs423x_isa_driver = { | |||
577 | 561 | ||
578 | 562 | ||
579 | #ifdef CONFIG_PNP | 563 | #ifdef CONFIG_PNP |
580 | #ifdef CS4232 | 564 | static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, |
581 | static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | ||
582 | const struct pnp_device_id *id) | 565 | const struct pnp_device_id *id) |
583 | { | 566 | { |
584 | static int dev; | 567 | static int dev; |
585 | int err; | 568 | int err; |
586 | struct snd_card *card; | 569 | struct snd_card *card; |
570 | struct pnp_dev *cdev; | ||
571 | char cid[PNP_ID_LEN]; | ||
587 | 572 | ||
588 | if (pnp_device_is_isapnp(pdev)) | 573 | if (pnp_device_is_isapnp(pdev)) |
589 | return -ENOENT; /* we have another procedure - card */ | 574 | return -ENOENT; /* we have another procedure - card */ |
@@ -594,10 +579,19 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |||
594 | if (dev >= SNDRV_CARDS) | 579 | if (dev >= SNDRV_CARDS) |
595 | return -ENODEV; | 580 | return -ENODEV; |
596 | 581 | ||
597 | card = snd_cs423x_card_new(dev); | 582 | /* prepare second id */ |
598 | if (! card) | 583 | strcpy(cid, pdev->id[0].id); |
599 | return -ENOMEM; | 584 | cid[5] = '1'; |
600 | if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) { | 585 | cdev = NULL; |
586 | list_for_each_entry(cdev, &(pdev->protocol->devices), protocol_list) { | ||
587 | if (!strcmp(cdev->id[0].id, cid)) | ||
588 | break; | ||
589 | } | ||
590 | err = snd_cs423x_card_new(dev, &card); | ||
591 | if (err < 0) | ||
592 | return err; | ||
593 | err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev); | ||
594 | if (err < 0) { | ||
601 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); | 595 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); |
602 | snd_card_free(card); | 596 | snd_card_free(card); |
603 | return err; | 597 | return err; |
@@ -612,35 +606,34 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |||
612 | return 0; | 606 | return 0; |
613 | } | 607 | } |
614 | 608 | ||
615 | static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev) | 609 | static void __devexit snd_cs423x_pnp_remove(struct pnp_dev *pdev) |
616 | { | 610 | { |
617 | snd_card_free(pnp_get_drvdata(pdev)); | 611 | snd_card_free(pnp_get_drvdata(pdev)); |
618 | pnp_set_drvdata(pdev, NULL); | 612 | pnp_set_drvdata(pdev, NULL); |
619 | } | 613 | } |
620 | 614 | ||
621 | #ifdef CONFIG_PM | 615 | #ifdef CONFIG_PM |
622 | static int snd_cs4232_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) | 616 | static int snd_cs423x_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) |
623 | { | 617 | { |
624 | return snd_cs423x_suspend(pnp_get_drvdata(pdev)); | 618 | return snd_cs423x_suspend(pnp_get_drvdata(pdev)); |
625 | } | 619 | } |
626 | 620 | ||
627 | static int snd_cs4232_pnp_resume(struct pnp_dev *pdev) | 621 | static int snd_cs423x_pnp_resume(struct pnp_dev *pdev) |
628 | { | 622 | { |
629 | return snd_cs423x_resume(pnp_get_drvdata(pdev)); | 623 | return snd_cs423x_resume(pnp_get_drvdata(pdev)); |
630 | } | 624 | } |
631 | #endif | 625 | #endif |
632 | 626 | ||
633 | static struct pnp_driver cs4232_pnp_driver = { | 627 | static struct pnp_driver cs423x_pnp_driver = { |
634 | .name = "cs4232-pnpbios", | 628 | .name = "cs423x-pnpbios", |
635 | .id_table = snd_cs4232_pnpbiosids, | 629 | .id_table = snd_cs423x_pnpbiosids, |
636 | .probe = snd_cs4232_pnpbios_detect, | 630 | .probe = snd_cs423x_pnpbios_detect, |
637 | .remove = __devexit_p(snd_cs4232_pnp_remove), | 631 | .remove = __devexit_p(snd_cs423x_pnp_remove), |
638 | #ifdef CONFIG_PM | 632 | #ifdef CONFIG_PM |
639 | .suspend = snd_cs4232_pnp_suspend, | 633 | .suspend = snd_cs423x_pnp_suspend, |
640 | .resume = snd_cs4232_pnp_resume, | 634 | .resume = snd_cs423x_pnp_resume, |
641 | #endif | 635 | #endif |
642 | }; | 636 | }; |
643 | #endif /* CS4232 */ | ||
644 | 637 | ||
645 | static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, | 638 | static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, |
646 | const struct pnp_card_device_id *pid) | 639 | const struct pnp_card_device_id *pid) |
@@ -656,9 +649,9 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, | |||
656 | if (dev >= SNDRV_CARDS) | 649 | if (dev >= SNDRV_CARDS) |
657 | return -ENODEV; | 650 | return -ENODEV; |
658 | 651 | ||
659 | card = snd_cs423x_card_new(dev); | 652 | res = snd_cs423x_card_new(dev, &card); |
660 | if (! card) | 653 | if (res < 0) |
661 | return -ENOMEM; | 654 | return res; |
662 | if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { | 655 | if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { |
663 | printk(KERN_ERR "isapnp detection failed and probing for " IDENT | 656 | printk(KERN_ERR "isapnp detection failed and probing for " IDENT |
664 | " is not supported\n"); | 657 | " is not supported\n"); |
@@ -714,18 +707,14 @@ static int __init alsa_card_cs423x_init(void) | |||
714 | #ifdef CONFIG_PNP | 707 | #ifdef CONFIG_PNP |
715 | if (!err) | 708 | if (!err) |
716 | isa_registered = 1; | 709 | isa_registered = 1; |
717 | #ifdef CS4232 | 710 | err = pnp_register_driver(&cs423x_pnp_driver); |
718 | err = pnp_register_driver(&cs4232_pnp_driver); | ||
719 | if (!err) | 711 | if (!err) |
720 | pnp_registered = 1; | 712 | pnp_registered = 1; |
721 | #endif | ||
722 | err = pnp_register_card_driver(&cs423x_pnpc_driver); | 713 | err = pnp_register_card_driver(&cs423x_pnpc_driver); |
723 | if (!err) | 714 | if (!err) |
724 | pnpc_registered = 1; | 715 | pnpc_registered = 1; |
725 | #ifdef CS4232 | ||
726 | if (pnp_registered) | 716 | if (pnp_registered) |
727 | err = 0; | 717 | err = 0; |
728 | #endif | ||
729 | if (isa_registered) | 718 | if (isa_registered) |
730 | err = 0; | 719 | err = 0; |
731 | #endif | 720 | #endif |
@@ -737,10 +726,8 @@ static void __exit alsa_card_cs423x_exit(void) | |||
737 | #ifdef CONFIG_PNP | 726 | #ifdef CONFIG_PNP |
738 | if (pnpc_registered) | 727 | if (pnpc_registered) |
739 | pnp_unregister_card_driver(&cs423x_pnpc_driver); | 728 | pnp_unregister_card_driver(&cs423x_pnpc_driver); |
740 | #ifdef CS4232 | ||
741 | if (pnp_registered) | 729 | if (pnp_registered) |
742 | pnp_unregister_driver(&cs4232_pnp_driver); | 730 | pnp_unregister_driver(&cs423x_pnp_driver); |
743 | #endif | ||
744 | if (isa_registered) | 731 | if (isa_registered) |
745 | #endif | 732 | #endif |
746 | isa_unregister_driver(&cs423x_isa_driver); | 733 | isa_unregister_driver(&cs423x_isa_driver); |
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index 6a85fdc53b60..38835f31298b 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c | |||
@@ -88,10 +88,6 @@ | |||
88 | #include <sound/wss.h> | 88 | #include <sound/wss.h> |
89 | #include <sound/asoundef.h> | 89 | #include <sound/asoundef.h> |
90 | 90 | ||
91 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | ||
92 | MODULE_DESCRIPTION("Routines for control of CS4235/4236B/4237B/4238B/4239 chips"); | ||
93 | MODULE_LICENSE("GPL"); | ||
94 | |||
95 | /* | 91 | /* |
96 | * | 92 | * |
97 | */ | 93 | */ |
@@ -286,7 +282,8 @@ int snd_cs4236_create(struct snd_card *card, | |||
286 | if (hardware == WSS_HW_DETECT) | 282 | if (hardware == WSS_HW_DETECT) |
287 | hardware = WSS_HW_DETECT3; | 283 | hardware = WSS_HW_DETECT3; |
288 | if (cport < 0x100) { | 284 | if (cport < 0x100) { |
289 | snd_printk("please, specify control port for CS4236+ chips\n"); | 285 | snd_printk(KERN_ERR "please, specify control port " |
286 | "for CS4236+ chips\n"); | ||
290 | return -ENODEV; | 287 | return -ENODEV; |
291 | } | 288 | } |
292 | err = snd_wss_create(card, port, cport, | 289 | err = snd_wss_create(card, port, cport, |
@@ -295,7 +292,8 @@ int snd_cs4236_create(struct snd_card *card, | |||
295 | return err; | 292 | return err; |
296 | 293 | ||
297 | if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { | 294 | if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { |
298 | snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware); | 295 | snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers " |
296 | "not available, hardware=0x%x\n", chip->hardware); | ||
299 | snd_device_free(card, chip); | 297 | snd_device_free(card, chip); |
300 | return -ENODEV; | 298 | return -ENODEV; |
301 | } | 299 | } |
@@ -303,16 +301,19 @@ int snd_cs4236_create(struct snd_card *card, | |||
303 | { | 301 | { |
304 | int idx; | 302 | int idx; |
305 | for (idx = 0; idx < 8; idx++) | 303 | for (idx = 0; idx < 8; idx++) |
306 | snd_printk("CD%i = 0x%x\n", idx, inb(chip->cport + idx)); | 304 | snd_printk(KERN_DEBUG "CD%i = 0x%x\n", |
305 | idx, inb(chip->cport + idx)); | ||
307 | for (idx = 0; idx < 9; idx++) | 306 | for (idx = 0; idx < 9; idx++) |
308 | snd_printk("C%i = 0x%x\n", idx, snd_cs4236_ctrl_in(chip, idx)); | 307 | snd_printk(KERN_DEBUG "C%i = 0x%x\n", |
308 | idx, snd_cs4236_ctrl_in(chip, idx)); | ||
309 | } | 309 | } |
310 | #endif | 310 | #endif |
311 | ver1 = snd_cs4236_ctrl_in(chip, 1); | 311 | ver1 = snd_cs4236_ctrl_in(chip, 1); |
312 | ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION); | 312 | ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION); |
313 | snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2); | 313 | snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2); |
314 | if (ver1 != ver2) { | 314 | if (ver1 != ver2) { |
315 | snd_printk("CS4236+ chip detected, but control port 0x%lx is not valid\n", cport); | 315 | snd_printk(KERN_ERR "CS4236+ chip detected, but " |
316 | "control port 0x%lx is not valid\n", cport); | ||
316 | snd_device_free(card, chip); | 317 | snd_device_free(card, chip); |
317 | return -ENODEV; | 318 | return -ENODEV; |
318 | } | 319 | } |
@@ -883,7 +884,8 @@ static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct sn | |||
883 | spin_lock_irqsave(&chip->reg_lock, flags); | 884 | spin_lock_irqsave(&chip->reg_lock, flags); |
884 | ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0; | 885 | ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0; |
885 | #if 0 | 886 | #if 0 |
886 | printk("get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", | 887 | printk(KERN_DEBUG "get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, " |
888 | "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", | ||
887 | snd_wss_in(chip, CS4231_ALT_FEATURE_1), | 889 | snd_wss_in(chip, CS4231_ALT_FEATURE_1), |
888 | snd_cs4236_ctrl_in(chip, 3), | 890 | snd_cs4236_ctrl_in(chip, 3), |
889 | snd_cs4236_ctrl_in(chip, 4), | 891 | snd_cs4236_ctrl_in(chip, 4), |
@@ -920,7 +922,8 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn | |||
920 | mutex_unlock(&chip->mce_mutex); | 922 | mutex_unlock(&chip->mce_mutex); |
921 | 923 | ||
922 | #if 0 | 924 | #if 0 |
923 | printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", | 925 | printk(KERN_DEBUG "set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, " |
926 | "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", | ||
924 | snd_wss_in(chip, CS4231_ALT_FEATURE_1), | 927 | snd_wss_in(chip, CS4231_ALT_FEATURE_1), |
925 | snd_cs4236_ctrl_in(chip, 3), | 928 | snd_cs4236_ctrl_in(chip, 3), |
926 | snd_cs4236_ctrl_in(chip, 4), | 929 | snd_cs4236_ctrl_in(chip, 4), |
@@ -1015,23 +1018,3 @@ int snd_cs4236_mixer(struct snd_wss *chip) | |||
1015 | } | 1018 | } |
1016 | return 0; | 1019 | return 0; |
1017 | } | 1020 | } |
1018 | |||
1019 | EXPORT_SYMBOL(snd_cs4236_create); | ||
1020 | EXPORT_SYMBOL(snd_cs4236_pcm); | ||
1021 | EXPORT_SYMBOL(snd_cs4236_mixer); | ||
1022 | |||
1023 | /* | ||
1024 | * INIT part | ||
1025 | */ | ||
1026 | |||
1027 | static int __init alsa_cs4236_init(void) | ||
1028 | { | ||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
1032 | static void __exit alsa_cs4236_exit(void) | ||
1033 | { | ||
1034 | } | ||
1035 | |||
1036 | module_init(alsa_cs4236_init) | ||
1037 | module_exit(alsa_cs4236_exit) | ||
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c index a0242c3b613e..80f5b1af9be8 100644 --- a/sound/isa/dt019x.c +++ b/sound/isa/dt019x.c | |||
@@ -150,9 +150,10 @@ static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, | |||
150 | struct snd_card_dt019x *acard; | 150 | struct snd_card_dt019x *acard; |
151 | struct snd_opl3 *opl3; | 151 | struct snd_opl3 *opl3; |
152 | 152 | ||
153 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 153 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
154 | sizeof(struct snd_card_dt019x))) == NULL) | 154 | sizeof(struct snd_card_dt019x), &card); |
155 | return -ENOMEM; | 155 | if (error < 0) |
156 | return error; | ||
156 | acard = card->private_data; | 157 | acard = card->private_data; |
157 | 158 | ||
158 | snd_card_set_dev(card, &pcard->card->dev); | 159 | snd_card_set_dev(card, &pcard->card->dev); |
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index b46377139cf8..442b081cafb7 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c | |||
@@ -49,6 +49,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | |||
49 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 49 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
50 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ | 50 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ |
51 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ | 51 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ |
52 | static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ | ||
52 | static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; | 53 | static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; |
53 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ | 54 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ |
54 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ | 55 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ |
@@ -65,6 +66,8 @@ MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); | |||
65 | module_param_array(mpu_port, long, NULL, 0444); | 66 | module_param_array(mpu_port, long, NULL, 0444); |
66 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); | 67 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); |
67 | module_param_array(irq, int, NULL, 0444); | 68 | module_param_array(irq, int, NULL, 0444); |
69 | module_param_array(fm_port, long, NULL, 0444); | ||
70 | MODULE_PARM_DESC(fm_port, "FM port # for ES1688 driver."); | ||
68 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); | 71 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); |
69 | module_param_array(mpu_irq, int, NULL, 0444); | 72 | module_param_array(mpu_irq, int, NULL, 0444); |
70 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); | 73 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); |
@@ -122,9 +125,9 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) | |||
122 | struct snd_pcm *pcm; | 125 | struct snd_pcm *pcm; |
123 | int error; | 126 | int error; |
124 | 127 | ||
125 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 128 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
126 | if (!card) | 129 | if (error < 0) |
127 | return -EINVAL; | 130 | return error; |
128 | 131 | ||
129 | error = snd_es1688_legacy_create(card, dev, n, &chip); | 132 | error = snd_es1688_legacy_create(card, dev, n, &chip); |
130 | if (error < 0) | 133 | if (error < 0) |
@@ -143,13 +146,19 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) | |||
143 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, | 146 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, |
144 | chip->port, chip->irq, chip->dma8); | 147 | chip->port, chip->irq, chip->dma8); |
145 | 148 | ||
146 | if (snd_opl3_create(card, chip->port, chip->port + 2, | 149 | if (fm_port[n] == SNDRV_AUTO_PORT) |
147 | OPL3_HW_OPL3, 0, &opl3) < 0) | 150 | fm_port[n] = port[n]; /* share the same port */ |
148 | dev_warn(dev, "opl3 not detected at 0x%lx\n", chip->port); | 151 | |
149 | else { | 152 | if (fm_port[n] > 0) { |
150 | error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | 153 | if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, |
151 | if (error < 0) | 154 | OPL3_HW_OPL3, 0, &opl3) < 0) |
152 | goto out; | 155 | dev_warn(dev, |
156 | "opl3 not detected at 0x%lx\n", fm_port[n]); | ||
157 | else { | ||
158 | error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | ||
159 | if (error < 0) | ||
160 | goto out; | ||
161 | } | ||
153 | } | 162 | } |
154 | 163 | ||
155 | if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && | 164 | if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && |
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 4fbb508a817f..4c6e14f87f2d 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c | |||
@@ -45,7 +45,7 @@ static int snd_es1688_dsp_command(struct snd_es1688 *chip, unsigned char val) | |||
45 | return 1; | 45 | return 1; |
46 | } | 46 | } |
47 | #ifdef CONFIG_SND_DEBUG | 47 | #ifdef CONFIG_SND_DEBUG |
48 | printk("snd_es1688_dsp_command: timeout (0x%x)\n", val); | 48 | printk(KERN_DEBUG "snd_es1688_dsp_command: timeout (0x%x)\n", val); |
49 | #endif | 49 | #endif |
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
@@ -167,13 +167,16 @@ static int snd_es1688_probe(struct snd_es1688 *chip) | |||
167 | hw = ES1688_HW_AUTO; | 167 | hw = ES1688_HW_AUTO; |
168 | switch (chip->version & 0xfff0) { | 168 | switch (chip->version & 0xfff0) { |
169 | case 0x4880: | 169 | case 0x4880: |
170 | snd_printk("[0x%lx] ESS: AudioDrive ES488 detected, but driver is in another place\n", chip->port); | 170 | snd_printk(KERN_ERR "[0x%lx] ESS: AudioDrive ES488 detected, " |
171 | "but driver is in another place\n", chip->port); | ||
171 | return -ENODEV; | 172 | return -ENODEV; |
172 | case 0x6880: | 173 | case 0x6880: |
173 | hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688; | 174 | hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688; |
174 | break; | 175 | break; |
175 | default: | 176 | default: |
176 | snd_printk("[0x%lx] ESS: unknown AudioDrive chip with version 0x%x (Jazz16 soundcard?)\n", chip->port, chip->version); | 177 | snd_printk(KERN_ERR "[0x%lx] ESS: unknown AudioDrive chip " |
178 | "with version 0x%x (Jazz16 soundcard?)\n", | ||
179 | chip->port, chip->version); | ||
177 | return -ENODEV; | 180 | return -ENODEV; |
178 | } | 181 | } |
179 | 182 | ||
@@ -223,7 +226,7 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) | |||
223 | } | 226 | } |
224 | } | 227 | } |
225 | #if 0 | 228 | #if 0 |
226 | snd_printk("mpu cfg = 0x%x\n", cfg); | 229 | snd_printk(KERN_DEBUG "mpu cfg = 0x%x\n", cfg); |
227 | #endif | 230 | #endif |
228 | spin_lock_irqsave(&chip->reg_lock, flags); | 231 | spin_lock_irqsave(&chip->reg_lock, flags); |
229 | snd_es1688_mixer_write(chip, 0x40, cfg); | 232 | snd_es1688_mixer_write(chip, 0x40, cfg); |
@@ -237,7 +240,9 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) | |||
237 | cfg = 0xf0; /* enable only DMA counter interrupt */ | 240 | cfg = 0xf0; /* enable only DMA counter interrupt */ |
238 | irq_bits = irqs[chip->irq & 0x0f]; | 241 | irq_bits = irqs[chip->irq & 0x0f]; |
239 | if (irq_bits < 0) { | 242 | if (irq_bits < 0) { |
240 | snd_printk("[0x%lx] ESS: bad IRQ %d for ES1688 chip!!\n", chip->port, chip->irq); | 243 | snd_printk(KERN_ERR "[0x%lx] ESS: bad IRQ %d " |
244 | "for ES1688 chip!!\n", | ||
245 | chip->port, chip->irq); | ||
241 | #if 0 | 246 | #if 0 |
242 | irq_bits = 0; | 247 | irq_bits = 0; |
243 | cfg = 0x10; | 248 | cfg = 0x10; |
@@ -250,7 +255,8 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) | |||
250 | cfg = 0xf0; /* extended mode DMA enable */ | 255 | cfg = 0xf0; /* extended mode DMA enable */ |
251 | dma = chip->dma8; | 256 | dma = chip->dma8; |
252 | if (dma > 3 || dma == 2) { | 257 | if (dma > 3 || dma == 2) { |
253 | snd_printk("[0x%lx] ESS: bad DMA channel %d for ES1688 chip!!\n", chip->port, dma); | 258 | snd_printk(KERN_ERR "[0x%lx] ESS: bad DMA channel %d " |
259 | "for ES1688 chip!!\n", chip->port, dma); | ||
254 | #if 0 | 260 | #if 0 |
255 | dma_bits = 0; | 261 | dma_bits = 0; |
256 | cfg = 0x00; /* disable all DMA */ | 262 | cfg = 0x00; /* disable all DMA */ |
@@ -341,8 +347,9 @@ static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char va | |||
341 | return -EINVAL; /* something is wrong */ | 347 | return -EINVAL; /* something is wrong */ |
342 | } | 348 | } |
343 | #if 0 | 349 | #if 0 |
344 | printk("trigger: val = 0x%x, value = 0x%x\n", val, value); | 350 | printk(KERN_DEBUG "trigger: val = 0x%x, value = 0x%x\n", val, value); |
345 | printk("trigger: pointer = 0x%x\n", snd_dma_pointer(chip->dma8, chip->dma_size)); | 351 | printk(KERN_DEBUG "trigger: pointer = 0x%x\n", |
352 | snd_dma_pointer(chip->dma8, chip->dma_size)); | ||
346 | #endif | 353 | #endif |
347 | snd_es1688_write(chip, 0xb8, (val & 0xf0) | value); | 354 | snd_es1688_write(chip, 0xb8, (val & 0xf0) | value); |
348 | spin_unlock(&chip->reg_lock); | 355 | spin_unlock(&chip->reg_lock); |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 90498e4ca260..8cfbff73a835 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -2125,10 +2125,10 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, | |||
2125 | #define is_isapnp_selected(dev) 0 | 2125 | #define is_isapnp_selected(dev) 0 |
2126 | #endif | 2126 | #endif |
2127 | 2127 | ||
2128 | static struct snd_card *snd_es18xx_card_new(int dev) | 2128 | static int snd_es18xx_card_new(int dev, struct snd_card **cardp) |
2129 | { | 2129 | { |
2130 | return snd_card_new(index[dev], id[dev], THIS_MODULE, | 2130 | return snd_card_create(index[dev], id[dev], THIS_MODULE, |
2131 | sizeof(struct snd_audiodrive)); | 2131 | sizeof(struct snd_audiodrive), cardp); |
2132 | } | 2132 | } |
2133 | 2133 | ||
2134 | static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) | 2134 | static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) |
@@ -2197,9 +2197,9 @@ static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr) | |||
2197 | struct snd_card *card; | 2197 | struct snd_card *card; |
2198 | int err; | 2198 | int err; |
2199 | 2199 | ||
2200 | card = snd_es18xx_card_new(dev); | 2200 | err = snd_es18xx_card_new(dev, &card); |
2201 | if (! card) | 2201 | if (err < 0) |
2202 | return -ENOMEM; | 2202 | return err; |
2203 | snd_card_set_dev(card, devptr); | 2203 | snd_card_set_dev(card, devptr); |
2204 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { | 2204 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { |
2205 | snd_card_free(card); | 2205 | snd_card_free(card); |
@@ -2303,9 +2303,9 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, | |||
2303 | if (dev >= SNDRV_CARDS) | 2303 | if (dev >= SNDRV_CARDS) |
2304 | return -ENODEV; | 2304 | return -ENODEV; |
2305 | 2305 | ||
2306 | card = snd_es18xx_card_new(dev); | 2306 | err = snd_es18xx_card_new(dev, &card); |
2307 | if (! card) | 2307 | if (err < 0) |
2308 | return -ENOMEM; | 2308 | return err; |
2309 | if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) { | 2309 | if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) { |
2310 | snd_card_free(card); | 2310 | snd_card_free(card); |
2311 | return err; | 2311 | return err; |
@@ -2362,9 +2362,9 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard, | |||
2362 | if (dev >= SNDRV_CARDS) | 2362 | if (dev >= SNDRV_CARDS) |
2363 | return -ENODEV; | 2363 | return -ENODEV; |
2364 | 2364 | ||
2365 | card = snd_es18xx_card_new(dev); | 2365 | res = snd_es18xx_card_new(dev, &card); |
2366 | if (! card) | 2366 | if (res < 0) |
2367 | return -ENOMEM; | 2367 | return res; |
2368 | 2368 | ||
2369 | if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) { | 2369 | if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) { |
2370 | snd_card_free(card); | 2370 | snd_card_free(card); |
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index f45f6116c77a..36c27c832360 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c | |||
@@ -45,7 +45,8 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus, | |||
45 | unsigned char dma_cmd; | 45 | unsigned char dma_cmd; |
46 | unsigned int address_high; | 46 | unsigned int address_high; |
47 | 47 | ||
48 | // snd_printk("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", addr, (long) buf, count); | 48 | snd_printdd("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", |
49 | addr, buf_addr, count); | ||
49 | 50 | ||
50 | if (gus->gf1.dma1 > 3) { | 51 | if (gus->gf1.dma1 > 3) { |
51 | if (gus->gf1.enh_mode) { | 52 | if (gus->gf1.enh_mode) { |
@@ -77,7 +78,8 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus, | |||
77 | snd_gf1_dma_ack(gus); | 78 | snd_gf1_dma_ack(gus); |
78 | snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE); | 79 | snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE); |
79 | #if 0 | 80 | #if 0 |
80 | snd_printk("address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", address << 1, count, dma_cmd); | 81 | snd_printk(KERN_DEBUG "address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", |
82 | address << 1, count, dma_cmd); | ||
81 | #endif | 83 | #endif |
82 | spin_lock_irqsave(&gus->reg_lock, flags); | 84 | spin_lock_irqsave(&gus->reg_lock, flags); |
83 | if (gus->gf1.enh_mode) { | 85 | if (gus->gf1.enh_mode) { |
@@ -142,7 +144,9 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) | |||
142 | snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd); | 144 | snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd); |
143 | kfree(block); | 145 | kfree(block); |
144 | #if 0 | 146 | #if 0 |
145 | printk("program dma (IRQ) - addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", addr, (long) buffer, count, cmd); | 147 | snd_printd(KERN_DEBUG "program dma (IRQ) - " |
148 | "addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", | ||
149 | block->addr, block->buf_addr, block->count, block->cmd); | ||
146 | #endif | 150 | #endif |
147 | } | 151 | } |
148 | 152 | ||
@@ -203,13 +207,16 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus, | |||
203 | } | 207 | } |
204 | *block = *__block; | 208 | *block = *__block; |
205 | block->next = NULL; | 209 | block->next = NULL; |
206 | #if 0 | 210 | |
207 | printk("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", block->addr, (long) block->buffer, block->count, block->cmd); | 211 | snd_printdd("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", |
208 | #endif | 212 | block->addr, (long) block->buffer, block->count, |
209 | #if 0 | 213 | block->cmd); |
210 | printk("gus->gf1.dma_data_pcm_last = 0x%lx\n", (long)gus->gf1.dma_data_pcm_last); | 214 | |
211 | printk("gus->gf1.dma_data_pcm = 0x%lx\n", (long)gus->gf1.dma_data_pcm); | 215 | snd_printdd("gus->gf1.dma_data_pcm_last = 0x%lx\n", |
212 | #endif | 216 | (long)gus->gf1.dma_data_pcm_last); |
217 | snd_printdd("gus->gf1.dma_data_pcm = 0x%lx\n", | ||
218 | (long)gus->gf1.dma_data_pcm); | ||
219 | |||
213 | spin_lock_irqsave(&gus->dma_lock, flags); | 220 | spin_lock_irqsave(&gus->dma_lock, flags); |
214 | if (synth) { | 221 | if (synth) { |
215 | if (gus->gf1.dma_data_synth_last) { | 222 | if (gus->gf1.dma_data_synth_last) { |
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c index 041894ddd014..2055aff71b50 100644 --- a/sound/isa/gus/gus_irq.c +++ b/sound/isa/gus/gus_irq.c | |||
@@ -41,7 +41,7 @@ __again: | |||
41 | if (status == 0) | 41 | if (status == 0) |
42 | return IRQ_RETVAL(handled); | 42 | return IRQ_RETVAL(handled); |
43 | handled = 1; | 43 | handled = 1; |
44 | // snd_printk("IRQ: status = 0x%x\n", status); | 44 | /* snd_printk(KERN_DEBUG "IRQ: status = 0x%x\n", status); */ |
45 | if (status & 0x02) { | 45 | if (status & 0x02) { |
46 | STAT_ADD(gus->gf1.interrupt_stat_midi_in); | 46 | STAT_ADD(gus->gf1.interrupt_stat_midi_in); |
47 | if (gus->gf1.interrupt_handler_midi_in) | 47 | if (gus->gf1.interrupt_handler_midi_in) |
@@ -65,7 +65,9 @@ __again: | |||
65 | continue; /* multi request */ | 65 | continue; /* multi request */ |
66 | already |= _current_; /* mark request */ | 66 | already |= _current_; /* mark request */ |
67 | #if 0 | 67 | #if 0 |
68 | printk("voice = %i, voice_status = 0x%x, voice_verify = %i\n", voice, voice_status, inb(GUSP(gus, GF1PAGE))); | 68 | printk(KERN_DEBUG "voice = %i, voice_status = 0x%x, " |
69 | "voice_verify = %i\n", | ||
70 | voice, voice_status, inb(GUSP(gus, GF1PAGE))); | ||
69 | #endif | 71 | #endif |
70 | pvoice = &gus->gf1.voices[voice]; | 72 | pvoice = &gus->gf1.voices[voice]; |
71 | if (pvoice->use) { | 73 | if (pvoice->use) { |
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 38510aeb21c6..edb11eefdfe3 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c | |||
@@ -82,7 +82,10 @@ static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream, | |||
82 | 82 | ||
83 | count += offset & 31; | 83 | count += offset & 31; |
84 | offset &= ~31; | 84 | offset &= ~31; |
85 | // snd_printk("block change - offset = 0x%x, count = 0x%x\n", offset, count); | 85 | /* |
86 | snd_printk(KERN_DEBUG "block change - offset = 0x%x, count = 0x%x\n", | ||
87 | offset, count); | ||
88 | */ | ||
86 | memset(&block, 0, sizeof(block)); | 89 | memset(&block, 0, sizeof(block)); |
87 | block.cmd = SNDRV_GF1_DMA_IRQ; | 90 | block.cmd = SNDRV_GF1_DMA_IRQ; |
88 | if (snd_pcm_format_unsigned(runtime->format)) | 91 | if (snd_pcm_format_unsigned(runtime->format)) |
@@ -135,7 +138,11 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream) | |||
135 | curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels; | 138 | curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels; |
136 | end = curr + (pcmp->block_size / runtime->channels); | 139 | end = curr + (pcmp->block_size / runtime->channels); |
137 | end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1; | 140 | end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1; |
138 | // snd_printk("init: curr=0x%x, begin=0x%x, end=0x%x, ctrl=0x%x, ramp=0x%x, rate=0x%x\n", curr, begin, end, voice_ctrl, ramp_ctrl, rate); | 141 | /* |
142 | snd_printk(KERN_DEBUG "init: curr=0x%x, begin=0x%x, end=0x%x, " | ||
143 | "ctrl=0x%x, ramp=0x%x, rate=0x%x\n", | ||
144 | curr, begin, end, voice_ctrl, ramp_ctrl, rate); | ||
145 | */ | ||
139 | pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8; | 146 | pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8; |
140 | vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; | 147 | vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; |
141 | spin_lock_irqsave(&gus->reg_lock, flags); | 148 | spin_lock_irqsave(&gus->reg_lock, flags); |
@@ -205,9 +212,11 @@ static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus, | |||
205 | ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03; | 212 | ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03; |
206 | #if 0 | 213 | #if 0 |
207 | snd_gf1_select_voice(gus, pvoice->number); | 214 | snd_gf1_select_voice(gus, pvoice->number); |
208 | printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); | 215 | printk(KERN_DEBUG "position = 0x%x\n", |
216 | (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); | ||
209 | snd_gf1_select_voice(gus, pcmp->pvoices[1]->number); | 217 | snd_gf1_select_voice(gus, pcmp->pvoices[1]->number); |
210 | printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); | 218 | printk(KERN_DEBUG "position = 0x%x\n", |
219 | (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); | ||
211 | snd_gf1_select_voice(gus, pvoice->number); | 220 | snd_gf1_select_voice(gus, pvoice->number); |
212 | #endif | 221 | #endif |
213 | pcmp->bpos++; | 222 | pcmp->bpos++; |
@@ -299,7 +308,11 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf, | |||
299 | unsigned int len; | 308 | unsigned int len; |
300 | unsigned long flags; | 309 | unsigned long flags; |
301 | 310 | ||
302 | // printk("poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", (int)buf, pos, count, gus->gf1.port); | 311 | /* |
312 | printk(KERN_DEBUG | ||
313 | "poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", | ||
314 | (int)buf, pos, count, gus->gf1.port); | ||
315 | */ | ||
303 | while (count > 0) { | 316 | while (count > 0) { |
304 | len = count; | 317 | len = count; |
305 | if (len > 512) /* limit, to allow IRQ */ | 318 | if (len > 512) /* limit, to allow IRQ */ |
@@ -680,7 +693,8 @@ static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream) | |||
680 | runtime->private_free = snd_gf1_pcm_playback_free; | 693 | runtime->private_free = snd_gf1_pcm_playback_free; |
681 | 694 | ||
682 | #if 0 | 695 | #if 0 |
683 | printk("playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer); | 696 | printk(KERN_DEBUG "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", |
697 | (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer); | ||
684 | #endif | 698 | #endif |
685 | if ((err = snd_gf1_dma_init(gus)) < 0) | 699 | if ((err = snd_gf1_dma_init(gus)) < 0) |
686 | return err; | 700 | return err; |
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c index f0af3f79b08b..21cc42e4c4be 100644 --- a/sound/isa/gus/gus_uart.c +++ b/sound/isa/gus/gus_uart.c | |||
@@ -129,8 +129,14 @@ static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream) | |||
129 | } | 129 | } |
130 | spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); | 130 | spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); |
131 | #if 0 | 131 | #if 0 |
132 | snd_printk("read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); | 132 | snd_printk(KERN_DEBUG |
133 | snd_printk("[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x (page = 0x%x)\n", gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102)); | 133 | "read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", |
134 | gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); | ||
135 | snd_printk(KERN_DEBUG | ||
136 | "[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x " | ||
137 | "(page = 0x%x)\n", | ||
138 | gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), | ||
139 | inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102)); | ||
134 | #endif | 140 | #endif |
135 | return 0; | 141 | return 0; |
136 | } | 142 | } |
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 426532a4d730..086b8f0e0f94 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c | |||
@@ -148,9 +148,9 @@ static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n) | |||
148 | struct snd_gus_card *gus; | 148 | struct snd_gus_card *gus; |
149 | int error; | 149 | int error; |
150 | 150 | ||
151 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 151 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
152 | if (!card) | 152 | if (error < 0) |
153 | return -EINVAL; | 153 | return error; |
154 | 154 | ||
155 | if (pcm_channels[n] < 2) | 155 | if (pcm_channels[n] < 2) |
156 | pcm_channels[n] = 2; | 156 | pcm_channels[n] = 2; |
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 7ad4c3b41a84..180a8dea6bd9 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c | |||
@@ -241,9 +241,9 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) | |||
241 | struct snd_opl3 *opl3; | 241 | struct snd_opl3 *opl3; |
242 | int error; | 242 | int error; |
243 | 243 | ||
244 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); | 244 | error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); |
245 | if (!card) | 245 | if (error < 0) |
246 | return -EINVAL; | 246 | return error; |
247 | 247 | ||
248 | if (mpu_port[n] == SNDRV_AUTO_PORT) | 248 | if (mpu_port[n] == SNDRV_AUTO_PORT) |
249 | mpu_port[n] = 0; | 249 | mpu_port[n] = 0; |
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index f94c1976e632..f26eac8d8110 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c | |||
@@ -214,10 +214,10 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) | |||
214 | struct snd_wss *wss; | 214 | struct snd_wss *wss; |
215 | struct snd_gusmax *maxcard; | 215 | struct snd_gusmax *maxcard; |
216 | 216 | ||
217 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 217 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
218 | sizeof(struct snd_gusmax)); | 218 | sizeof(struct snd_gusmax), &card); |
219 | if (card == NULL) | 219 | if (err < 0) |
220 | return -ENOMEM; | 220 | return err; |
221 | card->private_free = snd_gusmax_free; | 221 | card->private_free = snd_gusmax_free; |
222 | maxcard = (struct snd_gusmax *)card->private_data; | 222 | maxcard = (struct snd_gusmax *)card->private_data; |
223 | maxcard->card = card; | 223 | maxcard->card = card; |
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 5faecfb602d3..534a6eced2b8 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -170,7 +170,7 @@ static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int da | |||
170 | unsigned long port = bus->private_value; | 170 | unsigned long port = bus->private_value; |
171 | 171 | ||
172 | #if 0 | 172 | #if 0 |
173 | printk("i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); | 173 | printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); |
174 | #endif | 174 | #endif |
175 | outb((data << 1) | ctrl, port); | 175 | outb((data << 1) | ctrl, port); |
176 | udelay(10); | 176 | udelay(10); |
@@ -183,7 +183,7 @@ static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus) | |||
183 | 183 | ||
184 | res = inb(port) & 1; | 184 | res = inb(port) & 1; |
185 | #if 0 | 185 | #if 0 |
186 | printk("i2c_getclockline - 0x%lx -> %i\n", port, res); | 186 | printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res); |
187 | #endif | 187 | #endif |
188 | return res; | 188 | return res; |
189 | } | 189 | } |
@@ -197,7 +197,7 @@ static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack) | |||
197 | udelay(10); | 197 | udelay(10); |
198 | res = (inb(port) & 2) >> 1; | 198 | res = (inb(port) & 2) >> 1; |
199 | #if 0 | 199 | #if 0 |
200 | printk("i2c_getdataline - 0x%lx -> %i\n", port, res); | 200 | printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res); |
201 | #endif | 201 | #endif |
202 | return res; | 202 | return res; |
203 | } | 203 | } |
@@ -342,7 +342,8 @@ static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *s | |||
342 | snd_gf1_poke(gus, local, d); | 342 | snd_gf1_poke(gus, local, d); |
343 | snd_gf1_poke(gus, local + 1, d + 1); | 343 | snd_gf1_poke(gus, local + 1, d + 1); |
344 | #if 0 | 344 | #if 0 |
345 | printk("d = 0x%x, local = 0x%x, local + 1 = 0x%x, idx << 22 = 0x%x\n", | 345 | printk(KERN_DEBUG "d = 0x%x, local = 0x%x, " |
346 | "local + 1 = 0x%x, idx << 22 = 0x%x\n", | ||
346 | d, | 347 | d, |
347 | snd_gf1_peek(gus, local), | 348 | snd_gf1_peek(gus, local), |
348 | snd_gf1_peek(gus, local + 1), | 349 | snd_gf1_peek(gus, local + 1), |
@@ -356,7 +357,8 @@ static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *s | |||
356 | } | 357 | } |
357 | } | 358 | } |
358 | #if 0 | 359 | #if 0 |
359 | printk("sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]); | 360 | printk(KERN_DEBUG "sizes: %i %i %i %i\n", |
361 | sizes[0], sizes[1], sizes[2], sizes[3]); | ||
360 | #endif | 362 | #endif |
361 | } | 363 | } |
362 | 364 | ||
@@ -410,12 +412,12 @@ static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus) | |||
410 | lmct = (psizes[3] << 24) | (psizes[2] << 16) | | 412 | lmct = (psizes[3] << 24) | (psizes[2] << 16) | |
411 | (psizes[1] << 8) | psizes[0]; | 413 | (psizes[1] << 8) | psizes[0]; |
412 | #if 0 | 414 | #if 0 |
413 | printk("lmct = 0x%08x\n", lmct); | 415 | printk(KERN_DEBUG "lmct = 0x%08x\n", lmct); |
414 | #endif | 416 | #endif |
415 | for (i = 0; i < ARRAY_SIZE(lmc); i++) | 417 | for (i = 0; i < ARRAY_SIZE(lmc); i++) |
416 | if (lmct == lmc[i]) { | 418 | if (lmct == lmc[i]) { |
417 | #if 0 | 419 | #if 0 |
418 | printk("found !!! %i\n", i); | 420 | printk(KERN_DEBUG "found !!! %i\n", i); |
419 | #endif | 421 | #endif |
420 | snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i); | 422 | snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i); |
421 | snd_interwave_bank_sizes(gus, psizes); | 423 | snd_interwave_bank_sizes(gus, psizes); |
@@ -626,20 +628,22 @@ static void snd_interwave_free(struct snd_card *card) | |||
626 | free_irq(iwcard->irq, (void *)iwcard); | 628 | free_irq(iwcard->irq, (void *)iwcard); |
627 | } | 629 | } |
628 | 630 | ||
629 | static struct snd_card *snd_interwave_card_new(int dev) | 631 | static int snd_interwave_card_new(int dev, struct snd_card **cardp) |
630 | { | 632 | { |
631 | struct snd_card *card; | 633 | struct snd_card *card; |
632 | struct snd_interwave *iwcard; | 634 | struct snd_interwave *iwcard; |
635 | int err; | ||
633 | 636 | ||
634 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 637 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
635 | sizeof(struct snd_interwave)); | 638 | sizeof(struct snd_interwave), &card); |
636 | if (card == NULL) | 639 | if (err < 0) |
637 | return NULL; | 640 | return err; |
638 | iwcard = card->private_data; | 641 | iwcard = card->private_data; |
639 | iwcard->card = card; | 642 | iwcard->card = card; |
640 | iwcard->irq = -1; | 643 | iwcard->irq = -1; |
641 | card->private_free = snd_interwave_free; | 644 | card->private_free = snd_interwave_free; |
642 | return card; | 645 | *cardp = card; |
646 | return 0; | ||
643 | } | 647 | } |
644 | 648 | ||
645 | static int __devinit snd_interwave_probe(struct snd_card *card, int dev) | 649 | static int __devinit snd_interwave_probe(struct snd_card *card, int dev) |
@@ -778,9 +782,9 @@ static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr) | |||
778 | struct snd_card *card; | 782 | struct snd_card *card; |
779 | int err; | 783 | int err; |
780 | 784 | ||
781 | card = snd_interwave_card_new(dev); | 785 | err = snd_interwave_card_new(dev, &card); |
782 | if (! card) | 786 | if (err < 0) |
783 | return -ENOMEM; | 787 | return err; |
784 | 788 | ||
785 | snd_card_set_dev(card, devptr); | 789 | snd_card_set_dev(card, devptr); |
786 | if ((err = snd_interwave_probe(card, dev)) < 0) { | 790 | if ((err = snd_interwave_probe(card, dev)) < 0) { |
@@ -876,9 +880,9 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, | |||
876 | if (dev >= SNDRV_CARDS) | 880 | if (dev >= SNDRV_CARDS) |
877 | return -ENODEV; | 881 | return -ENODEV; |
878 | 882 | ||
879 | card = snd_interwave_card_new(dev); | 883 | res = snd_interwave_card_new(dev, &card); |
880 | if (! card) | 884 | if (res < 0) |
881 | return -ENOMEM; | 885 | return res; |
882 | 886 | ||
883 | if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { | 887 | if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { |
884 | snd_card_free(card); | 888 | snd_card_free(card); |
diff --git a/sound/isa/msnd/Makefile b/sound/isa/msnd/Makefile new file mode 100644 index 000000000000..2171c0aa2f62 --- /dev/null +++ b/sound/isa/msnd/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | |||
2 | snd-msnd-lib-objs := msnd.o msnd_midi.o msnd_pinnacle_mixer.o | ||
3 | snd-msnd-pinnacle-objs := msnd_pinnacle.o | ||
4 | snd-msnd-classic-objs := msnd_classic.o | ||
5 | |||
6 | # Toplevel Module Dependency | ||
7 | obj-$(CONFIG_SND_MSND_PINNACLE) += snd-msnd-pinnacle.o snd-msnd-lib.o | ||
8 | obj-$(CONFIG_SND_MSND_CLASSIC) += snd-msnd-classic.o snd-msnd-lib.o | ||
9 | |||
diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c new file mode 100644 index 000000000000..906454413ed2 --- /dev/null +++ b/sound/isa/msnd/msnd.c | |||
@@ -0,0 +1,705 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * 2002/06/30 Karsten Wiese: | ||
4 | * removed kernel-version dependencies. | ||
5 | * ripped from linux kernel 2.4.18 (OSS Implementation) by me. | ||
6 | * In the OSS Version, this file is compiled to a separate MODULE, | ||
7 | * that is used by the pinnacle and the classic driver. | ||
8 | * since there is no classic driver for alsa yet (i dont have a classic | ||
9 | * & writing one blindfold is difficult) this file's object is statically | ||
10 | * linked into the pinnacle-driver-module for now. look for the string | ||
11 | * "uncomment this to make this a module again" | ||
12 | * to do guess what. | ||
13 | * | ||
14 | * the following is a copy of the 2.4.18 OSS FREE file-heading comment: | ||
15 | * | ||
16 | * msnd.c - Driver Base | ||
17 | * | ||
18 | * Turtle Beach MultiSound Sound Card Driver for Linux | ||
19 | * | ||
20 | * Copyright (C) 1998 Andrew Veliath | ||
21 | * | ||
22 | * This program is free software; you can redistribute it and/or modify | ||
23 | * it under the terms of the GNU General Public License as published by | ||
24 | * the Free Software Foundation; either version 2 of the License, or | ||
25 | * (at your option) any later version. | ||
26 | * | ||
27 | * This program is distributed in the hope that it will be useful, | ||
28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
30 | * GNU General Public License for more details. | ||
31 | * | ||
32 | * You should have received a copy of the GNU General Public License | ||
33 | * along with this program; if not, write to the Free Software | ||
34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
35 | * | ||
36 | ********************************************************************/ | ||
37 | |||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/types.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/io.h> | ||
42 | #include <linux/fs.h> | ||
43 | #include <linux/delay.h> | ||
44 | |||
45 | #include <sound/core.h> | ||
46 | #include <sound/initval.h> | ||
47 | #include <sound/pcm.h> | ||
48 | #include <sound/pcm_params.h> | ||
49 | |||
50 | #include "msnd.h" | ||
51 | |||
52 | #define LOGNAME "msnd" | ||
53 | |||
54 | |||
55 | void snd_msnd_init_queue(void *base, int start, int size) | ||
56 | { | ||
57 | writew(PCTODSP_BASED(start), base + JQS_wStart); | ||
58 | writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize); | ||
59 | writew(0, base + JQS_wHead); | ||
60 | writew(0, base + JQS_wTail); | ||
61 | } | ||
62 | EXPORT_SYMBOL(snd_msnd_init_queue); | ||
63 | |||
64 | static int snd_msnd_wait_TXDE(struct snd_msnd *dev) | ||
65 | { | ||
66 | unsigned int io = dev->io; | ||
67 | int timeout = 1000; | ||
68 | |||
69 | while (timeout-- > 0) | ||
70 | if (inb(io + HP_ISR) & HPISR_TXDE) | ||
71 | return 0; | ||
72 | |||
73 | return -EIO; | ||
74 | } | ||
75 | |||
76 | static int snd_msnd_wait_HC0(struct snd_msnd *dev) | ||
77 | { | ||
78 | unsigned int io = dev->io; | ||
79 | int timeout = 1000; | ||
80 | |||
81 | while (timeout-- > 0) | ||
82 | if (!(inb(io + HP_CVR) & HPCVR_HC)) | ||
83 | return 0; | ||
84 | |||
85 | return -EIO; | ||
86 | } | ||
87 | |||
88 | int snd_msnd_send_dsp_cmd(struct snd_msnd *dev, u8 cmd) | ||
89 | { | ||
90 | unsigned long flags; | ||
91 | |||
92 | spin_lock_irqsave(&dev->lock, flags); | ||
93 | if (snd_msnd_wait_HC0(dev) == 0) { | ||
94 | outb(cmd, dev->io + HP_CVR); | ||
95 | spin_unlock_irqrestore(&dev->lock, flags); | ||
96 | return 0; | ||
97 | } | ||
98 | spin_unlock_irqrestore(&dev->lock, flags); | ||
99 | |||
100 | snd_printd(KERN_ERR LOGNAME ": Send DSP command timeout\n"); | ||
101 | |||
102 | return -EIO; | ||
103 | } | ||
104 | EXPORT_SYMBOL(snd_msnd_send_dsp_cmd); | ||
105 | |||
106 | int snd_msnd_send_word(struct snd_msnd *dev, unsigned char high, | ||
107 | unsigned char mid, unsigned char low) | ||
108 | { | ||
109 | unsigned int io = dev->io; | ||
110 | |||
111 | if (snd_msnd_wait_TXDE(dev) == 0) { | ||
112 | outb(high, io + HP_TXH); | ||
113 | outb(mid, io + HP_TXM); | ||
114 | outb(low, io + HP_TXL); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | snd_printd(KERN_ERR LOGNAME ": Send host word timeout\n"); | ||
119 | |||
120 | return -EIO; | ||
121 | } | ||
122 | EXPORT_SYMBOL(snd_msnd_send_word); | ||
123 | |||
124 | int snd_msnd_upload_host(struct snd_msnd *dev, const u8 *bin, int len) | ||
125 | { | ||
126 | int i; | ||
127 | |||
128 | if (len % 3 != 0) { | ||
129 | snd_printk(KERN_ERR LOGNAME | ||
130 | ": Upload host data not multiple of 3!\n"); | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | for (i = 0; i < len; i += 3) | ||
135 | if (snd_msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2])) | ||
136 | return -EIO; | ||
137 | |||
138 | inb(dev->io + HP_RXL); | ||
139 | inb(dev->io + HP_CVR); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | EXPORT_SYMBOL(snd_msnd_upload_host); | ||
144 | |||
145 | int snd_msnd_enable_irq(struct snd_msnd *dev) | ||
146 | { | ||
147 | unsigned long flags; | ||
148 | |||
149 | if (dev->irq_ref++) | ||
150 | return 0; | ||
151 | |||
152 | snd_printdd(LOGNAME ": Enabling IRQ\n"); | ||
153 | |||
154 | spin_lock_irqsave(&dev->lock, flags); | ||
155 | if (snd_msnd_wait_TXDE(dev) == 0) { | ||
156 | outb(inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR); | ||
157 | if (dev->type == msndClassic) | ||
158 | outb(dev->irqid, dev->io + HP_IRQM); | ||
159 | |||
160 | outb(inb(dev->io + HP_ICR) & ~HPICR_TREQ, dev->io + HP_ICR); | ||
161 | outb(inb(dev->io + HP_ICR) | HPICR_RREQ, dev->io + HP_ICR); | ||
162 | enable_irq(dev->irq); | ||
163 | snd_msnd_init_queue(dev->DSPQ, dev->dspq_data_buff, | ||
164 | dev->dspq_buff_size); | ||
165 | spin_unlock_irqrestore(&dev->lock, flags); | ||
166 | return 0; | ||
167 | } | ||
168 | spin_unlock_irqrestore(&dev->lock, flags); | ||
169 | |||
170 | snd_printd(KERN_ERR LOGNAME ": Enable IRQ failed\n"); | ||
171 | |||
172 | return -EIO; | ||
173 | } | ||
174 | EXPORT_SYMBOL(snd_msnd_enable_irq); | ||
175 | |||
176 | int snd_msnd_disable_irq(struct snd_msnd *dev) | ||
177 | { | ||
178 | unsigned long flags; | ||
179 | |||
180 | if (--dev->irq_ref > 0) | ||
181 | return 0; | ||
182 | |||
183 | if (dev->irq_ref < 0) | ||
184 | snd_printd(KERN_WARNING LOGNAME ": IRQ ref count is %d\n", | ||
185 | dev->irq_ref); | ||
186 | |||
187 | snd_printdd(LOGNAME ": Disabling IRQ\n"); | ||
188 | |||
189 | spin_lock_irqsave(&dev->lock, flags); | ||
190 | if (snd_msnd_wait_TXDE(dev) == 0) { | ||
191 | outb(inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR); | ||
192 | if (dev->type == msndClassic) | ||
193 | outb(HPIRQ_NONE, dev->io + HP_IRQM); | ||
194 | disable_irq(dev->irq); | ||
195 | spin_unlock_irqrestore(&dev->lock, flags); | ||
196 | return 0; | ||
197 | } | ||
198 | spin_unlock_irqrestore(&dev->lock, flags); | ||
199 | |||
200 | snd_printd(KERN_ERR LOGNAME ": Disable IRQ failed\n"); | ||
201 | |||
202 | return -EIO; | ||
203 | } | ||
204 | EXPORT_SYMBOL(snd_msnd_disable_irq); | ||
205 | |||
206 | static inline long get_play_delay_jiffies(struct snd_msnd *chip, long size) | ||
207 | { | ||
208 | long tmp = (size * HZ * chip->play_sample_size) / 8; | ||
209 | return tmp / (chip->play_sample_rate * chip->play_channels); | ||
210 | } | ||
211 | |||
212 | static void snd_msnd_dsp_write_flush(struct snd_msnd *chip) | ||
213 | { | ||
214 | if (!(chip->mode & FMODE_WRITE) || !test_bit(F_WRITING, &chip->flags)) | ||
215 | return; | ||
216 | set_bit(F_WRITEFLUSH, &chip->flags); | ||
217 | /* interruptible_sleep_on_timeout( | ||
218 | &chip->writeflush, | ||
219 | get_play_delay_jiffies(&chip, chip->DAPF.len));*/ | ||
220 | clear_bit(F_WRITEFLUSH, &chip->flags); | ||
221 | if (!signal_pending(current)) | ||
222 | schedule_timeout_interruptible( | ||
223 | get_play_delay_jiffies(chip, chip->play_period_bytes)); | ||
224 | clear_bit(F_WRITING, &chip->flags); | ||
225 | } | ||
226 | |||
227 | void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file) | ||
228 | { | ||
229 | if ((file ? file->f_mode : chip->mode) & FMODE_READ) { | ||
230 | clear_bit(F_READING, &chip->flags); | ||
231 | snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP); | ||
232 | snd_msnd_disable_irq(chip); | ||
233 | if (file) { | ||
234 | snd_printd(KERN_INFO LOGNAME | ||
235 | ": Stopping read for %p\n", file); | ||
236 | chip->mode &= ~FMODE_READ; | ||
237 | } | ||
238 | clear_bit(F_AUDIO_READ_INUSE, &chip->flags); | ||
239 | } | ||
240 | if ((file ? file->f_mode : chip->mode) & FMODE_WRITE) { | ||
241 | if (test_bit(F_WRITING, &chip->flags)) { | ||
242 | snd_msnd_dsp_write_flush(chip); | ||
243 | snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP); | ||
244 | } | ||
245 | snd_msnd_disable_irq(chip); | ||
246 | if (file) { | ||
247 | snd_printd(KERN_INFO | ||
248 | LOGNAME ": Stopping write for %p\n", file); | ||
249 | chip->mode &= ~FMODE_WRITE; | ||
250 | } | ||
251 | clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags); | ||
252 | } | ||
253 | } | ||
254 | EXPORT_SYMBOL(snd_msnd_dsp_halt); | ||
255 | |||
256 | |||
257 | int snd_msnd_DARQ(struct snd_msnd *chip, int bank) | ||
258 | { | ||
259 | int /*size, n,*/ timeout = 3; | ||
260 | u16 wTmp; | ||
261 | /* void *DAQD; */ | ||
262 | |||
263 | /* Increment the tail and check for queue wrap */ | ||
264 | wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size); | ||
265 | if (wTmp > readw(chip->DARQ + JQS_wSize)) | ||
266 | wTmp = 0; | ||
267 | while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--) | ||
268 | udelay(1); | ||
269 | |||
270 | if (chip->capturePeriods == 2) { | ||
271 | void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF + | ||
272 | bank * DAQDS__size + DAQDS_wStart; | ||
273 | unsigned short offset = 0x3000 + chip->capturePeriodBytes; | ||
274 | |||
275 | if (readw(pDAQ) != PCTODSP_BASED(0x3000)) | ||
276 | offset = 0x3000; | ||
277 | writew(PCTODSP_BASED(offset), pDAQ); | ||
278 | } | ||
279 | |||
280 | writew(wTmp, chip->DARQ + JQS_wTail); | ||
281 | |||
282 | #if 0 | ||
283 | /* Get our digital audio queue struct */ | ||
284 | DAQD = bank * DAQDS__size + chip->mappedbase + DARQ_DATA_BUFF; | ||
285 | |||
286 | /* Get length of data */ | ||
287 | size = readw(DAQD + DAQDS_wSize); | ||
288 | |||
289 | /* Read data from the head (unprotected bank 1 access okay | ||
290 | since this is only called inside an interrupt) */ | ||
291 | outb(HPBLKSEL_1, chip->io + HP_BLKS); | ||
292 | n = msnd_fifo_write(&chip->DARF, | ||
293 | (char *)(chip->base + bank * DAR_BUFF_SIZE), | ||
294 | size, 0); | ||
295 | if (n <= 0) { | ||
296 | outb(HPBLKSEL_0, chip->io + HP_BLKS); | ||
297 | return n; | ||
298 | } | ||
299 | outb(HPBLKSEL_0, chip->io + HP_BLKS); | ||
300 | #endif | ||
301 | |||
302 | return 1; | ||
303 | } | ||
304 | EXPORT_SYMBOL(snd_msnd_DARQ); | ||
305 | |||
306 | int snd_msnd_DAPQ(struct snd_msnd *chip, int start) | ||
307 | { | ||
308 | u16 DAPQ_tail; | ||
309 | int protect = start, nbanks = 0; | ||
310 | void *DAQD; | ||
311 | static int play_banks_submitted; | ||
312 | /* unsigned long flags; | ||
313 | spin_lock_irqsave(&chip->lock, flags); not necessary */ | ||
314 | |||
315 | DAPQ_tail = readw(chip->DAPQ + JQS_wTail); | ||
316 | while (DAPQ_tail != readw(chip->DAPQ + JQS_wHead) || start) { | ||
317 | int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size); | ||
318 | |||
319 | if (start) { | ||
320 | start = 0; | ||
321 | play_banks_submitted = 0; | ||
322 | } | ||
323 | |||
324 | /* Get our digital audio queue struct */ | ||
325 | DAQD = bank_num * DAQDS__size + chip->mappedbase + | ||
326 | DAPQ_DATA_BUFF; | ||
327 | |||
328 | /* Write size of this bank */ | ||
329 | writew(chip->play_period_bytes, DAQD + DAQDS_wSize); | ||
330 | if (play_banks_submitted < 3) | ||
331 | ++play_banks_submitted; | ||
332 | else if (chip->playPeriods == 2) { | ||
333 | unsigned short offset = chip->play_period_bytes; | ||
334 | |||
335 | if (readw(DAQD + DAQDS_wStart) != PCTODSP_BASED(0x0)) | ||
336 | offset = 0; | ||
337 | |||
338 | writew(PCTODSP_BASED(offset), DAQD + DAQDS_wStart); | ||
339 | } | ||
340 | ++nbanks; | ||
341 | |||
342 | /* Then advance the tail */ | ||
343 | /* | ||
344 | if (protect) | ||
345 | snd_printd(KERN_INFO "B %X %lX\n", | ||
346 | bank_num, xtime.tv_usec); | ||
347 | */ | ||
348 | |||
349 | DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size); | ||
350 | writew(DAPQ_tail, chip->DAPQ + JQS_wTail); | ||
351 | /* Tell the DSP to play the bank */ | ||
352 | snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_START); | ||
353 | if (protect) | ||
354 | if (2 == bank_num) | ||
355 | break; | ||
356 | } | ||
357 | /* | ||
358 | if (protect) | ||
359 | snd_printd(KERN_INFO "%lX\n", xtime.tv_usec); | ||
360 | */ | ||
361 | /* spin_unlock_irqrestore(&chip->lock, flags); not necessary */ | ||
362 | return nbanks; | ||
363 | } | ||
364 | EXPORT_SYMBOL(snd_msnd_DAPQ); | ||
365 | |||
366 | static void snd_msnd_play_reset_queue(struct snd_msnd *chip, | ||
367 | unsigned int pcm_periods, | ||
368 | unsigned int pcm_count) | ||
369 | { | ||
370 | int n; | ||
371 | void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; | ||
372 | |||
373 | chip->last_playbank = -1; | ||
374 | chip->playLimit = pcm_count * (pcm_periods - 1); | ||
375 | chip->playPeriods = pcm_periods; | ||
376 | writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wHead); | ||
377 | writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wTail); | ||
378 | |||
379 | chip->play_period_bytes = pcm_count; | ||
380 | |||
381 | for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { | ||
382 | writew(PCTODSP_BASED((u32)(pcm_count * n)), | ||
383 | pDAQ + DAQDS_wStart); | ||
384 | writew(0, pDAQ + DAQDS_wSize); | ||
385 | writew(1, pDAQ + DAQDS_wFormat); | ||
386 | writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize); | ||
387 | writew(chip->play_channels, pDAQ + DAQDS_wChannels); | ||
388 | writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate); | ||
389 | writew(HIMT_PLAY_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); | ||
390 | writew(n, pDAQ + DAQDS_wFlags); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, | ||
395 | unsigned int pcm_periods, | ||
396 | unsigned int pcm_count) | ||
397 | { | ||
398 | int n; | ||
399 | void *pDAQ; | ||
400 | /* unsigned long flags; */ | ||
401 | |||
402 | /* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */ | ||
403 | |||
404 | chip->last_recbank = 2; | ||
405 | chip->captureLimit = pcm_count * (pcm_periods - 1); | ||
406 | chip->capturePeriods = pcm_periods; | ||
407 | writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DARQ + JQS_wHead); | ||
408 | writew(PCTODSP_OFFSET(chip->last_recbank * DAQDS__size), | ||
409 | chip->DARQ + JQS_wTail); | ||
410 | |||
411 | #if 0 /* Critical section: bank 1 access. this is how the OSS driver does it:*/ | ||
412 | spin_lock_irqsave(&chip->lock, flags); | ||
413 | outb(HPBLKSEL_1, chip->io + HP_BLKS); | ||
414 | memset_io(chip->mappedbase, 0, DAR_BUFF_SIZE * 3); | ||
415 | outb(HPBLKSEL_0, chip->io + HP_BLKS); | ||
416 | spin_unlock_irqrestore(&chip->lock, flags); | ||
417 | #endif | ||
418 | |||
419 | chip->capturePeriodBytes = pcm_count; | ||
420 | snd_printdd("snd_msnd_capture_reset_queue() %i\n", pcm_count); | ||
421 | |||
422 | pDAQ = chip->mappedbase + DARQ_DATA_BUFF; | ||
423 | |||
424 | for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { | ||
425 | u32 tmp = pcm_count * n; | ||
426 | |||
427 | writew(PCTODSP_BASED(tmp + 0x3000), pDAQ + DAQDS_wStart); | ||
428 | writew(pcm_count, pDAQ + DAQDS_wSize); | ||
429 | writew(1, pDAQ + DAQDS_wFormat); | ||
430 | writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize); | ||
431 | writew(chip->capture_channels, pDAQ + DAQDS_wChannels); | ||
432 | writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate); | ||
433 | writew(HIMT_RECORD_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); | ||
434 | writew(n, pDAQ + DAQDS_wFlags); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | static struct snd_pcm_hardware snd_msnd_playback = { | ||
439 | .info = SNDRV_PCM_INFO_MMAP | | ||
440 | SNDRV_PCM_INFO_INTERLEAVED | | ||
441 | SNDRV_PCM_INFO_MMAP_VALID, | ||
442 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, | ||
443 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
444 | .rate_min = 8000, | ||
445 | .rate_max = 48000, | ||
446 | .channels_min = 1, | ||
447 | .channels_max = 2, | ||
448 | .buffer_bytes_max = 0x3000, | ||
449 | .period_bytes_min = 0x40, | ||
450 | .period_bytes_max = 0x1800, | ||
451 | .periods_min = 2, | ||
452 | .periods_max = 3, | ||
453 | .fifo_size = 0, | ||
454 | }; | ||
455 | |||
456 | static struct snd_pcm_hardware snd_msnd_capture = { | ||
457 | .info = SNDRV_PCM_INFO_MMAP | | ||
458 | SNDRV_PCM_INFO_INTERLEAVED | | ||
459 | SNDRV_PCM_INFO_MMAP_VALID, | ||
460 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, | ||
461 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
462 | .rate_min = 8000, | ||
463 | .rate_max = 48000, | ||
464 | .channels_min = 1, | ||
465 | .channels_max = 2, | ||
466 | .buffer_bytes_max = 0x3000, | ||
467 | .period_bytes_min = 0x40, | ||
468 | .period_bytes_max = 0x1800, | ||
469 | .periods_min = 2, | ||
470 | .periods_max = 3, | ||
471 | .fifo_size = 0, | ||
472 | }; | ||
473 | |||
474 | |||
475 | static int snd_msnd_playback_open(struct snd_pcm_substream *substream) | ||
476 | { | ||
477 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
478 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
479 | |||
480 | set_bit(F_AUDIO_WRITE_INUSE, &chip->flags); | ||
481 | clear_bit(F_WRITING, &chip->flags); | ||
482 | snd_msnd_enable_irq(chip); | ||
483 | |||
484 | runtime->dma_area = chip->mappedbase; | ||
485 | runtime->dma_bytes = 0x3000; | ||
486 | |||
487 | chip->playback_substream = substream; | ||
488 | runtime->hw = snd_msnd_playback; | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int snd_msnd_playback_close(struct snd_pcm_substream *substream) | ||
493 | { | ||
494 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
495 | |||
496 | snd_msnd_disable_irq(chip); | ||
497 | clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags); | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | |||
502 | static int snd_msnd_playback_hw_params(struct snd_pcm_substream *substream, | ||
503 | struct snd_pcm_hw_params *params) | ||
504 | { | ||
505 | int i; | ||
506 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
507 | void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; | ||
508 | |||
509 | chip->play_sample_size = snd_pcm_format_width(params_format(params)); | ||
510 | chip->play_channels = params_channels(params); | ||
511 | chip->play_sample_rate = params_rate(params); | ||
512 | |||
513 | for (i = 0; i < 3; ++i, pDAQ += DAQDS__size) { | ||
514 | writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize); | ||
515 | writew(chip->play_channels, pDAQ + DAQDS_wChannels); | ||
516 | writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate); | ||
517 | } | ||
518 | /* dont do this here: | ||
519 | * snd_msnd_calibrate_adc(chip->play_sample_rate); | ||
520 | */ | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static int snd_msnd_playback_prepare(struct snd_pcm_substream *substream) | ||
526 | { | ||
527 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
528 | unsigned int pcm_size = snd_pcm_lib_buffer_bytes(substream); | ||
529 | unsigned int pcm_count = snd_pcm_lib_period_bytes(substream); | ||
530 | unsigned int pcm_periods = pcm_size / pcm_count; | ||
531 | |||
532 | snd_msnd_play_reset_queue(chip, pcm_periods, pcm_count); | ||
533 | chip->playDMAPos = 0; | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static int snd_msnd_playback_trigger(struct snd_pcm_substream *substream, | ||
538 | int cmd) | ||
539 | { | ||
540 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
541 | int result = 0; | ||
542 | |||
543 | if (cmd == SNDRV_PCM_TRIGGER_START) { | ||
544 | snd_printdd("snd_msnd_playback_trigger(START)\n"); | ||
545 | chip->banksPlayed = 0; | ||
546 | set_bit(F_WRITING, &chip->flags); | ||
547 | snd_msnd_DAPQ(chip, 1); | ||
548 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { | ||
549 | snd_printdd("snd_msnd_playback_trigger(STop)\n"); | ||
550 | /* interrupt diagnostic, comment this out later */ | ||
551 | clear_bit(F_WRITING, &chip->flags); | ||
552 | snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP); | ||
553 | } else { | ||
554 | snd_printd(KERN_ERR "snd_msnd_playback_trigger(?????)\n"); | ||
555 | result = -EINVAL; | ||
556 | } | ||
557 | |||
558 | snd_printdd("snd_msnd_playback_trigger() ENDE\n"); | ||
559 | return result; | ||
560 | } | ||
561 | |||
562 | static snd_pcm_uframes_t | ||
563 | snd_msnd_playback_pointer(struct snd_pcm_substream *substream) | ||
564 | { | ||
565 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
566 | |||
567 | return bytes_to_frames(substream->runtime, chip->playDMAPos); | ||
568 | } | ||
569 | |||
570 | |||
571 | static struct snd_pcm_ops snd_msnd_playback_ops = { | ||
572 | .open = snd_msnd_playback_open, | ||
573 | .close = snd_msnd_playback_close, | ||
574 | .ioctl = snd_pcm_lib_ioctl, | ||
575 | .hw_params = snd_msnd_playback_hw_params, | ||
576 | .prepare = snd_msnd_playback_prepare, | ||
577 | .trigger = snd_msnd_playback_trigger, | ||
578 | .pointer = snd_msnd_playback_pointer, | ||
579 | }; | ||
580 | |||
581 | static int snd_msnd_capture_open(struct snd_pcm_substream *substream) | ||
582 | { | ||
583 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
584 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
585 | |||
586 | set_bit(F_AUDIO_READ_INUSE, &chip->flags); | ||
587 | snd_msnd_enable_irq(chip); | ||
588 | runtime->dma_area = chip->mappedbase + 0x3000; | ||
589 | runtime->dma_bytes = 0x3000; | ||
590 | memset(runtime->dma_area, 0, runtime->dma_bytes); | ||
591 | chip->capture_substream = substream; | ||
592 | runtime->hw = snd_msnd_capture; | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int snd_msnd_capture_close(struct snd_pcm_substream *substream) | ||
597 | { | ||
598 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
599 | |||
600 | snd_msnd_disable_irq(chip); | ||
601 | clear_bit(F_AUDIO_READ_INUSE, &chip->flags); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static int snd_msnd_capture_prepare(struct snd_pcm_substream *substream) | ||
606 | { | ||
607 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
608 | unsigned int pcm_size = snd_pcm_lib_buffer_bytes(substream); | ||
609 | unsigned int pcm_count = snd_pcm_lib_period_bytes(substream); | ||
610 | unsigned int pcm_periods = pcm_size / pcm_count; | ||
611 | |||
612 | snd_msnd_capture_reset_queue(chip, pcm_periods, pcm_count); | ||
613 | chip->captureDMAPos = 0; | ||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | static int snd_msnd_capture_trigger(struct snd_pcm_substream *substream, | ||
618 | int cmd) | ||
619 | { | ||
620 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
621 | |||
622 | if (cmd == SNDRV_PCM_TRIGGER_START) { | ||
623 | chip->last_recbank = -1; | ||
624 | set_bit(F_READING, &chip->flags); | ||
625 | if (snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_START) == 0) | ||
626 | return 0; | ||
627 | |||
628 | clear_bit(F_READING, &chip->flags); | ||
629 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { | ||
630 | clear_bit(F_READING, &chip->flags); | ||
631 | snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP); | ||
632 | return 0; | ||
633 | } | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
637 | |||
638 | static snd_pcm_uframes_t | ||
639 | snd_msnd_capture_pointer(struct snd_pcm_substream *substream) | ||
640 | { | ||
641 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
642 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
643 | |||
644 | return bytes_to_frames(runtime, chip->captureDMAPos); | ||
645 | } | ||
646 | |||
647 | |||
648 | static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream, | ||
649 | struct snd_pcm_hw_params *params) | ||
650 | { | ||
651 | int i; | ||
652 | struct snd_msnd *chip = snd_pcm_substream_chip(substream); | ||
653 | void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF; | ||
654 | |||
655 | chip->capture_sample_size = snd_pcm_format_width(params_format(params)); | ||
656 | chip->capture_channels = params_channels(params); | ||
657 | chip->capture_sample_rate = params_rate(params); | ||
658 | |||
659 | for (i = 0; i < 3; ++i, pDAQ += DAQDS__size) { | ||
660 | writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize); | ||
661 | writew(chip->capture_channels, pDAQ + DAQDS_wChannels); | ||
662 | writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate); | ||
663 | } | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | |||
668 | static struct snd_pcm_ops snd_msnd_capture_ops = { | ||
669 | .open = snd_msnd_capture_open, | ||
670 | .close = snd_msnd_capture_close, | ||
671 | .ioctl = snd_pcm_lib_ioctl, | ||
672 | .hw_params = snd_msnd_capture_hw_params, | ||
673 | .prepare = snd_msnd_capture_prepare, | ||
674 | .trigger = snd_msnd_capture_trigger, | ||
675 | .pointer = snd_msnd_capture_pointer, | ||
676 | }; | ||
677 | |||
678 | |||
679 | int snd_msnd_pcm(struct snd_card *card, int device, | ||
680 | struct snd_pcm **rpcm) | ||
681 | { | ||
682 | struct snd_msnd *chip = card->private_data; | ||
683 | struct snd_pcm *pcm; | ||
684 | int err; | ||
685 | |||
686 | err = snd_pcm_new(card, "MSNDPINNACLE", device, 1, 1, &pcm); | ||
687 | if (err < 0) | ||
688 | return err; | ||
689 | |||
690 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_msnd_playback_ops); | ||
691 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_msnd_capture_ops); | ||
692 | |||
693 | pcm->private_data = chip; | ||
694 | strcpy(pcm->name, "Hurricane"); | ||
695 | |||
696 | |||
697 | if (rpcm) | ||
698 | *rpcm = pcm; | ||
699 | return 0; | ||
700 | } | ||
701 | EXPORT_SYMBOL(snd_msnd_pcm); | ||
702 | |||
703 | MODULE_DESCRIPTION("Common routines for Turtle Beach Multisound drivers"); | ||
704 | MODULE_LICENSE("GPL"); | ||
705 | |||
diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h new file mode 100644 index 000000000000..3773e242b58e --- /dev/null +++ b/sound/isa/msnd/msnd.h | |||
@@ -0,0 +1,308 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * msnd.h | ||
4 | * | ||
5 | * Turtle Beach MultiSound Sound Card Driver for Linux | ||
6 | * | ||
7 | * Some parts of this header file were derived from the Turtle Beach | ||
8 | * MultiSound Driver Development Kit. | ||
9 | * | ||
10 | * Copyright (C) 1998 Andrew Veliath | ||
11 | * Copyright (C) 1993 Turtle Beach Systems, Inc. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | ********************************************************************/ | ||
28 | #ifndef __MSND_H | ||
29 | #define __MSND_H | ||
30 | |||
31 | #define DEFSAMPLERATE 44100 | ||
32 | #define DEFSAMPLESIZE SNDRV_PCM_FORMAT_S16 | ||
33 | #define DEFCHANNELS 1 | ||
34 | |||
35 | #define SRAM_BANK_SIZE 0x8000 | ||
36 | #define SRAM_CNTL_START 0x7F00 | ||
37 | #define SMA_STRUCT_START 0x7F40 | ||
38 | |||
39 | #define DSP_BASE_ADDR 0x4000 | ||
40 | #define DSP_BANK_BASE 0x4000 | ||
41 | |||
42 | #define AGND 0x01 | ||
43 | #define SIGNAL 0x02 | ||
44 | |||
45 | #define EXT_DSP_BIT_DCAL 0x0001 | ||
46 | #define EXT_DSP_BIT_MIDI_CON 0x0002 | ||
47 | |||
48 | #define BUFFSIZE 0x8000 | ||
49 | #define HOSTQ_SIZE 0x40 | ||
50 | |||
51 | #define DAP_BUFF_SIZE 0x2400 | ||
52 | |||
53 | #define DAPQ_STRUCT_SIZE 0x10 | ||
54 | #define DARQ_STRUCT_SIZE 0x10 | ||
55 | #define DAPQ_BUFF_SIZE (3 * 0x10) | ||
56 | #define DARQ_BUFF_SIZE (3 * 0x10) | ||
57 | #define MODQ_BUFF_SIZE 0x400 | ||
58 | |||
59 | #define DAPQ_DATA_BUFF 0x6C00 | ||
60 | #define DARQ_DATA_BUFF 0x6C30 | ||
61 | #define MODQ_DATA_BUFF 0x6C60 | ||
62 | #define MIDQ_DATA_BUFF 0x7060 | ||
63 | |||
64 | #define DAPQ_OFFSET SRAM_CNTL_START | ||
65 | #define DARQ_OFFSET (SRAM_CNTL_START + 0x08) | ||
66 | #define MODQ_OFFSET (SRAM_CNTL_START + 0x10) | ||
67 | #define MIDQ_OFFSET (SRAM_CNTL_START + 0x18) | ||
68 | #define DSPQ_OFFSET (SRAM_CNTL_START + 0x20) | ||
69 | |||
70 | #define HP_ICR 0x00 | ||
71 | #define HP_CVR 0x01 | ||
72 | #define HP_ISR 0x02 | ||
73 | #define HP_IVR 0x03 | ||
74 | #define HP_NU 0x04 | ||
75 | #define HP_INFO 0x04 | ||
76 | #define HP_TXH 0x05 | ||
77 | #define HP_RXH 0x05 | ||
78 | #define HP_TXM 0x06 | ||
79 | #define HP_RXM 0x06 | ||
80 | #define HP_TXL 0x07 | ||
81 | #define HP_RXL 0x07 | ||
82 | |||
83 | #define HP_ICR_DEF 0x00 | ||
84 | #define HP_CVR_DEF 0x12 | ||
85 | #define HP_ISR_DEF 0x06 | ||
86 | #define HP_IVR_DEF 0x0f | ||
87 | #define HP_NU_DEF 0x00 | ||
88 | |||
89 | #define HP_IRQM 0x09 | ||
90 | |||
91 | #define HPR_BLRC 0x08 | ||
92 | #define HPR_SPR1 0x09 | ||
93 | #define HPR_SPR2 0x0A | ||
94 | #define HPR_TCL0 0x0B | ||
95 | #define HPR_TCL1 0x0C | ||
96 | #define HPR_TCL2 0x0D | ||
97 | #define HPR_TCL3 0x0E | ||
98 | #define HPR_TCL4 0x0F | ||
99 | |||
100 | #define HPICR_INIT 0x80 | ||
101 | #define HPICR_HM1 0x40 | ||
102 | #define HPICR_HM0 0x20 | ||
103 | #define HPICR_HF1 0x10 | ||
104 | #define HPICR_HF0 0x08 | ||
105 | #define HPICR_TREQ 0x02 | ||
106 | #define HPICR_RREQ 0x01 | ||
107 | |||
108 | #define HPCVR_HC 0x80 | ||
109 | |||
110 | #define HPISR_HREQ 0x80 | ||
111 | #define HPISR_DMA 0x40 | ||
112 | #define HPISR_HF3 0x10 | ||
113 | #define HPISR_HF2 0x08 | ||
114 | #define HPISR_TRDY 0x04 | ||
115 | #define HPISR_TXDE 0x02 | ||
116 | #define HPISR_RXDF 0x01 | ||
117 | |||
118 | #define HPIO_290 0 | ||
119 | #define HPIO_260 1 | ||
120 | #define HPIO_250 2 | ||
121 | #define HPIO_240 3 | ||
122 | #define HPIO_230 4 | ||
123 | #define HPIO_220 5 | ||
124 | #define HPIO_210 6 | ||
125 | #define HPIO_3E0 7 | ||
126 | |||
127 | #define HPMEM_NONE 0 | ||
128 | #define HPMEM_B000 1 | ||
129 | #define HPMEM_C800 2 | ||
130 | #define HPMEM_D000 3 | ||
131 | #define HPMEM_D400 4 | ||
132 | #define HPMEM_D800 5 | ||
133 | #define HPMEM_E000 6 | ||
134 | #define HPMEM_E800 7 | ||
135 | |||
136 | #define HPIRQ_NONE 0 | ||
137 | #define HPIRQ_5 1 | ||
138 | #define HPIRQ_7 2 | ||
139 | #define HPIRQ_9 3 | ||
140 | #define HPIRQ_10 4 | ||
141 | #define HPIRQ_11 5 | ||
142 | #define HPIRQ_12 6 | ||
143 | #define HPIRQ_15 7 | ||
144 | |||
145 | #define HIMT_PLAY_DONE 0x00 | ||
146 | #define HIMT_RECORD_DONE 0x01 | ||
147 | #define HIMT_MIDI_EOS 0x02 | ||
148 | #define HIMT_MIDI_OUT 0x03 | ||
149 | |||
150 | #define HIMT_MIDI_IN_UCHAR 0x0E | ||
151 | #define HIMT_DSP 0x0F | ||
152 | |||
153 | #define HDEX_BASE 0x92 | ||
154 | #define HDEX_PLAY_START (0 + HDEX_BASE) | ||
155 | #define HDEX_PLAY_STOP (1 + HDEX_BASE) | ||
156 | #define HDEX_PLAY_PAUSE (2 + HDEX_BASE) | ||
157 | #define HDEX_PLAY_RESUME (3 + HDEX_BASE) | ||
158 | #define HDEX_RECORD_START (4 + HDEX_BASE) | ||
159 | #define HDEX_RECORD_STOP (5 + HDEX_BASE) | ||
160 | #define HDEX_MIDI_IN_START (6 + HDEX_BASE) | ||
161 | #define HDEX_MIDI_IN_STOP (7 + HDEX_BASE) | ||
162 | #define HDEX_MIDI_OUT_START (8 + HDEX_BASE) | ||
163 | #define HDEX_MIDI_OUT_STOP (9 + HDEX_BASE) | ||
164 | #define HDEX_AUX_REQ (10 + HDEX_BASE) | ||
165 | |||
166 | #define HDEXAR_CLEAR_PEAKS 1 | ||
167 | #define HDEXAR_IN_SET_POTS 2 | ||
168 | #define HDEXAR_AUX_SET_POTS 3 | ||
169 | #define HDEXAR_CAL_A_TO_D 4 | ||
170 | #define HDEXAR_RD_EXT_DSP_BITS 5 | ||
171 | |||
172 | /* Pinnacle only HDEXAR defs */ | ||
173 | #define HDEXAR_SET_ANA_IN 0 | ||
174 | #define HDEXAR_SET_SYNTH_IN 4 | ||
175 | #define HDEXAR_READ_DAT_IN 5 | ||
176 | #define HDEXAR_MIC_SET_POTS 6 | ||
177 | #define HDEXAR_SET_DAT_IN 7 | ||
178 | |||
179 | #define HDEXAR_SET_SYNTH_48 8 | ||
180 | #define HDEXAR_SET_SYNTH_44 9 | ||
181 | |||
182 | #define HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) | ||
183 | #define LOWORD(l) ((u16)(u32)(l)) | ||
184 | #define HIBYTE(w) ((u8)(((u16)(w) >> 8) & 0xFF)) | ||
185 | #define LOBYTE(w) ((u8)(w)) | ||
186 | #define MAKELONG(low, hi) ((long)(((u16)(low))|(((u32)((u16)(hi)))<<16))) | ||
187 | #define MAKEWORD(low, hi) ((u16)(((u8)(low))|(((u16)((u8)(hi)))<<8))) | ||
188 | |||
189 | #define PCTODSP_OFFSET(w) (u16)((w)/2) | ||
190 | #define PCTODSP_BASED(w) (u16)(((w)/2) + DSP_BASE_ADDR) | ||
191 | #define DSPTOPC_BASED(w) (((w) - DSP_BASE_ADDR) * 2) | ||
192 | |||
193 | #ifdef SLOWIO | ||
194 | # undef outb | ||
195 | # undef inb | ||
196 | # define outb outb_p | ||
197 | # define inb inb_p | ||
198 | #endif | ||
199 | |||
200 | /* JobQueueStruct */ | ||
201 | #define JQS_wStart 0x00 | ||
202 | #define JQS_wSize 0x02 | ||
203 | #define JQS_wHead 0x04 | ||
204 | #define JQS_wTail 0x06 | ||
205 | #define JQS__size 0x08 | ||
206 | |||
207 | /* DAQueueDataStruct */ | ||
208 | #define DAQDS_wStart 0x00 | ||
209 | #define DAQDS_wSize 0x02 | ||
210 | #define DAQDS_wFormat 0x04 | ||
211 | #define DAQDS_wSampleSize 0x06 | ||
212 | #define DAQDS_wChannels 0x08 | ||
213 | #define DAQDS_wSampleRate 0x0A | ||
214 | #define DAQDS_wIntMsg 0x0C | ||
215 | #define DAQDS_wFlags 0x0E | ||
216 | #define DAQDS__size 0x10 | ||
217 | |||
218 | #include <sound/pcm.h> | ||
219 | |||
220 | struct snd_msnd { | ||
221 | void __iomem *mappedbase; | ||
222 | int play_period_bytes; | ||
223 | int playLimit; | ||
224 | int playPeriods; | ||
225 | int playDMAPos; | ||
226 | int banksPlayed; | ||
227 | int captureDMAPos; | ||
228 | int capturePeriodBytes; | ||
229 | int captureLimit; | ||
230 | int capturePeriods; | ||
231 | struct snd_card *card; | ||
232 | void *msndmidi_mpu; | ||
233 | struct snd_rawmidi *rmidi; | ||
234 | |||
235 | /* Hardware resources */ | ||
236 | long io; | ||
237 | int memid, irqid; | ||
238 | int irq, irq_ref; | ||
239 | unsigned long base; | ||
240 | |||
241 | /* Motorola 56k DSP SMA */ | ||
242 | void __iomem *SMA; | ||
243 | void __iomem *DAPQ; | ||
244 | void __iomem *DARQ; | ||
245 | void __iomem *MODQ; | ||
246 | void __iomem *MIDQ; | ||
247 | void __iomem *DSPQ; | ||
248 | int dspq_data_buff, dspq_buff_size; | ||
249 | |||
250 | /* State variables */ | ||
251 | enum { msndClassic, msndPinnacle } type; | ||
252 | mode_t mode; | ||
253 | unsigned long flags; | ||
254 | #define F_RESETTING 0 | ||
255 | #define F_HAVEDIGITAL 1 | ||
256 | #define F_AUDIO_WRITE_INUSE 2 | ||
257 | #define F_WRITING 3 | ||
258 | #define F_WRITEBLOCK 4 | ||
259 | #define F_WRITEFLUSH 5 | ||
260 | #define F_AUDIO_READ_INUSE 6 | ||
261 | #define F_READING 7 | ||
262 | #define F_READBLOCK 8 | ||
263 | #define F_EXT_MIDI_INUSE 9 | ||
264 | #define F_HDR_MIDI_INUSE 10 | ||
265 | #define F_DISABLE_WRITE_NDELAY 11 | ||
266 | spinlock_t lock; | ||
267 | spinlock_t mixer_lock; | ||
268 | int nresets; | ||
269 | unsigned recsrc; | ||
270 | #define LEVEL_ENTRIES 32 | ||
271 | int left_levels[LEVEL_ENTRIES]; | ||
272 | int right_levels[LEVEL_ENTRIES]; | ||
273 | int calibrate_signal; | ||
274 | int play_sample_size, play_sample_rate, play_channels; | ||
275 | int play_ndelay; | ||
276 | int capture_sample_size, capture_sample_rate, capture_channels; | ||
277 | int capture_ndelay; | ||
278 | u8 bCurrentMidiPatch; | ||
279 | |||
280 | int last_playbank, last_recbank; | ||
281 | struct snd_pcm_substream *playback_substream; | ||
282 | struct snd_pcm_substream *capture_substream; | ||
283 | |||
284 | }; | ||
285 | |||
286 | void snd_msnd_init_queue(void *base, int start, int size); | ||
287 | |||
288 | int snd_msnd_send_dsp_cmd(struct snd_msnd *chip, u8 cmd); | ||
289 | int snd_msnd_send_word(struct snd_msnd *chip, | ||
290 | unsigned char high, | ||
291 | unsigned char mid, | ||
292 | unsigned char low); | ||
293 | int snd_msnd_upload_host(struct snd_msnd *chip, | ||
294 | const u8 *bin, int len); | ||
295 | int snd_msnd_enable_irq(struct snd_msnd *chip); | ||
296 | int snd_msnd_disable_irq(struct snd_msnd *chip); | ||
297 | void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file); | ||
298 | int snd_msnd_DAPQ(struct snd_msnd *chip, int start); | ||
299 | int snd_msnd_DARQ(struct snd_msnd *chip, int start); | ||
300 | int snd_msnd_pcm(struct snd_card *card, int device, struct snd_pcm **rpcm); | ||
301 | |||
302 | int snd_msndmidi_new(struct snd_card *card, int device); | ||
303 | void snd_msndmidi_input_read(void *mpu); | ||
304 | |||
305 | void snd_msndmix_setup(struct snd_msnd *chip); | ||
306 | int __devinit snd_msndmix_new(struct snd_card *card); | ||
307 | int snd_msndmix_force_recsrc(struct snd_msnd *chip, int recsrc); | ||
308 | #endif /* __MSND_H */ | ||
diff --git a/sound/isa/msnd/msnd_classic.c b/sound/isa/msnd/msnd_classic.c new file mode 100644 index 000000000000..3b23a096fa4e --- /dev/null +++ b/sound/isa/msnd/msnd_classic.c | |||
@@ -0,0 +1,3 @@ | |||
1 | /* The work is in msnd_pinnacle.c, just define MSND_CLASSIC before it. */ | ||
2 | #define MSND_CLASSIC | ||
3 | #include "msnd_pinnacle.c" | ||
diff --git a/sound/isa/msnd/msnd_classic.h b/sound/isa/msnd/msnd_classic.h new file mode 100644 index 000000000000..f18d5fa5baf4 --- /dev/null +++ b/sound/isa/msnd/msnd_classic.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * msnd_classic.h | ||
4 | * | ||
5 | * Turtle Beach MultiSound Sound Card Driver for Linux | ||
6 | * | ||
7 | * Some parts of this header file were derived from the Turtle Beach | ||
8 | * MultiSound Driver Development Kit. | ||
9 | * | ||
10 | * Copyright (C) 1998 Andrew Veliath | ||
11 | * Copyright (C) 1993 Turtle Beach Systems, Inc. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | ********************************************************************/ | ||
28 | #ifndef __MSND_CLASSIC_H | ||
29 | #define __MSND_CLASSIC_H | ||
30 | |||
31 | #define DSP_NUMIO 0x10 | ||
32 | |||
33 | #define HP_MEMM 0x08 | ||
34 | |||
35 | #define HP_BITM 0x0E | ||
36 | #define HP_WAIT 0x0D | ||
37 | #define HP_DSPR 0x0A | ||
38 | #define HP_PROR 0x0B | ||
39 | #define HP_BLKS 0x0C | ||
40 | |||
41 | #define HPPRORESET_OFF 0 | ||
42 | #define HPPRORESET_ON 1 | ||
43 | |||
44 | #define HPDSPRESET_OFF 0 | ||
45 | #define HPDSPRESET_ON 1 | ||
46 | |||
47 | #define HPBLKSEL_0 0 | ||
48 | #define HPBLKSEL_1 1 | ||
49 | |||
50 | #define HPWAITSTATE_0 0 | ||
51 | #define HPWAITSTATE_1 1 | ||
52 | |||
53 | #define HPBITMODE_16 0 | ||
54 | #define HPBITMODE_8 1 | ||
55 | |||
56 | #define HIDSP_INT_PLAY_UNDER 0x00 | ||
57 | #define HIDSP_INT_RECORD_OVER 0x01 | ||
58 | #define HIDSP_INPUT_CLIPPING 0x02 | ||
59 | #define HIDSP_MIDI_IN_OVER 0x10 | ||
60 | #define HIDSP_MIDI_OVERRUN_ERR 0x13 | ||
61 | |||
62 | #define TIME_PRO_RESET_DONE 0x028A | ||
63 | #define TIME_PRO_SYSEX 0x0040 | ||
64 | #define TIME_PRO_RESET 0x0032 | ||
65 | |||
66 | #define DAR_BUFF_SIZE 0x2000 | ||
67 | |||
68 | #define MIDQ_BUFF_SIZE 0x200 | ||
69 | #define DSPQ_BUFF_SIZE 0x40 | ||
70 | |||
71 | #define DSPQ_DATA_BUFF 0x7260 | ||
72 | |||
73 | #define MOP_SYNTH 0x10 | ||
74 | #define MOP_EXTOUT 0x32 | ||
75 | #define MOP_EXTTHRU 0x02 | ||
76 | #define MOP_OUTMASK 0x01 | ||
77 | |||
78 | #define MIP_EXTIN 0x01 | ||
79 | #define MIP_SYNTH 0x00 | ||
80 | #define MIP_INMASK 0x32 | ||
81 | |||
82 | /* Classic SMA Common Data */ | ||
83 | #define SMA_wCurrPlayBytes 0x0000 | ||
84 | #define SMA_wCurrRecordBytes 0x0002 | ||
85 | #define SMA_wCurrPlayVolLeft 0x0004 | ||
86 | #define SMA_wCurrPlayVolRight 0x0006 | ||
87 | #define SMA_wCurrInVolLeft 0x0008 | ||
88 | #define SMA_wCurrInVolRight 0x000a | ||
89 | #define SMA_wUser_3 0x000c | ||
90 | #define SMA_wUser_4 0x000e | ||
91 | #define SMA_dwUser_5 0x0010 | ||
92 | #define SMA_dwUser_6 0x0014 | ||
93 | #define SMA_wUser_7 0x0018 | ||
94 | #define SMA_wReserved_A 0x001a | ||
95 | #define SMA_wReserved_B 0x001c | ||
96 | #define SMA_wReserved_C 0x001e | ||
97 | #define SMA_wReserved_D 0x0020 | ||
98 | #define SMA_wReserved_E 0x0022 | ||
99 | #define SMA_wReserved_F 0x0024 | ||
100 | #define SMA_wReserved_G 0x0026 | ||
101 | #define SMA_wReserved_H 0x0028 | ||
102 | #define SMA_wCurrDSPStatusFlags 0x002a | ||
103 | #define SMA_wCurrHostStatusFlags 0x002c | ||
104 | #define SMA_wCurrInputTagBits 0x002e | ||
105 | #define SMA_wCurrLeftPeak 0x0030 | ||
106 | #define SMA_wCurrRightPeak 0x0032 | ||
107 | #define SMA_wExtDSPbits 0x0034 | ||
108 | #define SMA_bExtHostbits 0x0036 | ||
109 | #define SMA_bBoardLevel 0x0037 | ||
110 | #define SMA_bInPotPosRight 0x0038 | ||
111 | #define SMA_bInPotPosLeft 0x0039 | ||
112 | #define SMA_bAuxPotPosRight 0x003a | ||
113 | #define SMA_bAuxPotPosLeft 0x003b | ||
114 | #define SMA_wCurrMastVolLeft 0x003c | ||
115 | #define SMA_wCurrMastVolRight 0x003e | ||
116 | #define SMA_bUser_12 0x0040 | ||
117 | #define SMA_bUser_13 0x0041 | ||
118 | #define SMA_wUser_14 0x0042 | ||
119 | #define SMA_wUser_15 0x0044 | ||
120 | #define SMA_wCalFreqAtoD 0x0046 | ||
121 | #define SMA_wUser_16 0x0048 | ||
122 | #define SMA_wUser_17 0x004a | ||
123 | #define SMA__size 0x004c | ||
124 | |||
125 | #define INITCODEFILE "turtlebeach/msndinit.bin" | ||
126 | #define PERMCODEFILE "turtlebeach/msndperm.bin" | ||
127 | #define LONGNAME "MultiSound (Classic/Monterey/Tahiti)" | ||
128 | |||
129 | #endif /* __MSND_CLASSIC_H */ | ||
diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c new file mode 100644 index 000000000000..cb9aa4c4edd0 --- /dev/null +++ b/sound/isa/msnd/msnd_midi.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> | ||
3 | * Copyright (c) 2009 by Krzysztof Helt | ||
4 | * Routines for control of MPU-401 in UART mode | ||
5 | * | ||
6 | * MPU-401 supports UART mode which is not capable generate transmit | ||
7 | * interrupts thus output is done via polling. Also, if irq < 0, then | ||
8 | * input is done also via polling. Do not expect good performance. | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/io.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <sound/core.h> | ||
32 | #include <sound/rawmidi.h> | ||
33 | |||
34 | #include "msnd.h" | ||
35 | |||
36 | #define MSNDMIDI_MODE_BIT_INPUT 0 | ||
37 | #define MSNDMIDI_MODE_BIT_OUTPUT 1 | ||
38 | #define MSNDMIDI_MODE_BIT_INPUT_TRIGGER 2 | ||
39 | #define MSNDMIDI_MODE_BIT_OUTPUT_TRIGGER 3 | ||
40 | |||
41 | struct snd_msndmidi { | ||
42 | struct snd_msnd *dev; | ||
43 | |||
44 | unsigned long mode; /* MSNDMIDI_MODE_XXXX */ | ||
45 | |||
46 | struct snd_rawmidi_substream *substream_input; | ||
47 | |||
48 | spinlock_t input_lock; | ||
49 | }; | ||
50 | |||
51 | /* | ||
52 | * input/output open/close - protected by open_mutex in rawmidi.c | ||
53 | */ | ||
54 | static int snd_msndmidi_input_open(struct snd_rawmidi_substream *substream) | ||
55 | { | ||
56 | struct snd_msndmidi *mpu; | ||
57 | |||
58 | snd_printdd("snd_msndmidi_input_open()\n"); | ||
59 | |||
60 | mpu = substream->rmidi->private_data; | ||
61 | |||
62 | mpu->substream_input = substream; | ||
63 | |||
64 | snd_msnd_enable_irq(mpu->dev); | ||
65 | |||
66 | snd_msnd_send_dsp_cmd(mpu->dev, HDEX_MIDI_IN_START); | ||
67 | set_bit(MSNDMIDI_MODE_BIT_INPUT, &mpu->mode); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int snd_msndmidi_input_close(struct snd_rawmidi_substream *substream) | ||
72 | { | ||
73 | struct snd_msndmidi *mpu; | ||
74 | |||
75 | mpu = substream->rmidi->private_data; | ||
76 | snd_msnd_send_dsp_cmd(mpu->dev, HDEX_MIDI_IN_STOP); | ||
77 | clear_bit(MSNDMIDI_MODE_BIT_INPUT, &mpu->mode); | ||
78 | mpu->substream_input = NULL; | ||
79 | snd_msnd_disable_irq(mpu->dev); | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static void snd_msndmidi_input_drop(struct snd_msndmidi *mpu) | ||
84 | { | ||
85 | u16 tail; | ||
86 | |||
87 | tail = readw(mpu->dev->MIDQ + JQS_wTail); | ||
88 | writew(tail, mpu->dev->MIDQ + JQS_wHead); | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * trigger input | ||
93 | */ | ||
94 | static void snd_msndmidi_input_trigger(struct snd_rawmidi_substream *substream, | ||
95 | int up) | ||
96 | { | ||
97 | unsigned long flags; | ||
98 | struct snd_msndmidi *mpu; | ||
99 | |||
100 | snd_printdd("snd_msndmidi_input_trigger(, %i)\n", up); | ||
101 | |||
102 | mpu = substream->rmidi->private_data; | ||
103 | spin_lock_irqsave(&mpu->input_lock, flags); | ||
104 | if (up) { | ||
105 | if (!test_and_set_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, | ||
106 | &mpu->mode)) | ||
107 | snd_msndmidi_input_drop(mpu); | ||
108 | } else { | ||
109 | clear_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, &mpu->mode); | ||
110 | } | ||
111 | spin_unlock_irqrestore(&mpu->input_lock, flags); | ||
112 | if (up) | ||
113 | snd_msndmidi_input_read(mpu); | ||
114 | } | ||
115 | |||
116 | void snd_msndmidi_input_read(void *mpuv) | ||
117 | { | ||
118 | unsigned long flags; | ||
119 | struct snd_msndmidi *mpu = mpuv; | ||
120 | void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF; | ||
121 | |||
122 | spin_lock_irqsave(&mpu->input_lock, flags); | ||
123 | while (readw(mpu->dev->MIDQ + JQS_wTail) != | ||
124 | readw(mpu->dev->MIDQ + JQS_wHead)) { | ||
125 | u16 wTmp, val; | ||
126 | val = readw(pwMIDQData + 2 * readw(mpu->dev->MIDQ + JQS_wHead)); | ||
127 | |||
128 | if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, | ||
129 | &mpu->mode)) | ||
130 | snd_rawmidi_receive(mpu->substream_input, | ||
131 | (unsigned char *)&val, 1); | ||
132 | |||
133 | wTmp = readw(mpu->dev->MIDQ + JQS_wHead) + 1; | ||
134 | if (wTmp > readw(mpu->dev->MIDQ + JQS_wSize)) | ||
135 | writew(0, mpu->dev->MIDQ + JQS_wHead); | ||
136 | else | ||
137 | writew(wTmp, mpu->dev->MIDQ + JQS_wHead); | ||
138 | } | ||
139 | spin_unlock_irqrestore(&mpu->input_lock, flags); | ||
140 | } | ||
141 | EXPORT_SYMBOL(snd_msndmidi_input_read); | ||
142 | |||
143 | static struct snd_rawmidi_ops snd_msndmidi_input = { | ||
144 | .open = snd_msndmidi_input_open, | ||
145 | .close = snd_msndmidi_input_close, | ||
146 | .trigger = snd_msndmidi_input_trigger, | ||
147 | }; | ||
148 | |||
149 | static void snd_msndmidi_free(struct snd_rawmidi *rmidi) | ||
150 | { | ||
151 | struct snd_msndmidi *mpu = rmidi->private_data; | ||
152 | kfree(mpu); | ||
153 | } | ||
154 | |||
155 | int snd_msndmidi_new(struct snd_card *card, int device) | ||
156 | { | ||
157 | struct snd_msnd *chip = card->private_data; | ||
158 | struct snd_msndmidi *mpu; | ||
159 | struct snd_rawmidi *rmidi; | ||
160 | int err; | ||
161 | |||
162 | err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi); | ||
163 | if (err < 0) | ||
164 | return err; | ||
165 | mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL); | ||
166 | if (mpu == NULL) { | ||
167 | snd_device_free(card, rmidi); | ||
168 | return -ENOMEM; | ||
169 | } | ||
170 | mpu->dev = chip; | ||
171 | chip->msndmidi_mpu = mpu; | ||
172 | rmidi->private_data = mpu; | ||
173 | rmidi->private_free = snd_msndmidi_free; | ||
174 | spin_lock_init(&mpu->input_lock); | ||
175 | strcpy(rmidi->name, "MSND MIDI"); | ||
176 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
177 | &snd_msndmidi_input); | ||
178 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
179 | return 0; | ||
180 | } | ||
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c new file mode 100644 index 000000000000..60b6abd71612 --- /dev/null +++ b/sound/isa/msnd/msnd_pinnacle.c | |||
@@ -0,0 +1,1238 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Linux multisound pinnacle/fiji driver for ALSA. | ||
4 | * | ||
5 | * 2002/06/30 Karsten Wiese: | ||
6 | * for now this is only used to build a pinnacle / fiji driver. | ||
7 | * the OSS parent of this code is designed to also support | ||
8 | * the multisound classic via the file msnd_classic.c. | ||
9 | * to make it easier for some brave heart to implemt classic | ||
10 | * support in alsa, i left all the MSND_CLASSIC tokens in this file. | ||
11 | * but for now this untested & undone. | ||
12 | * | ||
13 | * | ||
14 | * ripped from linux kernel 2.4.18 by Karsten Wiese. | ||
15 | * | ||
16 | * the following is a copy of the 2.4.18 OSS FREE file-heading comment: | ||
17 | * | ||
18 | * Turtle Beach MultiSound Sound Card Driver for Linux | ||
19 | * msnd_pinnacle.c / msnd_classic.c | ||
20 | * | ||
21 | * -- If MSND_CLASSIC is defined: | ||
22 | * | ||
23 | * -> driver for Turtle Beach Classic/Monterey/Tahiti | ||
24 | * | ||
25 | * -- Else | ||
26 | * | ||
27 | * -> driver for Turtle Beach Pinnacle/Fiji | ||
28 | * | ||
29 | * 12-3-2000 Modified IO port validation Steve Sycamore | ||
30 | * | ||
31 | * Copyright (C) 1998 Andrew Veliath | ||
32 | * | ||
33 | * This program is free software; you can redistribute it and/or modify | ||
34 | * it under the terms of the GNU General Public License as published by | ||
35 | * the Free Software Foundation; either version 2 of the License, or | ||
36 | * (at your option) any later version. | ||
37 | * | ||
38 | * This program is distributed in the hope that it will be useful, | ||
39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
41 | * GNU General Public License for more details. | ||
42 | * | ||
43 | * You should have received a copy of the GNU General Public License | ||
44 | * along with this program; if not, write to the Free Software | ||
45 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
46 | * | ||
47 | ********************************************************************/ | ||
48 | |||
49 | #include <linux/kernel.h> | ||
50 | #include <linux/module.h> | ||
51 | #include <linux/interrupt.h> | ||
52 | #include <linux/types.h> | ||
53 | #include <linux/delay.h> | ||
54 | #include <linux/ioport.h> | ||
55 | #include <linux/firmware.h> | ||
56 | #include <linux/isa.h> | ||
57 | #include <linux/isapnp.h> | ||
58 | #include <linux/irq.h> | ||
59 | #include <linux/io.h> | ||
60 | |||
61 | #include <sound/core.h> | ||
62 | #include <sound/initval.h> | ||
63 | #include <sound/asound.h> | ||
64 | #include <sound/pcm.h> | ||
65 | #include <sound/mpu401.h> | ||
66 | |||
67 | #ifdef MSND_CLASSIC | ||
68 | # ifndef __alpha__ | ||
69 | # define SLOWIO | ||
70 | # endif | ||
71 | #endif | ||
72 | #include "msnd.h" | ||
73 | #ifdef MSND_CLASSIC | ||
74 | # include "msnd_classic.h" | ||
75 | # define LOGNAME "msnd_classic" | ||
76 | #else | ||
77 | # include "msnd_pinnacle.h" | ||
78 | # define LOGNAME "snd_msnd_pinnacle" | ||
79 | #endif | ||
80 | |||
81 | static void __devinit set_default_audio_parameters(struct snd_msnd *chip) | ||
82 | { | ||
83 | chip->play_sample_size = DEFSAMPLESIZE; | ||
84 | chip->play_sample_rate = DEFSAMPLERATE; | ||
85 | chip->play_channels = DEFCHANNELS; | ||
86 | chip->capture_sample_size = DEFSAMPLESIZE; | ||
87 | chip->capture_sample_rate = DEFSAMPLERATE; | ||
88 | chip->capture_channels = DEFCHANNELS; | ||
89 | } | ||
90 | |||
91 | static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage) | ||
92 | { | ||
93 | switch (HIBYTE(wMessage)) { | ||
94 | case HIMT_PLAY_DONE: { | ||
95 | if (chip->banksPlayed < 3) | ||
96 | snd_printdd("%08X: HIMT_PLAY_DONE: %i\n", | ||
97 | (unsigned)jiffies, LOBYTE(wMessage)); | ||
98 | |||
99 | if (chip->last_playbank == LOBYTE(wMessage)) { | ||
100 | snd_printdd("chip.last_playbank == LOBYTE(wMessage)\n"); | ||
101 | break; | ||
102 | } | ||
103 | chip->banksPlayed++; | ||
104 | |||
105 | if (test_bit(F_WRITING, &chip->flags)) | ||
106 | snd_msnd_DAPQ(chip, 0); | ||
107 | |||
108 | chip->last_playbank = LOBYTE(wMessage); | ||
109 | chip->playDMAPos += chip->play_period_bytes; | ||
110 | if (chip->playDMAPos > chip->playLimit) | ||
111 | chip->playDMAPos = 0; | ||
112 | snd_pcm_period_elapsed(chip->playback_substream); | ||
113 | |||
114 | break; | ||
115 | } | ||
116 | case HIMT_RECORD_DONE: | ||
117 | if (chip->last_recbank == LOBYTE(wMessage)) | ||
118 | break; | ||
119 | chip->last_recbank = LOBYTE(wMessage); | ||
120 | chip->captureDMAPos += chip->capturePeriodBytes; | ||
121 | if (chip->captureDMAPos > (chip->captureLimit)) | ||
122 | chip->captureDMAPos = 0; | ||
123 | |||
124 | if (test_bit(F_READING, &chip->flags)) | ||
125 | snd_msnd_DARQ(chip, chip->last_recbank); | ||
126 | |||
127 | snd_pcm_period_elapsed(chip->capture_substream); | ||
128 | break; | ||
129 | |||
130 | case HIMT_DSP: | ||
131 | switch (LOBYTE(wMessage)) { | ||
132 | #ifndef MSND_CLASSIC | ||
133 | case HIDSP_PLAY_UNDER: | ||
134 | #endif | ||
135 | case HIDSP_INT_PLAY_UNDER: | ||
136 | snd_printd(KERN_WARNING LOGNAME ": Play underflow %i\n", | ||
137 | chip->banksPlayed); | ||
138 | if (chip->banksPlayed > 2) | ||
139 | clear_bit(F_WRITING, &chip->flags); | ||
140 | break; | ||
141 | |||
142 | case HIDSP_INT_RECORD_OVER: | ||
143 | snd_printd(KERN_WARNING LOGNAME ": Record overflow\n"); | ||
144 | clear_bit(F_READING, &chip->flags); | ||
145 | break; | ||
146 | |||
147 | default: | ||
148 | snd_printd(KERN_WARNING LOGNAME | ||
149 | ": DSP message %d 0x%02x\n", | ||
150 | LOBYTE(wMessage), LOBYTE(wMessage)); | ||
151 | break; | ||
152 | } | ||
153 | break; | ||
154 | |||
155 | case HIMT_MIDI_IN_UCHAR: | ||
156 | if (chip->msndmidi_mpu) | ||
157 | snd_msndmidi_input_read(chip->msndmidi_mpu); | ||
158 | break; | ||
159 | |||
160 | default: | ||
161 | snd_printd(KERN_WARNING LOGNAME ": HIMT message %d 0x%02x\n", | ||
162 | HIBYTE(wMessage), HIBYTE(wMessage)); | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id) | ||
168 | { | ||
169 | struct snd_msnd *chip = dev_id; | ||
170 | void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF; | ||
171 | |||
172 | /* Send ack to DSP */ | ||
173 | /* inb(chip->io + HP_RXL); */ | ||
174 | |||
175 | /* Evaluate queued DSP messages */ | ||
176 | while (readw(chip->DSPQ + JQS_wTail) != readw(chip->DSPQ + JQS_wHead)) { | ||
177 | u16 wTmp; | ||
178 | |||
179 | snd_msnd_eval_dsp_msg(chip, | ||
180 | readw(pwDSPQData + 2 * readw(chip->DSPQ + JQS_wHead))); | ||
181 | |||
182 | wTmp = readw(chip->DSPQ + JQS_wHead) + 1; | ||
183 | if (wTmp > readw(chip->DSPQ + JQS_wSize)) | ||
184 | writew(0, chip->DSPQ + JQS_wHead); | ||
185 | else | ||
186 | writew(wTmp, chip->DSPQ + JQS_wHead); | ||
187 | } | ||
188 | /* Send ack to DSP */ | ||
189 | inb(chip->io + HP_RXL); | ||
190 | return IRQ_HANDLED; | ||
191 | } | ||
192 | |||
193 | |||
194 | static int snd_msnd_reset_dsp(long io, unsigned char *info) | ||
195 | { | ||
196 | int timeout = 100; | ||
197 | |||
198 | outb(HPDSPRESET_ON, io + HP_DSPR); | ||
199 | msleep(1); | ||
200 | #ifndef MSND_CLASSIC | ||
201 | if (info) | ||
202 | *info = inb(io + HP_INFO); | ||
203 | #endif | ||
204 | outb(HPDSPRESET_OFF, io + HP_DSPR); | ||
205 | msleep(1); | ||
206 | while (timeout-- > 0) { | ||
207 | if (inb(io + HP_CVR) == HP_CVR_DEF) | ||
208 | return 0; | ||
209 | msleep(1); | ||
210 | } | ||
211 | snd_printk(KERN_ERR LOGNAME ": Cannot reset DSP\n"); | ||
212 | |||
213 | return -EIO; | ||
214 | } | ||
215 | |||
216 | static int __devinit snd_msnd_probe(struct snd_card *card) | ||
217 | { | ||
218 | struct snd_msnd *chip = card->private_data; | ||
219 | unsigned char info; | ||
220 | #ifndef MSND_CLASSIC | ||
221 | char *xv, *rev = NULL; | ||
222 | char *pin = "TB Pinnacle", *fiji = "TB Fiji"; | ||
223 | char *pinfiji = "TB Pinnacle/Fiji"; | ||
224 | #endif | ||
225 | |||
226 | if (!request_region(chip->io, DSP_NUMIO, "probing")) { | ||
227 | snd_printk(KERN_ERR LOGNAME ": I/O port conflict\n"); | ||
228 | return -ENODEV; | ||
229 | } | ||
230 | |||
231 | if (snd_msnd_reset_dsp(chip->io, &info) < 0) { | ||
232 | release_region(chip->io, DSP_NUMIO); | ||
233 | return -ENODEV; | ||
234 | } | ||
235 | |||
236 | #ifdef MSND_CLASSIC | ||
237 | strcpy(card->shortname, "Classic/Tahiti/Monterey"); | ||
238 | strcpy(card->longname, "Turtle Beach Multisound"); | ||
239 | printk(KERN_INFO LOGNAME ": %s, " | ||
240 | "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n", | ||
241 | card->shortname, | ||
242 | chip->io, chip->io + DSP_NUMIO - 1, | ||
243 | chip->irq, | ||
244 | chip->base, chip->base + 0x7fff); | ||
245 | #else | ||
246 | switch (info >> 4) { | ||
247 | case 0xf: | ||
248 | xv = "<= 1.15"; | ||
249 | break; | ||
250 | case 0x1: | ||
251 | xv = "1.18/1.2"; | ||
252 | break; | ||
253 | case 0x2: | ||
254 | xv = "1.3"; | ||
255 | break; | ||
256 | case 0x3: | ||
257 | xv = "1.4"; | ||
258 | break; | ||
259 | default: | ||
260 | xv = "unknown"; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | switch (info & 0x7) { | ||
265 | case 0x0: | ||
266 | rev = "I"; | ||
267 | strcpy(card->shortname, pin); | ||
268 | break; | ||
269 | case 0x1: | ||
270 | rev = "F"; | ||
271 | strcpy(card->shortname, pin); | ||
272 | break; | ||
273 | case 0x2: | ||
274 | rev = "G"; | ||
275 | strcpy(card->shortname, pin); | ||
276 | break; | ||
277 | case 0x3: | ||
278 | rev = "H"; | ||
279 | strcpy(card->shortname, pin); | ||
280 | break; | ||
281 | case 0x4: | ||
282 | rev = "E"; | ||
283 | strcpy(card->shortname, fiji); | ||
284 | break; | ||
285 | case 0x5: | ||
286 | rev = "C"; | ||
287 | strcpy(card->shortname, fiji); | ||
288 | break; | ||
289 | case 0x6: | ||
290 | rev = "D"; | ||
291 | strcpy(card->shortname, fiji); | ||
292 | break; | ||
293 | case 0x7: | ||
294 | rev = "A-B (Fiji) or A-E (Pinnacle)"; | ||
295 | strcpy(card->shortname, pinfiji); | ||
296 | break; | ||
297 | } | ||
298 | strcpy(card->longname, "Turtle Beach Multisound Pinnacle"); | ||
299 | printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, " | ||
300 | "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n", | ||
301 | card->shortname, | ||
302 | rev, xv, | ||
303 | chip->io, chip->io + DSP_NUMIO - 1, | ||
304 | chip->irq, | ||
305 | chip->base, chip->base + 0x7fff); | ||
306 | #endif | ||
307 | |||
308 | release_region(chip->io, DSP_NUMIO); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int snd_msnd_init_sma(struct snd_msnd *chip) | ||
313 | { | ||
314 | static int initted; | ||
315 | u16 mastVolLeft, mastVolRight; | ||
316 | unsigned long flags; | ||
317 | |||
318 | #ifdef MSND_CLASSIC | ||
319 | outb(chip->memid, chip->io + HP_MEMM); | ||
320 | #endif | ||
321 | outb(HPBLKSEL_0, chip->io + HP_BLKS); | ||
322 | /* Motorola 56k shared memory base */ | ||
323 | chip->SMA = chip->mappedbase + SMA_STRUCT_START; | ||
324 | |||
325 | if (initted) { | ||
326 | mastVolLeft = readw(chip->SMA + SMA_wCurrMastVolLeft); | ||
327 | mastVolRight = readw(chip->SMA + SMA_wCurrMastVolRight); | ||
328 | } else | ||
329 | mastVolLeft = mastVolRight = 0; | ||
330 | memset_io(chip->mappedbase, 0, 0x8000); | ||
331 | |||
332 | /* Critical section: bank 1 access */ | ||
333 | spin_lock_irqsave(&chip->lock, flags); | ||
334 | outb(HPBLKSEL_1, chip->io + HP_BLKS); | ||
335 | memset_io(chip->mappedbase, 0, 0x8000); | ||
336 | outb(HPBLKSEL_0, chip->io + HP_BLKS); | ||
337 | spin_unlock_irqrestore(&chip->lock, flags); | ||
338 | |||
339 | /* Digital audio play queue */ | ||
340 | chip->DAPQ = chip->mappedbase + DAPQ_OFFSET; | ||
341 | snd_msnd_init_queue(chip->DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE); | ||
342 | |||
343 | /* Digital audio record queue */ | ||
344 | chip->DARQ = chip->mappedbase + DARQ_OFFSET; | ||
345 | snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); | ||
346 | |||
347 | /* MIDI out queue */ | ||
348 | chip->MODQ = chip->mappedbase + MODQ_OFFSET; | ||
349 | snd_msnd_init_queue(chip->MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE); | ||
350 | |||
351 | /* MIDI in queue */ | ||
352 | chip->MIDQ = chip->mappedbase + MIDQ_OFFSET; | ||
353 | snd_msnd_init_queue(chip->MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE); | ||
354 | |||
355 | /* DSP -> host message queue */ | ||
356 | chip->DSPQ = chip->mappedbase + DSPQ_OFFSET; | ||
357 | snd_msnd_init_queue(chip->DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE); | ||
358 | |||
359 | /* Setup some DSP values */ | ||
360 | #ifndef MSND_CLASSIC | ||
361 | writew(1, chip->SMA + SMA_wCurrPlayFormat); | ||
362 | writew(chip->play_sample_size, chip->SMA + SMA_wCurrPlaySampleSize); | ||
363 | writew(chip->play_channels, chip->SMA + SMA_wCurrPlayChannels); | ||
364 | writew(chip->play_sample_rate, chip->SMA + SMA_wCurrPlaySampleRate); | ||
365 | #endif | ||
366 | writew(chip->play_sample_rate, chip->SMA + SMA_wCalFreqAtoD); | ||
367 | writew(mastVolLeft, chip->SMA + SMA_wCurrMastVolLeft); | ||
368 | writew(mastVolRight, chip->SMA + SMA_wCurrMastVolRight); | ||
369 | #ifndef MSND_CLASSIC | ||
370 | writel(0x00010000, chip->SMA + SMA_dwCurrPlayPitch); | ||
371 | writel(0x00000001, chip->SMA + SMA_dwCurrPlayRate); | ||
372 | #endif | ||
373 | writew(0x303, chip->SMA + SMA_wCurrInputTagBits); | ||
374 | |||
375 | initted = 1; | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | |||
381 | static int upload_dsp_code(struct snd_card *card) | ||
382 | { | ||
383 | struct snd_msnd *chip = card->private_data; | ||
384 | const struct firmware *init_fw = NULL, *perm_fw = NULL; | ||
385 | int err; | ||
386 | |||
387 | outb(HPBLKSEL_0, chip->io + HP_BLKS); | ||
388 | |||
389 | err = request_firmware(&init_fw, INITCODEFILE, card->dev); | ||
390 | if (err < 0) { | ||
391 | printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE); | ||
392 | goto cleanup1; | ||
393 | } | ||
394 | err = request_firmware(&perm_fw, PERMCODEFILE, card->dev); | ||
395 | if (err < 0) { | ||
396 | printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE); | ||
397 | goto cleanup; | ||
398 | } | ||
399 | |||
400 | memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size); | ||
401 | if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) { | ||
402 | printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n"); | ||
403 | err = -ENODEV; | ||
404 | goto cleanup; | ||
405 | } | ||
406 | printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n"); | ||
407 | err = 0; | ||
408 | |||
409 | cleanup: | ||
410 | release_firmware(perm_fw); | ||
411 | cleanup1: | ||
412 | release_firmware(init_fw); | ||
413 | return err; | ||
414 | } | ||
415 | |||
416 | #ifdef MSND_CLASSIC | ||
417 | static void reset_proteus(struct snd_msnd *chip) | ||
418 | { | ||
419 | outb(HPPRORESET_ON, chip->io + HP_PROR); | ||
420 | msleep(TIME_PRO_RESET); | ||
421 | outb(HPPRORESET_OFF, chip->io + HP_PROR); | ||
422 | msleep(TIME_PRO_RESET_DONE); | ||
423 | } | ||
424 | #endif | ||
425 | |||
426 | static int snd_msnd_initialize(struct snd_card *card) | ||
427 | { | ||
428 | struct snd_msnd *chip = card->private_data; | ||
429 | int err, timeout; | ||
430 | |||
431 | #ifdef MSND_CLASSIC | ||
432 | outb(HPWAITSTATE_0, chip->io + HP_WAIT); | ||
433 | outb(HPBITMODE_16, chip->io + HP_BITM); | ||
434 | |||
435 | reset_proteus(chip); | ||
436 | #endif | ||
437 | err = snd_msnd_init_sma(chip); | ||
438 | if (err < 0) { | ||
439 | printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n"); | ||
440 | return err; | ||
441 | } | ||
442 | |||
443 | err = snd_msnd_reset_dsp(chip->io, NULL); | ||
444 | if (err < 0) | ||
445 | return err; | ||
446 | |||
447 | err = upload_dsp_code(card); | ||
448 | if (err < 0) { | ||
449 | printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n"); | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | timeout = 200; | ||
454 | |||
455 | while (readw(chip->mappedbase)) { | ||
456 | msleep(1); | ||
457 | if (!timeout--) { | ||
458 | snd_printd(KERN_ERR LOGNAME ": DSP reset timeout\n"); | ||
459 | return -EIO; | ||
460 | } | ||
461 | } | ||
462 | |||
463 | snd_msndmix_setup(chip); | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int snd_msnd_dsp_full_reset(struct snd_card *card) | ||
468 | { | ||
469 | struct snd_msnd *chip = card->private_data; | ||
470 | int rv; | ||
471 | |||
472 | if (test_bit(F_RESETTING, &chip->flags) || ++chip->nresets > 10) | ||
473 | return 0; | ||
474 | |||
475 | set_bit(F_RESETTING, &chip->flags); | ||
476 | snd_msnd_dsp_halt(chip, NULL); /* Unconditionally halt */ | ||
477 | |||
478 | rv = snd_msnd_initialize(card); | ||
479 | if (rv) | ||
480 | printk(KERN_WARNING LOGNAME ": DSP reset failed\n"); | ||
481 | snd_msndmix_force_recsrc(chip, 0); | ||
482 | clear_bit(F_RESETTING, &chip->flags); | ||
483 | return rv; | ||
484 | } | ||
485 | |||
486 | static int snd_msnd_dev_free(struct snd_device *device) | ||
487 | { | ||
488 | snd_printdd("snd_msnd_chip_free()\n"); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd) | ||
493 | { | ||
494 | if (snd_msnd_send_dsp_cmd(chip, cmd) == 0) | ||
495 | return 0; | ||
496 | snd_msnd_dsp_full_reset(chip->card); | ||
497 | return snd_msnd_send_dsp_cmd(chip, cmd); | ||
498 | } | ||
499 | |||
500 | static int __devinit snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate) | ||
501 | { | ||
502 | snd_printdd("snd_msnd_calibrate_adc(%i)\n", srate); | ||
503 | writew(srate, chip->SMA + SMA_wCalFreqAtoD); | ||
504 | if (chip->calibrate_signal == 0) | ||
505 | writew(readw(chip->SMA + SMA_wCurrHostStatusFlags) | ||
506 | | 0x0001, chip->SMA + SMA_wCurrHostStatusFlags); | ||
507 | else | ||
508 | writew(readw(chip->SMA + SMA_wCurrHostStatusFlags) | ||
509 | & ~0x0001, chip->SMA + SMA_wCurrHostStatusFlags); | ||
510 | if (snd_msnd_send_word(chip, 0, 0, HDEXAR_CAL_A_TO_D) == 0 && | ||
511 | snd_msnd_send_dsp_cmd_chk(chip, HDEX_AUX_REQ) == 0) { | ||
512 | schedule_timeout_interruptible(msecs_to_jiffies(333)); | ||
513 | return 0; | ||
514 | } | ||
515 | printk(KERN_WARNING LOGNAME ": ADC calibration failed\n"); | ||
516 | return -EIO; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * ALSA callback function, called when attempting to open the MIDI device. | ||
521 | */ | ||
522 | static int snd_msnd_mpu401_open(struct snd_mpu401 *mpu) | ||
523 | { | ||
524 | snd_msnd_enable_irq(mpu->private_data); | ||
525 | snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_START); | ||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu) | ||
530 | { | ||
531 | snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_STOP); | ||
532 | snd_msnd_disable_irq(mpu->private_data); | ||
533 | } | ||
534 | |||
535 | static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
536 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | ||
537 | |||
538 | static int __devinit snd_msnd_attach(struct snd_card *card) | ||
539 | { | ||
540 | struct snd_msnd *chip = card->private_data; | ||
541 | int err; | ||
542 | static struct snd_device_ops ops = { | ||
543 | .dev_free = snd_msnd_dev_free, | ||
544 | }; | ||
545 | |||
546 | err = request_irq(chip->irq, snd_msnd_interrupt, 0, card->shortname, | ||
547 | chip); | ||
548 | if (err < 0) { | ||
549 | printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq); | ||
550 | return err; | ||
551 | } | ||
552 | request_region(chip->io, DSP_NUMIO, card->shortname); | ||
553 | |||
554 | if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) { | ||
555 | printk(KERN_ERR LOGNAME | ||
556 | ": unable to grab memory region 0x%lx-0x%lx\n", | ||
557 | chip->base, chip->base + BUFFSIZE - 1); | ||
558 | release_region(chip->io, DSP_NUMIO); | ||
559 | free_irq(chip->irq, chip); | ||
560 | return -EBUSY; | ||
561 | } | ||
562 | chip->mappedbase = ioremap_nocache(chip->base, 0x8000); | ||
563 | if (!chip->mappedbase) { | ||
564 | printk(KERN_ERR LOGNAME | ||
565 | ": unable to map memory region 0x%lx-0x%lx\n", | ||
566 | chip->base, chip->base + BUFFSIZE - 1); | ||
567 | err = -EIO; | ||
568 | goto err_release_region; | ||
569 | } | ||
570 | |||
571 | err = snd_msnd_dsp_full_reset(card); | ||
572 | if (err < 0) | ||
573 | goto err_release_region; | ||
574 | |||
575 | /* Register device */ | ||
576 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | ||
577 | if (err < 0) | ||
578 | goto err_release_region; | ||
579 | |||
580 | err = snd_msnd_pcm(card, 0, NULL); | ||
581 | if (err < 0) { | ||
582 | printk(KERN_ERR LOGNAME ": error creating new PCM device\n"); | ||
583 | goto err_release_region; | ||
584 | } | ||
585 | |||
586 | err = snd_msndmix_new(card); | ||
587 | if (err < 0) { | ||
588 | printk(KERN_ERR LOGNAME ": error creating new Mixer device\n"); | ||
589 | goto err_release_region; | ||
590 | } | ||
591 | |||
592 | |||
593 | if (mpu_io[0] != SNDRV_AUTO_PORT) { | ||
594 | struct snd_mpu401 *mpu; | ||
595 | |||
596 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | ||
597 | mpu_io[0], | ||
598 | MPU401_MODE_INPUT | | ||
599 | MPU401_MODE_OUTPUT, | ||
600 | mpu_irq[0], IRQF_DISABLED, | ||
601 | &chip->rmidi); | ||
602 | if (err < 0) { | ||
603 | printk(KERN_ERR LOGNAME | ||
604 | ": error creating new Midi device\n"); | ||
605 | goto err_release_region; | ||
606 | } | ||
607 | mpu = chip->rmidi->private_data; | ||
608 | |||
609 | mpu->open_input = snd_msnd_mpu401_open; | ||
610 | mpu->close_input = snd_msnd_mpu401_close; | ||
611 | mpu->private_data = chip; | ||
612 | } | ||
613 | |||
614 | disable_irq(chip->irq); | ||
615 | snd_msnd_calibrate_adc(chip, chip->play_sample_rate); | ||
616 | snd_msndmix_force_recsrc(chip, 0); | ||
617 | |||
618 | err = snd_card_register(card); | ||
619 | if (err < 0) | ||
620 | goto err_release_region; | ||
621 | |||
622 | return 0; | ||
623 | |||
624 | err_release_region: | ||
625 | if (chip->mappedbase) | ||
626 | iounmap(chip->mappedbase); | ||
627 | release_mem_region(chip->base, BUFFSIZE); | ||
628 | release_region(chip->io, DSP_NUMIO); | ||
629 | free_irq(chip->irq, chip); | ||
630 | return err; | ||
631 | } | ||
632 | |||
633 | |||
634 | static void __devexit snd_msnd_unload(struct snd_card *card) | ||
635 | { | ||
636 | struct snd_msnd *chip = card->private_data; | ||
637 | |||
638 | iounmap(chip->mappedbase); | ||
639 | release_mem_region(chip->base, BUFFSIZE); | ||
640 | release_region(chip->io, DSP_NUMIO); | ||
641 | free_irq(chip->irq, chip); | ||
642 | snd_card_free(card); | ||
643 | } | ||
644 | |||
645 | #ifndef MSND_CLASSIC | ||
646 | |||
647 | /* Pinnacle/Fiji Logical Device Configuration */ | ||
648 | |||
649 | static int __devinit snd_msnd_write_cfg(int cfg, int reg, int value) | ||
650 | { | ||
651 | outb(reg, cfg); | ||
652 | outb(value, cfg + 1); | ||
653 | if (value != inb(cfg + 1)) { | ||
654 | printk(KERN_ERR LOGNAME ": snd_msnd_write_cfg: I/O error\n"); | ||
655 | return -EIO; | ||
656 | } | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static int __devinit snd_msnd_write_cfg_io0(int cfg, int num, u16 io) | ||
661 | { | ||
662 | if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) | ||
663 | return -EIO; | ||
664 | if (snd_msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io))) | ||
665 | return -EIO; | ||
666 | if (snd_msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io))) | ||
667 | return -EIO; | ||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static int __devinit snd_msnd_write_cfg_io1(int cfg, int num, u16 io) | ||
672 | { | ||
673 | if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) | ||
674 | return -EIO; | ||
675 | if (snd_msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io))) | ||
676 | return -EIO; | ||
677 | if (snd_msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io))) | ||
678 | return -EIO; | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | static int __devinit snd_msnd_write_cfg_irq(int cfg, int num, u16 irq) | ||
683 | { | ||
684 | if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) | ||
685 | return -EIO; | ||
686 | if (snd_msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq))) | ||
687 | return -EIO; | ||
688 | if (snd_msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE)) | ||
689 | return -EIO; | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int __devinit snd_msnd_write_cfg_mem(int cfg, int num, int mem) | ||
694 | { | ||
695 | u16 wmem; | ||
696 | |||
697 | mem >>= 8; | ||
698 | wmem = (u16)(mem & 0xfff); | ||
699 | if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) | ||
700 | return -EIO; | ||
701 | if (snd_msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem))) | ||
702 | return -EIO; | ||
703 | if (snd_msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem))) | ||
704 | return -EIO; | ||
705 | if (wmem && snd_msnd_write_cfg(cfg, IREG_MEMCONTROL, | ||
706 | MEMTYPE_HIADDR | MEMTYPE_16BIT)) | ||
707 | return -EIO; | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static int __devinit snd_msnd_activate_logical(int cfg, int num) | ||
712 | { | ||
713 | if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) | ||
714 | return -EIO; | ||
715 | if (snd_msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE)) | ||
716 | return -EIO; | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int __devinit snd_msnd_write_cfg_logical(int cfg, int num, u16 io0, | ||
721 | u16 io1, u16 irq, int mem) | ||
722 | { | ||
723 | if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) | ||
724 | return -EIO; | ||
725 | if (snd_msnd_write_cfg_io0(cfg, num, io0)) | ||
726 | return -EIO; | ||
727 | if (snd_msnd_write_cfg_io1(cfg, num, io1)) | ||
728 | return -EIO; | ||
729 | if (snd_msnd_write_cfg_irq(cfg, num, irq)) | ||
730 | return -EIO; | ||
731 | if (snd_msnd_write_cfg_mem(cfg, num, mem)) | ||
732 | return -EIO; | ||
733 | if (snd_msnd_activate_logical(cfg, num)) | ||
734 | return -EIO; | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static int __devinit snd_msnd_pinnacle_cfg_reset(int cfg) | ||
739 | { | ||
740 | int i; | ||
741 | |||
742 | /* Reset devices if told to */ | ||
743 | printk(KERN_INFO LOGNAME ": Resetting all devices\n"); | ||
744 | for (i = 0; i < 4; ++i) | ||
745 | if (snd_msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0)) | ||
746 | return -EIO; | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | #endif | ||
751 | |||
752 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
753 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
754 | |||
755 | module_param_array(index, int, NULL, S_IRUGO); | ||
756 | MODULE_PARM_DESC(index, "Index value for msnd_pinnacle soundcard."); | ||
757 | module_param_array(id, charp, NULL, S_IRUGO); | ||
758 | MODULE_PARM_DESC(id, "ID string for msnd_pinnacle soundcard."); | ||
759 | |||
760 | static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
761 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | ||
762 | static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
763 | |||
764 | static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
765 | |||
766 | #ifndef MSND_CLASSIC | ||
767 | /* Extra Peripheral Configuration (Default: Disable) */ | ||
768 | static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
769 | static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
770 | static int ide_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | ||
771 | |||
772 | static long joystick_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
773 | /* If we have the digital daugherboard... */ | ||
774 | static int digital[SNDRV_CARDS]; | ||
775 | |||
776 | /* Extra Peripheral Configuration */ | ||
777 | static int reset[SNDRV_CARDS]; | ||
778 | #endif | ||
779 | |||
780 | static int write_ndelay[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 }; | ||
781 | |||
782 | static int calibrate_signal; | ||
783 | |||
784 | #ifdef CONFIG_PNP | ||
785 | static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
786 | module_param_array(isapnp, bool, NULL, 0444); | ||
787 | MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard."); | ||
788 | #define has_isapnp(x) isapnp[x] | ||
789 | #else | ||
790 | #define has_isapnp(x) 0 | ||
791 | #endif | ||
792 | |||
793 | MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>"); | ||
794 | MODULE_DESCRIPTION("Turtle Beach " LONGNAME " Linux Driver"); | ||
795 | MODULE_LICENSE("GPL"); | ||
796 | MODULE_FIRMWARE(INITCODEFILE); | ||
797 | MODULE_FIRMWARE(PERMCODEFILE); | ||
798 | |||
799 | module_param_array(io, long, NULL, S_IRUGO); | ||
800 | MODULE_PARM_DESC(io, "IO port #"); | ||
801 | module_param_array(irq, int, NULL, S_IRUGO); | ||
802 | module_param_array(mem, long, NULL, S_IRUGO); | ||
803 | module_param_array(write_ndelay, int, NULL, S_IRUGO); | ||
804 | module_param(calibrate_signal, int, S_IRUGO); | ||
805 | #ifndef MSND_CLASSIC | ||
806 | module_param_array(digital, int, NULL, S_IRUGO); | ||
807 | module_param_array(cfg, long, NULL, S_IRUGO); | ||
808 | module_param_array(reset, int, 0, S_IRUGO); | ||
809 | module_param_array(mpu_io, long, NULL, S_IRUGO); | ||
810 | module_param_array(mpu_irq, int, NULL, S_IRUGO); | ||
811 | module_param_array(ide_io0, long, NULL, S_IRUGO); | ||
812 | module_param_array(ide_io1, long, NULL, S_IRUGO); | ||
813 | module_param_array(ide_irq, int, NULL, S_IRUGO); | ||
814 | module_param_array(joystick_io, long, NULL, S_IRUGO); | ||
815 | #endif | ||
816 | |||
817 | |||
818 | static int __devinit snd_msnd_isa_match(struct device *pdev, unsigned int i) | ||
819 | { | ||
820 | if (io[i] == SNDRV_AUTO_PORT) | ||
821 | return 0; | ||
822 | |||
823 | if (irq[i] == SNDRV_AUTO_PORT || mem[i] == SNDRV_AUTO_PORT) { | ||
824 | printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n"); | ||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | #ifdef MSND_CLASSIC | ||
829 | if (!(io[i] == 0x290 || | ||
830 | io[i] == 0x260 || | ||
831 | io[i] == 0x250 || | ||
832 | io[i] == 0x240 || | ||
833 | io[i] == 0x230 || | ||
834 | io[i] == 0x220 || | ||
835 | io[i] == 0x210 || | ||
836 | io[i] == 0x3e0)) { | ||
837 | printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set " | ||
838 | " to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, " | ||
839 | "or 0x3E0\n"); | ||
840 | return 0; | ||
841 | } | ||
842 | #else | ||
843 | if (io[i] < 0x100 || io[i] > 0x3e0 || (io[i] % 0x10) != 0) { | ||
844 | printk(KERN_ERR LOGNAME | ||
845 | ": \"io\" - DSP I/O base must within the range 0x100 " | ||
846 | "to 0x3E0 and must be evenly divisible by 0x10\n"); | ||
847 | return 0; | ||
848 | } | ||
849 | #endif /* MSND_CLASSIC */ | ||
850 | |||
851 | if (!(irq[i] == 5 || | ||
852 | irq[i] == 7 || | ||
853 | irq[i] == 9 || | ||
854 | irq[i] == 10 || | ||
855 | irq[i] == 11 || | ||
856 | irq[i] == 12)) { | ||
857 | printk(KERN_ERR LOGNAME | ||
858 | ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n"); | ||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | if (!(mem[i] == 0xb0000 || | ||
863 | mem[i] == 0xc8000 || | ||
864 | mem[i] == 0xd0000 || | ||
865 | mem[i] == 0xd8000 || | ||
866 | mem[i] == 0xe0000 || | ||
867 | mem[i] == 0xe8000)) { | ||
868 | printk(KERN_ERR LOGNAME ": \"mem\" - must be set to " | ||
869 | "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or " | ||
870 | "0xe8000\n"); | ||
871 | return 0; | ||
872 | } | ||
873 | |||
874 | #ifndef MSND_CLASSIC | ||
875 | if (cfg[i] == SNDRV_AUTO_PORT) { | ||
876 | printk(KERN_INFO LOGNAME ": Assuming PnP mode\n"); | ||
877 | } else if (cfg[i] != 0x250 && cfg[i] != 0x260 && cfg[i] != 0x270) { | ||
878 | printk(KERN_INFO LOGNAME | ||
879 | ": Config port must be 0x250, 0x260 or 0x270 " | ||
880 | "(or unspecified for PnP mode)\n"); | ||
881 | return 0; | ||
882 | } | ||
883 | #endif /* MSND_CLASSIC */ | ||
884 | |||
885 | return 1; | ||
886 | } | ||
887 | |||
888 | static int __devinit snd_msnd_isa_probe(struct device *pdev, unsigned int idx) | ||
889 | { | ||
890 | int err; | ||
891 | struct snd_card *card; | ||
892 | struct snd_msnd *chip; | ||
893 | |||
894 | if (has_isapnp(idx) || cfg[idx] == SNDRV_AUTO_PORT) { | ||
895 | printk(KERN_INFO LOGNAME ": Assuming PnP mode\n"); | ||
896 | return -ENODEV; | ||
897 | } | ||
898 | |||
899 | err = snd_card_create(index[idx], id[idx], THIS_MODULE, | ||
900 | sizeof(struct snd_msnd), &card); | ||
901 | if (err < 0) | ||
902 | return err; | ||
903 | |||
904 | snd_card_set_dev(card, pdev); | ||
905 | chip = card->private_data; | ||
906 | chip->card = card; | ||
907 | |||
908 | #ifdef MSND_CLASSIC | ||
909 | switch (irq[idx]) { | ||
910 | case 5: | ||
911 | chip->irqid = HPIRQ_5; break; | ||
912 | case 7: | ||
913 | chip->irqid = HPIRQ_7; break; | ||
914 | case 9: | ||
915 | chip->irqid = HPIRQ_9; break; | ||
916 | case 10: | ||
917 | chip->irqid = HPIRQ_10; break; | ||
918 | case 11: | ||
919 | chip->irqid = HPIRQ_11; break; | ||
920 | case 12: | ||
921 | chip->irqid = HPIRQ_12; break; | ||
922 | } | ||
923 | |||
924 | switch (mem[idx]) { | ||
925 | case 0xb0000: | ||
926 | chip->memid = HPMEM_B000; break; | ||
927 | case 0xc8000: | ||
928 | chip->memid = HPMEM_C800; break; | ||
929 | case 0xd0000: | ||
930 | chip->memid = HPMEM_D000; break; | ||
931 | case 0xd8000: | ||
932 | chip->memid = HPMEM_D800; break; | ||
933 | case 0xe0000: | ||
934 | chip->memid = HPMEM_E000; break; | ||
935 | case 0xe8000: | ||
936 | chip->memid = HPMEM_E800; break; | ||
937 | } | ||
938 | #else | ||
939 | printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%lx\n", | ||
940 | cfg[idx]); | ||
941 | |||
942 | if (!request_region(cfg[idx], 2, "Pinnacle/Fiji Config")) { | ||
943 | printk(KERN_ERR LOGNAME ": Config port 0x%lx conflict\n", | ||
944 | cfg[idx]); | ||
945 | snd_card_free(card); | ||
946 | return -EIO; | ||
947 | } | ||
948 | if (reset[idx]) | ||
949 | if (snd_msnd_pinnacle_cfg_reset(cfg[idx])) { | ||
950 | err = -EIO; | ||
951 | goto cfg_error; | ||
952 | } | ||
953 | |||
954 | /* DSP */ | ||
955 | err = snd_msnd_write_cfg_logical(cfg[idx], 0, | ||
956 | io[idx], 0, | ||
957 | irq[idx], mem[idx]); | ||
958 | |||
959 | if (err) | ||
960 | goto cfg_error; | ||
961 | |||
962 | /* The following are Pinnacle specific */ | ||
963 | |||
964 | /* MPU */ | ||
965 | if (mpu_io[idx] != SNDRV_AUTO_PORT | ||
966 | && mpu_irq[idx] != SNDRV_AUTO_IRQ) { | ||
967 | printk(KERN_INFO LOGNAME | ||
968 | ": Configuring MPU to I/O 0x%lx IRQ %d\n", | ||
969 | mpu_io[idx], mpu_irq[idx]); | ||
970 | err = snd_msnd_write_cfg_logical(cfg[idx], 1, | ||
971 | mpu_io[idx], 0, | ||
972 | mpu_irq[idx], 0); | ||
973 | |||
974 | if (err) | ||
975 | goto cfg_error; | ||
976 | } | ||
977 | |||
978 | /* IDE */ | ||
979 | if (ide_io0[idx] != SNDRV_AUTO_PORT | ||
980 | && ide_io1[idx] != SNDRV_AUTO_PORT | ||
981 | && ide_irq[idx] != SNDRV_AUTO_IRQ) { | ||
982 | printk(KERN_INFO LOGNAME | ||
983 | ": Configuring IDE to I/O 0x%lx, 0x%lx IRQ %d\n", | ||
984 | ide_io0[idx], ide_io1[idx], ide_irq[idx]); | ||
985 | err = snd_msnd_write_cfg_logical(cfg[idx], 2, | ||
986 | ide_io0[idx], ide_io1[idx], | ||
987 | ide_irq[idx], 0); | ||
988 | |||
989 | if (err) | ||
990 | goto cfg_error; | ||
991 | } | ||
992 | |||
993 | /* Joystick */ | ||
994 | if (joystick_io[idx] != SNDRV_AUTO_PORT) { | ||
995 | printk(KERN_INFO LOGNAME | ||
996 | ": Configuring joystick to I/O 0x%lx\n", | ||
997 | joystick_io[idx]); | ||
998 | err = snd_msnd_write_cfg_logical(cfg[idx], 3, | ||
999 | joystick_io[idx], 0, | ||
1000 | 0, 0); | ||
1001 | |||
1002 | if (err) | ||
1003 | goto cfg_error; | ||
1004 | } | ||
1005 | release_region(cfg[idx], 2); | ||
1006 | |||
1007 | #endif /* MSND_CLASSIC */ | ||
1008 | |||
1009 | set_default_audio_parameters(chip); | ||
1010 | #ifdef MSND_CLASSIC | ||
1011 | chip->type = msndClassic; | ||
1012 | #else | ||
1013 | chip->type = msndPinnacle; | ||
1014 | #endif | ||
1015 | chip->io = io[idx]; | ||
1016 | chip->irq = irq[idx]; | ||
1017 | chip->base = mem[idx]; | ||
1018 | |||
1019 | chip->calibrate_signal = calibrate_signal ? 1 : 0; | ||
1020 | chip->recsrc = 0; | ||
1021 | chip->dspq_data_buff = DSPQ_DATA_BUFF; | ||
1022 | chip->dspq_buff_size = DSPQ_BUFF_SIZE; | ||
1023 | if (write_ndelay[idx]) | ||
1024 | clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags); | ||
1025 | else | ||
1026 | set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags); | ||
1027 | #ifndef MSND_CLASSIC | ||
1028 | if (digital[idx]) | ||
1029 | set_bit(F_HAVEDIGITAL, &chip->flags); | ||
1030 | #endif | ||
1031 | spin_lock_init(&chip->lock); | ||
1032 | err = snd_msnd_probe(card); | ||
1033 | if (err < 0) { | ||
1034 | printk(KERN_ERR LOGNAME ": Probe failed\n"); | ||
1035 | snd_card_free(card); | ||
1036 | return err; | ||
1037 | } | ||
1038 | |||
1039 | err = snd_msnd_attach(card); | ||
1040 | if (err < 0) { | ||
1041 | printk(KERN_ERR LOGNAME ": Attach failed\n"); | ||
1042 | snd_card_free(card); | ||
1043 | return err; | ||
1044 | } | ||
1045 | dev_set_drvdata(pdev, card); | ||
1046 | |||
1047 | return 0; | ||
1048 | |||
1049 | #ifndef MSND_CLASSIC | ||
1050 | cfg_error: | ||
1051 | release_region(cfg[idx], 2); | ||
1052 | snd_card_free(card); | ||
1053 | return err; | ||
1054 | #endif | ||
1055 | } | ||
1056 | |||
1057 | static int __devexit snd_msnd_isa_remove(struct device *pdev, unsigned int dev) | ||
1058 | { | ||
1059 | snd_msnd_unload(dev_get_drvdata(pdev)); | ||
1060 | dev_set_drvdata(pdev, NULL); | ||
1061 | return 0; | ||
1062 | } | ||
1063 | |||
1064 | #define DEV_NAME "msnd-pinnacle" | ||
1065 | |||
1066 | static struct isa_driver snd_msnd_driver = { | ||
1067 | .match = snd_msnd_isa_match, | ||
1068 | .probe = snd_msnd_isa_probe, | ||
1069 | .remove = __devexit_p(snd_msnd_isa_remove), | ||
1070 | /* FIXME: suspend, resume */ | ||
1071 | .driver = { | ||
1072 | .name = DEV_NAME | ||
1073 | }, | ||
1074 | }; | ||
1075 | |||
1076 | #ifdef CONFIG_PNP | ||
1077 | static int __devinit snd_msnd_pnp_detect(struct pnp_card_link *pcard, | ||
1078 | const struct pnp_card_device_id *pid) | ||
1079 | { | ||
1080 | static int idx; | ||
1081 | struct pnp_dev *pnp_dev; | ||
1082 | struct pnp_dev *mpu_dev; | ||
1083 | struct snd_card *card; | ||
1084 | struct snd_msnd *chip; | ||
1085 | int ret; | ||
1086 | |||
1087 | for ( ; idx < SNDRV_CARDS; idx++) { | ||
1088 | if (has_isapnp(idx)) | ||
1089 | break; | ||
1090 | } | ||
1091 | if (idx >= SNDRV_CARDS) | ||
1092 | return -ENODEV; | ||
1093 | |||
1094 | /* | ||
1095 | * Check that we still have room for another sound card ... | ||
1096 | */ | ||
1097 | pnp_dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); | ||
1098 | if (!pnp_dev) | ||
1099 | return -ENODEV; | ||
1100 | |||
1101 | mpu_dev = pnp_request_card_device(pcard, pid->devs[1].id, NULL); | ||
1102 | if (!mpu_dev) | ||
1103 | return -ENODEV; | ||
1104 | |||
1105 | if (!pnp_is_active(pnp_dev) && pnp_activate_dev(pnp_dev) < 0) { | ||
1106 | printk(KERN_INFO "msnd_pinnacle: device is inactive\n"); | ||
1107 | return -EBUSY; | ||
1108 | } | ||
1109 | |||
1110 | if (!pnp_is_active(mpu_dev) && pnp_activate_dev(mpu_dev) < 0) { | ||
1111 | printk(KERN_INFO "msnd_pinnacle: MPU device is inactive\n"); | ||
1112 | return -EBUSY; | ||
1113 | } | ||
1114 | |||
1115 | /* | ||
1116 | * Create a new ALSA sound card entry, in anticipation | ||
1117 | * of detecting our hardware ... | ||
1118 | */ | ||
1119 | ret = snd_card_create(index[idx], id[idx], THIS_MODULE, | ||
1120 | sizeof(struct snd_msnd), &card); | ||
1121 | if (ret < 0) | ||
1122 | return ret; | ||
1123 | |||
1124 | chip = card->private_data; | ||
1125 | chip->card = card; | ||
1126 | snd_card_set_dev(card, &pcard->card->dev); | ||
1127 | |||
1128 | /* | ||
1129 | * Read the correct parameters off the ISA PnP bus ... | ||
1130 | */ | ||
1131 | io[idx] = pnp_port_start(pnp_dev, 0); | ||
1132 | irq[idx] = pnp_irq(pnp_dev, 0); | ||
1133 | mem[idx] = pnp_mem_start(pnp_dev, 0); | ||
1134 | mpu_io[idx] = pnp_port_start(mpu_dev, 0); | ||
1135 | mpu_irq[idx] = pnp_irq(mpu_dev, 0); | ||
1136 | |||
1137 | set_default_audio_parameters(chip); | ||
1138 | #ifdef MSND_CLASSIC | ||
1139 | chip->type = msndClassic; | ||
1140 | #else | ||
1141 | chip->type = msndPinnacle; | ||
1142 | #endif | ||
1143 | chip->io = io[idx]; | ||
1144 | chip->irq = irq[idx]; | ||
1145 | chip->base = mem[idx]; | ||
1146 | |||
1147 | chip->calibrate_signal = calibrate_signal ? 1 : 0; | ||
1148 | chip->recsrc = 0; | ||
1149 | chip->dspq_data_buff = DSPQ_DATA_BUFF; | ||
1150 | chip->dspq_buff_size = DSPQ_BUFF_SIZE; | ||
1151 | if (write_ndelay[idx]) | ||
1152 | clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags); | ||
1153 | else | ||
1154 | set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags); | ||
1155 | #ifndef MSND_CLASSIC | ||
1156 | if (digital[idx]) | ||
1157 | set_bit(F_HAVEDIGITAL, &chip->flags); | ||
1158 | #endif | ||
1159 | spin_lock_init(&chip->lock); | ||
1160 | ret = snd_msnd_probe(card); | ||
1161 | if (ret < 0) { | ||
1162 | printk(KERN_ERR LOGNAME ": Probe failed\n"); | ||
1163 | goto _release_card; | ||
1164 | } | ||
1165 | |||
1166 | ret = snd_msnd_attach(card); | ||
1167 | if (ret < 0) { | ||
1168 | printk(KERN_ERR LOGNAME ": Attach failed\n"); | ||
1169 | goto _release_card; | ||
1170 | } | ||
1171 | |||
1172 | pnp_set_card_drvdata(pcard, card); | ||
1173 | ++idx; | ||
1174 | return 0; | ||
1175 | |||
1176 | _release_card: | ||
1177 | snd_card_free(card); | ||
1178 | return ret; | ||
1179 | } | ||
1180 | |||
1181 | static void __devexit snd_msnd_pnp_remove(struct pnp_card_link *pcard) | ||
1182 | { | ||
1183 | snd_msnd_unload(pnp_get_card_drvdata(pcard)); | ||
1184 | pnp_set_card_drvdata(pcard, NULL); | ||
1185 | } | ||
1186 | |||
1187 | static int isa_registered; | ||
1188 | static int pnp_registered; | ||
1189 | |||
1190 | static struct pnp_card_device_id msnd_pnpids[] = { | ||
1191 | /* Pinnacle PnP */ | ||
1192 | { .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } }, | ||
1193 | { .id = "" } /* end */ | ||
1194 | }; | ||
1195 | |||
1196 | MODULE_DEVICE_TABLE(pnp_card, msnd_pnpids); | ||
1197 | |||
1198 | static struct pnp_card_driver msnd_pnpc_driver = { | ||
1199 | .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, | ||
1200 | .name = "msnd_pinnacle", | ||
1201 | .id_table = msnd_pnpids, | ||
1202 | .probe = snd_msnd_pnp_detect, | ||
1203 | .remove = __devexit_p(snd_msnd_pnp_remove), | ||
1204 | }; | ||
1205 | #endif /* CONFIG_PNP */ | ||
1206 | |||
1207 | static int __init snd_msnd_init(void) | ||
1208 | { | ||
1209 | int err; | ||
1210 | |||
1211 | err = isa_register_driver(&snd_msnd_driver, SNDRV_CARDS); | ||
1212 | #ifdef CONFIG_PNP | ||
1213 | if (!err) | ||
1214 | isa_registered = 1; | ||
1215 | |||
1216 | err = pnp_register_card_driver(&msnd_pnpc_driver); | ||
1217 | if (!err) | ||
1218 | pnp_registered = 1; | ||
1219 | |||
1220 | if (isa_registered) | ||
1221 | err = 0; | ||
1222 | #endif | ||
1223 | return err; | ||
1224 | } | ||
1225 | |||
1226 | static void __exit snd_msnd_exit(void) | ||
1227 | { | ||
1228 | #ifdef CONFIG_PNP | ||
1229 | if (pnp_registered) | ||
1230 | pnp_unregister_card_driver(&msnd_pnpc_driver); | ||
1231 | if (isa_registered) | ||
1232 | #endif | ||
1233 | isa_unregister_driver(&snd_msnd_driver); | ||
1234 | } | ||
1235 | |||
1236 | module_init(snd_msnd_init); | ||
1237 | module_exit(snd_msnd_exit); | ||
1238 | |||
diff --git a/sound/isa/msnd/msnd_pinnacle.h b/sound/isa/msnd/msnd_pinnacle.h new file mode 100644 index 000000000000..48318d1ee340 --- /dev/null +++ b/sound/isa/msnd/msnd_pinnacle.h | |||
@@ -0,0 +1,181 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * msnd_pinnacle.h | ||
4 | * | ||
5 | * Turtle Beach MultiSound Sound Card Driver for Linux | ||
6 | * | ||
7 | * Some parts of this header file were derived from the Turtle Beach | ||
8 | * MultiSound Driver Development Kit. | ||
9 | * | ||
10 | * Copyright (C) 1998 Andrew Veliath | ||
11 | * Copyright (C) 1993 Turtle Beach Systems, Inc. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | ********************************************************************/ | ||
28 | #ifndef __MSND_PINNACLE_H | ||
29 | #define __MSND_PINNACLE_H | ||
30 | |||
31 | #define DSP_NUMIO 0x08 | ||
32 | |||
33 | #define IREG_LOGDEVICE 0x07 | ||
34 | #define IREG_ACTIVATE 0x30 | ||
35 | #define LD_ACTIVATE 0x01 | ||
36 | #define LD_DISACTIVATE 0x00 | ||
37 | #define IREG_EECONTROL 0x3F | ||
38 | #define IREG_MEMBASEHI 0x40 | ||
39 | #define IREG_MEMBASELO 0x41 | ||
40 | #define IREG_MEMCONTROL 0x42 | ||
41 | #define IREG_MEMRANGEHI 0x43 | ||
42 | #define IREG_MEMRANGELO 0x44 | ||
43 | #define MEMTYPE_8BIT 0x00 | ||
44 | #define MEMTYPE_16BIT 0x02 | ||
45 | #define MEMTYPE_RANGE 0x00 | ||
46 | #define MEMTYPE_HIADDR 0x01 | ||
47 | #define IREG_IO0_BASEHI 0x60 | ||
48 | #define IREG_IO0_BASELO 0x61 | ||
49 | #define IREG_IO1_BASEHI 0x62 | ||
50 | #define IREG_IO1_BASELO 0x63 | ||
51 | #define IREG_IRQ_NUMBER 0x70 | ||
52 | #define IREG_IRQ_TYPE 0x71 | ||
53 | #define IRQTYPE_HIGH 0x02 | ||
54 | #define IRQTYPE_LOW 0x00 | ||
55 | #define IRQTYPE_LEVEL 0x01 | ||
56 | #define IRQTYPE_EDGE 0x00 | ||
57 | |||
58 | #define HP_DSPR 0x04 | ||
59 | #define HP_BLKS 0x04 | ||
60 | |||
61 | #define HPDSPRESET_OFF 2 | ||
62 | #define HPDSPRESET_ON 0 | ||
63 | |||
64 | #define HPBLKSEL_0 2 | ||
65 | #define HPBLKSEL_1 3 | ||
66 | |||
67 | #define HIMT_DAT_OFF 0x03 | ||
68 | |||
69 | #define HIDSP_PLAY_UNDER 0x00 | ||
70 | #define HIDSP_INT_PLAY_UNDER 0x01 | ||
71 | #define HIDSP_SSI_TX_UNDER 0x02 | ||
72 | #define HIDSP_RECQ_OVERFLOW 0x08 | ||
73 | #define HIDSP_INT_RECORD_OVER 0x09 | ||
74 | #define HIDSP_SSI_RX_OVERFLOW 0x0a | ||
75 | |||
76 | #define HIDSP_MIDI_IN_OVER 0x10 | ||
77 | |||
78 | #define HIDSP_MIDI_FRAME_ERR 0x11 | ||
79 | #define HIDSP_MIDI_PARITY_ERR 0x12 | ||
80 | #define HIDSP_MIDI_OVERRUN_ERR 0x13 | ||
81 | |||
82 | #define HIDSP_INPUT_CLIPPING 0x20 | ||
83 | #define HIDSP_MIX_CLIPPING 0x30 | ||
84 | #define HIDSP_DAT_IN_OFF 0x21 | ||
85 | |||
86 | #define TIME_PRO_RESET_DONE 0x028A | ||
87 | #define TIME_PRO_SYSEX 0x001E | ||
88 | #define TIME_PRO_RESET 0x0032 | ||
89 | |||
90 | #define DAR_BUFF_SIZE 0x1000 | ||
91 | |||
92 | #define MIDQ_BUFF_SIZE 0x800 | ||
93 | #define DSPQ_BUFF_SIZE 0x5A0 | ||
94 | |||
95 | #define DSPQ_DATA_BUFF 0x7860 | ||
96 | |||
97 | #define MOP_WAVEHDR 0 | ||
98 | #define MOP_EXTOUT 1 | ||
99 | #define MOP_HWINIT 0xfe | ||
100 | #define MOP_NONE 0xff | ||
101 | #define MOP_MAX 1 | ||
102 | |||
103 | #define MIP_EXTIN 0 | ||
104 | #define MIP_WAVEHDR 1 | ||
105 | #define MIP_HWINIT 0xfe | ||
106 | #define MIP_MAX 1 | ||
107 | |||
108 | /* Pinnacle/Fiji SMA Common Data */ | ||
109 | #define SMA_wCurrPlayBytes 0x0000 | ||
110 | #define SMA_wCurrRecordBytes 0x0002 | ||
111 | #define SMA_wCurrPlayVolLeft 0x0004 | ||
112 | #define SMA_wCurrPlayVolRight 0x0006 | ||
113 | #define SMA_wCurrInVolLeft 0x0008 | ||
114 | #define SMA_wCurrInVolRight 0x000a | ||
115 | #define SMA_wCurrMHdrVolLeft 0x000c | ||
116 | #define SMA_wCurrMHdrVolRight 0x000e | ||
117 | #define SMA_dwCurrPlayPitch 0x0010 | ||
118 | #define SMA_dwCurrPlayRate 0x0014 | ||
119 | #define SMA_wCurrMIDIIOPatch 0x0018 | ||
120 | #define SMA_wCurrPlayFormat 0x001a | ||
121 | #define SMA_wCurrPlaySampleSize 0x001c | ||
122 | #define SMA_wCurrPlayChannels 0x001e | ||
123 | #define SMA_wCurrPlaySampleRate 0x0020 | ||
124 | #define SMA_wCurrRecordFormat 0x0022 | ||
125 | #define SMA_wCurrRecordSampleSize 0x0024 | ||
126 | #define SMA_wCurrRecordChannels 0x0026 | ||
127 | #define SMA_wCurrRecordSampleRate 0x0028 | ||
128 | #define SMA_wCurrDSPStatusFlags 0x002a | ||
129 | #define SMA_wCurrHostStatusFlags 0x002c | ||
130 | #define SMA_wCurrInputTagBits 0x002e | ||
131 | #define SMA_wCurrLeftPeak 0x0030 | ||
132 | #define SMA_wCurrRightPeak 0x0032 | ||
133 | #define SMA_bMicPotPosLeft 0x0034 | ||
134 | #define SMA_bMicPotPosRight 0x0035 | ||
135 | #define SMA_bMicPotMaxLeft 0x0036 | ||
136 | #define SMA_bMicPotMaxRight 0x0037 | ||
137 | #define SMA_bInPotPosLeft 0x0038 | ||
138 | #define SMA_bInPotPosRight 0x0039 | ||
139 | #define SMA_bAuxPotPosLeft 0x003a | ||
140 | #define SMA_bAuxPotPosRight 0x003b | ||
141 | #define SMA_bInPotMaxLeft 0x003c | ||
142 | #define SMA_bInPotMaxRight 0x003d | ||
143 | #define SMA_bAuxPotMaxLeft 0x003e | ||
144 | #define SMA_bAuxPotMaxRight 0x003f | ||
145 | #define SMA_bInPotMaxMethod 0x0040 | ||
146 | #define SMA_bAuxPotMaxMethod 0x0041 | ||
147 | #define SMA_wCurrMastVolLeft 0x0042 | ||
148 | #define SMA_wCurrMastVolRight 0x0044 | ||
149 | #define SMA_wCalFreqAtoD 0x0046 | ||
150 | #define SMA_wCurrAuxVolLeft 0x0048 | ||
151 | #define SMA_wCurrAuxVolRight 0x004a | ||
152 | #define SMA_wCurrPlay1VolLeft 0x004c | ||
153 | #define SMA_wCurrPlay1VolRight 0x004e | ||
154 | #define SMA_wCurrPlay2VolLeft 0x0050 | ||
155 | #define SMA_wCurrPlay2VolRight 0x0052 | ||
156 | #define SMA_wCurrPlay3VolLeft 0x0054 | ||
157 | #define SMA_wCurrPlay3VolRight 0x0056 | ||
158 | #define SMA_wCurrPlay4VolLeft 0x0058 | ||
159 | #define SMA_wCurrPlay4VolRight 0x005a | ||
160 | #define SMA_wCurrPlay1PeakLeft 0x005c | ||
161 | #define SMA_wCurrPlay1PeakRight 0x005e | ||
162 | #define SMA_wCurrPlay2PeakLeft 0x0060 | ||
163 | #define SMA_wCurrPlay2PeakRight 0x0062 | ||
164 | #define SMA_wCurrPlay3PeakLeft 0x0064 | ||
165 | #define SMA_wCurrPlay3PeakRight 0x0066 | ||
166 | #define SMA_wCurrPlay4PeakLeft 0x0068 | ||
167 | #define SMA_wCurrPlay4PeakRight 0x006a | ||
168 | #define SMA_wCurrPlayPeakLeft 0x006c | ||
169 | #define SMA_wCurrPlayPeakRight 0x006e | ||
170 | #define SMA_wCurrDATSR 0x0070 | ||
171 | #define SMA_wCurrDATRXCHNL 0x0072 | ||
172 | #define SMA_wCurrDATTXCHNL 0x0074 | ||
173 | #define SMA_wCurrDATRXRate 0x0076 | ||
174 | #define SMA_dwDSPPlayCount 0x0078 | ||
175 | #define SMA__size 0x007c | ||
176 | |||
177 | #define INITCODEFILE "turtlebeach/pndspini.bin" | ||
178 | #define PERMCODEFILE "turtlebeach/pndsperm.bin" | ||
179 | #define LONGNAME "MultiSound (Pinnacle/Fiji)" | ||
180 | |||
181 | #endif /* __MSND_PINNACLE_H */ | ||
diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c new file mode 100644 index 000000000000..494058a1a502 --- /dev/null +++ b/sound/isa/msnd/msnd_pinnacle_mixer.c | |||
@@ -0,0 +1,343 @@ | |||
1 | /*************************************************************************** | ||
2 | msnd_pinnacle_mixer.c - description | ||
3 | ------------------- | ||
4 | begin : Fre Jun 7 2002 | ||
5 | copyright : (C) 2002 by karsten wiese | ||
6 | email : annabellesgarden@yahoo.de | ||
7 | ***************************************************************************/ | ||
8 | |||
9 | /*************************************************************************** | ||
10 | * * | ||
11 | * This program is free software; you can redistribute it and/or modify * | ||
12 | * it under the terms of the GNU General Public License as published by * | ||
13 | * the Free Software Foundation; either version 2 of the License, or * | ||
14 | * (at your option) any later version. * | ||
15 | * * | ||
16 | ***************************************************************************/ | ||
17 | |||
18 | #include <linux/io.h> | ||
19 | |||
20 | #include <sound/core.h> | ||
21 | #include <sound/control.h> | ||
22 | #include "msnd.h" | ||
23 | #include "msnd_pinnacle.h" | ||
24 | |||
25 | |||
26 | #define MSND_MIXER_VOLUME 0 | ||
27 | #define MSND_MIXER_PCM 1 | ||
28 | #define MSND_MIXER_AUX 2 /* Input source 1 (aux1) */ | ||
29 | #define MSND_MIXER_IMIX 3 /* Recording monitor */ | ||
30 | #define MSND_MIXER_SYNTH 4 | ||
31 | #define MSND_MIXER_SPEAKER 5 | ||
32 | #define MSND_MIXER_LINE 6 | ||
33 | #define MSND_MIXER_MIC 7 | ||
34 | #define MSND_MIXER_RECLEV 11 /* Recording level */ | ||
35 | #define MSND_MIXER_IGAIN 12 /* Input gain */ | ||
36 | #define MSND_MIXER_OGAIN 13 /* Output gain */ | ||
37 | #define MSND_MIXER_DIGITAL 17 /* Digital (input) 1 */ | ||
38 | |||
39 | /* Device mask bits */ | ||
40 | |||
41 | #define MSND_MASK_VOLUME (1 << MSND_MIXER_VOLUME) | ||
42 | #define MSND_MASK_SYNTH (1 << MSND_MIXER_SYNTH) | ||
43 | #define MSND_MASK_PCM (1 << MSND_MIXER_PCM) | ||
44 | #define MSND_MASK_SPEAKER (1 << MSND_MIXER_SPEAKER) | ||
45 | #define MSND_MASK_LINE (1 << MSND_MIXER_LINE) | ||
46 | #define MSND_MASK_MIC (1 << MSND_MIXER_MIC) | ||
47 | #define MSND_MASK_IMIX (1 << MSND_MIXER_IMIX) | ||
48 | #define MSND_MASK_RECLEV (1 << MSND_MIXER_RECLEV) | ||
49 | #define MSND_MASK_IGAIN (1 << MSND_MIXER_IGAIN) | ||
50 | #define MSND_MASK_OGAIN (1 << MSND_MIXER_OGAIN) | ||
51 | #define MSND_MASK_AUX (1 << MSND_MIXER_AUX) | ||
52 | #define MSND_MASK_DIGITAL (1 << MSND_MIXER_DIGITAL) | ||
53 | |||
54 | static int snd_msndmix_info_mux(struct snd_kcontrol *kcontrol, | ||
55 | struct snd_ctl_elem_info *uinfo) | ||
56 | { | ||
57 | static char *texts[3] = { | ||
58 | "Analog", "MASS", "SPDIF", | ||
59 | }; | ||
60 | struct snd_msnd *chip = snd_kcontrol_chip(kcontrol); | ||
61 | unsigned items = test_bit(F_HAVEDIGITAL, &chip->flags) ? 3 : 2; | ||
62 | |||
63 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
64 | uinfo->count = 1; | ||
65 | uinfo->value.enumerated.items = items; | ||
66 | if (uinfo->value.enumerated.item >= items) | ||
67 | uinfo->value.enumerated.item = items - 1; | ||
68 | strcpy(uinfo->value.enumerated.name, | ||
69 | texts[uinfo->value.enumerated.item]); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int snd_msndmix_get_mux(struct snd_kcontrol *kcontrol, | ||
74 | struct snd_ctl_elem_value *ucontrol) | ||
75 | { | ||
76 | struct snd_msnd *chip = snd_kcontrol_chip(kcontrol); | ||
77 | /* MSND_MASK_IMIX is the default */ | ||
78 | ucontrol->value.enumerated.item[0] = 0; | ||
79 | |||
80 | if (chip->recsrc & MSND_MASK_SYNTH) { | ||
81 | ucontrol->value.enumerated.item[0] = 1; | ||
82 | } else if ((chip->recsrc & MSND_MASK_DIGITAL) && | ||
83 | test_bit(F_HAVEDIGITAL, &chip->flags)) { | ||
84 | ucontrol->value.enumerated.item[0] = 2; | ||
85 | } | ||
86 | |||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int snd_msndmix_set_mux(struct snd_msnd *chip, int val) | ||
92 | { | ||
93 | unsigned newrecsrc; | ||
94 | int change; | ||
95 | unsigned char msndbyte; | ||
96 | |||
97 | switch (val) { | ||
98 | case 0: | ||
99 | newrecsrc = MSND_MASK_IMIX; | ||
100 | msndbyte = HDEXAR_SET_ANA_IN; | ||
101 | break; | ||
102 | case 1: | ||
103 | newrecsrc = MSND_MASK_SYNTH; | ||
104 | msndbyte = HDEXAR_SET_SYNTH_IN; | ||
105 | break; | ||
106 | case 2: | ||
107 | newrecsrc = MSND_MASK_DIGITAL; | ||
108 | msndbyte = HDEXAR_SET_DAT_IN; | ||
109 | break; | ||
110 | default: | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | change = newrecsrc != chip->recsrc; | ||
114 | if (change) { | ||
115 | change = 0; | ||
116 | if (!snd_msnd_send_word(chip, 0, 0, msndbyte)) | ||
117 | if (!snd_msnd_send_dsp_cmd(chip, HDEX_AUX_REQ)) { | ||
118 | chip->recsrc = newrecsrc; | ||
119 | change = 1; | ||
120 | } | ||
121 | } | ||
122 | return change; | ||
123 | } | ||
124 | |||
125 | static int snd_msndmix_put_mux(struct snd_kcontrol *kcontrol, | ||
126 | struct snd_ctl_elem_value *ucontrol) | ||
127 | { | ||
128 | struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol); | ||
129 | return snd_msndmix_set_mux(msnd, ucontrol->value.enumerated.item[0]); | ||
130 | } | ||
131 | |||
132 | |||
133 | static int snd_msndmix_volume_info(struct snd_kcontrol *kcontrol, | ||
134 | struct snd_ctl_elem_info *uinfo) | ||
135 | { | ||
136 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
137 | uinfo->count = 2; | ||
138 | uinfo->value.integer.min = 0; | ||
139 | uinfo->value.integer.max = 100; | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int snd_msndmix_volume_get(struct snd_kcontrol *kcontrol, | ||
144 | struct snd_ctl_elem_value *ucontrol) | ||
145 | { | ||
146 | struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol); | ||
147 | int addr = kcontrol->private_value; | ||
148 | unsigned long flags; | ||
149 | |||
150 | spin_lock_irqsave(&msnd->mixer_lock, flags); | ||
151 | ucontrol->value.integer.value[0] = msnd->left_levels[addr] * 100; | ||
152 | ucontrol->value.integer.value[0] /= 0xFFFF; | ||
153 | ucontrol->value.integer.value[1] = msnd->right_levels[addr] * 100; | ||
154 | ucontrol->value.integer.value[1] /= 0xFFFF; | ||
155 | spin_unlock_irqrestore(&msnd->mixer_lock, flags); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | #define update_volm(a, b) \ | ||
160 | do { \ | ||
161 | writew((dev->left_levels[a] >> 1) * \ | ||
162 | readw(dev->SMA + SMA_wCurrMastVolLeft) / 0xffff, \ | ||
163 | dev->SMA + SMA_##b##Left); \ | ||
164 | writew((dev->right_levels[a] >> 1) * \ | ||
165 | readw(dev->SMA + SMA_wCurrMastVolRight) / 0xffff, \ | ||
166 | dev->SMA + SMA_##b##Right); \ | ||
167 | } while (0); | ||
168 | |||
169 | #define update_potm(d, s, ar) \ | ||
170 | do { \ | ||
171 | writeb((dev->left_levels[d] >> 8) * \ | ||
172 | readw(dev->SMA + SMA_wCurrMastVolLeft) / 0xffff, \ | ||
173 | dev->SMA + SMA_##s##Left); \ | ||
174 | writeb((dev->right_levels[d] >> 8) * \ | ||
175 | readw(dev->SMA + SMA_wCurrMastVolRight) / 0xffff, \ | ||
176 | dev->SMA + SMA_##s##Right); \ | ||
177 | if (snd_msnd_send_word(dev, 0, 0, ar) == 0) \ | ||
178 | snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); \ | ||
179 | } while (0); | ||
180 | |||
181 | #define update_pot(d, s, ar) \ | ||
182 | do { \ | ||
183 | writeb(dev->left_levels[d] >> 8, \ | ||
184 | dev->SMA + SMA_##s##Left); \ | ||
185 | writeb(dev->right_levels[d] >> 8, \ | ||
186 | dev->SMA + SMA_##s##Right); \ | ||
187 | if (snd_msnd_send_word(dev, 0, 0, ar) == 0) \ | ||
188 | snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); \ | ||
189 | } while (0); | ||
190 | |||
191 | |||
192 | static int snd_msndmix_set(struct snd_msnd *dev, int d, int left, int right) | ||
193 | { | ||
194 | int bLeft, bRight; | ||
195 | int wLeft, wRight; | ||
196 | int updatemaster = 0; | ||
197 | |||
198 | if (d >= LEVEL_ENTRIES) | ||
199 | return -EINVAL; | ||
200 | |||
201 | bLeft = left * 0xff / 100; | ||
202 | wLeft = left * 0xffff / 100; | ||
203 | |||
204 | bRight = right * 0xff / 100; | ||
205 | wRight = right * 0xffff / 100; | ||
206 | |||
207 | dev->left_levels[d] = wLeft; | ||
208 | dev->right_levels[d] = wRight; | ||
209 | |||
210 | switch (d) { | ||
211 | /* master volume unscaled controls */ | ||
212 | case MSND_MIXER_LINE: /* line pot control */ | ||
213 | /* scaled by IMIX in digital mix */ | ||
214 | writeb(bLeft, dev->SMA + SMA_bInPotPosLeft); | ||
215 | writeb(bRight, dev->SMA + SMA_bInPotPosRight); | ||
216 | if (snd_msnd_send_word(dev, 0, 0, HDEXAR_IN_SET_POTS) == 0) | ||
217 | snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); | ||
218 | break; | ||
219 | case MSND_MIXER_MIC: /* mic pot control */ | ||
220 | if (dev->type == msndClassic) | ||
221 | return -EINVAL; | ||
222 | /* scaled by IMIX in digital mix */ | ||
223 | writeb(bLeft, dev->SMA + SMA_bMicPotPosLeft); | ||
224 | writeb(bRight, dev->SMA + SMA_bMicPotPosRight); | ||
225 | if (snd_msnd_send_word(dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0) | ||
226 | snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); | ||
227 | break; | ||
228 | case MSND_MIXER_VOLUME: /* master volume */ | ||
229 | writew(wLeft, dev->SMA + SMA_wCurrMastVolLeft); | ||
230 | writew(wRight, dev->SMA + SMA_wCurrMastVolRight); | ||
231 | /* fall through */ | ||
232 | |||
233 | case MSND_MIXER_AUX: /* aux pot control */ | ||
234 | /* scaled by master volume */ | ||
235 | /* fall through */ | ||
236 | |||
237 | /* digital controls */ | ||
238 | case MSND_MIXER_SYNTH: /* synth vol (dsp mix) */ | ||
239 | case MSND_MIXER_PCM: /* pcm vol (dsp mix) */ | ||
240 | case MSND_MIXER_IMIX: /* input monitor (dsp mix) */ | ||
241 | /* scaled by master volume */ | ||
242 | updatemaster = 1; | ||
243 | break; | ||
244 | |||
245 | default: | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | if (updatemaster) { | ||
250 | /* update master volume scaled controls */ | ||
251 | update_volm(MSND_MIXER_PCM, wCurrPlayVol); | ||
252 | update_volm(MSND_MIXER_IMIX, wCurrInVol); | ||
253 | if (dev->type == msndPinnacle) | ||
254 | update_volm(MSND_MIXER_SYNTH, wCurrMHdrVol); | ||
255 | update_potm(MSND_MIXER_AUX, bAuxPotPos, HDEXAR_AUX_SET_POTS); | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int snd_msndmix_volume_put(struct snd_kcontrol *kcontrol, | ||
262 | struct snd_ctl_elem_value *ucontrol) | ||
263 | { | ||
264 | struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol); | ||
265 | int change, addr = kcontrol->private_value; | ||
266 | int left, right; | ||
267 | unsigned long flags; | ||
268 | |||
269 | left = ucontrol->value.integer.value[0] % 101; | ||
270 | right = ucontrol->value.integer.value[1] % 101; | ||
271 | spin_lock_irqsave(&msnd->mixer_lock, flags); | ||
272 | change = msnd->left_levels[addr] != left | ||
273 | || msnd->right_levels[addr] != right; | ||
274 | snd_msndmix_set(msnd, addr, left, right); | ||
275 | spin_unlock_irqrestore(&msnd->mixer_lock, flags); | ||
276 | return change; | ||
277 | } | ||
278 | |||
279 | |||
280 | #define DUMMY_VOLUME(xname, xindex, addr) \ | ||
281 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
282 | .info = snd_msndmix_volume_info, \ | ||
283 | .get = snd_msndmix_volume_get, .put = snd_msndmix_volume_put, \ | ||
284 | .private_value = addr } | ||
285 | |||
286 | |||
287 | static struct snd_kcontrol_new snd_msnd_controls[] = { | ||
288 | DUMMY_VOLUME("Master Volume", 0, MSND_MIXER_VOLUME), | ||
289 | DUMMY_VOLUME("PCM Volume", 0, MSND_MIXER_PCM), | ||
290 | DUMMY_VOLUME("Aux Volume", 0, MSND_MIXER_AUX), | ||
291 | DUMMY_VOLUME("Line Volume", 0, MSND_MIXER_LINE), | ||
292 | DUMMY_VOLUME("Mic Volume", 0, MSND_MIXER_MIC), | ||
293 | DUMMY_VOLUME("Monitor", 0, MSND_MIXER_IMIX), | ||
294 | { | ||
295 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
296 | .name = "Capture Source", | ||
297 | .info = snd_msndmix_info_mux, | ||
298 | .get = snd_msndmix_get_mux, | ||
299 | .put = snd_msndmix_put_mux, | ||
300 | } | ||
301 | }; | ||
302 | |||
303 | |||
304 | int __devinit snd_msndmix_new(struct snd_card *card) | ||
305 | { | ||
306 | struct snd_msnd *chip = card->private_data; | ||
307 | unsigned int idx; | ||
308 | int err; | ||
309 | |||
310 | if (snd_BUG_ON(!chip)) | ||
311 | return -EINVAL; | ||
312 | spin_lock_init(&chip->mixer_lock); | ||
313 | strcpy(card->mixername, "MSND Pinnacle Mixer"); | ||
314 | |||
315 | for (idx = 0; idx < ARRAY_SIZE(snd_msnd_controls); idx++) | ||
316 | err = snd_ctl_add(card, | ||
317 | snd_ctl_new1(snd_msnd_controls + idx, chip)); | ||
318 | if (err < 0) | ||
319 | return err; | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | EXPORT_SYMBOL(snd_msndmix_new); | ||
324 | |||
325 | void snd_msndmix_setup(struct snd_msnd *dev) | ||
326 | { | ||
327 | update_pot(MSND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS); | ||
328 | update_potm(MSND_MIXER_AUX, bAuxPotPos, HDEXAR_AUX_SET_POTS); | ||
329 | update_volm(MSND_MIXER_PCM, wCurrPlayVol); | ||
330 | update_volm(MSND_MIXER_IMIX, wCurrInVol); | ||
331 | if (dev->type == msndPinnacle) { | ||
332 | update_pot(MSND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS); | ||
333 | update_volm(MSND_MIXER_SYNTH, wCurrMHdrVol); | ||
334 | } | ||
335 | } | ||
336 | EXPORT_SYMBOL(snd_msndmix_setup); | ||
337 | |||
338 | int snd_msndmix_force_recsrc(struct snd_msnd *dev, int recsrc) | ||
339 | { | ||
340 | dev->recsrc = -1; | ||
341 | return snd_msndmix_set_mux(dev, recsrc); | ||
342 | } | ||
343 | EXPORT_SYMBOL(snd_msndmix_force_recsrc); | ||
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 58c972b2af03..ef95279da7a3 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -179,12 +179,13 @@ static unsigned char __snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char | |||
179 | unsigned char result; | 179 | unsigned char result; |
180 | #if 0 | 180 | #if 0 |
181 | outb(0x1d, port); /* password */ | 181 | outb(0x1d, port); /* password */ |
182 | printk("read [0x%lx] = 0x%x\n", port, inb(port)); | 182 | printk(KERN_DEBUG "read [0x%lx] = 0x%x\n", port, inb(port)); |
183 | #endif | 183 | #endif |
184 | outb(reg, chip->port); /* register */ | 184 | outb(reg, chip->port); /* register */ |
185 | result = inb(chip->port + 1); | 185 | result = inb(chip->port + 1); |
186 | #if 0 | 186 | #if 0 |
187 | printk("read [0x%lx] = 0x%x [0x%x]\n", port, result, inb(port)); | 187 | printk(KERN_DEBUG "read [0x%lx] = 0x%x [0x%x]\n", |
188 | port, result, inb(port)); | ||
188 | #endif | 189 | #endif |
189 | return result; | 190 | return result; |
190 | } | 191 | } |
@@ -233,7 +234,10 @@ static int __devinit snd_opl3sa2_detect(struct snd_card *card) | |||
233 | snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port); | 234 | snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port); |
234 | return -EBUSY; | 235 | return -EBUSY; |
235 | } | 236 | } |
236 | // snd_printk("REG 0A = 0x%x\n", snd_opl3sa2_read(chip, 0x0a)); | 237 | /* |
238 | snd_printk(KERN_DEBUG "REG 0A = 0x%x\n", | ||
239 | snd_opl3sa2_read(chip, 0x0a)); | ||
240 | */ | ||
237 | chip->version = 0; | 241 | chip->version = 0; |
238 | tmp = snd_opl3sa2_read(chip, OPL3SA2_MISC); | 242 | tmp = snd_opl3sa2_read(chip, OPL3SA2_MISC); |
239 | if (tmp == 0xff) { | 243 | if (tmp == 0xff) { |
@@ -550,21 +554,27 @@ static int __devinit snd_opl3sa2_mixer(struct snd_card *card) | |||
550 | #ifdef CONFIG_PM | 554 | #ifdef CONFIG_PM |
551 | static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) | 555 | static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) |
552 | { | 556 | { |
553 | struct snd_opl3sa2 *chip = card->private_data; | 557 | if (card) { |
558 | struct snd_opl3sa2 *chip = card->private_data; | ||
554 | 559 | ||
555 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 560 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
556 | chip->wss->suspend(chip->wss); | 561 | chip->wss->suspend(chip->wss); |
557 | /* power down */ | 562 | /* power down */ |
558 | snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); | 563 | snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); |
564 | } | ||
559 | 565 | ||
560 | return 0; | 566 | return 0; |
561 | } | 567 | } |
562 | 568 | ||
563 | static int snd_opl3sa2_resume(struct snd_card *card) | 569 | static int snd_opl3sa2_resume(struct snd_card *card) |
564 | { | 570 | { |
565 | struct snd_opl3sa2 *chip = card->private_data; | 571 | struct snd_opl3sa2 *chip; |
566 | int i; | 572 | int i; |
567 | 573 | ||
574 | if (!card) | ||
575 | return 0; | ||
576 | |||
577 | chip = card->private_data; | ||
568 | /* power up */ | 578 | /* power up */ |
569 | snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); | 579 | snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); |
570 | 580 | ||
@@ -613,25 +623,28 @@ static void snd_opl3sa2_free(struct snd_card *card) | |||
613 | { | 623 | { |
614 | struct snd_opl3sa2 *chip = card->private_data; | 624 | struct snd_opl3sa2 *chip = card->private_data; |
615 | if (chip->irq >= 0) | 625 | if (chip->irq >= 0) |
616 | free_irq(chip->irq, (void *)chip); | 626 | free_irq(chip->irq, card); |
617 | release_and_free_resource(chip->res_port); | 627 | release_and_free_resource(chip->res_port); |
618 | } | 628 | } |
619 | 629 | ||
620 | static struct snd_card *snd_opl3sa2_card_new(int dev) | 630 | static int snd_opl3sa2_card_new(int dev, struct snd_card **cardp) |
621 | { | 631 | { |
622 | struct snd_card *card; | 632 | struct snd_card *card; |
623 | struct snd_opl3sa2 *chip; | 633 | struct snd_opl3sa2 *chip; |
634 | int err; | ||
624 | 635 | ||
625 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_opl3sa2)); | 636 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
626 | if (card == NULL) | 637 | sizeof(struct snd_opl3sa2), &card); |
627 | return NULL; | 638 | if (err < 0) |
639 | return err; | ||
628 | strcpy(card->driver, "OPL3SA2"); | 640 | strcpy(card->driver, "OPL3SA2"); |
629 | strcpy(card->shortname, "Yamaha OPL3-SA2"); | 641 | strcpy(card->shortname, "Yamaha OPL3-SA"); |
630 | chip = card->private_data; | 642 | chip = card->private_data; |
631 | spin_lock_init(&chip->reg_lock); | 643 | spin_lock_init(&chip->reg_lock); |
632 | chip->irq = -1; | 644 | chip->irq = -1; |
633 | card->private_free = snd_opl3sa2_free; | 645 | card->private_free = snd_opl3sa2_free; |
634 | return card; | 646 | *cardp = card; |
647 | return 0; | ||
635 | } | 648 | } |
636 | 649 | ||
637 | static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) | 650 | static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) |
@@ -723,9 +736,9 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, | |||
723 | if (dev >= SNDRV_CARDS) | 736 | if (dev >= SNDRV_CARDS) |
724 | return -ENODEV; | 737 | return -ENODEV; |
725 | 738 | ||
726 | card = snd_opl3sa2_card_new(dev); | 739 | err = snd_opl3sa2_card_new(dev, &card); |
727 | if (! card) | 740 | if (err < 0) |
728 | return -ENOMEM; | 741 | return err; |
729 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { | 742 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { |
730 | snd_card_free(card); | 743 | snd_card_free(card); |
731 | return err; | 744 | return err; |
@@ -789,9 +802,9 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, | |||
789 | if (dev >= SNDRV_CARDS) | 802 | if (dev >= SNDRV_CARDS) |
790 | return -ENODEV; | 803 | return -ENODEV; |
791 | 804 | ||
792 | card = snd_opl3sa2_card_new(dev); | 805 | err = snd_opl3sa2_card_new(dev, &card); |
793 | if (! card) | 806 | if (err < 0) |
794 | return -ENOMEM; | 807 | return err; |
795 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { | 808 | if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) { |
796 | snd_card_free(card); | 809 | snd_card_free(card); |
797 | return err; | 810 | return err; |
@@ -870,9 +883,9 @@ static int __devinit snd_opl3sa2_isa_probe(struct device *pdev, | |||
870 | struct snd_card *card; | 883 | struct snd_card *card; |
871 | int err; | 884 | int err; |
872 | 885 | ||
873 | card = snd_opl3sa2_card_new(dev); | 886 | err = snd_opl3sa2_card_new(dev, &card); |
874 | if (! card) | 887 | if (err < 0) |
875 | return -ENOMEM; | 888 | return err; |
876 | snd_card_set_dev(card, pdev); | 889 | snd_card_set_dev(card, pdev); |
877 | if ((err = snd_opl3sa2_probe(card, dev)) < 0) { | 890 | if ((err = snd_opl3sa2_probe(card, dev)) < 0) { |
878 | snd_card_free(card); | 891 | snd_card_free(card); |
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 440755cc0013..02e30d7c6a93 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c | |||
@@ -1228,9 +1228,10 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) | |||
1228 | struct snd_pcm *pcm; | 1228 | struct snd_pcm *pcm; |
1229 | struct snd_rawmidi *rmidi; | 1229 | struct snd_rawmidi *rmidi; |
1230 | 1230 | ||
1231 | if (!(card = snd_card_new(index, id, THIS_MODULE, | 1231 | error = snd_card_create(index, id, THIS_MODULE, |
1232 | sizeof(struct snd_miro)))) | 1232 | sizeof(struct snd_miro), &card); |
1233 | return -ENOMEM; | 1233 | if (error < 0) |
1234 | return error; | ||
1234 | 1235 | ||
1235 | card->private_free = snd_card_miro_free; | 1236 | card->private_free = snd_card_miro_free; |
1236 | miro = card->private_data; | 1237 | miro = card->private_data; |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 19706b0d8497..5cd555325b9d 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -252,7 +252,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, | |||
252 | #endif /* OPTi93X */ | 252 | #endif /* OPTi93X */ |
253 | 253 | ||
254 | default: | 254 | default: |
255 | snd_printk("chip %d not supported\n", hardware); | 255 | snd_printk(KERN_ERR "chip %d not supported\n", hardware); |
256 | return -ENODEV; | 256 | return -ENODEV; |
257 | } | 257 | } |
258 | return 0; | 258 | return 0; |
@@ -294,7 +294,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip, | |||
294 | #endif /* OPTi93X */ | 294 | #endif /* OPTi93X */ |
295 | 295 | ||
296 | default: | 296 | default: |
297 | snd_printk("chip %d not supported\n", chip->hardware); | 297 | snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); |
298 | } | 298 | } |
299 | 299 | ||
300 | spin_unlock_irqrestore(&chip->lock, flags); | 300 | spin_unlock_irqrestore(&chip->lock, flags); |
@@ -336,7 +336,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, | |||
336 | #endif /* OPTi93X */ | 336 | #endif /* OPTi93X */ |
337 | 337 | ||
338 | default: | 338 | default: |
339 | snd_printk("chip %d not supported\n", chip->hardware); | 339 | snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); |
340 | } | 340 | } |
341 | 341 | ||
342 | spin_unlock_irqrestore(&chip->lock, flags); | 342 | spin_unlock_irqrestore(&chip->lock, flags); |
@@ -412,7 +412,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) | |||
412 | #endif /* OPTi93X */ | 412 | #endif /* OPTi93X */ |
413 | 413 | ||
414 | default: | 414 | default: |
415 | snd_printk("chip %d not supported\n", chip->hardware); | 415 | snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); |
416 | return -EINVAL; | 416 | return -EINVAL; |
417 | } | 417 | } |
418 | 418 | ||
@@ -430,7 +430,8 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) | |||
430 | wss_base_bits = 0x02; | 430 | wss_base_bits = 0x02; |
431 | break; | 431 | break; |
432 | default: | 432 | default: |
433 | snd_printk("WSS port 0x%lx not valid\n", chip->wss_base); | 433 | snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", |
434 | chip->wss_base); | ||
434 | goto __skip_base; | 435 | goto __skip_base; |
435 | } | 436 | } |
436 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); | 437 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); |
@@ -455,7 +456,7 @@ __skip_base: | |||
455 | irq_bits = 0x04; | 456 | irq_bits = 0x04; |
456 | break; | 457 | break; |
457 | default: | 458 | default: |
458 | snd_printk("WSS irq # %d not valid\n", chip->irq); | 459 | snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq); |
459 | goto __skip_resources; | 460 | goto __skip_resources; |
460 | } | 461 | } |
461 | 462 | ||
@@ -470,13 +471,14 @@ __skip_base: | |||
470 | dma_bits = 0x03; | 471 | dma_bits = 0x03; |
471 | break; | 472 | break; |
472 | default: | 473 | default: |
473 | snd_printk("WSS dma1 # %d not valid\n", chip->dma1); | 474 | snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", |
475 | chip->dma1); | ||
474 | goto __skip_resources; | 476 | goto __skip_resources; |
475 | } | 477 | } |
476 | 478 | ||
477 | #if defined(CS4231) || defined(OPTi93X) | 479 | #if defined(CS4231) || defined(OPTi93X) |
478 | if (chip->dma1 == chip->dma2) { | 480 | if (chip->dma1 == chip->dma2) { |
479 | snd_printk("don't want to share dmas\n"); | 481 | snd_printk(KERN_ERR "don't want to share dmas\n"); |
480 | return -EBUSY; | 482 | return -EBUSY; |
481 | } | 483 | } |
482 | 484 | ||
@@ -485,7 +487,8 @@ __skip_base: | |||
485 | case 1: | 487 | case 1: |
486 | break; | 488 | break; |
487 | default: | 489 | default: |
488 | snd_printk("WSS dma2 # %d not valid\n", chip->dma2); | 490 | snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", |
491 | chip->dma2); | ||
489 | goto __skip_resources; | 492 | goto __skip_resources; |
490 | } | 493 | } |
491 | dma_bits |= 0x04; | 494 | dma_bits |= 0x04; |
@@ -516,7 +519,8 @@ __skip_resources: | |||
516 | mpu_port_bits = 0x00; | 519 | mpu_port_bits = 0x00; |
517 | break; | 520 | break; |
518 | default: | 521 | default: |
519 | snd_printk("MPU-401 port 0x%lx not valid\n", | 522 | snd_printk(KERN_WARNING |
523 | "MPU-401 port 0x%lx not valid\n", | ||
520 | chip->mpu_port); | 524 | chip->mpu_port); |
521 | goto __skip_mpu; | 525 | goto __skip_mpu; |
522 | } | 526 | } |
@@ -535,7 +539,7 @@ __skip_resources: | |||
535 | mpu_irq_bits = 0x01; | 539 | mpu_irq_bits = 0x01; |
536 | break; | 540 | break; |
537 | default: | 541 | default: |
538 | snd_printk("MPU-401 irq # %d not valid\n", | 542 | snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n", |
539 | chip->mpu_irq); | 543 | chip->mpu_irq); |
540 | goto __skip_mpu; | 544 | goto __skip_mpu; |
541 | } | 545 | } |
@@ -726,7 +730,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
726 | if (chip->wss_base == SNDRV_AUTO_PORT) { | 730 | if (chip->wss_base == SNDRV_AUTO_PORT) { |
727 | chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); | 731 | chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); |
728 | if (chip->wss_base < 0) { | 732 | if (chip->wss_base < 0) { |
729 | snd_printk("unable to find a free WSS port\n"); | 733 | snd_printk(KERN_ERR "unable to find a free WSS port\n"); |
730 | return -EBUSY; | 734 | return -EBUSY; |
731 | } | 735 | } |
732 | } | 736 | } |
@@ -815,14 +819,8 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
815 | chip->fm_port, chip->fm_port + 4 - 1); | 819 | chip->fm_port, chip->fm_port + 4 - 1); |
816 | } | 820 | } |
817 | if (opl3) { | 821 | if (opl3) { |
818 | #ifdef CS4231 | 822 | error = snd_opl3_hwdep_new(opl3, 0, 1, &synth); |
819 | const int t1dev = 1; | 823 | if (error < 0) |
820 | #else | ||
821 | const int t1dev = 0; | ||
822 | #endif | ||
823 | if ((error = snd_opl3_timer_new(opl3, t1dev, t1dev+1)) < 0) | ||
824 | return error; | ||
825 | if ((error = snd_opl3_hwdep_new(opl3, 0, 1, &synth)) < 0) | ||
826 | return error; | 824 | return error; |
827 | } | 825 | } |
828 | } | 826 | } |
@@ -830,15 +828,18 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
830 | return snd_card_register(card); | 828 | return snd_card_register(card); |
831 | } | 829 | } |
832 | 830 | ||
833 | static struct snd_card *snd_opti9xx_card_new(void) | 831 | static int snd_opti9xx_card_new(struct snd_card **cardp) |
834 | { | 832 | { |
835 | struct snd_card *card; | 833 | struct snd_card *card; |
834 | int err; | ||
836 | 835 | ||
837 | card = snd_card_new(index, id, THIS_MODULE, sizeof(struct snd_opti9xx)); | 836 | err = snd_card_create(index, id, THIS_MODULE, |
838 | if (! card) | 837 | sizeof(struct snd_opti9xx), &card); |
839 | return NULL; | 838 | if (err < 0) |
839 | return err; | ||
840 | card->private_free = snd_card_opti9xx_free; | 840 | card->private_free = snd_card_opti9xx_free; |
841 | return card; | 841 | *cardp = card; |
842 | return 0; | ||
842 | } | 843 | } |
843 | 844 | ||
844 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, | 845 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, |
@@ -897,15 +898,15 @@ static int __devinit snd_opti9xx_isa_probe(struct device *devptr, | |||
897 | #if defined(CS4231) || defined(OPTi93X) | 898 | #if defined(CS4231) || defined(OPTi93X) |
898 | if (dma2 == SNDRV_AUTO_DMA) { | 899 | if (dma2 == SNDRV_AUTO_DMA) { |
899 | if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) { | 900 | if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) { |
900 | snd_printk("unable to find a free DMA2\n"); | 901 | snd_printk(KERN_ERR "unable to find a free DMA2\n"); |
901 | return -EBUSY; | 902 | return -EBUSY; |
902 | } | 903 | } |
903 | } | 904 | } |
904 | #endif | 905 | #endif |
905 | 906 | ||
906 | card = snd_opti9xx_card_new(); | 907 | error = snd_opti9xx_card_new(&card); |
907 | if (! card) | 908 | if (error < 0) |
908 | return -ENOMEM; | 909 | return error; |
909 | 910 | ||
910 | if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) { | 911 | if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) { |
911 | snd_card_free(card); | 912 | snd_card_free(card); |
@@ -950,9 +951,9 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, | |||
950 | return -EBUSY; | 951 | return -EBUSY; |
951 | if (! isapnp) | 952 | if (! isapnp) |
952 | return -ENODEV; | 953 | return -ENODEV; |
953 | card = snd_opti9xx_card_new(); | 954 | error = snd_opti9xx_card_new(&card); |
954 | if (! card) | 955 | if (error < 0) |
955 | return -ENOMEM; | 956 | return error; |
956 | chip = card->private_data; | 957 | chip = card->private_data; |
957 | 958 | ||
958 | hw = snd_card_opti9xx_pnp(chip, pcard, pid); | 959 | hw = snd_card_opti9xx_pnp(chip, pcard, pid); |
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c index c8c8e214c843..cafc3a7316a8 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c | |||
@@ -108,9 +108,10 @@ static int __devinit snd_card_es968_probe(int dev, | |||
108 | struct snd_card *card; | 108 | struct snd_card *card; |
109 | struct snd_card_es968 *acard; | 109 | struct snd_card_es968 *acard; |
110 | 110 | ||
111 | if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 111 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, |
112 | sizeof(struct snd_card_es968))) == NULL) | 112 | sizeof(struct snd_card_es968), &card); |
113 | return -ENOMEM; | 113 | if (error < 0) |
114 | return error; | ||
114 | acard = card->private_data; | 115 | acard = card->private_data; |
115 | if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { | 116 | if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { |
116 | snd_card_free(card); | 117 | snd_card_free(card); |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 2c201f78ce50..519c36346dec 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -324,14 +324,18 @@ static void snd_sb16_free(struct snd_card *card) | |||
324 | #define is_isapnp_selected(dev) 0 | 324 | #define is_isapnp_selected(dev) 0 |
325 | #endif | 325 | #endif |
326 | 326 | ||
327 | static struct snd_card *snd_sb16_card_new(int dev) | 327 | static int snd_sb16_card_new(int dev, struct snd_card **cardp) |
328 | { | 328 | { |
329 | struct snd_card *card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 329 | struct snd_card *card; |
330 | sizeof(struct snd_card_sb16)); | 330 | int err; |
331 | if (card == NULL) | 331 | |
332 | return NULL; | 332 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
333 | sizeof(struct snd_card_sb16), &card); | ||
334 | if (err < 0) | ||
335 | return err; | ||
333 | card->private_free = snd_sb16_free; | 336 | card->private_free = snd_sb16_free; |
334 | return card; | 337 | *cardp = card; |
338 | return 0; | ||
335 | } | 339 | } |
336 | 340 | ||
337 | static int __devinit snd_sb16_probe(struct snd_card *card, int dev) | 341 | static int __devinit snd_sb16_probe(struct snd_card *card, int dev) |
@@ -489,9 +493,9 @@ static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev) | |||
489 | struct snd_card *card; | 493 | struct snd_card *card; |
490 | int err; | 494 | int err; |
491 | 495 | ||
492 | card = snd_sb16_card_new(dev); | 496 | err = snd_sb16_card_new(dev, &card); |
493 | if (! card) | 497 | if (err < 0) |
494 | return -ENOMEM; | 498 | return err; |
495 | 499 | ||
496 | acard = card->private_data; | 500 | acard = card->private_data; |
497 | /* non-PnP FM port address is hardwired with base port address */ | 501 | /* non-PnP FM port address is hardwired with base port address */ |
@@ -610,9 +614,9 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, | |||
610 | for ( ; dev < SNDRV_CARDS; dev++) { | 614 | for ( ; dev < SNDRV_CARDS; dev++) { |
611 | if (!enable[dev] || !isapnp[dev]) | 615 | if (!enable[dev] || !isapnp[dev]) |
612 | continue; | 616 | continue; |
613 | card = snd_sb16_card_new(dev); | 617 | res = snd_sb16_card_new(dev, &card); |
614 | if (! card) | 618 | if (res < 0) |
615 | return -ENOMEM; | 619 | return res; |
616 | snd_card_set_dev(card, &pcard->card->dev); | 620 | snd_card_set_dev(card, &pcard->card->dev); |
617 | if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 || | 621 | if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 || |
618 | (res = snd_sb16_probe(card, dev)) < 0) { | 622 | (res = snd_sb16_probe(card, dev)) < 0) { |
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index ea06877be4b1..3cd57ee54660 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c | |||
@@ -103,10 +103,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev) | |||
103 | struct snd_opl3 *opl3; | 103 | struct snd_opl3 *opl3; |
104 | int err; | 104 | int err; |
105 | 105 | ||
106 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 106 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
107 | sizeof(struct snd_sb8)); | 107 | sizeof(struct snd_sb8), &card); |
108 | if (card == NULL) | 108 | if (err < 0) |
109 | return -ENOMEM; | 109 | return err; |
110 | acard = card->private_data; | 110 | acard = card->private_data; |
111 | card->private_free = snd_sb8_free; | 111 | card->private_free = snd_sb8_free; |
112 | 112 | ||
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 406a431af91e..475220bbcc96 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -182,7 +182,7 @@ static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
182 | 182 | ||
183 | static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 183 | static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
184 | { | 184 | { |
185 | static char *texts[5] = { | 185 | static const char *texts[5] = { |
186 | "CD", "Mic", "Line", "Synth", "Master" | 186 | "CD", "Mic", "Line", "Synth", "Master" |
187 | }; | 187 | }; |
188 | 188 | ||
@@ -269,12 +269,73 @@ static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
269 | } | 269 | } |
270 | 270 | ||
271 | /* | 271 | /* |
272 | * ALS4000 mono recording control switch | ||
273 | */ | ||
274 | |||
275 | static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol, | ||
276 | struct snd_ctl_elem_info *uinfo) | ||
277 | { | ||
278 | static const char *texts[3] = { | ||
279 | "L chan only", "R chan only", "L ch/2 + R ch/2" | ||
280 | }; | ||
281 | |||
282 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
283 | uinfo->count = 1; | ||
284 | uinfo->value.enumerated.items = 3; | ||
285 | if (uinfo->value.enumerated.item > 2) | ||
286 | uinfo->value.enumerated.item = 2; | ||
287 | strcpy(uinfo->value.enumerated.name, | ||
288 | texts[uinfo->value.enumerated.item]); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol, | ||
293 | struct snd_ctl_elem_value *ucontrol) | ||
294 | { | ||
295 | struct snd_sb *sb = snd_kcontrol_chip(kcontrol); | ||
296 | unsigned long flags; | ||
297 | unsigned char oval; | ||
298 | |||
299 | spin_lock_irqsave(&sb->mixer_lock, flags); | ||
300 | oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL); | ||
301 | spin_unlock_irqrestore(&sb->mixer_lock, flags); | ||
302 | oval >>= 6; | ||
303 | if (oval > 2) | ||
304 | oval = 2; | ||
305 | |||
306 | ucontrol->value.enumerated.item[0] = oval; | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol, | ||
311 | struct snd_ctl_elem_value *ucontrol) | ||
312 | { | ||
313 | struct snd_sb *sb = snd_kcontrol_chip(kcontrol); | ||
314 | unsigned long flags; | ||
315 | int change; | ||
316 | unsigned char nval, oval; | ||
317 | |||
318 | if (ucontrol->value.enumerated.item[0] > 2) | ||
319 | return -EINVAL; | ||
320 | spin_lock_irqsave(&sb->mixer_lock, flags); | ||
321 | oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL); | ||
322 | |||
323 | nval = (oval & ~(3 << 6)) | ||
324 | | (ucontrol->value.enumerated.item[0] << 6); | ||
325 | change = nval != oval; | ||
326 | if (change) | ||
327 | snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval); | ||
328 | spin_unlock_irqrestore(&sb->mixer_lock, flags); | ||
329 | return change; | ||
330 | } | ||
331 | |||
332 | /* | ||
272 | * SBPRO input multiplexer | 333 | * SBPRO input multiplexer |
273 | */ | 334 | */ |
274 | 335 | ||
275 | static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 336 | static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
276 | { | 337 | { |
277 | static char *texts[3] = { | 338 | static const char *texts[3] = { |
278 | "Mic", "CD", "Line" | 339 | "Mic", "CD", "Line" |
279 | }; | 340 | }; |
280 | 341 | ||
@@ -442,6 +503,12 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty | |||
442 | .get = snd_dt019x_input_sw_get, | 503 | .get = snd_dt019x_input_sw_get, |
443 | .put = snd_dt019x_input_sw_put, | 504 | .put = snd_dt019x_input_sw_put, |
444 | }, | 505 | }, |
506 | [SB_MIX_MONO_CAPTURE_ALS4K] = { | ||
507 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
508 | .info = snd_als4k_mono_capture_route_info, | ||
509 | .get = snd_als4k_mono_capture_route_get, | ||
510 | .put = snd_als4k_mono_capture_route_put, | ||
511 | }, | ||
445 | }; | 512 | }; |
446 | struct snd_kcontrol *ctl; | 513 | struct snd_kcontrol *ctl; |
447 | int err; | 514 | int err; |
@@ -636,6 +703,8 @@ static struct sbmix_elem snd_dt019x_ctl_capture_source = | |||
636 | }; | 703 | }; |
637 | 704 | ||
638 | static struct sbmix_elem *snd_dt019x_controls[] = { | 705 | static struct sbmix_elem *snd_dt019x_controls[] = { |
706 | /* ALS4000 below has some parts which we might be lacking, | ||
707 | * e.g. snd_als4000_ctl_mono_playback_switch - check it! */ | ||
639 | &snd_dt019x_ctl_master_play_vol, | 708 | &snd_dt019x_ctl_master_play_vol, |
640 | &snd_dt019x_ctl_pcm_play_vol, | 709 | &snd_dt019x_ctl_pcm_play_vol, |
641 | &snd_dt019x_ctl_synth_play_vol, | 710 | &snd_dt019x_ctl_synth_play_vol, |
@@ -666,18 +735,21 @@ static unsigned char snd_dt019x_init_values[][2] = { | |||
666 | /* | 735 | /* |
667 | * ALS4000 specific mixer elements | 736 | * ALS4000 specific mixer elements |
668 | */ | 737 | */ |
669 | /* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl! */ | ||
670 | static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch = | 738 | static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch = |
671 | SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); | 739 | SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); |
672 | static struct sbmix_elem snd_als4000_ctl_master_mono_capture_route = | 740 | static struct sbmix_elem snd_als4k_ctl_master_mono_capture_route = { |
673 | SB_SINGLE("Master Mono Capture Route", SB_ALS4000_MONO_IO_CTRL, 6, 0x03); | 741 | .name = "Master Mono Capture Route", |
674 | /* FIXME: mono playback switch also available on DT019X? */ | 742 | .type = SB_MIX_MONO_CAPTURE_ALS4K |
743 | }; | ||
675 | static struct sbmix_elem snd_als4000_ctl_mono_playback_switch = | 744 | static struct sbmix_elem snd_als4000_ctl_mono_playback_switch = |
676 | SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1); | 745 | SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1); |
677 | static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = | 746 | static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = |
678 | SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03); | 747 | SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03); |
679 | static struct sbmix_elem snd_als4000_ctl_mixer_loopback = | 748 | static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback = |
680 | SB_SINGLE("Analog Loopback", SB_ALS4000_MIC_IN_GAIN, 7, 0x01); | 749 | SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01); |
750 | static struct sbmix_elem snd_als4000_ctl_mixer_digital_loopback = | ||
751 | SB_SINGLE("Digital Loopback Switch", | ||
752 | SB_ALS4000_CR3_CONFIGURATION, 7, 0x01); | ||
681 | /* FIXME: functionality of 3D controls might be swapped, I didn't find | 753 | /* FIXME: functionality of 3D controls might be swapped, I didn't find |
682 | * a description of how to identify what is supposed to be what */ | 754 | * a description of how to identify what is supposed to be what */ |
683 | static struct sbmix_elem snd_als4000_3d_control_switch = | 755 | static struct sbmix_elem snd_als4000_3d_control_switch = |
@@ -694,6 +766,9 @@ static struct sbmix_elem snd_als4000_3d_control_delay = | |||
694 | SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); | 766 | SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); |
695 | static struct sbmix_elem snd_als4000_3d_control_poweroff_switch = | 767 | static struct sbmix_elem snd_als4000_3d_control_poweroff_switch = |
696 | SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01); | 768 | SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01); |
769 | static struct sbmix_elem snd_als4000_ctl_3db_freq_control_switch = | ||
770 | SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch", | ||
771 | SB_ALS4000_FMDAC, 5, 0x01); | ||
697 | #ifdef NOT_AVAILABLE | 772 | #ifdef NOT_AVAILABLE |
698 | static struct sbmix_elem snd_als4000_ctl_fmdac = | 773 | static struct sbmix_elem snd_als4000_ctl_fmdac = |
699 | SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); | 774 | SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); |
@@ -702,35 +777,37 @@ static struct sbmix_elem snd_als4000_ctl_qsound = | |||
702 | #endif | 777 | #endif |
703 | 778 | ||
704 | static struct sbmix_elem *snd_als4000_controls[] = { | 779 | static struct sbmix_elem *snd_als4000_controls[] = { |
705 | &snd_sb16_ctl_master_play_vol, | 780 | /* ALS4000a.PDF regs page */ |
706 | &snd_dt019x_ctl_pcm_play_switch, | 781 | &snd_sb16_ctl_master_play_vol, /* MX30/31 12 */ |
707 | &snd_sb16_ctl_pcm_play_vol, | 782 | &snd_dt019x_ctl_pcm_play_switch, /* MX4C 16 */ |
708 | &snd_sb16_ctl_synth_capture_route, | 783 | &snd_sb16_ctl_pcm_play_vol, /* MX32/33 12 */ |
709 | &snd_dt019x_ctl_synth_play_switch, | 784 | &snd_sb16_ctl_synth_capture_route, /* MX3D/3E 14 */ |
710 | &snd_sb16_ctl_synth_play_vol, | 785 | &snd_dt019x_ctl_synth_play_switch, /* MX4C 16 */ |
711 | &snd_sb16_ctl_cd_capture_route, | 786 | &snd_sb16_ctl_synth_play_vol, /* MX34/35 12/13 */ |
712 | &snd_sb16_ctl_cd_play_switch, | 787 | &snd_sb16_ctl_cd_capture_route, /* MX3D/3E 14 */ |
713 | &snd_sb16_ctl_cd_play_vol, | 788 | &snd_sb16_ctl_cd_play_switch, /* MX3C 14 */ |
714 | &snd_sb16_ctl_line_capture_route, | 789 | &snd_sb16_ctl_cd_play_vol, /* MX36/37 13 */ |
715 | &snd_sb16_ctl_line_play_switch, | 790 | &snd_sb16_ctl_line_capture_route, /* MX3D/3E 14 */ |
716 | &snd_sb16_ctl_line_play_vol, | 791 | &snd_sb16_ctl_line_play_switch, /* MX3C 14 */ |
717 | &snd_sb16_ctl_mic_capture_route, | 792 | &snd_sb16_ctl_line_play_vol, /* MX38/39 13 */ |
718 | &snd_als4000_ctl_mic_20db_boost, | 793 | &snd_sb16_ctl_mic_capture_route, /* MX3D/3E 14 */ |
719 | &snd_sb16_ctl_auto_mic_gain, | 794 | &snd_als4000_ctl_mic_20db_boost, /* MX4D 16 */ |
720 | &snd_sb16_ctl_mic_play_switch, | 795 | &snd_sb16_ctl_mic_play_switch, /* MX3C 14 */ |
721 | &snd_sb16_ctl_mic_play_vol, | 796 | &snd_sb16_ctl_mic_play_vol, /* MX3A 13 */ |
722 | &snd_sb16_ctl_pc_speaker_vol, | 797 | &snd_sb16_ctl_pc_speaker_vol, /* MX3B 14 */ |
723 | &snd_sb16_ctl_capture_vol, | 798 | &snd_sb16_ctl_capture_vol, /* MX3F/40 15 */ |
724 | &snd_sb16_ctl_play_vol, | 799 | &snd_sb16_ctl_play_vol, /* MX41/42 15 */ |
725 | &snd_als4000_ctl_master_mono_playback_switch, | 800 | &snd_als4000_ctl_master_mono_playback_switch, /* MX4C 16 */ |
726 | &snd_als4000_ctl_master_mono_capture_route, | 801 | &snd_als4k_ctl_master_mono_capture_route, /* MX4B 16 */ |
727 | &snd_als4000_ctl_mono_playback_switch, | 802 | &snd_als4000_ctl_mono_playback_switch, /* MX4C 16 */ |
728 | &snd_als4000_ctl_mixer_loopback, | 803 | &snd_als4000_ctl_mixer_analog_loopback, /* MX4D 16 */ |
729 | &snd_als4000_3d_control_switch, | 804 | &snd_als4000_ctl_mixer_digital_loopback, /* CR3 21 */ |
730 | &snd_als4000_3d_control_ratio, | 805 | &snd_als4000_3d_control_switch, /* MX50 17 */ |
731 | &snd_als4000_3d_control_freq, | 806 | &snd_als4000_3d_control_ratio, /* MX50 17 */ |
732 | &snd_als4000_3d_control_delay, | 807 | &snd_als4000_3d_control_freq, /* MX50 17 */ |
733 | &snd_als4000_3d_control_poweroff_switch, | 808 | &snd_als4000_3d_control_delay, /* MX51 18 */ |
809 | &snd_als4000_3d_control_poweroff_switch, /* MX51 18 */ | ||
810 | &snd_als4000_ctl_3db_freq_control_switch, /* MX4F 17 */ | ||
734 | #ifdef NOT_AVAILABLE | 811 | #ifdef NOT_AVAILABLE |
735 | &snd_als4000_ctl_fmdac, | 812 | &snd_als4000_ctl_fmdac, |
736 | &snd_als4000_ctl_qsound, | 813 | &snd_als4000_ctl_qsound, |
@@ -905,13 +982,14 @@ static unsigned char dt019x_saved_regs[] = { | |||
905 | }; | 982 | }; |
906 | 983 | ||
907 | static unsigned char als4000_saved_regs[] = { | 984 | static unsigned char als4000_saved_regs[] = { |
985 | /* please verify in dsheet whether regs to be added | ||
986 | are actually real H/W or just dummy */ | ||
908 | SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1, | 987 | SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1, |
909 | SB_DSP4_OUTPUT_SW, | 988 | SB_DSP4_OUTPUT_SW, |
910 | SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1, | 989 | SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1, |
911 | SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, | 990 | SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, |
912 | SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1, | 991 | SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1, |
913 | SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1, | 992 | SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1, |
914 | SB_DSP4_MIC_AGC, | ||
915 | SB_DSP4_MIC_DEV, | 993 | SB_DSP4_MIC_DEV, |
916 | SB_DSP4_SPEAKER_DEV, | 994 | SB_DSP4_SPEAKER_DEV, |
917 | SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1, | 995 | SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1, |
@@ -919,8 +997,10 @@ static unsigned char als4000_saved_regs[] = { | |||
919 | SB_DT019X_OUTPUT_SW2, | 997 | SB_DT019X_OUTPUT_SW2, |
920 | SB_ALS4000_MONO_IO_CTRL, | 998 | SB_ALS4000_MONO_IO_CTRL, |
921 | SB_ALS4000_MIC_IN_GAIN, | 999 | SB_ALS4000_MIC_IN_GAIN, |
1000 | SB_ALS4000_FMDAC, | ||
922 | SB_ALS4000_3D_SND_FX, | 1001 | SB_ALS4000_3D_SND_FX, |
923 | SB_ALS4000_3D_TIME_DELAY, | 1002 | SB_ALS4000_3D_TIME_DELAY, |
1003 | SB_ALS4000_CR3_CONFIGURATION, | ||
924 | }; | 1004 | }; |
925 | 1005 | ||
926 | static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) | 1006 | static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) |
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index ca35924dc3b3..782010608ef4 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c | |||
@@ -489,9 +489,9 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) | |||
489 | char __iomem *vmss_port; | 489 | char __iomem *vmss_port; |
490 | 490 | ||
491 | 491 | ||
492 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 492 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
493 | if (!card) | 493 | if (err < 0) |
494 | return -ENOMEM; | 494 | return err; |
495 | 495 | ||
496 | if (xirq == SNDRV_AUTO_IRQ) { | 496 | if (xirq == SNDRV_AUTO_IRQ) { |
497 | xirq = snd_legacy_find_free_irq(possible_irqs); | 497 | xirq = snd_legacy_find_free_irq(possible_irqs); |
@@ -576,10 +576,6 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) | |||
576 | snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n", | 576 | snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n", |
577 | 0x388, 0x388 + 2); | 577 | 0x388, 0x388 + 2); |
578 | } else { | 578 | } else { |
579 | err = snd_opl3_timer_new(opl3, 0, 1); | ||
580 | if (err < 0) | ||
581 | goto err_unmap2; | ||
582 | |||
583 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | 579 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); |
584 | if (err < 0) | 580 | if (err < 0) |
585 | goto err_unmap2; | 581 | goto err_unmap2; |
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 2c7503bf1271..6fe27b9d9440 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c | |||
@@ -243,9 +243,9 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) | |||
243 | struct snd_card *card; | 243 | struct snd_card *card; |
244 | struct snd_wss *chip; | 244 | struct snd_wss *chip; |
245 | 245 | ||
246 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 246 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
247 | if (card == NULL) | 247 | if (err < 0) |
248 | return -ENOMEM; | 248 | return err; |
249 | 249 | ||
250 | xirq = irq[dev]; | 250 | xirq = irq[dev]; |
251 | if (xirq == SNDRV_AUTO_IRQ) { | 251 | if (xirq == SNDRV_AUTO_IRQ) { |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 33c1258029f9..66187122377c 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -1244,10 +1244,10 @@ static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) | |||
1244 | struct soundscape *sscape; | 1244 | struct soundscape *sscape; |
1245 | int ret; | 1245 | int ret; |
1246 | 1246 | ||
1247 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 1247 | ret = snd_card_create(index[dev], id[dev], THIS_MODULE, |
1248 | sizeof(struct soundscape)); | 1248 | sizeof(struct soundscape), &card); |
1249 | if (!card) | 1249 | if (ret < 0) |
1250 | return -ENOMEM; | 1250 | return ret; |
1251 | 1251 | ||
1252 | sscape = get_card_soundscape(card); | 1252 | sscape = get_card_soundscape(card); |
1253 | sscape->type = SSCAPE; | 1253 | sscape->type = SSCAPE; |
@@ -1349,10 +1349,10 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard, | |||
1349 | * Create a new ALSA sound card entry, in anticipation | 1349 | * Create a new ALSA sound card entry, in anticipation |
1350 | * of detecting our hardware ... | 1350 | * of detecting our hardware ... |
1351 | */ | 1351 | */ |
1352 | card = snd_card_new(index[idx], id[idx], THIS_MODULE, | 1352 | ret = snd_card_create(index[idx], id[idx], THIS_MODULE, |
1353 | sizeof(struct soundscape)); | 1353 | sizeof(struct soundscape), &card); |
1354 | if (!card) | 1354 | if (ret < 0) |
1355 | return -ENOMEM; | 1355 | return ret; |
1356 | 1356 | ||
1357 | sscape = get_card_soundscape(card); | 1357 | sscape = get_card_soundscape(card); |
1358 | 1358 | ||
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 4c095bc7c729..a34ae7b1f7d0 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c | |||
@@ -338,15 +338,16 @@ snd_wavefront_free(struct snd_card *card) | |||
338 | } | 338 | } |
339 | } | 339 | } |
340 | 340 | ||
341 | static struct snd_card *snd_wavefront_card_new(int dev) | 341 | static int snd_wavefront_card_new(int dev, struct snd_card **cardp) |
342 | { | 342 | { |
343 | struct snd_card *card; | 343 | struct snd_card *card; |
344 | snd_wavefront_card_t *acard; | 344 | snd_wavefront_card_t *acard; |
345 | int err; | ||
345 | 346 | ||
346 | card = snd_card_new (index[dev], id[dev], THIS_MODULE, | 347 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
347 | sizeof(snd_wavefront_card_t)); | 348 | sizeof(snd_wavefront_card_t), &card); |
348 | if (card == NULL) | 349 | if (err < 0) |
349 | return NULL; | 350 | return err; |
350 | 351 | ||
351 | acard = card->private_data; | 352 | acard = card->private_data; |
352 | acard->wavefront.irq = -1; | 353 | acard->wavefront.irq = -1; |
@@ -357,7 +358,8 @@ static struct snd_card *snd_wavefront_card_new(int dev) | |||
357 | acard->wavefront.card = card; | 358 | acard->wavefront.card = card; |
358 | card->private_free = snd_wavefront_free; | 359 | card->private_free = snd_wavefront_free; |
359 | 360 | ||
360 | return card; | 361 | *cardp = card; |
362 | return 0; | ||
361 | } | 363 | } |
362 | 364 | ||
363 | static int __devinit | 365 | static int __devinit |
@@ -551,11 +553,11 @@ static int __devinit snd_wavefront_isa_match(struct device *pdev, | |||
551 | return 0; | 553 | return 0; |
552 | #endif | 554 | #endif |
553 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { | 555 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { |
554 | snd_printk("specify CS4232 port\n"); | 556 | snd_printk(KERN_ERR "specify CS4232 port\n"); |
555 | return 0; | 557 | return 0; |
556 | } | 558 | } |
557 | if (ics2115_port[dev] == SNDRV_AUTO_PORT) { | 559 | if (ics2115_port[dev] == SNDRV_AUTO_PORT) { |
558 | snd_printk("specify ICS2115 port\n"); | 560 | snd_printk(KERN_ERR "specify ICS2115 port\n"); |
559 | return 0; | 561 | return 0; |
560 | } | 562 | } |
561 | return 1; | 563 | return 1; |
@@ -567,9 +569,9 @@ static int __devinit snd_wavefront_isa_probe(struct device *pdev, | |||
567 | struct snd_card *card; | 569 | struct snd_card *card; |
568 | int err; | 570 | int err; |
569 | 571 | ||
570 | card = snd_wavefront_card_new(dev); | 572 | err = snd_wavefront_card_new(dev, &card); |
571 | if (! card) | 573 | if (err < 0) |
572 | return -ENOMEM; | 574 | return err; |
573 | snd_card_set_dev(card, pdev); | 575 | snd_card_set_dev(card, pdev); |
574 | if ((err = snd_wavefront_probe(card, dev)) < 0) { | 576 | if ((err = snd_wavefront_probe(card, dev)) < 0) { |
575 | snd_card_free(card); | 577 | snd_card_free(card); |
@@ -616,9 +618,9 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, | |||
616 | if (dev >= SNDRV_CARDS) | 618 | if (dev >= SNDRV_CARDS) |
617 | return -ENODEV; | 619 | return -ENODEV; |
618 | 620 | ||
619 | card = snd_wavefront_card_new(dev); | 621 | res = snd_wavefront_card_new(dev, &card); |
620 | if (! card) | 622 | if (res < 0) |
621 | return -ENOMEM; | 623 | return res; |
622 | 624 | ||
623 | if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) { | 625 | if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) { |
624 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { | 626 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { |
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 4c410820a994..beb312cca75b 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c | |||
@@ -633,7 +633,7 @@ wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom) | |||
633 | wbuf[1] = i >> 7; | 633 | wbuf[1] = i >> 7; |
634 | 634 | ||
635 | if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) { | 635 | if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) { |
636 | snd_printk("cannot identify sample " | 636 | snd_printk(KERN_WARNING "cannot identify sample " |
637 | "type of slot %d\n", i); | 637 | "type of slot %d\n", i); |
638 | dev->sample_status[i] = WF_ST_EMPTY; | 638 | dev->sample_status[i] = WF_ST_EMPTY; |
639 | continue; | 639 | continue; |
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index f0c0be5bb684..5d2ba1b749ab 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -200,7 +200,8 @@ void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value) | |||
200 | snd_wss_wait(chip); | 200 | snd_wss_wait(chip); |
201 | #ifdef CONFIG_SND_DEBUG | 201 | #ifdef CONFIG_SND_DEBUG |
202 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) | 202 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) |
203 | snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | 203 | snd_printk(KERN_DEBUG "out: auto calibration time out " |
204 | "- reg = 0x%x, value = 0x%x\n", reg, value); | ||
204 | #endif | 205 | #endif |
205 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); | 206 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); |
206 | wss_outb(chip, CS4231P(REG), value); | 207 | wss_outb(chip, CS4231P(REG), value); |
@@ -216,7 +217,8 @@ unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg) | |||
216 | snd_wss_wait(chip); | 217 | snd_wss_wait(chip); |
217 | #ifdef CONFIG_SND_DEBUG | 218 | #ifdef CONFIG_SND_DEBUG |
218 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) | 219 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) |
219 | snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); | 220 | snd_printk(KERN_DEBUG "in: auto calibration time out " |
221 | "- reg = 0x%x\n", reg); | ||
220 | #endif | 222 | #endif |
221 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); | 223 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); |
222 | mb(); | 224 | mb(); |
@@ -233,7 +235,7 @@ void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg, | |||
233 | wss_outb(chip, CS4231P(REG), val); | 235 | wss_outb(chip, CS4231P(REG), val); |
234 | chip->eimage[CS4236_REG(reg)] = val; | 236 | chip->eimage[CS4236_REG(reg)] = val; |
235 | #if 0 | 237 | #if 0 |
236 | printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val); | 238 | printk(KERN_DEBUG "ext out : reg = 0x%x, val = 0x%x\n", reg, val); |
237 | #endif | 239 | #endif |
238 | } | 240 | } |
239 | EXPORT_SYMBOL(snd_cs4236_ext_out); | 241 | EXPORT_SYMBOL(snd_cs4236_ext_out); |
@@ -249,7 +251,8 @@ unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg) | |||
249 | { | 251 | { |
250 | unsigned char res; | 252 | unsigned char res; |
251 | res = wss_inb(chip, CS4231P(REG)); | 253 | res = wss_inb(chip, CS4231P(REG)); |
252 | printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res); | 254 | printk(KERN_DEBUG "ext in : reg = 0x%x, val = 0x%x\n", |
255 | reg, res); | ||
253 | return res; | 256 | return res; |
254 | } | 257 | } |
255 | #endif | 258 | #endif |
@@ -375,13 +378,16 @@ void snd_wss_mce_up(struct snd_wss *chip) | |||
375 | snd_wss_wait(chip); | 378 | snd_wss_wait(chip); |
376 | #ifdef CONFIG_SND_DEBUG | 379 | #ifdef CONFIG_SND_DEBUG |
377 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) | 380 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) |
378 | snd_printk("mce_up - auto calibration time out (0)\n"); | 381 | snd_printk(KERN_DEBUG |
382 | "mce_up - auto calibration time out (0)\n"); | ||
379 | #endif | 383 | #endif |
380 | spin_lock_irqsave(&chip->reg_lock, flags); | 384 | spin_lock_irqsave(&chip->reg_lock, flags); |
381 | chip->mce_bit |= CS4231_MCE; | 385 | chip->mce_bit |= CS4231_MCE; |
382 | timeout = wss_inb(chip, CS4231P(REGSEL)); | 386 | timeout = wss_inb(chip, CS4231P(REGSEL)); |
383 | if (timeout == 0x80) | 387 | if (timeout == 0x80) |
384 | snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); | 388 | snd_printk(KERN_DEBUG "mce_up [0x%lx]: " |
389 | "serious init problem - codec still busy\n", | ||
390 | chip->port); | ||
385 | if (!(timeout & CS4231_MCE)) | 391 | if (!(timeout & CS4231_MCE)) |
386 | wss_outb(chip, CS4231P(REGSEL), | 392 | wss_outb(chip, CS4231P(REGSEL), |
387 | chip->mce_bit | (timeout & 0x1f)); | 393 | chip->mce_bit | (timeout & 0x1f)); |
@@ -400,7 +406,9 @@ void snd_wss_mce_down(struct snd_wss *chip) | |||
400 | 406 | ||
401 | #ifdef CONFIG_SND_DEBUG | 407 | #ifdef CONFIG_SND_DEBUG |
402 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) | 408 | if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) |
403 | snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); | 409 | snd_printk(KERN_DEBUG "mce_down [0x%lx] - " |
410 | "auto calibration time out (0)\n", | ||
411 | (long)CS4231P(REGSEL)); | ||
404 | #endif | 412 | #endif |
405 | spin_lock_irqsave(&chip->reg_lock, flags); | 413 | spin_lock_irqsave(&chip->reg_lock, flags); |
406 | chip->mce_bit &= ~CS4231_MCE; | 414 | chip->mce_bit &= ~CS4231_MCE; |
@@ -408,7 +416,9 @@ void snd_wss_mce_down(struct snd_wss *chip) | |||
408 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); | 416 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); |
409 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 417 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
410 | if (timeout == 0x80) | 418 | if (timeout == 0x80) |
411 | snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); | 419 | snd_printk(KERN_DEBUG "mce_down [0x%lx]: " |
420 | "serious init problem - codec still busy\n", | ||
421 | chip->port); | ||
412 | if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask)) | 422 | if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask)) |
413 | return; | 423 | return; |
414 | 424 | ||
@@ -546,7 +556,7 @@ static unsigned char snd_wss_get_format(struct snd_wss *chip, | |||
546 | if (channels > 1) | 556 | if (channels > 1) |
547 | rformat |= CS4231_STEREO; | 557 | rformat |= CS4231_STEREO; |
548 | #if 0 | 558 | #if 0 |
549 | snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode); | 559 | snd_printk(KERN_DEBUG "get_format: 0x%x (mode=0x%x)\n", format, mode); |
550 | #endif | 560 | #endif |
551 | return rformat; | 561 | return rformat; |
552 | } | 562 | } |
@@ -796,7 +806,7 @@ static void snd_wss_init(struct snd_wss *chip) | |||
796 | snd_wss_mce_down(chip); | 806 | snd_wss_mce_down(chip); |
797 | 807 | ||
798 | #ifdef SNDRV_DEBUG_MCE | 808 | #ifdef SNDRV_DEBUG_MCE |
799 | snd_printk("init: (1)\n"); | 809 | snd_printk(KERN_DEBUG "init: (1)\n"); |
800 | #endif | 810 | #endif |
801 | snd_wss_mce_up(chip); | 811 | snd_wss_mce_up(chip); |
802 | spin_lock_irqsave(&chip->reg_lock, flags); | 812 | spin_lock_irqsave(&chip->reg_lock, flags); |
@@ -811,7 +821,7 @@ static void snd_wss_init(struct snd_wss *chip) | |||
811 | snd_wss_mce_down(chip); | 821 | snd_wss_mce_down(chip); |
812 | 822 | ||
813 | #ifdef SNDRV_DEBUG_MCE | 823 | #ifdef SNDRV_DEBUG_MCE |
814 | snd_printk("init: (2)\n"); | 824 | snd_printk(KERN_DEBUG "init: (2)\n"); |
815 | #endif | 825 | #endif |
816 | 826 | ||
817 | snd_wss_mce_up(chip); | 827 | snd_wss_mce_up(chip); |
@@ -824,7 +834,7 @@ static void snd_wss_init(struct snd_wss *chip) | |||
824 | snd_wss_mce_down(chip); | 834 | snd_wss_mce_down(chip); |
825 | 835 | ||
826 | #ifdef SNDRV_DEBUG_MCE | 836 | #ifdef SNDRV_DEBUG_MCE |
827 | snd_printk("init: (3) - afei = 0x%x\n", | 837 | snd_printk(KERN_DEBUG "init: (3) - afei = 0x%x\n", |
828 | chip->image[CS4231_ALT_FEATURE_1]); | 838 | chip->image[CS4231_ALT_FEATURE_1]); |
829 | #endif | 839 | #endif |
830 | 840 | ||
@@ -841,7 +851,7 @@ static void snd_wss_init(struct snd_wss *chip) | |||
841 | snd_wss_mce_down(chip); | 851 | snd_wss_mce_down(chip); |
842 | 852 | ||
843 | #ifdef SNDRV_DEBUG_MCE | 853 | #ifdef SNDRV_DEBUG_MCE |
844 | snd_printk("init: (4)\n"); | 854 | snd_printk(KERN_DEBUG "init: (4)\n"); |
845 | #endif | 855 | #endif |
846 | 856 | ||
847 | snd_wss_mce_up(chip); | 857 | snd_wss_mce_up(chip); |
@@ -854,7 +864,7 @@ static void snd_wss_init(struct snd_wss *chip) | |||
854 | snd_wss_calibrate_mute(chip, 0); | 864 | snd_wss_calibrate_mute(chip, 0); |
855 | 865 | ||
856 | #ifdef SNDRV_DEBUG_MCE | 866 | #ifdef SNDRV_DEBUG_MCE |
857 | snd_printk("init: (5)\n"); | 867 | snd_printk(KERN_DEBUG "init: (5)\n"); |
858 | #endif | 868 | #endif |
859 | } | 869 | } |
860 | 870 | ||
@@ -1299,7 +1309,8 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1299 | } else if (rev == 0x03) { | 1309 | } else if (rev == 0x03) { |
1300 | chip->hardware = WSS_HW_CS4236B; | 1310 | chip->hardware = WSS_HW_CS4236B; |
1301 | } else { | 1311 | } else { |
1302 | snd_printk("unknown CS chip with version 0x%x\n", rev); | 1312 | snd_printk(KERN_ERR |
1313 | "unknown CS chip with version 0x%x\n", rev); | ||
1303 | return -ENODEV; /* unknown CS4231 chip? */ | 1314 | return -ENODEV; /* unknown CS4231 chip? */ |
1304 | } | 1315 | } |
1305 | } | 1316 | } |
@@ -1367,7 +1378,10 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1367 | case 6: | 1378 | case 6: |
1368 | break; | 1379 | break; |
1369 | default: | 1380 | default: |
1370 | snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id); | 1381 | snd_printk(KERN_WARNING |
1382 | "unknown CS4235 chip " | ||
1383 | "(enhanced version = 0x%x)\n", | ||
1384 | id); | ||
1371 | } | 1385 | } |
1372 | } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */ | 1386 | } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */ |
1373 | switch (id >> 5) { | 1387 | switch (id >> 5) { |
@@ -1378,7 +1392,10 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1378 | chip->hardware = WSS_HW_CS4236B; | 1392 | chip->hardware = WSS_HW_CS4236B; |
1379 | break; | 1393 | break; |
1380 | default: | 1394 | default: |
1381 | snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id); | 1395 | snd_printk(KERN_WARNING |
1396 | "unknown CS4236 chip " | ||
1397 | "(enhanced version = 0x%x)\n", | ||
1398 | id); | ||
1382 | } | 1399 | } |
1383 | } else if ((id & 0x1f) == 0x08) { /* CS4237B */ | 1400 | } else if ((id & 0x1f) == 0x08) { /* CS4237B */ |
1384 | chip->hardware = WSS_HW_CS4237B; | 1401 | chip->hardware = WSS_HW_CS4237B; |
@@ -1389,7 +1406,10 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1389 | case 7: | 1406 | case 7: |
1390 | break; | 1407 | break; |
1391 | default: | 1408 | default: |
1392 | snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id); | 1409 | snd_printk(KERN_WARNING |
1410 | "unknown CS4237B chip " | ||
1411 | "(enhanced version = 0x%x)\n", | ||
1412 | id); | ||
1393 | } | 1413 | } |
1394 | } else if ((id & 0x1f) == 0x09) { /* CS4238B */ | 1414 | } else if ((id & 0x1f) == 0x09) { /* CS4238B */ |
1395 | chip->hardware = WSS_HW_CS4238B; | 1415 | chip->hardware = WSS_HW_CS4238B; |
@@ -1399,7 +1419,10 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1399 | case 7: | 1419 | case 7: |
1400 | break; | 1420 | break; |
1401 | default: | 1421 | default: |
1402 | snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id); | 1422 | snd_printk(KERN_WARNING |
1423 | "unknown CS4238B chip " | ||
1424 | "(enhanced version = 0x%x)\n", | ||
1425 | id); | ||
1403 | } | 1426 | } |
1404 | } else if ((id & 0x1f) == 0x1e) { /* CS4239 */ | 1427 | } else if ((id & 0x1f) == 0x1e) { /* CS4239 */ |
1405 | chip->hardware = WSS_HW_CS4239; | 1428 | chip->hardware = WSS_HW_CS4239; |
@@ -1409,10 +1432,15 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1409 | case 6: | 1432 | case 6: |
1410 | break; | 1433 | break; |
1411 | default: | 1434 | default: |
1412 | snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id); | 1435 | snd_printk(KERN_WARNING |
1436 | "unknown CS4239 chip " | ||
1437 | "(enhanced version = 0x%x)\n", | ||
1438 | id); | ||
1413 | } | 1439 | } |
1414 | } else { | 1440 | } else { |
1415 | snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id); | 1441 | snd_printk(KERN_WARNING |
1442 | "unknown CS4236/CS423xB chip " | ||
1443 | "(enhanced version = 0x%x)\n", id); | ||
1416 | } | 1444 | } |
1417 | } | 1445 | } |
1418 | } | 1446 | } |
@@ -1643,7 +1671,8 @@ static void snd_wss_resume(struct snd_wss *chip) | |||
1643 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); | 1671 | wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); |
1644 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1672 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1645 | if (timeout == 0x80) | 1673 | if (timeout == 0x80) |
1646 | snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); | 1674 | snd_printk(KERN_ERR "down [0x%lx]: serious init problem " |
1675 | "- codec still busy\n", chip->port); | ||
1647 | if ((timeout & CS4231_MCE) == 0 || | 1676 | if ((timeout & CS4231_MCE) == 0 || |
1648 | !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) { | 1677 | !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) { |
1649 | return; | 1678 | return; |
@@ -1653,7 +1682,7 @@ static void snd_wss_resume(struct snd_wss *chip) | |||
1653 | } | 1682 | } |
1654 | #endif /* CONFIG_PM */ | 1683 | #endif /* CONFIG_PM */ |
1655 | 1684 | ||
1656 | static int snd_wss_free(struct snd_wss *chip) | 1685 | int snd_wss_free(struct snd_wss *chip) |
1657 | { | 1686 | { |
1658 | release_and_free_resource(chip->res_port); | 1687 | release_and_free_resource(chip->res_port); |
1659 | release_and_free_resource(chip->res_cport); | 1688 | release_and_free_resource(chip->res_cport); |
@@ -1676,6 +1705,7 @@ static int snd_wss_free(struct snd_wss *chip) | |||
1676 | kfree(chip); | 1705 | kfree(chip); |
1677 | return 0; | 1706 | return 0; |
1678 | } | 1707 | } |
1708 | EXPORT_SYMBOL(snd_wss_free); | ||
1679 | 1709 | ||
1680 | static int snd_wss_dev_free(struct snd_device *device) | 1710 | static int snd_wss_dev_free(struct snd_device *device) |
1681 | { | 1711 | { |
@@ -1845,7 +1875,8 @@ int snd_wss_create(struct snd_card *card, | |||
1845 | #if 0 | 1875 | #if 0 |
1846 | if (chip->hardware & WSS_HW_CS4232_MASK) { | 1876 | if (chip->hardware & WSS_HW_CS4232_MASK) { |
1847 | if (chip->res_cport == NULL) | 1877 | if (chip->res_cport == NULL) |
1848 | snd_printk("CS4232 control port features are not accessible\n"); | 1878 | snd_printk(KERN_ERR "CS4232 control port features are " |
1879 | "not accessible\n"); | ||
1849 | } | 1880 | } |
1850 | #endif | 1881 | #endif |
1851 | 1882 | ||