diff options
author | Jaroslav Kysela <perex@perex.cz> | 2010-02-16 05:25:03 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2010-02-16 05:25:03 -0500 |
commit | b8f1f5983fbe751aa3d07d9ce7ebb0c23bf4b7e4 (patch) | |
tree | e9f11863f683a9f4eb03d76008740a36d6b4ff3c /sound/isa/sb | |
parent | ba9341dfef6b0201cd30e3904dcd0a47d3dc35e0 (diff) | |
parent | 47b5d028fdce8f809bf22852ac900338fb90e8aa (diff) |
Merge branch 'topic/misc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6 into devel
Diffstat (limited to 'sound/isa/sb')
-rw-r--r-- | sound/isa/sb/Makefile | 2 | ||||
-rw-r--r-- | sound/isa/sb/jazz16.c | 404 | ||||
-rw-r--r-- | sound/isa/sb/sb8_main.c | 118 | ||||
-rw-r--r-- | sound/isa/sb/sb_common.c | 3 | ||||
-rw-r--r-- | sound/isa/sb/sb_mixer.c | 333 |
5 files changed, 629 insertions, 231 deletions
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index faeffceb01b7..af3669681788 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile | |||
@@ -12,6 +12,7 @@ snd-sb16-objs := sb16.o | |||
12 | snd-sbawe-objs := sbawe.o emu8000.o | 12 | snd-sbawe-objs := sbawe.o emu8000.o |
13 | snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o | 13 | snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o |
14 | snd-es968-objs := es968.o | 14 | snd-es968-objs := es968.o |
15 | snd-jazz16-objs := jazz16.o | ||
15 | 16 | ||
16 | # Toplevel Module Dependency | 17 | # Toplevel Module Dependency |
17 | obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o | 18 | obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o |
@@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SB8) += snd-sb8.o | |||
21 | obj-$(CONFIG_SND_SB16) += snd-sb16.o | 22 | obj-$(CONFIG_SND_SB16) += snd-sb16.o |
22 | obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o | 23 | obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o |
23 | obj-$(CONFIG_SND_ES968) += snd-es968.o | 24 | obj-$(CONFIG_SND_ES968) += snd-es968.o |
25 | obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o | ||
24 | ifeq ($(CONFIG_SND_SB16_CSP),y) | 26 | ifeq ($(CONFIG_SND_SB16_CSP),y) |
25 | obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o | 27 | obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o |
26 | obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o | 28 | obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o |
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c new file mode 100644 index 000000000000..8d21a3feda3a --- /dev/null +++ b/sound/isa/sb/jazz16.c | |||
@@ -0,0 +1,404 @@ | |||
1 | |||
2 | /* | ||
3 | * jazz16.c - driver for Media Vision Jazz16 based soundcards. | ||
4 | * Copyright (C) 2009 Krzysztof Helt <krzysztof.h1@wp.pl> | ||
5 | * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman. | ||
6 | * Based on OSS Sound Blaster driver. | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file COPYING in the main directory of this archive for | ||
10 | * more details. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <asm/dma.h> | ||
18 | #include <linux/isa.h> | ||
19 | #include <sound/core.h> | ||
20 | #include <sound/mpu401.h> | ||
21 | #include <sound/opl3.h> | ||
22 | #include <sound/sb.h> | ||
23 | #define SNDRV_LEGACY_FIND_FREE_IRQ | ||
24 | #define SNDRV_LEGACY_FIND_FREE_DMA | ||
25 | #include <sound/initval.h> | ||
26 | |||
27 | #define PFX "jazz16: " | ||
28 | |||
29 | MODULE_DESCRIPTION("Media Vision Jazz16"); | ||
30 | MODULE_SUPPORTED_DEVICE("{{Media Vision ??? }," | ||
31 | "{RTL,RTL3000}}"); | ||
32 | |||
33 | MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
37 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
38 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ | ||
39 | static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
40 | static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | ||
41 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | ||
42 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | ||
43 | static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; | ||
44 | static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; | ||
45 | |||
46 | module_param_array(index, int, NULL, 0444); | ||
47 | MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard."); | ||
48 | module_param_array(id, charp, NULL, 0444); | ||
49 | MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard."); | ||
50 | module_param_array(enable, bool, NULL, 0444); | ||
51 | MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard."); | ||
52 | module_param_array(port, long, NULL, 0444); | ||
53 | MODULE_PARM_DESC(port, "Port # for jazz16 driver."); | ||
54 | module_param_array(mpu_port, long, NULL, 0444); | ||
55 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver."); | ||
56 | module_param_array(irq, int, NULL, 0444); | ||
57 | MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver."); | ||
58 | module_param_array(mpu_irq, int, NULL, 0444); | ||
59 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver."); | ||
60 | module_param_array(dma8, int, NULL, 0444); | ||
61 | MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver."); | ||
62 | module_param_array(dma16, int, NULL, 0444); | ||
63 | MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver."); | ||
64 | |||
65 | #define SB_JAZZ16_WAKEUP 0xaf | ||
66 | #define SB_JAZZ16_SET_PORTS 0x50 | ||
67 | #define SB_DSP_GET_JAZZ_BRD_REV 0xfa | ||
68 | #define SB_JAZZ16_SET_DMAINTR 0xfb | ||
69 | #define SB_DSP_GET_JAZZ_MODEL 0xfe | ||
70 | |||
71 | struct snd_card_jazz16 { | ||
72 | struct snd_sb *chip; | ||
73 | }; | ||
74 | |||
75 | static irqreturn_t jazz16_interrupt(int irq, void *chip) | ||
76 | { | ||
77 | return snd_sb8dsp_interrupt(chip); | ||
78 | } | ||
79 | |||
80 | static int __devinit jazz16_configure_ports(unsigned long port, | ||
81 | unsigned long mpu_port, int idx) | ||
82 | { | ||
83 | unsigned char val; | ||
84 | |||
85 | if (!request_region(0x201, 1, "jazz16 config")) { | ||
86 | snd_printk(KERN_ERR "config port region is already in use.\n"); | ||
87 | return -EBUSY; | ||
88 | } | ||
89 | outb(SB_JAZZ16_WAKEUP - idx, 0x201); | ||
90 | udelay(100); | ||
91 | outb(SB_JAZZ16_SET_PORTS + idx, 0x201); | ||
92 | udelay(100); | ||
93 | val = port & 0x70; | ||
94 | val |= (mpu_port & 0x30) >> 4; | ||
95 | outb(val, 0x201); | ||
96 | |||
97 | release_region(0x201, 1); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int __devinit jazz16_detect_board(unsigned long port, | ||
102 | unsigned long mpu_port) | ||
103 | { | ||
104 | int err; | ||
105 | int val; | ||
106 | struct snd_sb chip; | ||
107 | |||
108 | if (!request_region(port, 0x10, "jazz16")) { | ||
109 | snd_printk(KERN_ERR "I/O port region is already in use.\n"); | ||
110 | return -EBUSY; | ||
111 | } | ||
112 | /* just to call snd_sbdsp_command/reset/get_byte() */ | ||
113 | chip.port = port; | ||
114 | |||
115 | err = snd_sbdsp_reset(&chip); | ||
116 | if (err < 0) | ||
117 | for (val = 0; val < 4; val++) { | ||
118 | err = jazz16_configure_ports(port, mpu_port, val); | ||
119 | if (err < 0) | ||
120 | break; | ||
121 | |||
122 | err = snd_sbdsp_reset(&chip); | ||
123 | if (!err) | ||
124 | break; | ||
125 | } | ||
126 | if (err < 0) { | ||
127 | err = -ENODEV; | ||
128 | goto err_unmap; | ||
129 | } | ||
130 | if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) { | ||
131 | err = -EBUSY; | ||
132 | goto err_unmap; | ||
133 | } | ||
134 | val = snd_sbdsp_get_byte(&chip); | ||
135 | if (val >= 0x30) | ||
136 | snd_sbdsp_get_byte(&chip); | ||
137 | |||
138 | if ((val & 0xf0) != 0x10) { | ||
139 | err = -ENODEV; | ||
140 | goto err_unmap; | ||
141 | } | ||
142 | if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) { | ||
143 | err = -EBUSY; | ||
144 | goto err_unmap; | ||
145 | } | ||
146 | snd_sbdsp_get_byte(&chip); | ||
147 | err = snd_sbdsp_get_byte(&chip); | ||
148 | snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n", | ||
149 | val, err); | ||
150 | |||
151 | err = 0; | ||
152 | |||
153 | err_unmap: | ||
154 | release_region(port, 0x10); | ||
155 | return err; | ||
156 | } | ||
157 | |||
158 | static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq) | ||
159 | { | ||
160 | static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4, | ||
161 | 0, 2, 5, 0, 0, 0, 0, 6 }; | ||
162 | static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 }; | ||
163 | |||
164 | if (jazz_dma_bits[chip->dma8] == 0 || | ||
165 | jazz_dma_bits[chip->dma16] == 0 || | ||
166 | jazz_irq_bits[chip->irq] == 0) | ||
167 | return -EINVAL; | ||
168 | |||
169 | if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR)) | ||
170 | return -EBUSY; | ||
171 | |||
172 | if (!snd_sbdsp_command(chip, | ||
173 | jazz_dma_bits[chip->dma8] | | ||
174 | (jazz_dma_bits[chip->dma16] << 4))) | ||
175 | return -EBUSY; | ||
176 | |||
177 | if (!snd_sbdsp_command(chip, | ||
178 | jazz_irq_bits[chip->irq] | | ||
179 | (jazz_irq_bits[mpu_irq] << 4))) | ||
180 | return -EBUSY; | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev) | ||
186 | { | ||
187 | if (!enable[dev]) | ||
188 | return 0; | ||
189 | if (port[dev] == SNDRV_AUTO_PORT) { | ||
190 | snd_printk(KERN_ERR "please specify port\n"); | ||
191 | return 0; | ||
192 | } else if (port[dev] == 0x200 || (port[dev] & ~0x270)) { | ||
193 | snd_printk(KERN_ERR "incorrect port specified\n"); | ||
194 | return 0; | ||
195 | } | ||
196 | if (dma8[dev] != SNDRV_AUTO_DMA && | ||
197 | dma8[dev] != 1 && dma8[dev] != 3) { | ||
198 | snd_printk(KERN_ERR "dma8 must be 1 or 3\n"); | ||
199 | return 0; | ||
200 | } | ||
201 | if (dma16[dev] != SNDRV_AUTO_DMA && | ||
202 | dma16[dev] != 5 && dma16[dev] != 7) { | ||
203 | snd_printk(KERN_ERR "dma16 must be 5 or 7\n"); | ||
204 | return 0; | ||
205 | } | ||
206 | if (mpu_port[dev] != SNDRV_AUTO_PORT && | ||
207 | (mpu_port[dev] & ~0x030) != 0x300) { | ||
208 | snd_printk(KERN_ERR "incorrect mpu_port specified\n"); | ||
209 | return 0; | ||
210 | } | ||
211 | if (mpu_irq[dev] != SNDRV_AUTO_DMA && | ||
212 | mpu_irq[dev] != 2 && mpu_irq[dev] != 3 && | ||
213 | mpu_irq[dev] != 5 && mpu_irq[dev] != 7) { | ||
214 | snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n"); | ||
215 | return 0; | ||
216 | } | ||
217 | return 1; | ||
218 | } | ||
219 | |||
220 | static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev) | ||
221 | { | ||
222 | struct snd_card *card; | ||
223 | struct snd_card_jazz16 *jazz16; | ||
224 | struct snd_sb *chip; | ||
225 | struct snd_opl3 *opl3; | ||
226 | static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1}; | ||
227 | static int possible_dmas8[] = {1, 3, -1}; | ||
228 | static int possible_dmas16[] = {5, 7, -1}; | ||
229 | int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq; | ||
230 | |||
231 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, | ||
232 | sizeof(struct snd_card_jazz16), &card); | ||
233 | if (err < 0) | ||
234 | return err; | ||
235 | |||
236 | jazz16 = card->private_data; | ||
237 | |||
238 | xirq = irq[dev]; | ||
239 | if (xirq == SNDRV_AUTO_IRQ) { | ||
240 | xirq = snd_legacy_find_free_irq(possible_irqs); | ||
241 | if (xirq < 0) { | ||
242 | snd_printk(KERN_ERR "unable to find a free IRQ\n"); | ||
243 | err = -EBUSY; | ||
244 | goto err_free; | ||
245 | } | ||
246 | } | ||
247 | xdma8 = dma8[dev]; | ||
248 | if (xdma8 == SNDRV_AUTO_DMA) { | ||
249 | xdma8 = snd_legacy_find_free_dma(possible_dmas8); | ||
250 | if (xdma8 < 0) { | ||
251 | snd_printk(KERN_ERR "unable to find a free DMA8\n"); | ||
252 | err = -EBUSY; | ||
253 | goto err_free; | ||
254 | } | ||
255 | } | ||
256 | xdma16 = dma16[dev]; | ||
257 | if (xdma16 == SNDRV_AUTO_DMA) { | ||
258 | xdma16 = snd_legacy_find_free_dma(possible_dmas16); | ||
259 | if (xdma16 < 0) { | ||
260 | snd_printk(KERN_ERR "unable to find a free DMA16\n"); | ||
261 | err = -EBUSY; | ||
262 | goto err_free; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | xmpu_port = mpu_port[dev]; | ||
267 | if (xmpu_port == SNDRV_AUTO_PORT) | ||
268 | xmpu_port = 0; | ||
269 | err = jazz16_detect_board(port[dev], xmpu_port); | ||
270 | if (err < 0) { | ||
271 | printk(KERN_ERR "Media Vision Jazz16 board not detected\n"); | ||
272 | goto err_free; | ||
273 | } | ||
274 | err = snd_sbdsp_create(card, port[dev], irq[dev], | ||
275 | jazz16_interrupt, | ||
276 | dma8[dev], dma16[dev], | ||
277 | SB_HW_JAZZ16, | ||
278 | &chip); | ||
279 | if (err < 0) | ||
280 | goto err_free; | ||
281 | |||
282 | xmpu_irq = mpu_irq[dev]; | ||
283 | if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT) | ||
284 | xmpu_irq = 0; | ||
285 | err = jazz16_configure_board(chip, xmpu_irq); | ||
286 | if (err < 0) { | ||
287 | printk(KERN_ERR "Media Vision Jazz16 configuration failed\n"); | ||
288 | goto err_free; | ||
289 | } | ||
290 | |||
291 | jazz16->chip = chip; | ||
292 | |||
293 | strcpy(card->driver, "jazz16"); | ||
294 | strcpy(card->shortname, "Media Vision Jazz16"); | ||
295 | sprintf(card->longname, | ||
296 | "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d", | ||
297 | port[dev], xirq, xdma8, xdma16); | ||
298 | |||
299 | err = snd_sb8dsp_pcm(chip, 0, NULL); | ||
300 | if (err < 0) | ||
301 | goto err_free; | ||
302 | err = snd_sbmixer_new(chip); | ||
303 | if (err < 0) | ||
304 | goto err_free; | ||
305 | |||
306 | err = snd_opl3_create(card, chip->port, chip->port + 2, | ||
307 | OPL3_HW_AUTO, 1, &opl3); | ||
308 | if (err < 0) | ||
309 | snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", | ||
310 | chip->port, chip->port + 2); | ||
311 | else { | ||
312 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | ||
313 | if (err < 0) | ||
314 | goto err_free; | ||
315 | } | ||
316 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | ||
317 | if (mpu_irq[dev] == SNDRV_AUTO_IRQ) | ||
318 | mpu_irq[dev] = -1; | ||
319 | |||
320 | if (snd_mpu401_uart_new(card, 0, | ||
321 | MPU401_HW_MPU401, | ||
322 | mpu_port[dev], 0, | ||
323 | mpu_irq[dev], | ||
324 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, | ||
325 | NULL) < 0) | ||
326 | snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", | ||
327 | mpu_port[dev]); | ||
328 | } | ||
329 | |||
330 | snd_card_set_dev(card, devptr); | ||
331 | |||
332 | err = snd_card_register(card); | ||
333 | if (err < 0) | ||
334 | goto err_free; | ||
335 | |||
336 | dev_set_drvdata(devptr, card); | ||
337 | return 0; | ||
338 | |||
339 | err_free: | ||
340 | snd_card_free(card); | ||
341 | return err; | ||
342 | } | ||
343 | |||
344 | static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev) | ||
345 | { | ||
346 | struct snd_card *card = dev_get_drvdata(devptr); | ||
347 | |||
348 | dev_set_drvdata(devptr, NULL); | ||
349 | snd_card_free(card); | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | #ifdef CONFIG_PM | ||
354 | static int snd_jazz16_suspend(struct device *pdev, unsigned int n, | ||
355 | pm_message_t state) | ||
356 | { | ||
357 | struct snd_card *card = dev_get_drvdata(pdev); | ||
358 | struct snd_card_jazz16 *acard = card->private_data; | ||
359 | struct snd_sb *chip = acard->chip; | ||
360 | |||
361 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
362 | snd_pcm_suspend_all(chip->pcm); | ||
363 | snd_sbmixer_suspend(chip); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int snd_jazz16_resume(struct device *pdev, unsigned int n) | ||
368 | { | ||
369 | struct snd_card *card = dev_get_drvdata(pdev); | ||
370 | struct snd_card_jazz16 *acard = card->private_data; | ||
371 | struct snd_sb *chip = acard->chip; | ||
372 | |||
373 | snd_sbdsp_reset(chip); | ||
374 | snd_sbmixer_resume(chip); | ||
375 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
376 | return 0; | ||
377 | } | ||
378 | #endif | ||
379 | |||
380 | static struct isa_driver snd_jazz16_driver = { | ||
381 | .match = snd_jazz16_match, | ||
382 | .probe = snd_jazz16_probe, | ||
383 | .remove = __devexit_p(snd_jazz16_remove), | ||
384 | #ifdef CONFIG_PM | ||
385 | .suspend = snd_jazz16_suspend, | ||
386 | .resume = snd_jazz16_resume, | ||
387 | #endif | ||
388 | .driver = { | ||
389 | .name = "jazz16" | ||
390 | }, | ||
391 | }; | ||
392 | |||
393 | static int __init alsa_card_jazz16_init(void) | ||
394 | { | ||
395 | return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS); | ||
396 | } | ||
397 | |||
398 | static void __exit alsa_card_jazz16_exit(void) | ||
399 | { | ||
400 | isa_unregister_driver(&snd_jazz16_driver); | ||
401 | } | ||
402 | |||
403 | module_init(alsa_card_jazz16_init) | ||
404 | module_exit(alsa_card_jazz16_exit) | ||
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 658d55769c9c..7d84c9f34dc9 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c | |||
@@ -106,9 +106,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) | |||
106 | struct snd_sb *chip = snd_pcm_substream_chip(substream); | 106 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
107 | struct snd_pcm_runtime *runtime = substream->runtime; | 107 | struct snd_pcm_runtime *runtime = substream->runtime; |
108 | unsigned int mixreg, rate, size, count; | 108 | unsigned int mixreg, rate, size, count; |
109 | unsigned char format; | ||
110 | unsigned char stereo = runtime->channels > 1; | ||
111 | int dma; | ||
109 | 112 | ||
110 | rate = runtime->rate; | 113 | rate = runtime->rate; |
111 | switch (chip->hardware) { | 114 | switch (chip->hardware) { |
115 | case SB_HW_JAZZ16: | ||
116 | if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { | ||
117 | if (chip->mode & SB_MODE_CAPTURE_16) | ||
118 | return -EBUSY; | ||
119 | else | ||
120 | chip->mode |= SB_MODE_PLAYBACK_16; | ||
121 | } | ||
122 | chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; | ||
123 | break; | ||
112 | case SB_HW_PRO: | 124 | case SB_HW_PRO: |
113 | if (runtime->channels > 1) { | 125 | if (runtime->channels > 1) { |
114 | if (snd_BUG_ON(rate != SB8_RATE(11025) && | 126 | if (snd_BUG_ON(rate != SB8_RATE(11025) && |
@@ -133,11 +145,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) | |||
133 | default: | 145 | default: |
134 | return -EINVAL; | 146 | return -EINVAL; |
135 | } | 147 | } |
148 | if (chip->mode & SB_MODE_PLAYBACK_16) { | ||
149 | format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; | ||
150 | dma = chip->dma16; | ||
151 | } else { | ||
152 | format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; | ||
153 | chip->mode |= SB_MODE_PLAYBACK_8; | ||
154 | dma = chip->dma8; | ||
155 | } | ||
136 | size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); | 156 | size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); |
137 | count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); | 157 | count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); |
138 | spin_lock_irqsave(&chip->reg_lock, flags); | 158 | spin_lock_irqsave(&chip->reg_lock, flags); |
139 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); | 159 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); |
140 | if (runtime->channels > 1) { | 160 | if (chip->hardware == SB_HW_JAZZ16) |
161 | snd_sbdsp_command(chip, format); | ||
162 | else if (stereo) { | ||
141 | /* set playback stereo mode */ | 163 | /* set playback stereo mode */ |
142 | spin_lock(&chip->mixer_lock); | 164 | spin_lock(&chip->mixer_lock); |
143 | mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); | 165 | mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); |
@@ -147,15 +169,14 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) | |||
147 | /* Soundblaster hardware programming reference guide, 3-23 */ | 169 | /* Soundblaster hardware programming reference guide, 3-23 */ |
148 | snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); | 170 | snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); |
149 | runtime->dma_area[0] = 0x80; | 171 | runtime->dma_area[0] = 0x80; |
150 | snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); | 172 | snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); |
151 | /* force interrupt */ | 173 | /* force interrupt */ |
152 | chip->mode = SB_MODE_HALT; | ||
153 | snd_sbdsp_command(chip, SB_DSP_OUTPUT); | 174 | snd_sbdsp_command(chip, SB_DSP_OUTPUT); |
154 | snd_sbdsp_command(chip, 0); | 175 | snd_sbdsp_command(chip, 0); |
155 | snd_sbdsp_command(chip, 0); | 176 | snd_sbdsp_command(chip, 0); |
156 | } | 177 | } |
157 | snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); | 178 | snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); |
158 | if (runtime->channels > 1) { | 179 | if (stereo) { |
159 | snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); | 180 | snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); |
160 | spin_lock(&chip->mixer_lock); | 181 | spin_lock(&chip->mixer_lock); |
161 | /* save output filter status and turn it off */ | 182 | /* save output filter status and turn it off */ |
@@ -168,13 +189,15 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) | |||
168 | snd_sbdsp_command(chip, 256 - runtime->rate_den); | 189 | snd_sbdsp_command(chip, 256 - runtime->rate_den); |
169 | } | 190 | } |
170 | if (chip->playback_format != SB_DSP_OUTPUT) { | 191 | if (chip->playback_format != SB_DSP_OUTPUT) { |
192 | if (chip->mode & SB_MODE_PLAYBACK_16) | ||
193 | count /= 2; | ||
171 | count--; | 194 | count--; |
172 | snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); | 195 | snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); |
173 | snd_sbdsp_command(chip, count & 0xff); | 196 | snd_sbdsp_command(chip, count & 0xff); |
174 | snd_sbdsp_command(chip, count >> 8); | 197 | snd_sbdsp_command(chip, count >> 8); |
175 | } | 198 | } |
176 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 199 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
177 | snd_dma_program(chip->dma8, runtime->dma_addr, | 200 | snd_dma_program(dma, runtime->dma_addr, |
178 | size, DMA_MODE_WRITE | DMA_AUTOINIT); | 201 | size, DMA_MODE_WRITE | DMA_AUTOINIT); |
179 | return 0; | 202 | return 0; |
180 | } | 203 | } |
@@ -212,7 +235,6 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, | |||
212 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); | 235 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); |
213 | } | 236 | } |
214 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 237 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
215 | chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT; | ||
216 | return 0; | 238 | return 0; |
217 | } | 239 | } |
218 | 240 | ||
@@ -234,9 +256,21 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) | |||
234 | struct snd_sb *chip = snd_pcm_substream_chip(substream); | 256 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
235 | struct snd_pcm_runtime *runtime = substream->runtime; | 257 | struct snd_pcm_runtime *runtime = substream->runtime; |
236 | unsigned int mixreg, rate, size, count; | 258 | unsigned int mixreg, rate, size, count; |
259 | unsigned char format; | ||
260 | unsigned char stereo = runtime->channels > 1; | ||
261 | int dma; | ||
237 | 262 | ||
238 | rate = runtime->rate; | 263 | rate = runtime->rate; |
239 | switch (chip->hardware) { | 264 | switch (chip->hardware) { |
265 | case SB_HW_JAZZ16: | ||
266 | if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { | ||
267 | if (chip->mode & SB_MODE_PLAYBACK_16) | ||
268 | return -EBUSY; | ||
269 | else | ||
270 | chip->mode |= SB_MODE_CAPTURE_16; | ||
271 | } | ||
272 | chip->capture_format = SB_DSP_LO_INPUT_AUTO; | ||
273 | break; | ||
240 | case SB_HW_PRO: | 274 | case SB_HW_PRO: |
241 | if (runtime->channels > 1) { | 275 | if (runtime->channels > 1) { |
242 | if (snd_BUG_ON(rate != SB8_RATE(11025) && | 276 | if (snd_BUG_ON(rate != SB8_RATE(11025) && |
@@ -262,14 +296,24 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) | |||
262 | default: | 296 | default: |
263 | return -EINVAL; | 297 | return -EINVAL; |
264 | } | 298 | } |
299 | if (chip->mode & SB_MODE_CAPTURE_16) { | ||
300 | format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; | ||
301 | dma = chip->dma16; | ||
302 | } else { | ||
303 | format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; | ||
304 | chip->mode |= SB_MODE_CAPTURE_8; | ||
305 | dma = chip->dma8; | ||
306 | } | ||
265 | size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); | 307 | size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); |
266 | count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); | 308 | count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); |
267 | spin_lock_irqsave(&chip->reg_lock, flags); | 309 | spin_lock_irqsave(&chip->reg_lock, flags); |
268 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); | 310 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); |
269 | if (runtime->channels > 1) | 311 | if (chip->hardware == SB_HW_JAZZ16) |
312 | snd_sbdsp_command(chip, format); | ||
313 | else if (stereo) | ||
270 | snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); | 314 | snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); |
271 | snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); | 315 | snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); |
272 | if (runtime->channels > 1) { | 316 | if (stereo) { |
273 | snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); | 317 | snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); |
274 | spin_lock(&chip->mixer_lock); | 318 | spin_lock(&chip->mixer_lock); |
275 | /* save input filter status and turn it off */ | 319 | /* save input filter status and turn it off */ |
@@ -282,13 +326,15 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) | |||
282 | snd_sbdsp_command(chip, 256 - runtime->rate_den); | 326 | snd_sbdsp_command(chip, 256 - runtime->rate_den); |
283 | } | 327 | } |
284 | if (chip->capture_format != SB_DSP_INPUT) { | 328 | if (chip->capture_format != SB_DSP_INPUT) { |
329 | if (chip->mode & SB_MODE_PLAYBACK_16) | ||
330 | count /= 2; | ||
285 | count--; | 331 | count--; |
286 | snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); | 332 | snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); |
287 | snd_sbdsp_command(chip, count & 0xff); | 333 | snd_sbdsp_command(chip, count & 0xff); |
288 | snd_sbdsp_command(chip, count >> 8); | 334 | snd_sbdsp_command(chip, count >> 8); |
289 | } | 335 | } |
290 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 336 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
291 | snd_dma_program(chip->dma8, runtime->dma_addr, | 337 | snd_dma_program(dma, runtime->dma_addr, |
292 | size, DMA_MODE_READ | DMA_AUTOINIT); | 338 | size, DMA_MODE_READ | DMA_AUTOINIT); |
293 | return 0; | 339 | return 0; |
294 | } | 340 | } |
@@ -328,7 +374,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, | |||
328 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); | 374 | snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); |
329 | } | 375 | } |
330 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 376 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
331 | chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT; | ||
332 | return 0; | 377 | return 0; |
333 | } | 378 | } |
334 | 379 | ||
@@ -339,13 +384,21 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) | |||
339 | 384 | ||
340 | snd_sb_ack_8bit(chip); | 385 | snd_sb_ack_8bit(chip); |
341 | switch (chip->mode) { | 386 | switch (chip->mode) { |
342 | case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ | 387 | case SB_MODE_PLAYBACK_16: /* ok.. playback is active */ |
388 | if (chip->hardware != SB_HW_JAZZ16) | ||
389 | break; | ||
390 | /* fallthru */ | ||
391 | case SB_MODE_PLAYBACK_8: | ||
343 | substream = chip->playback_substream; | 392 | substream = chip->playback_substream; |
344 | runtime = substream->runtime; | 393 | runtime = substream->runtime; |
345 | if (chip->playback_format == SB_DSP_OUTPUT) | 394 | if (chip->playback_format == SB_DSP_OUTPUT) |
346 | snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); | 395 | snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); |
347 | snd_pcm_period_elapsed(substream); | 396 | snd_pcm_period_elapsed(substream); |
348 | break; | 397 | break; |
398 | case SB_MODE_CAPTURE_16: | ||
399 | if (chip->hardware != SB_HW_JAZZ16) | ||
400 | break; | ||
401 | /* fallthru */ | ||
349 | case SB_MODE_CAPTURE_8: | 402 | case SB_MODE_CAPTURE_8: |
350 | substream = chip->capture_substream; | 403 | substream = chip->capture_substream; |
351 | runtime = substream->runtime; | 404 | runtime = substream->runtime; |
@@ -361,10 +414,15 @@ static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *subs | |||
361 | { | 414 | { |
362 | struct snd_sb *chip = snd_pcm_substream_chip(substream); | 415 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
363 | size_t ptr; | 416 | size_t ptr; |
417 | int dma; | ||
364 | 418 | ||
365 | if (chip->mode != SB_MODE_PLAYBACK_8) | 419 | if (chip->mode & SB_MODE_PLAYBACK_8) |
420 | dma = chip->dma8; | ||
421 | else if (chip->mode & SB_MODE_PLAYBACK_16) | ||
422 | dma = chip->dma16; | ||
423 | else | ||
366 | return 0; | 424 | return 0; |
367 | ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); | 425 | ptr = snd_dma_pointer(dma, chip->p_dma_size); |
368 | return bytes_to_frames(substream->runtime, ptr); | 426 | return bytes_to_frames(substream->runtime, ptr); |
369 | } | 427 | } |
370 | 428 | ||
@@ -372,10 +430,15 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst | |||
372 | { | 430 | { |
373 | struct snd_sb *chip = snd_pcm_substream_chip(substream); | 431 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
374 | size_t ptr; | 432 | size_t ptr; |
433 | int dma; | ||
375 | 434 | ||
376 | if (chip->mode != SB_MODE_CAPTURE_8) | 435 | if (chip->mode & SB_MODE_CAPTURE_8) |
436 | dma = chip->dma8; | ||
437 | else if (chip->mode & SB_MODE_CAPTURE_16) | ||
438 | dma = chip->dma16; | ||
439 | else | ||
377 | return 0; | 440 | return 0; |
378 | ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); | 441 | ptr = snd_dma_pointer(dma, chip->c_dma_size); |
379 | return bytes_to_frames(substream->runtime, ptr); | 442 | return bytes_to_frames(substream->runtime, ptr); |
380 | } | 443 | } |
381 | 444 | ||
@@ -446,6 +509,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) | |||
446 | runtime->hw = snd_sb8_capture; | 509 | runtime->hw = snd_sb8_capture; |
447 | } | 510 | } |
448 | switch (chip->hardware) { | 511 | switch (chip->hardware) { |
512 | case SB_HW_JAZZ16: | ||
513 | if (chip->dma16 == 5 || chip->dma16 == 7) | ||
514 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE; | ||
515 | runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000; | ||
516 | runtime->hw.rate_min = 4000; | ||
517 | runtime->hw.rate_max = 50000; | ||
518 | runtime->hw.channels_max = 2; | ||
519 | break; | ||
449 | case SB_HW_PRO: | 520 | case SB_HW_PRO: |
450 | runtime->hw.rate_max = 44100; | 521 | runtime->hw.rate_max = 44100; |
451 | runtime->hw.channels_max = 2; | 522 | runtime->hw.channels_max = 2; |
@@ -468,6 +539,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) | |||
468 | } | 539 | } |
469 | snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 540 | snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
470 | &hw_constraints_clock); | 541 | &hw_constraints_clock); |
542 | if (chip->dma8 > 3 || chip->dma16 >= 0) { | ||
543 | snd_pcm_hw_constraint_step(runtime, 0, | ||
544 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2); | ||
545 | snd_pcm_hw_constraint_step(runtime, 0, | ||
546 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2); | ||
547 | runtime->hw.buffer_bytes_max = 128 * 1024 * 1024; | ||
548 | runtime->hw.period_bytes_max = 128 * 1024 * 1024; | ||
549 | } | ||
471 | return 0; | 550 | return 0; |
472 | } | 551 | } |
473 | 552 | ||
@@ -480,6 +559,10 @@ static int snd_sb8_close(struct snd_pcm_substream *substream) | |||
480 | chip->capture_substream = NULL; | 559 | chip->capture_substream = NULL; |
481 | spin_lock_irqsave(&chip->open_lock, flags); | 560 | spin_lock_irqsave(&chip->open_lock, flags); |
482 | chip->open &= ~SB_OPEN_PCM; | 561 | chip->open &= ~SB_OPEN_PCM; |
562 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
563 | chip->mode &= ~SB_MODE_PLAYBACK; | ||
564 | else | ||
565 | chip->mode &= ~SB_MODE_CAPTURE; | ||
483 | spin_unlock_irqrestore(&chip->open_lock, flags); | 566 | spin_unlock_irqrestore(&chip->open_lock, flags); |
484 | return 0; | 567 | return 0; |
485 | } | 568 | } |
@@ -515,6 +598,7 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) | |||
515 | struct snd_card *card = chip->card; | 598 | struct snd_card *card = chip->card; |
516 | struct snd_pcm *pcm; | 599 | struct snd_pcm *pcm; |
517 | int err; | 600 | int err; |
601 | size_t max_prealloc = 64 * 1024; | ||
518 | 602 | ||
519 | if (rpcm) | 603 | if (rpcm) |
520 | *rpcm = NULL; | 604 | *rpcm = NULL; |
@@ -527,9 +611,11 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) | |||
527 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); | 611 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); |
528 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); | 612 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); |
529 | 613 | ||
614 | if (chip->dma8 > 3 || chip->dma16 >= 0) | ||
615 | max_prealloc = 128 * 1024; | ||
530 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 616 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
531 | snd_dma_isa_data(), | 617 | snd_dma_isa_data(), |
532 | 64*1024, 64*1024); | 618 | 64*1024, max_prealloc); |
533 | 619 | ||
534 | if (rpcm) | 620 | if (rpcm) |
535 | *rpcm = pcm; | 621 | *rpcm = pcm; |
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 27a651502251..eae6c1c0eff9 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c | |||
@@ -170,6 +170,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip) | |||
170 | case SB_HW_CS5530: | 170 | case SB_HW_CS5530: |
171 | str = "16 (CS5530)"; | 171 | str = "16 (CS5530)"; |
172 | break; | 172 | break; |
173 | case SB_HW_JAZZ16: | ||
174 | str = "Pro (Jazz16)"; | ||
175 | break; | ||
173 | default: | 176 | default: |
174 | return -ENODEV; | 177 | return -ENODEV; |
175 | } | 178 | } |
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 318ff0c823e7..6496822c1808 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -528,20 +528,11 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty | |||
528 | * SB 2.0 specific mixer elements | 528 | * SB 2.0 specific mixer elements |
529 | */ | 529 | */ |
530 | 530 | ||
531 | static struct sbmix_elem snd_sb20_ctl_master_play_vol = | 531 | static struct sbmix_elem snd_sb20_controls[] = { |
532 | SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7); | 532 | SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7), |
533 | static struct sbmix_elem snd_sb20_ctl_pcm_play_vol = | 533 | SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3), |
534 | SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3); | 534 | SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7), |
535 | static struct sbmix_elem snd_sb20_ctl_synth_play_vol = | 535 | SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7) |
536 | SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7); | ||
537 | static struct sbmix_elem snd_sb20_ctl_cd_play_vol = | ||
538 | SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7); | ||
539 | |||
540 | static struct sbmix_elem *snd_sb20_controls[] = { | ||
541 | &snd_sb20_ctl_master_play_vol, | ||
542 | &snd_sb20_ctl_pcm_play_vol, | ||
543 | &snd_sb20_ctl_synth_play_vol, | ||
544 | &snd_sb20_ctl_cd_play_vol | ||
545 | }; | 536 | }; |
546 | 537 | ||
547 | static unsigned char snd_sb20_init_values[][2] = { | 538 | static unsigned char snd_sb20_init_values[][2] = { |
@@ -552,41 +543,24 @@ static unsigned char snd_sb20_init_values[][2] = { | |||
552 | /* | 543 | /* |
553 | * SB Pro specific mixer elements | 544 | * SB Pro specific mixer elements |
554 | */ | 545 | */ |
555 | static struct sbmix_elem snd_sbpro_ctl_master_play_vol = | 546 | static struct sbmix_elem snd_sbpro_controls[] = { |
556 | SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7); | 547 | SB_DOUBLE("Master Playback Volume", |
557 | static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol = | 548 | SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7), |
558 | SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7); | 549 | SB_DOUBLE("PCM Playback Volume", |
559 | static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter = | 550 | SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7), |
560 | SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1); | 551 | SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1), |
561 | static struct sbmix_elem snd_sbpro_ctl_synth_play_vol = | 552 | SB_DOUBLE("Synth Playback Volume", |
562 | SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7); | 553 | SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7), |
563 | static struct sbmix_elem snd_sbpro_ctl_cd_play_vol = | 554 | SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7), |
564 | SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7); | 555 | SB_DOUBLE("Line Playback Volume", |
565 | static struct sbmix_elem snd_sbpro_ctl_line_play_vol = | 556 | SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7), |
566 | SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7); | 557 | SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3), |
567 | static struct sbmix_elem snd_sbpro_ctl_mic_play_vol = | ||
568 | SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3); | ||
569 | static struct sbmix_elem snd_sbpro_ctl_capture_source = | ||
570 | { | 558 | { |
571 | .name = "Capture Source", | 559 | .name = "Capture Source", |
572 | .type = SB_MIX_CAPTURE_PRO | 560 | .type = SB_MIX_CAPTURE_PRO |
573 | }; | 561 | }, |
574 | static struct sbmix_elem snd_sbpro_ctl_capture_filter = | 562 | SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1), |
575 | SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1); | 563 | SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1) |
576 | static struct sbmix_elem snd_sbpro_ctl_capture_low_filter = | ||
577 | SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1); | ||
578 | |||
579 | static struct sbmix_elem *snd_sbpro_controls[] = { | ||
580 | &snd_sbpro_ctl_master_play_vol, | ||
581 | &snd_sbpro_ctl_pcm_play_vol, | ||
582 | &snd_sbpro_ctl_pcm_play_filter, | ||
583 | &snd_sbpro_ctl_synth_play_vol, | ||
584 | &snd_sbpro_ctl_cd_play_vol, | ||
585 | &snd_sbpro_ctl_line_play_vol, | ||
586 | &snd_sbpro_ctl_mic_play_vol, | ||
587 | &snd_sbpro_ctl_capture_source, | ||
588 | &snd_sbpro_ctl_capture_filter, | ||
589 | &snd_sbpro_ctl_capture_low_filter | ||
590 | }; | 564 | }; |
591 | 565 | ||
592 | static unsigned char snd_sbpro_init_values[][2] = { | 566 | static unsigned char snd_sbpro_init_values[][2] = { |
@@ -598,68 +572,42 @@ static unsigned char snd_sbpro_init_values[][2] = { | |||
598 | /* | 572 | /* |
599 | * SB16 specific mixer elements | 573 | * SB16 specific mixer elements |
600 | */ | 574 | */ |
601 | static struct sbmix_elem snd_sb16_ctl_master_play_vol = | 575 | static struct sbmix_elem snd_sb16_controls[] = { |
602 | SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31); | 576 | SB_DOUBLE("Master Playback Volume", |
603 | static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch = | 577 | SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31), |
604 | SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1); | 578 | SB_DOUBLE("PCM Playback Volume", |
605 | static struct sbmix_elem snd_sb16_ctl_tone_bass = | 579 | SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31), |
606 | SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15); | 580 | SB16_INPUT_SW("Synth Capture Route", |
607 | static struct sbmix_elem snd_sb16_ctl_tone_treble = | 581 | SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5), |
608 | SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15); | 582 | SB_DOUBLE("Synth Playback Volume", |
609 | static struct sbmix_elem snd_sb16_ctl_pcm_play_vol = | 583 | SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31), |
610 | SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31); | 584 | SB16_INPUT_SW("CD Capture Route", |
611 | static struct sbmix_elem snd_sb16_ctl_synth_capture_route = | 585 | SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1), |
612 | SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5); | 586 | SB_DOUBLE("CD Playback Switch", |
613 | static struct sbmix_elem snd_sb16_ctl_synth_play_vol = | 587 | SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1), |
614 | SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31); | 588 | SB_DOUBLE("CD Playback Volume", |
615 | static struct sbmix_elem snd_sb16_ctl_cd_capture_route = | 589 | SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31), |
616 | SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1); | 590 | SB16_INPUT_SW("Mic Capture Route", |
617 | static struct sbmix_elem snd_sb16_ctl_cd_play_switch = | 591 | SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0), |
618 | SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1); | 592 | SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), |
619 | static struct sbmix_elem snd_sb16_ctl_cd_play_vol = | 593 | SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), |
620 | SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31); | 594 | SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3), |
621 | static struct sbmix_elem snd_sb16_ctl_line_capture_route = | 595 | SB_DOUBLE("Capture Volume", |
622 | SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3); | 596 | SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3), |
623 | static struct sbmix_elem snd_sb16_ctl_line_play_switch = | 597 | SB_DOUBLE("Playback Volume", |
624 | SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1); | 598 | SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3), |
625 | static struct sbmix_elem snd_sb16_ctl_line_play_vol = | 599 | SB16_INPUT_SW("Line Capture Route", |
626 | SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31); | 600 | SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3), |
627 | static struct sbmix_elem snd_sb16_ctl_mic_capture_route = | 601 | SB_DOUBLE("Line Playback Switch", |
628 | SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0); | 602 | SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1), |
629 | static struct sbmix_elem snd_sb16_ctl_mic_play_switch = | 603 | SB_DOUBLE("Line Playback Volume", |
630 | SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1); | 604 | SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31), |
631 | static struct sbmix_elem snd_sb16_ctl_mic_play_vol = | 605 | SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), |
632 | SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31); | 606 | SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1), |
633 | static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol = | 607 | SB_DOUBLE("Tone Control - Bass", |
634 | SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3); | 608 | SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15), |
635 | static struct sbmix_elem snd_sb16_ctl_capture_vol = | 609 | SB_DOUBLE("Tone Control - Treble", |
636 | SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3); | 610 | SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15) |
637 | static struct sbmix_elem snd_sb16_ctl_play_vol = | ||
638 | SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3); | ||
639 | static struct sbmix_elem snd_sb16_ctl_auto_mic_gain = | ||
640 | SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1); | ||
641 | |||
642 | static struct sbmix_elem *snd_sb16_controls[] = { | ||
643 | &snd_sb16_ctl_master_play_vol, | ||
644 | &snd_sb16_ctl_3d_enhance_switch, | ||
645 | &snd_sb16_ctl_tone_bass, | ||
646 | &snd_sb16_ctl_tone_treble, | ||
647 | &snd_sb16_ctl_pcm_play_vol, | ||
648 | &snd_sb16_ctl_synth_capture_route, | ||
649 | &snd_sb16_ctl_synth_play_vol, | ||
650 | &snd_sb16_ctl_cd_capture_route, | ||
651 | &snd_sb16_ctl_cd_play_switch, | ||
652 | &snd_sb16_ctl_cd_play_vol, | ||
653 | &snd_sb16_ctl_line_capture_route, | ||
654 | &snd_sb16_ctl_line_play_switch, | ||
655 | &snd_sb16_ctl_line_play_vol, | ||
656 | &snd_sb16_ctl_mic_capture_route, | ||
657 | &snd_sb16_ctl_mic_play_switch, | ||
658 | &snd_sb16_ctl_mic_play_vol, | ||
659 | &snd_sb16_ctl_pc_speaker_vol, | ||
660 | &snd_sb16_ctl_capture_vol, | ||
661 | &snd_sb16_ctl_play_vol, | ||
662 | &snd_sb16_ctl_auto_mic_gain | ||
663 | }; | 611 | }; |
664 | 612 | ||
665 | static unsigned char snd_sb16_init_values[][2] = { | 613 | static unsigned char snd_sb16_init_values[][2] = { |
@@ -678,46 +626,34 @@ static unsigned char snd_sb16_init_values[][2] = { | |||
678 | /* | 626 | /* |
679 | * DT019x specific mixer elements | 627 | * DT019x specific mixer elements |
680 | */ | 628 | */ |
681 | static struct sbmix_elem snd_dt019x_ctl_master_play_vol = | 629 | static struct sbmix_elem snd_dt019x_controls[] = { |
682 | SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15); | 630 | /* ALS4000 below has some parts which we might be lacking, |
683 | static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol = | 631 | * e.g. snd_als4000_ctl_mono_playback_switch - check it! */ |
684 | SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15); | 632 | SB_DOUBLE("Master Playback Volume", |
685 | static struct sbmix_elem snd_dt019x_ctl_synth_play_vol = | 633 | SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4, 0, 15), |
686 | SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15); | 634 | SB_DOUBLE("PCM Playback Switch", |
687 | static struct sbmix_elem snd_dt019x_ctl_cd_play_vol = | 635 | SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1), |
688 | SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15); | 636 | SB_DOUBLE("PCM Playback Volume", |
689 | static struct sbmix_elem snd_dt019x_ctl_mic_play_vol = | 637 | SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4, 0, 15), |
690 | SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7); | 638 | SB_DOUBLE("Synth Playback Switch", |
691 | static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol = | 639 | SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1), |
692 | SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7); | 640 | SB_DOUBLE("Synth Playback Volume", |
693 | static struct sbmix_elem snd_dt019x_ctl_line_play_vol = | 641 | SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4, 0, 15), |
694 | SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15); | 642 | SB_DOUBLE("CD Playback Switch", |
695 | static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch = | 643 | SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1), |
696 | SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1); | 644 | SB_DOUBLE("CD Playback Volume", |
697 | static struct sbmix_elem snd_dt019x_ctl_synth_play_switch = | 645 | SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4, 0, 15), |
698 | SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1); | 646 | SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), |
699 | static struct sbmix_elem snd_dt019x_ctl_capture_source = | 647 | SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7), |
648 | SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7), | ||
649 | SB_DOUBLE("Line Playback Switch", | ||
650 | SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1), | ||
651 | SB_DOUBLE("Line Playback Volume", | ||
652 | SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4, 0, 15), | ||
700 | { | 653 | { |
701 | .name = "Capture Source", | 654 | .name = "Capture Source", |
702 | .type = SB_MIX_CAPTURE_DT019X | 655 | .type = SB_MIX_CAPTURE_DT019X |
703 | }; | 656 | } |
704 | |||
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! */ | ||
708 | &snd_dt019x_ctl_master_play_vol, | ||
709 | &snd_dt019x_ctl_pcm_play_vol, | ||
710 | &snd_dt019x_ctl_synth_play_vol, | ||
711 | &snd_dt019x_ctl_cd_play_vol, | ||
712 | &snd_dt019x_ctl_mic_play_vol, | ||
713 | &snd_dt019x_ctl_pc_speaker_vol, | ||
714 | &snd_dt019x_ctl_line_play_vol, | ||
715 | &snd_sb16_ctl_mic_play_switch, | ||
716 | &snd_sb16_ctl_cd_play_switch, | ||
717 | &snd_sb16_ctl_line_play_switch, | ||
718 | &snd_dt019x_ctl_pcm_play_switch, | ||
719 | &snd_dt019x_ctl_synth_play_switch, | ||
720 | &snd_dt019x_ctl_capture_source | ||
721 | }; | 657 | }; |
722 | 658 | ||
723 | static unsigned char snd_dt019x_init_values[][2] = { | 659 | static unsigned char snd_dt019x_init_values[][2] = { |
@@ -735,82 +671,37 @@ static unsigned char snd_dt019x_init_values[][2] = { | |||
735 | /* | 671 | /* |
736 | * ALS4000 specific mixer elements | 672 | * ALS4000 specific mixer elements |
737 | */ | 673 | */ |
738 | static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch = | 674 | static struct sbmix_elem snd_als4000_controls[] = { |
739 | SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); | 675 | SB_DOUBLE("PCM Playback Switch", |
740 | static struct sbmix_elem snd_als4k_ctl_master_mono_capture_route = { | 676 | SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1), |
677 | SB_DOUBLE("Synth Playback Switch", | ||
678 | SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1), | ||
679 | SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03), | ||
680 | SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1), | ||
681 | { | ||
741 | .name = "Master Mono Capture Route", | 682 | .name = "Master Mono Capture Route", |
742 | .type = SB_MIX_MONO_CAPTURE_ALS4K | 683 | .type = SB_MIX_MONO_CAPTURE_ALS4K |
743 | }; | 684 | }, |
744 | static struct sbmix_elem snd_als4000_ctl_mono_playback_switch = | 685 | SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1), |
745 | SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1); | 686 | SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01), |
746 | static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = | 687 | SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01), |
747 | SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03); | ||
748 | static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback = | ||
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", | 688 | SB_SINGLE("Digital Loopback Switch", |
752 | SB_ALS4000_CR3_CONFIGURATION, 7, 0x01); | 689 | SB_ALS4000_CR3_CONFIGURATION, 7, 0x01), |
753 | /* FIXME: functionality of 3D controls might be swapped, I didn't find | 690 | /* FIXME: functionality of 3D controls might be swapped, I didn't find |
754 | * a description of how to identify what is supposed to be what */ | 691 | * a description of how to identify what is supposed to be what */ |
755 | static struct sbmix_elem snd_als4000_3d_control_switch = | 692 | SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07), |
756 | SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01); | ||
757 | static struct sbmix_elem snd_als4000_3d_control_ratio = | ||
758 | SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07); | ||
759 | static struct sbmix_elem snd_als4000_3d_control_freq = | ||
760 | /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */ | 693 | /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */ |
761 | SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03); | 694 | SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03), |
762 | static struct sbmix_elem snd_als4000_3d_control_delay = | ||
763 | /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay, | 695 | /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay, |
764 | * but what ALSA 3D attribute is that actually? "Center", "Depth", | 696 | * but what ALSA 3D attribute is that actually? "Center", "Depth", |
765 | * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */ | 697 | * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */ |
766 | SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); | 698 | SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f), |
767 | static struct sbmix_elem snd_als4000_3d_control_poweroff_switch = | 699 | 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", | 700 | SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch", |
771 | SB_ALS4000_FMDAC, 5, 0x01); | 701 | SB_ALS4000_FMDAC, 5, 0x01), |
772 | #ifdef NOT_AVAILABLE | 702 | #ifdef NOT_AVAILABLE |
773 | static struct sbmix_elem snd_als4000_ctl_fmdac = | 703 | SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01), |
774 | SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); | 704 | SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f), |
775 | static struct sbmix_elem snd_als4000_ctl_qsound = | ||
776 | SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f); | ||
777 | #endif | ||
778 | |||
779 | static struct sbmix_elem *snd_als4000_controls[] = { | ||
780 | /* ALS4000a.PDF regs page */ | ||
781 | &snd_sb16_ctl_master_play_vol, /* MX30/31 12 */ | ||
782 | &snd_dt019x_ctl_pcm_play_switch, /* MX4C 16 */ | ||
783 | &snd_sb16_ctl_pcm_play_vol, /* MX32/33 12 */ | ||
784 | &snd_sb16_ctl_synth_capture_route, /* MX3D/3E 14 */ | ||
785 | &snd_dt019x_ctl_synth_play_switch, /* MX4C 16 */ | ||
786 | &snd_sb16_ctl_synth_play_vol, /* MX34/35 12/13 */ | ||
787 | &snd_sb16_ctl_cd_capture_route, /* MX3D/3E 14 */ | ||
788 | &snd_sb16_ctl_cd_play_switch, /* MX3C 14 */ | ||
789 | &snd_sb16_ctl_cd_play_vol, /* MX36/37 13 */ | ||
790 | &snd_sb16_ctl_line_capture_route, /* MX3D/3E 14 */ | ||
791 | &snd_sb16_ctl_line_play_switch, /* MX3C 14 */ | ||
792 | &snd_sb16_ctl_line_play_vol, /* MX38/39 13 */ | ||
793 | &snd_sb16_ctl_mic_capture_route, /* MX3D/3E 14 */ | ||
794 | &snd_als4000_ctl_mic_20db_boost, /* MX4D 16 */ | ||
795 | &snd_sb16_ctl_mic_play_switch, /* MX3C 14 */ | ||
796 | &snd_sb16_ctl_mic_play_vol, /* MX3A 13 */ | ||
797 | &snd_sb16_ctl_pc_speaker_vol, /* MX3B 14 */ | ||
798 | &snd_sb16_ctl_capture_vol, /* MX3F/40 15 */ | ||
799 | &snd_sb16_ctl_play_vol, /* MX41/42 15 */ | ||
800 | &snd_als4000_ctl_master_mono_playback_switch, /* MX4C 16 */ | ||
801 | &snd_als4k_ctl_master_mono_capture_route, /* MX4B 16 */ | ||
802 | &snd_als4000_ctl_mono_playback_switch, /* MX4C 16 */ | ||
803 | &snd_als4000_ctl_mixer_analog_loopback, /* MX4D 16 */ | ||
804 | &snd_als4000_ctl_mixer_digital_loopback, /* CR3 21 */ | ||
805 | &snd_als4000_3d_control_switch, /* MX50 17 */ | ||
806 | &snd_als4000_3d_control_ratio, /* MX50 17 */ | ||
807 | &snd_als4000_3d_control_freq, /* MX50 17 */ | ||
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 */ | ||
811 | #ifdef NOT_AVAILABLE | ||
812 | &snd_als4000_ctl_fmdac, | ||
813 | &snd_als4000_ctl_qsound, | ||
814 | #endif | 705 | #endif |
815 | }; | 706 | }; |
816 | 707 | ||
@@ -829,11 +720,10 @@ static unsigned char snd_als4000_init_values[][2] = { | |||
829 | { SB_ALS4000_MIC_IN_GAIN, 0 }, | 720 | { SB_ALS4000_MIC_IN_GAIN, 0 }, |
830 | }; | 721 | }; |
831 | 722 | ||
832 | |||
833 | /* | 723 | /* |
834 | */ | 724 | */ |
835 | static int snd_sbmixer_init(struct snd_sb *chip, | 725 | static int snd_sbmixer_init(struct snd_sb *chip, |
836 | struct sbmix_elem **controls, | 726 | struct sbmix_elem *controls, |
837 | int controls_count, | 727 | int controls_count, |
838 | unsigned char map[][2], | 728 | unsigned char map[][2], |
839 | int map_count, | 729 | int map_count, |
@@ -856,7 +746,8 @@ static int snd_sbmixer_init(struct snd_sb *chip, | |||
856 | } | 746 | } |
857 | 747 | ||
858 | for (idx = 0; idx < controls_count; idx++) { | 748 | for (idx = 0; idx < controls_count; idx++) { |
859 | if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0) | 749 | err = snd_sbmixer_add_ctl_elem(chip, &controls[idx]); |
750 | if (err < 0) | ||
860 | return err; | 751 | return err; |
861 | } | 752 | } |
862 | snd_component_add(card, name); | 753 | snd_component_add(card, name); |
@@ -888,6 +779,7 @@ int snd_sbmixer_new(struct snd_sb *chip) | |||
888 | return err; | 779 | return err; |
889 | break; | 780 | break; |
890 | case SB_HW_PRO: | 781 | case SB_HW_PRO: |
782 | case SB_HW_JAZZ16: | ||
891 | if ((err = snd_sbmixer_init(chip, | 783 | if ((err = snd_sbmixer_init(chip, |
892 | snd_sbpro_controls, | 784 | snd_sbpro_controls, |
893 | ARRAY_SIZE(snd_sbpro_controls), | 785 | ARRAY_SIZE(snd_sbpro_controls), |
@@ -908,6 +800,15 @@ int snd_sbmixer_new(struct snd_sb *chip) | |||
908 | return err; | 800 | return err; |
909 | break; | 801 | break; |
910 | case SB_HW_ALS4000: | 802 | case SB_HW_ALS4000: |
803 | /* use only the first 16 controls from SB16 */ | ||
804 | err = snd_sbmixer_init(chip, | ||
805 | snd_sb16_controls, | ||
806 | 16, | ||
807 | snd_sb16_init_values, | ||
808 | ARRAY_SIZE(snd_sb16_init_values), | ||
809 | "ALS4000"); | ||
810 | if (err < 0) | ||
811 | return err; | ||
911 | if ((err = snd_sbmixer_init(chip, | 812 | if ((err = snd_sbmixer_init(chip, |
912 | snd_als4000_controls, | 813 | snd_als4000_controls, |
913 | ARRAY_SIZE(snd_als4000_controls), | 814 | ARRAY_SIZE(snd_als4000_controls), |
@@ -1029,6 +930,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip) | |||
1029 | save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); | 930 | save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); |
1030 | break; | 931 | break; |
1031 | case SB_HW_PRO: | 932 | case SB_HW_PRO: |
933 | case SB_HW_JAZZ16: | ||
1032 | save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); | 934 | save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); |
1033 | break; | 935 | break; |
1034 | case SB_HW_16: | 936 | case SB_HW_16: |
@@ -1055,6 +957,7 @@ void snd_sbmixer_resume(struct snd_sb *chip) | |||
1055 | restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); | 957 | restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); |
1056 | break; | 958 | break; |
1057 | case SB_HW_PRO: | 959 | case SB_HW_PRO: |
960 | case SB_HW_JAZZ16: | ||
1058 | restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); | 961 | restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); |
1059 | break; | 962 | break; |
1060 | case SB_HW_16: | 963 | case SB_HW_16: |