aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-02-16 05:25:03 -0500
committerJaroslav Kysela <perex@perex.cz>2010-02-16 05:25:03 -0500
commitb8f1f5983fbe751aa3d07d9ce7ebb0c23bf4b7e4 (patch)
treee9f11863f683a9f4eb03d76008740a36d6b4ff3c /sound/isa
parentba9341dfef6b0201cd30e3904dcd0a47d3dc35e0 (diff)
parent47b5d028fdce8f809bf22852ac900338fb90e8aa (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')
-rw-r--r--sound/isa/Kconfig37
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/als100.c121
-rw-r--r--sound/isa/dt019x.c321
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c93
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/jazz16.c404
-rw-r--r--sound/isa/sb/sb8_main.c118
-rw-r--r--sound/isa/sb/sb_common.c3
-rw-r--r--sound/isa/sb/sb_mixer.c333
-rw-r--r--sound/isa/wss/wss_lib.c80
11 files changed, 843 insertions, 671 deletions
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 02fe81ca88fd..755a0a5f0e3f 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -63,15 +63,16 @@ config SND_AD1848
63 will be called snd-ad1848. 63 will be called snd-ad1848.
64 64
65config SND_ALS100 65config SND_ALS100
66 tristate "Avance Logic ALS100/ALS120" 66 tristate "Diamond Tech. DT-019x and Avance Logic ALSxxx"
67 depends on PNP 67 depends on PNP
68 select ISAPNP 68 select ISAPNP
69 select SND_OPL3_LIB 69 select SND_OPL3_LIB
70 select SND_MPU401_UART 70 select SND_MPU401_UART
71 select SND_SB16_DSP 71 select SND_SB16_DSP
72 help 72 help
73 Say Y here to include support for soundcards based on Avance 73 Say Y here to include support for soundcards based on the
74 Logic ALS100, ALS110, ALS120 and ALS200 chips. 74 Diamond Technologies DT-019X or Avance Logic chips: ALS007,
75 ALS100, ALS110, ALS120 and ALS200 chips.
75 76
76 To compile this driver as a module, choose M here: the module 77 To compile this driver as a module, choose M here: the module
77 will be called snd-als100. 78 will be called snd-als100.
@@ -127,20 +128,6 @@ config SND_CS4236
127 To compile this driver as a module, choose M here: the module 128 To compile this driver as a module, choose M here: the module
128 will be called snd-cs4236. 129 will be called snd-cs4236.
129 130
130config SND_DT019X
131 tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
132 depends on PNP
133 select ISAPNP
134 select SND_OPL3_LIB
135 select SND_MPU401_UART
136 select SND_SB16_DSP
137 help
138 Say Y here to include support for soundcards based on the
139 Diamond Technologies DT-019X or Avance Logic ALS-007 chips.
140
141 To compile this driver as a module, choose M here: the module
142 will be called snd-dt019x.
143
144config SND_ES968 131config SND_ES968
145 tristate "Generic ESS ES968 driver" 132 tristate "Generic ESS ES968 driver"
146 depends on PNP 133 depends on PNP
@@ -252,6 +239,22 @@ config SND_INTERWAVE_STB
252 To compile this driver as a module, choose M here: the module 239 To compile this driver as a module, choose M here: the module
253 will be called snd-interwave-stb. 240 will be called snd-interwave-stb.
254 241
242config SND_JAZZ16
243 tristate "Media Vision Jazz16 card and compatibles"
244 select SND_OPL3_LIB
245 select SND_MPU401_UART
246 select SND_SB8_DSP
247 help
248 Say Y here to include support for soundcards based on the
249 Media Vision Jazz16 chipset: digital chip MVD1216 (Jazz16),
250 codec MVA416 (CS4216) and mixer MVA514 (ICS2514).
251 Media Vision's Jazz16 cards were sold under names Pro Sonic 16,
252 Premium 3-D and Pro 3-D. There were also OEMs cards with the
253 Jazz16 chipset.
254
255 To compile this driver as a module, choose M here: the module
256 will be called snd-jazz16.
257
255config SND_OPL3SA2 258config SND_OPL3SA2
256 tristate "Yamaha OPL3-SA2/SA3" 259 tristate "Yamaha OPL3-SA2/SA3"
257 select SND_OPL3_LIB 260 select SND_OPL3_LIB
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index b906b9a1a81e..c73d30c4f462 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -7,7 +7,6 @@ snd-adlib-objs := adlib.o
7snd-als100-objs := als100.o 7snd-als100-objs := als100.o
8snd-azt2320-objs := azt2320.o 8snd-azt2320-objs := azt2320.o
9snd-cmi8330-objs := cmi8330.o 9snd-cmi8330-objs := cmi8330.o
10snd-dt019x-objs := dt019x.o
11snd-es18xx-objs := es18xx.o 10snd-es18xx-objs := es18xx.o
12snd-opl3sa2-objs := opl3sa2.o 11snd-opl3sa2-objs := opl3sa2.o
13snd-sc6000-objs := sc6000.o 12snd-sc6000-objs := sc6000.o
@@ -19,7 +18,6 @@ obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
19obj-$(CONFIG_SND_ALS100) += snd-als100.o 18obj-$(CONFIG_SND_ALS100) += snd-als100.o
20obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o 19obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
21obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o 20obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
22obj-$(CONFIG_SND_DT019X) += snd-dt019x.o
23obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o 21obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
24obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o 22obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
25obj-$(CONFIG_SND_SC6000) += snd-sc6000.o 23obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 5fd52e4d7079..20becc89f6f6 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -2,9 +2,13 @@
2/* 2/*
3 card-als100.c - driver for Avance Logic ALS100 based soundcards. 3 card-als100.c - driver for Avance Logic ALS100 based soundcards.
4 Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it> 4 Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
5 Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it>
5 6
6 Thanks to Pierfrancesco 'qM2' Passerini. 7 Thanks to Pierfrancesco 'qM2' Passerini.
7 8
9 Generalised for soundcards based on DT-0196 and ALS-007 chips
10 by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
11
8 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 13 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 14 the Free Software Foundation; either version 2 of the License, or
@@ -33,10 +37,10 @@
33 37
34#define PFX "als100: " 38#define PFX "als100: "
35 39
36MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); 40MODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0");
37MODULE_DESCRIPTION("Avance Logic ALS1X0"); 41MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
38MODULE_LICENSE("GPL"); 42 "{Avance Logic ALS-007}}"
39MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP}," 43 "{{Avance Logic,ALS100 - PRO16PNP},"
40 "{Avance Logic,ALS110}," 44 "{Avance Logic,ALS110},"
41 "{Avance Logic,ALS120}," 45 "{Avance Logic,ALS120},"
42 "{Avance Logic,ALS200}," 46 "{Avance Logic,ALS200},"
@@ -45,9 +49,12 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP},"
45 "{Avance Logic,ALS120}," 49 "{Avance Logic,ALS120},"
46 "{RTL,RTL3000}}"); 50 "{RTL,RTL3000}}");
47 51
52MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
53MODULE_LICENSE("GPL");
54
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 56static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ 57static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 58static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
52static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 59static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
53static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 60static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@@ -57,14 +64,15 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
57static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ 64static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
58 65
59module_param_array(index, int, NULL, 0444); 66module_param_array(index, int, NULL, 0444);
60MODULE_PARM_DESC(index, "Index value for als100 based soundcard."); 67MODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard.");
61module_param_array(id, charp, NULL, 0444); 68module_param_array(id, charp, NULL, 0444);
62MODULE_PARM_DESC(id, "ID string for als100 based soundcard."); 69MODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard.");
63module_param_array(enable, bool, NULL, 0444); 70module_param_array(enable, bool, NULL, 0444);
64MODULE_PARM_DESC(enable, "Enable als100 based soundcard."); 71MODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard.");
72
73MODULE_ALIAS("snd-dt019x");
65 74
66struct snd_card_als100 { 75struct snd_card_als100 {
67 int dev_no;
68 struct pnp_dev *dev; 76 struct pnp_dev *dev;
69 struct pnp_dev *devmpu; 77 struct pnp_dev *devmpu;
70 struct pnp_dev *devopl; 78 struct pnp_dev *devopl;
@@ -72,25 +80,43 @@ struct snd_card_als100 {
72}; 80};
73 81
74static struct pnp_card_device_id snd_als100_pnpids[] = { 82static struct pnp_card_device_id snd_als100_pnpids[] = {
83 /* DT197A30 */
84 { .id = "RWB1688",
85 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
86 .driver_data = SB_HW_DT019X },
87 /* DT0196 / ALS-007 */
88 { .id = "ALS0007",
89 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
90 .driver_data = SB_HW_DT019X },
75 /* ALS100 - PRO16PNP */ 91 /* ALS100 - PRO16PNP */
76 { .id = "ALS0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, 92 { .id = "ALS0001",
93 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
94 .driver_data = SB_HW_ALS100 },
77 /* ALS110 - MF1000 - Digimate 3D Sound */ 95 /* ALS110 - MF1000 - Digimate 3D Sound */
78 { .id = "ALS0110", .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } } }, 96 { .id = "ALS0110",
97 .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } },
98 .driver_data = SB_HW_ALS100 },
79 /* ALS120 */ 99 /* ALS120 */
80 { .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, 100 { .id = "ALS0120",
101 .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
102 .driver_data = SB_HW_ALS100 },
81 /* ALS200 */ 103 /* ALS200 */
82 { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } }, 104 { .id = "ALS0200",
105 .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } },
106 .driver_data = SB_HW_ALS100 },
83 /* ALS200 OEM */ 107 /* ALS200 OEM */
84 { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } }, 108 { .id = "ALS0200",
109 .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } },
110 .driver_data = SB_HW_ALS100 },
85 /* RTL3000 */ 111 /* RTL3000 */
86 { .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, 112 { .id = "RTL3000",
87 { .id = "", } /* end */ 113 .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
114 .driver_data = SB_HW_ALS100 },
115 { .id = "" } /* end */
88}; 116};
89 117
90MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids); 118MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
91 119
92#define DRIVER_NAME "snd-card-als100"
93
94static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, 120static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
95 struct pnp_card_link *card, 121 struct pnp_card_link *card,
96 const struct pnp_card_device_id *id) 122 const struct pnp_card_device_id *id)
@@ -113,8 +139,12 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
113 return err; 139 return err;
114 } 140 }
115 port[dev] = pnp_port_start(pdev, 0); 141 port[dev] = pnp_port_start(pdev, 0);
116 dma8[dev] = pnp_dma(pdev, 1); 142 if (id->driver_data == SB_HW_DT019X)
117 dma16[dev] = pnp_dma(pdev, 0); 143 dma8[dev] = pnp_dma(pdev, 0);
144 else {
145 dma8[dev] = pnp_dma(pdev, 1);
146 dma16[dev] = pnp_dma(pdev, 0);
147 }
118 irq[dev] = pnp_irq(pdev, 0); 148 irq[dev] = pnp_irq(pdev, 0);
119 149
120 pdev = acard->devmpu; 150 pdev = acard->devmpu;
@@ -175,22 +205,33 @@ static int __devinit snd_card_als100_probe(int dev,
175 } 205 }
176 snd_card_set_dev(card, &pcard->card->dev); 206 snd_card_set_dev(card, &pcard->card->dev);
177 207
178 if ((error = snd_sbdsp_create(card, port[dev], 208 if (pid->driver_data == SB_HW_DT019X)
179 irq[dev], 209 dma16[dev] = -1;
180 snd_sb16dsp_interrupt, 210
181 dma8[dev], 211 error = snd_sbdsp_create(card, port[dev], irq[dev],
182 dma16[dev], 212 snd_sb16dsp_interrupt,
183 SB_HW_ALS100, &chip)) < 0) { 213 dma8[dev], dma16[dev],
214 pid->driver_data,
215 &chip);
216 if (error < 0) {
184 snd_card_free(card); 217 snd_card_free(card);
185 return error; 218 return error;
186 } 219 }
187 acard->chip = chip; 220 acard->chip = chip;
188 221
189 strcpy(card->driver, "ALS100"); 222 if (pid->driver_data == SB_HW_DT019X) {
190 strcpy(card->shortname, "Avance Logic ALS100"); 223 strcpy(card->driver, "DT-019X");
191 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 224 strcpy(card->shortname, "Diamond Tech. DT-019X");
192 card->shortname, chip->name, chip->port, 225 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
193 irq[dev], dma8[dev], dma16[dev]); 226 card->shortname, chip->name, chip->port,
227 irq[dev], dma8[dev]);
228 } else {
229 strcpy(card->driver, "ALS100");
230 strcpy(card->shortname, "Avance Logic ALS100");
231 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
232 card->shortname, chip->name, chip->port,
233 irq[dev], dma8[dev], dma16[dev]);
234 }
194 235
195 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { 236 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
196 snd_card_free(card); 237 snd_card_free(card);
@@ -203,9 +244,19 @@ static int __devinit snd_card_als100_probe(int dev,
203 } 244 }
204 245
205 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 246 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
206 if (snd_mpu401_uart_new(card, 0, MPU401_HW_ALS100, 247 int mpu_type = MPU401_HW_ALS100;
248
249 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
250 mpu_irq[dev] = -1;
251
252 if (pid->driver_data == SB_HW_DT019X)
253 mpu_type = MPU401_HW_MPU401;
254
255 if (snd_mpu401_uart_new(card, 0,
256 mpu_type,
207 mpu_port[dev], 0, 257 mpu_port[dev], 0,
208 mpu_irq[dev], IRQF_DISABLED, 258 mpu_irq[dev],
259 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
209 NULL) < 0) 260 NULL) < 0)
210 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); 261 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
211 } 262 }
@@ -291,7 +342,7 @@ static int snd_als100_pnp_resume(struct pnp_card_link *pcard)
291 342
292static struct pnp_card_driver als100_pnpc_driver = { 343static struct pnp_card_driver als100_pnpc_driver = {
293 .flags = PNP_DRIVER_RES_DISABLE, 344 .flags = PNP_DRIVER_RES_DISABLE,
294 .name = "als100", 345 .name = "als100",
295 .id_table = snd_als100_pnpids, 346 .id_table = snd_als100_pnpids,
296 .probe = snd_als100_pnp_detect, 347 .probe = snd_als100_pnp_detect,
297 .remove = __devexit_p(snd_als100_pnp_remove), 348 .remove = __devexit_p(snd_als100_pnp_remove),
@@ -312,7 +363,7 @@ static int __init alsa_card_als100_init(void)
312 if (!als100_devices) { 363 if (!als100_devices) {
313 pnp_unregister_card_driver(&als100_pnpc_driver); 364 pnp_unregister_card_driver(&als100_pnpc_driver);
314#ifdef MODULE 365#ifdef MODULE
315 snd_printk(KERN_ERR "no ALS100 based soundcards found\n"); 366 snd_printk(KERN_ERR "no Avance Logic based soundcards found\n");
316#endif 367#endif
317 return -ENODEV; 368 return -ENODEV;
318 } 369 }
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c
deleted file mode 100644
index 80f5b1af9be8..000000000000
--- a/sound/isa/dt019x.c
+++ /dev/null
@@ -1,321 +0,0 @@
1
2/*
3 dt019x.c - driver for Diamond Technologies DT-0197H based soundcards.
4 Copyright (C) 1999, 2002 by Massimo Piccioni <dafastidio@libero.it>
5
6 Generalised for soundcards based on DT-0196 and ALS-007 chips
7 by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*/
23
24#include <linux/init.h>
25#include <linux/wait.h>
26#include <linux/pnp.h>
27#include <linux/moduleparam.h>
28#include <sound/core.h>
29#include <sound/initval.h>
30#include <sound/mpu401.h>
31#include <sound/opl3.h>
32#include <sound/sb.h>
33
34#define PFX "dt019x: "
35
36MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
37MODULE_DESCRIPTION("Diamond Technologies DT-019X / Avance Logic ALS-007");
38MODULE_LICENSE("GPL");
39MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
40 "{Avance Logic ALS-007}}");
41
42static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
43static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
44static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
45static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
46static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
47static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
48static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
49static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
50static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
51
52module_param_array(index, int, NULL, 0444);
53MODULE_PARM_DESC(index, "Index value for DT-019X based soundcard.");
54module_param_array(id, charp, NULL, 0444);
55MODULE_PARM_DESC(id, "ID string for DT-019X based soundcard.");
56module_param_array(enable, bool, NULL, 0444);
57MODULE_PARM_DESC(enable, "Enable DT-019X based soundcard.");
58
59struct snd_card_dt019x {
60 struct pnp_dev *dev;
61 struct pnp_dev *devmpu;
62 struct pnp_dev *devopl;
63 struct snd_sb *chip;
64};
65
66static struct pnp_card_device_id snd_dt019x_pnpids[] = {
67 /* DT197A30 */
68 { .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
69 /* DT0196 / ALS-007 */
70 { .id = "ALS0007", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
71 { .id = "", }
72};
73
74MODULE_DEVICE_TABLE(pnp_card, snd_dt019x_pnpids);
75
76
77#define DRIVER_NAME "snd-card-dt019x"
78
79
80static int __devinit snd_card_dt019x_pnp(int dev, struct snd_card_dt019x *acard,
81 struct pnp_card_link *card,
82 const struct pnp_card_device_id *pid)
83{
84 struct pnp_dev *pdev;
85 int err;
86
87 acard->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
88 if (acard->dev == NULL)
89 return -ENODEV;
90
91 acard->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
92 acard->devopl = pnp_request_card_device(card, pid->devs[2].id, NULL);
93
94 pdev = acard->dev;
95
96 err = pnp_activate_dev(pdev);
97 if (err < 0) {
98 snd_printk(KERN_ERR PFX "DT-019X AUDIO pnp configure failure\n");
99 return err;
100 }
101
102 port[dev] = pnp_port_start(pdev, 0);
103 dma8[dev] = pnp_dma(pdev, 0);
104 irq[dev] = pnp_irq(pdev, 0);
105 snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%x, dma=0x%x\n",
106 port[dev],irq[dev],dma8[dev]);
107
108 pdev = acard->devmpu;
109 if (pdev != NULL) {
110 err = pnp_activate_dev(pdev);
111 if (err < 0) {
112 pnp_release_card_device(pdev);
113 snd_printk(KERN_ERR PFX "DT-019X MPU401 pnp configure failure, skipping\n");
114 goto __mpu_error;
115 }
116 mpu_port[dev] = pnp_port_start(pdev, 0);
117 mpu_irq[dev] = pnp_irq(pdev, 0);
118 snd_printdd("dt019x: found MPU-401: port=0x%lx, irq=0x%x\n",
119 mpu_port[dev],mpu_irq[dev]);
120 } else {
121 __mpu_error:
122 acard->devmpu = NULL;
123 mpu_port[dev] = -1;
124 }
125
126 pdev = acard->devopl;
127 if (pdev != NULL) {
128 err = pnp_activate_dev(pdev);
129 if (err < 0) {
130 pnp_release_card_device(pdev);
131 snd_printk(KERN_ERR PFX "DT-019X OPL3 pnp configure failure, skipping\n");
132 goto __fm_error;
133 }
134 fm_port[dev] = pnp_port_start(pdev, 0);
135 snd_printdd("dt019x: found OPL3 synth: port=0x%lx\n",fm_port[dev]);
136 } else {
137 __fm_error:
138 acard->devopl = NULL;
139 fm_port[dev] = -1;
140 }
141
142 return 0;
143}
144
145static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid)
146{
147 int error;
148 struct snd_sb *chip;
149 struct snd_card *card;
150 struct snd_card_dt019x *acard;
151 struct snd_opl3 *opl3;
152
153 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
154 sizeof(struct snd_card_dt019x), &card);
155 if (error < 0)
156 return error;
157 acard = card->private_data;
158
159 snd_card_set_dev(card, &pcard->card->dev);
160 if ((error = snd_card_dt019x_pnp(dev, acard, pcard, pid))) {
161 snd_card_free(card);
162 return error;
163 }
164
165 if ((error = snd_sbdsp_create(card, port[dev],
166 irq[dev],
167 snd_sb16dsp_interrupt,
168 dma8[dev],
169 -1,
170 SB_HW_DT019X,
171 &chip)) < 0) {
172 snd_card_free(card);
173 return error;
174 }
175 acard->chip = chip;
176
177 strcpy(card->driver, "DT-019X");
178 strcpy(card->shortname, "Diamond Tech. DT-019X");
179 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
180 card->shortname, chip->name, chip->port,
181 irq[dev], dma8[dev]);
182
183 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
184 snd_card_free(card);
185 return error;
186 }
187 if ((error = snd_sbmixer_new(chip)) < 0) {
188 snd_card_free(card);
189 return error;
190 }
191
192 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
193 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
194 mpu_irq[dev] = -1;
195 if (snd_mpu401_uart_new(card, 0,
196/* MPU401_HW_SB,*/
197 MPU401_HW_MPU401,
198 mpu_port[dev], 0,
199 mpu_irq[dev],
200 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
201 NULL) < 0)
202 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx ?\n", mpu_port[dev]);
203 }
204
205 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
206 if (snd_opl3_create(card,
207 fm_port[dev],
208 fm_port[dev] + 2,
209 OPL3_HW_AUTO, 0, &opl3) < 0) {
210 snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx ?\n",
211 fm_port[dev], fm_port[dev] + 2);
212 } else {
213 if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
214 snd_card_free(card);
215 return error;
216 }
217 if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
218 snd_card_free(card);
219 return error;
220 }
221 }
222 }
223
224 if ((error = snd_card_register(card)) < 0) {
225 snd_card_free(card);
226 return error;
227 }
228 pnp_set_card_drvdata(pcard, card);
229 return 0;
230}
231
232static unsigned int __devinitdata dt019x_devices;
233
234static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card,
235 const struct pnp_card_device_id *pid)
236{
237 static int dev;
238 int res;
239
240 for ( ; dev < SNDRV_CARDS; dev++) {
241 if (!enable[dev])
242 continue;
243 res = snd_card_dt019x_probe(dev, card, pid);
244 if (res < 0)
245 return res;
246 dev++;
247 dt019x_devices++;
248 return 0;
249 }
250 return -ENODEV;
251}
252
253static void __devexit snd_dt019x_pnp_remove(struct pnp_card_link * pcard)
254{
255 snd_card_free(pnp_get_card_drvdata(pcard));
256 pnp_set_card_drvdata(pcard, NULL);
257}
258
259#ifdef CONFIG_PM
260static int snd_dt019x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
261{
262 struct snd_card *card = pnp_get_card_drvdata(pcard);
263 struct snd_card_dt019x *acard = card->private_data;
264 struct snd_sb *chip = acard->chip;
265
266 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
267 snd_pcm_suspend_all(chip->pcm);
268 snd_sbmixer_suspend(chip);
269 return 0;
270}
271
272static int snd_dt019x_pnp_resume(struct pnp_card_link *pcard)
273{
274 struct snd_card *card = pnp_get_card_drvdata(pcard);
275 struct snd_card_dt019x *acard = card->private_data;
276 struct snd_sb *chip = acard->chip;
277
278 snd_sbdsp_reset(chip);
279 snd_sbmixer_resume(chip);
280 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
281 return 0;
282}
283#endif
284
285static struct pnp_card_driver dt019x_pnpc_driver = {
286 .flags = PNP_DRIVER_RES_DISABLE,
287 .name = "dt019x",
288 .id_table = snd_dt019x_pnpids,
289 .probe = snd_dt019x_pnp_probe,
290 .remove = __devexit_p(snd_dt019x_pnp_remove),
291#ifdef CONFIG_PM
292 .suspend = snd_dt019x_pnp_suspend,
293 .resume = snd_dt019x_pnp_resume,
294#endif
295};
296
297static int __init alsa_card_dt019x_init(void)
298{
299 int err;
300
301 err = pnp_register_card_driver(&dt019x_pnpc_driver);
302 if (err)
303 return err;
304
305 if (!dt019x_devices) {
306 pnp_unregister_card_driver(&dt019x_pnpc_driver);
307#ifdef MODULE
308 snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n");
309#endif
310 return -ENODEV;
311 }
312 return 0;
313}
314
315static void __exit alsa_card_dt019x_exit(void)
316{
317 pnp_unregister_card_driver(&dt019x_pnpc_driver);
318}
319
320module_init(alsa_card_dt019x_init)
321module_exit(alsa_card_dt019x_exit)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index c8a8da0d4036..a4af53b5c1cf 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -33,6 +33,7 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/tlv.h>
36#include <sound/wss.h> 37#include <sound/wss.h>
37#include <sound/mpu401.h> 38#include <sound/mpu401.h>
38#include <sound/opl3.h> 39#include <sound/opl3.h>
@@ -546,6 +547,93 @@ __skip_mpu:
546 547
547#ifdef OPTi93X 548#ifdef OPTi93X
548 549
550static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
551static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
552static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
553
554static struct snd_kcontrol_new snd_opti93x_controls[] = {
555WSS_DOUBLE("Master Playback Switch", 0,
556 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
557WSS_DOUBLE_TLV("Master Playback Volume", 0,
558 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
559 db_scale_5bit_3db_step),
560WSS_DOUBLE_TLV("PCM Playback Volume", 0,
561 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
562 db_scale_5bit),
563WSS_DOUBLE_TLV("FM Playback Volume", 0,
564 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
565 db_scale_4bit_12db_max),
566WSS_DOUBLE("Line Playback Switch", 0,
567 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
568WSS_DOUBLE_TLV("Line Playback Volume", 0,
569 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
570 db_scale_4bit_12db_max),
571WSS_DOUBLE("Mic Playback Switch", 0,
572 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
573WSS_DOUBLE_TLV("Mic Playback Volume", 0,
574 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
575 db_scale_4bit_12db_max),
576WSS_DOUBLE_TLV("CD Playback Volume", 0,
577 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
578 db_scale_4bit_12db_max),
579WSS_DOUBLE("Aux Playback Switch", 0,
580 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
581WSS_DOUBLE_TLV("Aux Playback Volume", 0,
582 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
583 db_scale_4bit_12db_max),
584};
585
586static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
587{
588 struct snd_card *card;
589 unsigned int idx;
590 struct snd_ctl_elem_id id1, id2;
591 int err;
592
593 if (snd_BUG_ON(!chip || !chip->pcm))
594 return -EINVAL;
595
596 card = chip->card;
597
598 strcpy(card->mixername, chip->pcm->name);
599
600 memset(&id1, 0, sizeof(id1));
601 memset(&id2, 0, sizeof(id2));
602 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
603 /* reassign AUX0 switch to CD */
604 strcpy(id1.name, "Aux Playback Switch");
605 strcpy(id2.name, "CD Playback Switch");
606 err = snd_ctl_rename_id(card, &id1, &id2);
607 if (err < 0) {
608 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
609 return err;
610 }
611 /* reassign AUX1 switch to FM */
612 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
613 strcpy(id2.name, "FM Playback Switch");
614 err = snd_ctl_rename_id(card, &id1, &id2);
615 if (err < 0) {
616 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
617 return err;
618 }
619 /* remove AUX1 volume */
620 strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
621 snd_ctl_remove_id(card, &id1);
622
623 /* Replace WSS volume controls with OPTi93x volume controls */
624 id1.index = 0;
625 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
626 strcpy(id1.name, snd_opti93x_controls[idx].name);
627 snd_ctl_remove_id(card, &id1);
628
629 err = snd_ctl_add(card,
630 snd_ctl_new1(&snd_opti93x_controls[idx], chip));
631 if (err < 0)
632 return err;
633 }
634 return 0;
635}
636
549static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 637static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
550{ 638{
551 struct snd_opti9xx *chip = dev_id; 639 struct snd_opti9xx *chip = dev_id;
@@ -754,6 +842,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
754 error = snd_wss_mixer(codec); 842 error = snd_wss_mixer(codec);
755 if (error < 0) 843 if (error < 0)
756 return error; 844 return error;
845#ifdef OPTi93X
846 error = snd_opti93x_mixer(codec);
847 if (error < 0)
848 return error;
849#endif
757#ifdef CS4231 850#ifdef CS4231
758 error = snd_wss_timer(codec, 0, &timer); 851 error = snd_wss_timer(codec, 0, &timer);
759 if (error < 0) 852 if (error < 0)
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
12snd-sbawe-objs := sbawe.o emu8000.o 12snd-sbawe-objs := sbawe.o emu8000.o
13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
14snd-es968-objs := es968.o 14snd-es968-objs := es968.o
15snd-jazz16-objs := jazz16.o
15 16
16# Toplevel Module Dependency 17# Toplevel Module Dependency
17obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o 18obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SB8) += snd-sb8.o
21obj-$(CONFIG_SND_SB16) += snd-sb16.o 22obj-$(CONFIG_SND_SB16) += snd-sb16.o
22obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 23obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
23obj-$(CONFIG_SND_ES968) += snd-es968.o 24obj-$(CONFIG_SND_ES968) += snd-es968.o
25obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
24ifeq ($(CONFIG_SND_SB16_CSP),y) 26ifeq ($(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
29MODULE_DESCRIPTION("Media Vision Jazz16");
30MODULE_SUPPORTED_DEVICE("{{Media Vision ??? },"
31 "{RTL,RTL3000}}");
32
33MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
34MODULE_LICENSE("GPL");
35
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
39static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
40static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
41static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
42static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
43static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
44static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
45
46module_param_array(index, int, NULL, 0444);
47MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard.");
48module_param_array(id, charp, NULL, 0444);
49MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
50module_param_array(enable, bool, NULL, 0444);
51MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
52module_param_array(port, long, NULL, 0444);
53MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
54module_param_array(mpu_port, long, NULL, 0444);
55MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
56module_param_array(irq, int, NULL, 0444);
57MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
58module_param_array(mpu_irq, int, NULL, 0444);
59MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
60module_param_array(dma8, int, NULL, 0444);
61MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
62module_param_array(dma16, int, NULL, 0444);
63MODULE_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
71struct snd_card_jazz16 {
72 struct snd_sb *chip;
73};
74
75static irqreturn_t jazz16_interrupt(int irq, void *chip)
76{
77 return snd_sb8dsp_interrupt(chip);
78}
79
80static 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
101static 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
153err_unmap:
154 release_region(port, 0x10);
155 return err;
156}
157
158static 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
185static 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
220static 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
339err_free:
340 snd_card_free(card);
341 return err;
342}
343
344static 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
354static 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
367static 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
380static 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
393static int __init alsa_card_jazz16_init(void)
394{
395 return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS);
396}
397
398static void __exit alsa_card_jazz16_exit(void)
399{
400 isa_unregister_driver(&snd_jazz16_driver);
401}
402
403module_init(alsa_card_jazz16_init)
404module_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
531static struct sbmix_elem snd_sb20_ctl_master_play_vol = 531static 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),
533static 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),
535static 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);
537static struct sbmix_elem snd_sb20_ctl_cd_play_vol =
538 SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7);
539
540static 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
547static unsigned char snd_sb20_init_values[][2] = { 538static 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 */
555static struct sbmix_elem snd_sbpro_ctl_master_play_vol = 546static 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",
557static 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",
559static 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),
561static 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),
563static 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",
565static 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),
567static struct sbmix_elem snd_sbpro_ctl_mic_play_vol =
568 SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3);
569static 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 },
574static 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)
576static struct sbmix_elem snd_sbpro_ctl_capture_low_filter =
577 SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1);
578
579static 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
592static unsigned char snd_sbpro_init_values[][2] = { 566static 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 */
601static struct sbmix_elem snd_sb16_ctl_master_play_vol = 575static 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",
603static 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",
605static 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",
607static 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",
609static 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",
611static 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",
613static 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",
615static 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",
617static 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),
619static 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),
621static 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),
623static 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),
625static 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),
627static 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),
629static 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),
631static 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),
633static 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),
635static 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)
637static 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);
639static struct sbmix_elem snd_sb16_ctl_auto_mic_gain =
640 SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1);
641
642static 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
665static unsigned char snd_sb16_init_values[][2] = { 613static 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 */
681static struct sbmix_elem snd_dt019x_ctl_master_play_vol = 629static 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,
683static 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",
685static 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",
687static 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",
689static 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",
691static 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",
693static 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",
695static 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",
697static 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),
699static 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
705static 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
723static unsigned char snd_dt019x_init_values[][2] = { 659static 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 */
738static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch = 674static 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",
740static 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 },
744static 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),
746static 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);
748static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback =
749 SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
750static 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 */
755static 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);
757static struct sbmix_elem snd_als4000_3d_control_ratio =
758 SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07);
759static 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),
762static 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),
767static 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);
769static 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
773static 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),
775static struct sbmix_elem snd_als4000_ctl_qsound =
776 SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f);
777#endif
778
779static 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 */
835static int snd_sbmixer_init(struct snd_sb *chip, 725static 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:
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 5b9d6c18bc45..9191b32d9130 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -2014,6 +2014,7 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
2014 case WSS_HW_INTERWAVE: 2014 case WSS_HW_INTERWAVE:
2015 ptexts = gusmax_texts; 2015 ptexts = gusmax_texts;
2016 break; 2016 break;
2017 case WSS_HW_OPTI93X:
2017 case WSS_HW_OPL3SA2: 2018 case WSS_HW_OPL3SA2:
2018 ptexts = opl3sa_texts; 2019 ptexts = opl3sa_texts;
2019 break; 2020 break;
@@ -2246,54 +2247,12 @@ WSS_SINGLE("Beep Bypass Playback Switch", 0,
2246 CS4231_MONO_CTRL, 5, 1, 0), 2247 CS4231_MONO_CTRL, 5, 1, 0),
2247}; 2248};
2248 2249
2249static struct snd_kcontrol_new snd_opti93x_controls[] = {
2250WSS_DOUBLE("Master Playback Switch", 0,
2251 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
2252WSS_DOUBLE_TLV("Master Playback Volume", 0,
2253 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
2254 db_scale_6bit),
2255WSS_DOUBLE("PCM Playback Switch", 0,
2256 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2257WSS_DOUBLE("PCM Playback Volume", 0,
2258 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
2259WSS_DOUBLE("FM Playback Switch", 0,
2260 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2261WSS_DOUBLE("FM Playback Volume", 0,
2262 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
2263WSS_DOUBLE("Line Playback Switch", 0,
2264 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2265WSS_DOUBLE("Line Playback Volume", 0,
2266 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
2267WSS_DOUBLE("Mic Playback Switch", 0,
2268 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
2269WSS_DOUBLE("Mic Playback Volume", 0,
2270 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
2271WSS_DOUBLE("Mic Boost", 0,
2272 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2273WSS_DOUBLE("CD Playback Switch", 0,
2274 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2275WSS_DOUBLE("CD Playback Volume", 0,
2276 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
2277WSS_DOUBLE("Aux Playback Switch", 0,
2278 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
2279WSS_DOUBLE("Aux Playback Volume", 0,
2280 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
2281WSS_DOUBLE("Capture Volume", 0,
2282 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2283{
2284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2285 .name = "Capture Source",
2286 .info = snd_wss_info_mux,
2287 .get = snd_wss_get_mux,
2288 .put = snd_wss_put_mux,
2289}
2290};
2291
2292int snd_wss_mixer(struct snd_wss *chip) 2250int snd_wss_mixer(struct snd_wss *chip)
2293{ 2251{
2294 struct snd_card *card; 2252 struct snd_card *card;
2295 unsigned int idx; 2253 unsigned int idx;
2296 int err; 2254 int err;
2255 int count = ARRAY_SIZE(snd_wss_controls);
2297 2256
2298 if (snd_BUG_ON(!chip || !chip->pcm)) 2257 if (snd_BUG_ON(!chip || !chip->pcm))
2299 return -EINVAL; 2258 return -EINVAL;
@@ -2302,28 +2261,19 @@ int snd_wss_mixer(struct snd_wss *chip)
2302 2261
2303 strcpy(card->mixername, chip->pcm->name); 2262 strcpy(card->mixername, chip->pcm->name);
2304 2263
2305 if (chip->hardware == WSS_HW_OPTI93X) 2264 /* Use only the first 11 entries on AD1848 */
2306 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { 2265 if (chip->hardware & WSS_HW_AD1848_MASK)
2307 err = snd_ctl_add(card, 2266 count = 11;
2308 snd_ctl_new1(&snd_opti93x_controls[idx], 2267 /* There is no loopback on OPTI93X */
2309 chip)); 2268 else if (chip->hardware == WSS_HW_OPTI93X)
2310 if (err < 0) 2269 count = 9;
2311 return err; 2270
2312 } 2271 for (idx = 0; idx < count; idx++) {
2313 else { 2272 err = snd_ctl_add(card,
2314 int count = ARRAY_SIZE(snd_wss_controls); 2273 snd_ctl_new1(&snd_wss_controls[idx],
2315 2274 chip));
2316 /* Use only the first 11 entries on AD1848 */ 2275 if (err < 0)
2317 if (chip->hardware & WSS_HW_AD1848_MASK) 2276 return err;
2318 count = 11;
2319
2320 for (idx = 0; idx < count; idx++) {
2321 err = snd_ctl_add(card,
2322 snd_ctl_new1(&snd_wss_controls[idx],
2323 chip));
2324 if (err < 0)
2325 return err;
2326 }
2327 } 2277 }
2328 return 0; 2278 return 0;
2329} 2279}