Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: jazz16: Add support for Media Vision Jazz16 chipset

This is one of Sound Blaster Pro compatible chipsets which is supported
by Linux OSS driver and was missing native supoort for ALSA.

The Jazz16 audio codec is Crystal CS4216 which is capable
of playback and recording up to 48 kHz stereo.

Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Krzysztof Helt and committed by
Takashi Iwai
ad8decb7 5b4b2a41

+511 -16
+1
include/sound/sb.h
··· 33 33 SB_HW_20, 34 34 SB_HW_201, 35 35 SB_HW_PRO, 36 + SB_HW_JAZZ16, /* Media Vision Jazz16 */ 36 37 SB_HW_16, 37 38 SB_HW_16CSP, /* SB16 with CSP chip */ 38 39 SB_HW_ALS100, /* Avance Logic ALS100 chip */
+16
sound/isa/Kconfig
··· 239 239 To compile this driver as a module, choose M here: the module 240 240 will be called snd-interwave-stb. 241 241 242 + config 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 + 242 258 config SND_OPL3SA2 243 259 tristate "Yamaha OPL3-SA2/SA3" 244 260 select SND_OPL3_LIB
+2
sound/isa/sb/Makefile
··· 12 12 snd-sbawe-objs := sbawe.o emu8000.o 13 13 snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 14 14 snd-es968-objs := es968.o 15 + snd-jazz16-objs := jazz16.o 15 16 16 17 # Toplevel Module Dependency 17 18 obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o ··· 22 21 obj-$(CONFIG_SND_SB16) += snd-sb16.o 23 22 obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 24 23 obj-$(CONFIG_SND_ES968) += snd-es968.o 24 + obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o 25 25 ifeq ($(CONFIG_SND_SB16_CSP),y) 26 26 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 27 27 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
+385
sound/isa/sb/jazz16.c
··· 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 + } 193 + if (dma16[dev] != SNDRV_AUTO_DMA && 194 + dma16[dev] != 5 && dma16[dev] != 7) { 195 + snd_printk(KERN_ERR "dma16 must be 5 or 7"); 196 + return 0; 197 + } 198 + return 1; 199 + } 200 + 201 + static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev) 202 + { 203 + struct snd_card *card; 204 + struct snd_card_jazz16 *jazz16; 205 + struct snd_sb *chip; 206 + struct snd_opl3 *opl3; 207 + static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1}; 208 + static int possible_dmas8[] = {1, 3, -1}; 209 + static int possible_dmas16[] = {5, 7, -1}; 210 + int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq; 211 + 212 + err = snd_card_create(index[dev], id[dev], THIS_MODULE, 213 + sizeof(struct snd_card_jazz16), &card); 214 + if (err < 0) 215 + return err; 216 + 217 + jazz16 = card->private_data; 218 + 219 + xirq = irq[dev]; 220 + if (xirq == SNDRV_AUTO_IRQ) { 221 + xirq = snd_legacy_find_free_irq(possible_irqs); 222 + if (xirq < 0) { 223 + snd_printk(KERN_ERR "unable to find a free IRQ\n"); 224 + err = -EBUSY; 225 + goto err_free; 226 + } 227 + } 228 + xdma8 = dma8[dev]; 229 + if (xdma8 == SNDRV_AUTO_DMA) { 230 + xdma8 = snd_legacy_find_free_dma(possible_dmas8); 231 + if (xdma8 < 0) { 232 + snd_printk(KERN_ERR "unable to find a free DMA8\n"); 233 + err = -EBUSY; 234 + goto err_free; 235 + } 236 + } 237 + xdma16 = dma16[dev]; 238 + if (xdma16 == SNDRV_AUTO_DMA) { 239 + xdma16 = snd_legacy_find_free_dma(possible_dmas16); 240 + if (xdma16 < 0) { 241 + snd_printk(KERN_ERR "unable to find a free DMA16\n"); 242 + err = -EBUSY; 243 + goto err_free; 244 + } 245 + } 246 + 247 + xmpu_port = mpu_port[dev]; 248 + if (xmpu_port == SNDRV_AUTO_PORT) 249 + xmpu_port = 0; 250 + err = jazz16_detect_board(port[dev], xmpu_port); 251 + if (err < 0) { 252 + printk(KERN_ERR "Media Vision Jazz16 board not detected\n"); 253 + goto err_free; 254 + } 255 + err = snd_sbdsp_create(card, port[dev], irq[dev], 256 + jazz16_interrupt, 257 + dma8[dev], dma16[dev], 258 + SB_HW_JAZZ16, 259 + &chip); 260 + if (err < 0) 261 + goto err_free; 262 + 263 + xmpu_irq = mpu_irq[dev]; 264 + if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT) 265 + xmpu_irq = 0; 266 + err = jazz16_configure_board(chip, xmpu_irq); 267 + if (err < 0) { 268 + printk(KERN_ERR "Media Vision Jazz16 configuration failed\n"); 269 + goto err_free; 270 + } 271 + 272 + jazz16->chip = chip; 273 + 274 + strcpy(card->driver, "jazz16"); 275 + strcpy(card->shortname, "Media Vision Jazz16"); 276 + sprintf(card->longname, 277 + "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d", 278 + port[dev], xirq, xdma8, xdma16); 279 + 280 + err = snd_sb8dsp_pcm(chip, 0, NULL); 281 + if (err < 0) 282 + goto err_free; 283 + err = snd_sbmixer_new(chip); 284 + if (err < 0) 285 + goto err_free; 286 + 287 + err = snd_opl3_create(card, chip->port, chip->port + 2, 288 + OPL3_HW_AUTO, 1, &opl3); 289 + if (err < 0) 290 + snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", 291 + chip->port, chip->port + 2); 292 + else { 293 + err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 294 + if (err < 0) 295 + goto err_free; 296 + } 297 + if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 298 + if (mpu_irq[dev] == SNDRV_AUTO_IRQ) 299 + mpu_irq[dev] = -1; 300 + 301 + if (snd_mpu401_uart_new(card, 0, 302 + MPU401_HW_MPU401, 303 + mpu_port[dev], 0, 304 + mpu_irq[dev], 305 + mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, 306 + NULL) < 0) 307 + snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", 308 + mpu_port[dev]); 309 + } 310 + 311 + snd_card_set_dev(card, devptr); 312 + 313 + err = snd_card_register(card); 314 + if (err < 0) 315 + goto err_free; 316 + 317 + dev_set_drvdata(devptr, card); 318 + return 0; 319 + 320 + err_free: 321 + snd_card_free(card); 322 + return err; 323 + } 324 + 325 + static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev) 326 + { 327 + struct snd_card *card = dev_get_drvdata(devptr); 328 + 329 + dev_set_drvdata(devptr, NULL); 330 + snd_card_free(card); 331 + return 0; 332 + } 333 + 334 + #ifdef CONFIG_PM 335 + static int snd_jazz16_suspend(struct device *pdev, unsigned int n, 336 + pm_message_t state) 337 + { 338 + struct snd_card *card = dev_get_drvdata(pdev); 339 + struct snd_card_jazz16 *acard = card->private_data; 340 + struct snd_sb *chip = acard->chip; 341 + 342 + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 343 + snd_pcm_suspend_all(chip->pcm); 344 + snd_sbmixer_suspend(chip); 345 + return 0; 346 + } 347 + 348 + static int snd_jazz16_resume(struct device *pdev, unsigned int n) 349 + { 350 + struct snd_card *card = dev_get_drvdata(pdev); 351 + struct snd_card_jazz16 *acard = card->private_data; 352 + struct snd_sb *chip = acard->chip; 353 + 354 + snd_sbdsp_reset(chip); 355 + snd_sbmixer_resume(chip); 356 + snd_power_change_state(card, SNDRV_CTL_POWER_D0); 357 + return 0; 358 + } 359 + #endif 360 + 361 + static struct isa_driver snd_jazz16_driver = { 362 + .match = snd_jazz16_match, 363 + .probe = snd_jazz16_probe, 364 + .remove = __devexit_p(snd_jazz16_remove), 365 + #ifdef CONFIG_PM 366 + .suspend = snd_jazz16_suspend, 367 + .resume = snd_jazz16_resume, 368 + #endif 369 + .driver = { 370 + .name = "jazz16" 371 + }, 372 + }; 373 + 374 + static int __init alsa_card_jazz16_init(void) 375 + { 376 + return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS); 377 + } 378 + 379 + static void __exit alsa_card_jazz16_exit(void) 380 + { 381 + isa_unregister_driver(&snd_jazz16_driver); 382 + } 383 + 384 + module_init(alsa_card_jazz16_init) 385 + module_exit(alsa_card_jazz16_exit)
+101 -16
sound/isa/sb/sb8_main.c
··· 106 106 struct snd_sb *chip = snd_pcm_substream_chip(substream); 107 107 struct snd_pcm_runtime *runtime = substream->runtime; 108 108 unsigned int mixreg, rate, size, count; 109 + unsigned char format; 110 + unsigned char stereo = runtime->channels > 1; 111 + int dma; 109 112 110 113 rate = runtime->rate; 111 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 124 case SB_HW_PRO: 113 125 if (runtime->channels > 1) { 114 126 if (snd_BUG_ON(rate != SB8_RATE(11025) && ··· 145 133 default: 146 134 return -EINVAL; 147 135 } 136 + if (chip->mode & SB_MODE_PLAYBACK_16) { 137 + format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; 138 + dma = chip->dma16; 139 + } else { 140 + format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; 141 + chip->mode |= SB_MODE_PLAYBACK_8; 142 + dma = chip->dma8; 143 + } 148 144 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); 149 145 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); 150 146 spin_lock_irqsave(&chip->reg_lock, flags); 151 147 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); 152 - if (runtime->channels > 1) { 148 + if (chip->hardware == SB_HW_JAZZ16) 149 + snd_sbdsp_command(chip, format); 150 + else if (stereo) { 153 151 /* set playback stereo mode */ 154 152 spin_lock(&chip->mixer_lock); 155 153 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); ··· 169 147 /* Soundblaster hardware programming reference guide, 3-23 */ 170 148 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); 171 149 runtime->dma_area[0] = 0x80; 172 - snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); 150 + snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); 173 151 /* force interrupt */ 174 - chip->mode = SB_MODE_HALT; 175 152 snd_sbdsp_command(chip, SB_DSP_OUTPUT); 176 153 snd_sbdsp_command(chip, 0); 177 154 snd_sbdsp_command(chip, 0); 178 155 } 179 156 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 180 - if (runtime->channels > 1) { 157 + if (stereo) { 181 158 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 182 159 spin_lock(&chip->mixer_lock); 183 160 /* save output filter status and turn it off */ ··· 189 168 snd_sbdsp_command(chip, 256 - runtime->rate_den); 190 169 } 191 170 if (chip->playback_format != SB_DSP_OUTPUT) { 171 + if (chip->mode & SB_MODE_PLAYBACK_16) 172 + count /= 2; 192 173 count--; 193 174 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 194 175 snd_sbdsp_command(chip, count & 0xff); 195 176 snd_sbdsp_command(chip, count >> 8); 196 177 } 197 178 spin_unlock_irqrestore(&chip->reg_lock, flags); 198 - snd_dma_program(chip->dma8, runtime->dma_addr, 179 + snd_dma_program(dma, runtime->dma_addr, 199 180 size, DMA_MODE_WRITE | DMA_AUTOINIT); 200 181 return 0; 201 182 } ··· 235 212 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 236 213 } 237 214 spin_unlock_irqrestore(&chip->reg_lock, flags); 238 - chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT; 239 215 return 0; 240 216 } 241 217 ··· 256 234 struct snd_sb *chip = snd_pcm_substream_chip(substream); 257 235 struct snd_pcm_runtime *runtime = substream->runtime; 258 236 unsigned int mixreg, rate, size, count; 237 + unsigned char format; 238 + unsigned char stereo = runtime->channels > 1; 239 + int dma; 259 240 260 241 rate = runtime->rate; 261 242 switch (chip->hardware) { 243 + case SB_HW_JAZZ16: 244 + if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { 245 + if (chip->mode & SB_MODE_PLAYBACK_16) 246 + return -EBUSY; 247 + else 248 + chip->mode |= SB_MODE_CAPTURE_16; 249 + } 250 + chip->capture_format = SB_DSP_LO_INPUT_AUTO; 251 + break; 262 252 case SB_HW_PRO: 263 253 if (runtime->channels > 1) { 264 254 if (snd_BUG_ON(rate != SB8_RATE(11025) && ··· 296 262 default: 297 263 return -EINVAL; 298 264 } 265 + if (chip->mode & SB_MODE_CAPTURE_16) { 266 + format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; 267 + dma = chip->dma16; 268 + } else { 269 + format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; 270 + chip->mode |= SB_MODE_CAPTURE_8; 271 + dma = chip->dma8; 272 + } 299 273 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); 300 274 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); 301 275 spin_lock_irqsave(&chip->reg_lock, flags); 302 276 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 303 - if (runtime->channels > 1) 277 + if (chip->hardware == SB_HW_JAZZ16) 278 + snd_sbdsp_command(chip, format); 279 + else if (stereo) 304 280 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); 305 281 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 306 - if (runtime->channels > 1) { 282 + if (stereo) { 307 283 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 308 284 spin_lock(&chip->mixer_lock); 309 285 /* save input filter status and turn it off */ ··· 326 282 snd_sbdsp_command(chip, 256 - runtime->rate_den); 327 283 } 328 284 if (chip->capture_format != SB_DSP_INPUT) { 285 + if (chip->mode & SB_MODE_PLAYBACK_16) 286 + count /= 2; 329 287 count--; 330 288 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 331 289 snd_sbdsp_command(chip, count & 0xff); 332 290 snd_sbdsp_command(chip, count >> 8); 333 291 } 334 292 spin_unlock_irqrestore(&chip->reg_lock, flags); 335 - snd_dma_program(chip->dma8, runtime->dma_addr, 293 + snd_dma_program(dma, runtime->dma_addr, 336 294 size, DMA_MODE_READ | DMA_AUTOINIT); 337 295 return 0; 338 296 } ··· 374 328 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 375 329 } 376 330 spin_unlock_irqrestore(&chip->reg_lock, flags); 377 - chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT; 378 331 return 0; 379 332 } 380 333 ··· 384 339 385 340 snd_sb_ack_8bit(chip); 386 341 switch (chip->mode) { 387 - case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ 342 + case SB_MODE_PLAYBACK_16: /* ok.. playback is active */ 343 + if (chip->hardware != SB_HW_JAZZ16) 344 + break; 345 + /* fallthru */ 346 + case SB_MODE_PLAYBACK_8: 388 347 substream = chip->playback_substream; 389 348 runtime = substream->runtime; 390 349 if (chip->playback_format == SB_DSP_OUTPUT) 391 350 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); 392 351 snd_pcm_period_elapsed(substream); 393 352 break; 353 + case SB_MODE_CAPTURE_16: 354 + if (chip->hardware != SB_HW_JAZZ16) 355 + break; 356 + /* fallthru */ 394 357 case SB_MODE_CAPTURE_8: 395 358 substream = chip->capture_substream; 396 359 runtime = substream->runtime; ··· 414 361 { 415 362 struct snd_sb *chip = snd_pcm_substream_chip(substream); 416 363 size_t ptr; 364 + int dma; 417 365 418 - if (chip->mode != SB_MODE_PLAYBACK_8) 366 + if (chip->mode & SB_MODE_PLAYBACK_8) 367 + dma = chip->dma8; 368 + else if (chip->mode & SB_MODE_PLAYBACK_16) 369 + dma = chip->dma16; 370 + else 419 371 return 0; 420 - ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); 372 + ptr = snd_dma_pointer(dma, chip->p_dma_size); 421 373 return bytes_to_frames(substream->runtime, ptr); 422 374 } 423 375 ··· 430 372 { 431 373 struct snd_sb *chip = snd_pcm_substream_chip(substream); 432 374 size_t ptr; 375 + int dma; 433 376 434 - if (chip->mode != SB_MODE_CAPTURE_8) 377 + if (chip->mode & SB_MODE_CAPTURE_8) 378 + dma = chip->dma8; 379 + else if (chip->mode & SB_MODE_CAPTURE_16) 380 + dma = chip->dma16; 381 + else 435 382 return 0; 436 - ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); 383 + ptr = snd_dma_pointer(dma, chip->c_dma_size); 437 384 return bytes_to_frames(substream->runtime, ptr); 438 385 } 439 386 ··· 509 446 runtime->hw = snd_sb8_capture; 510 447 } 511 448 switch (chip->hardware) { 449 + case SB_HW_JAZZ16: 450 + runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE; 451 + runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000; 452 + runtime->hw.rate_min = 4000; 453 + runtime->hw.rate_max = 50000; 454 + runtime->hw.channels_max = 2; 455 + break; 512 456 case SB_HW_PRO: 513 457 runtime->hw.rate_max = 44100; 514 458 runtime->hw.channels_max = 2; ··· 538 468 } 539 469 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 540 470 &hw_constraints_clock); 471 + if (chip->dma8 > 3 || chip->dma16 >= 0) { 472 + snd_pcm_hw_constraint_step(runtime, 0, 473 + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2); 474 + snd_pcm_hw_constraint_step(runtime, 0, 475 + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2); 476 + runtime->hw.buffer_bytes_max = 128 * 1024 * 1024; 477 + runtime->hw.period_bytes_max = 128 * 1024 * 1024; 478 + } 541 479 return 0; 542 480 } 543 481 ··· 558 480 chip->capture_substream = NULL; 559 481 spin_lock_irqsave(&chip->open_lock, flags); 560 482 chip->open &= ~SB_OPEN_PCM; 483 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 484 + chip->mode &= ~SB_MODE_PLAYBACK; 485 + else 486 + chip->mode &= ~SB_MODE_CAPTURE; 561 487 spin_unlock_irqrestore(&chip->open_lock, flags); 562 488 return 0; 563 489 } ··· 597 515 struct snd_card *card = chip->card; 598 516 struct snd_pcm *pcm; 599 517 int err; 518 + size_t max_prealloc = 64 * 1024; 600 519 601 520 if (rpcm) 602 521 *rpcm = NULL; ··· 610 527 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); 611 528 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); 612 529 530 + if (chip->dma8 > 3 || chip->dma16 >= 0) 531 + max_prealloc = 128 * 1024; 613 532 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 614 533 snd_dma_isa_data(), 615 - 64*1024, 64*1024); 534 + 64*1024, max_prealloc); 616 535 617 536 if (rpcm) 618 537 *rpcm = pcm;
+3
sound/isa/sb/sb_common.c
··· 170 170 case SB_HW_CS5530: 171 171 str = "16 (CS5530)"; 172 172 break; 173 + case SB_HW_JAZZ16: 174 + str = "Pro (Jazz16)"; 175 + break; 173 176 default: 174 177 return -ENODEV; 175 178 }
+3
sound/isa/sb/sb_mixer.c
··· 779 779 return err; 780 780 break; 781 781 case SB_HW_PRO: 782 + case SB_HW_JAZZ16: 782 783 if ((err = snd_sbmixer_init(chip, 783 784 snd_sbpro_controls, 784 785 ARRAY_SIZE(snd_sbpro_controls), ··· 930 929 save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); 931 930 break; 932 931 case SB_HW_PRO: 932 + case SB_HW_JAZZ16: 933 933 save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); 934 934 break; 935 935 case SB_HW_16: ··· 957 955 restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); 958 956 break; 959 957 case SB_HW_PRO: 958 + case SB_HW_JAZZ16: 960 959 restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); 961 960 break; 962 961 case SB_HW_16: