From: Rask Ingemann Lambertsen <rask(a)sygehus.dk>
- Add support for Jazz16 features to the common SoundBlaster
code.
- Add a front end for Jazz16 based sound cards.
Tested with a Jazz16 based sound card and Linux 2.6.20.
Signed-off-by: Rask Ingemann Lambertsen <rask(a)sygehus.dk>
---
This patch is a prerequisite for the Jazz PnP patch, which needs the
patched include/sound/sb.h.
Documentation/sound/alsa/ALSA-Configuration.txt | 10
include/sound/sb.h | 5
sound/isa/Kconfig | 15 +
sound/isa/sb/Makefile | 2
sound/isa/sb/jazz16.c | 193 ++++++++++++++
sound/isa/sb/sb8_main.c | 105 +++++++
sound/isa/sb/sb_common.c | 12
sound/isa/sb/sb_mixer.c | 3
8 files changed, 335 insertions(+), 10 deletions(-)
--- linux-2.6.20/sound/isa/sb/Makefile.orig 2007-02-19 21:00:09.000000000 +0100
+++ linux-2.6.20/sound/isa/sb/Makefile 2007-03-02 20:14:48.000000000 +0100
@@ -12,6 +12,7 @@ snd-sb16-objs := sb16.o
snd-sbawe-objs := sbawe.o emu8000.o
snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
snd-es968-objs := es968.o
+snd-jazz16-objs := jazz16.o
#
# this function returns:
@@ -30,6 +31,7 @@ obj-$(CONFIG_SND_SB16) += snd-sb16.o snd
obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o
obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o
obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o
+obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o snd-sb8-dsp.o snd-sb-common.o
ifeq ($(CONFIG_SND_SB16_CSP),y)
obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
--- linux-2.6.20/sound/isa/sb/jazz16.c-orig 2007-02-17 20:01:40.000000000 +0100
+++ linux-2.6.20/sound/isa/sb/jazz16.c 2007-03-18 13:43:35.000000000 +0100
@@ -0,0 +1,193 @@
+/* Driver for Media Vision Jazz16 based boards.
+ *
+ * Copyright (c) 2007 by Rask Ingemann Lambertsen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * The Jazz16 is an SB Pro compatible chip with a 16-bit mode and higher
+ * playback and capture rates added to it. It is not SB 16 compatible.
+ * There is also an MPU-401 interface.
+ *
+ * The IBM PPS Model 6015 has a Jazz16 chip on board. Please tell me if it
+ * works with this driver or not.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/pnp.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/sb.h>
+#include <sound/mpu401.h>
+#include <sound/opl3.h>
+#include <sound/initval.h>
+
+MODULE_AUTHOR ("Rask Ingemann Lambertsen <rask(a)sygehus.dk>");
+MODULE_DESCRIPTION ("Jazz16");
+MODULE_LICENSE("GPL");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for Jazz16 soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for Jazz16 soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable Jazz16 soundcard.");
+
+#define PFX "jazz16: "
+#define PFX_WARN KERN_WARNING PFX
+#define PFX_ERR KERN_ERR PFX
+
+static struct pnp_driver snd_jazz16_pnp_driver;
+
+static irqreturn_t jazz16_interrupt(int irq, void *dev_id)
+{
+ struct snd_sb *chip = (struct snd_sb *) dev_id;
+ return snd_sb8dsp_interrupt(chip);
+}
+
+static struct pnp_device_id snd_jazz16_pnpids[] = {
+ { .id = "PNPb00f" },
+ { .id = "" }
+};
+MODULE_DEVICE_TABLE(pnp, snd_jazz16_pnpids);
+
+static int __devinit snd_jazz16_pnp_probe(struct pnp_dev *pnp_dev,
+ const struct pnp_device_id *pnp_id)
+{ struct snd_sb *chip;
+ struct snd_card *card;
+ struct snd_opl3 *opl3;
+ int err;
+ uint sbport, sbirq, sbdma8, sbdma16, mpuport, mpuirq;
+ static uint dev_num = 0;
+
+ if (enable[dev_num])
+ card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0);
+ else
+ card = NULL;
+ dev_num ++;
+ if (card == NULL)
+ return -ENOMEM;
+ pnp_set_drvdata(pnp_dev, card);
+ /* TODO use pnp_port_valid(), pnp_port_flags(), pnp_port_length()... */
+ sbport = pnp_port_start(pnp_dev, 0);
+ sbirq = pnp_irq(pnp_dev, 0);
+ sbdma8 = pnp_dma(pnp_dev, 0);
+ sbdma16 = pnp_dma(pnp_dev, 1);
+ err = snd_sbdsp_create(card, sbport, sbirq, jazz16_interrupt,
+ sbdma8, sbdma16, SB_HW_AUTO, &chip);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ /* TODO length limits - strncpy()/snprintf() and friends. */
+ strcpy(card->driver, "Jazz16");
+ strcpy(card->shortname, "Media Vision Jazz16");
+ sprintf(card->longname, "%s at 0x%x, irq %u, dma8 %u, dma16 %u",
+ chip->name, sbport, sbirq, sbdma8, sbdma16);
+
+ if (chip->hardware != SB_HW_JAZZ16) {
+ snd_printk(PFX_ERR "Not a Jazz16 chip at 0x%x.\n", sbport);
+ snd_card_free(card);
+ return -ENODEV;
+ }
+ err = snd_sb8dsp_pcm(chip, 0, NULL);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ err = snd_sbmixer_new(chip);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ err = snd_opl3_create(card, sbport, sbport + 2,
+ OPL3_HW_AUTO, 1, &opl3);
+ if (err < 0) {
+ snd_printk(PFX_WARN "No OPL device found, skipping.\n");
+ } else {
+ err = snd_opl3_timer_new(opl3, 1, 2);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ }
+ if (pnp_port_valid(pnp_dev, 1)
+ && !(pnp_port_flags(pnp_dev, 1) & IORESOURCE_DISABLED)) {
+ int mpuirqflags;
+ if (!pnp_irq_valid(pnp_dev, 1)
+ || pnp_irq_flags(pnp_dev, 1) & IORESOURCE_DISABLED) {
+ mpuirq = -1;
+ mpuirqflags = 0;
+ } else {
+ mpuirq = pnp_irq(pnp_dev, 1);
+ mpuirqflags = IRQF_DISABLED;
+ }
+ mpuport = pnp_port_start(pnp_dev, 1);
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
+ mpuport, 0, mpuirq,
+ mpuirqflags, NULL);
+ if (err < 0) {
+ snd_printk(PFX_WARN "MPU-401 device not configured, skipping.\n");
+ }
+ }
+ err = snd_card_register(card);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ return 0;
+}
+
+static void __devexit snd_jazz16_pnp_remove(struct pnp_dev *dev)
+{
+ snd_card_free(pnp_get_drvdata(dev));
+ pnp_set_drvdata(dev, NULL);
+}
+
+static struct pnp_driver snd_jazz16_pnp_driver = {
+ .name = "Jazz16",
+ .id_table = snd_jazz16_pnpids,
+ .probe = snd_jazz16_pnp_probe,
+ .remove = __devexit_p(snd_jazz16_pnp_remove),
+};
+
+static int __devinit alsa_card_jazz16_init (void)
+{
+ return pnp_register_driver(&snd_jazz16_pnp_driver);
+}
+
+static void __devexit alsa_card_jazz16_exit(void)
+{
+ pnp_unregister_driver(&snd_jazz16_pnp_driver);
+}
+
+module_init (alsa_card_jazz16_init);
+module_exit (alsa_card_jazz16_exit);
--- linux-2.6.20/sound/isa/sb/sb_mixer.c.orig 2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/sound/isa/sb/sb_mixer.c 2007-02-25 01:09:05.000000000 +0100
@@ -811,6 +811,7 @@ int snd_sbmixer_new(struct snd_sb *chip)
return err;
break;
case SB_HW_PRO:
+ case SB_HW_JAZZ16:
if ((err = snd_sbmixer_init(chip,
snd_sbpro_controls,
ARRAY_SIZE(snd_sbpro_controls),
@@ -946,6 +947,7 @@ void snd_sbmixer_suspend(struct snd_sb *
save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
break;
case SB_HW_PRO:
+ case SB_HW_JAZZ16:
save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
break;
case SB_HW_16:
@@ -971,6 +973,7 @@ void snd_sbmixer_resume(struct snd_sb *c
restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
break;
case SB_HW_PRO:
+ case SB_HW_JAZZ16:
restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
break;
case SB_HW_16:
--- linux-2.6.20/sound/isa/sb/sb_common.c.orig 2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/sound/isa/sb/sb_common.c 2007-03-03 12:50:32.000000000 +0100
@@ -146,8 +146,16 @@ static int snd_sbdsp_probe(struct snd_sb
}
break;
case 3:
- chip->hardware = SB_HW_PRO;
- str = "Pro";
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ if (snd_sbdsp_command(chip, SB_DSP_GET_JAZZ_VERSION) &&
+ SB_VERSION_IS_JAZZ16(snd_sbdsp_get_byte (chip))) {
+ chip->hardware = SB_HW_JAZZ16;
+ str = "Pro (Jazz16)";
+ } else {
+ chip->hardware = SB_HW_PRO;
+ str = "Pro";
+ }
+ spin_unlock_irqrestore (&chip->reg_lock, flags);
break;
case 4:
chip->hardware = SB_HW_16;
--- linux-2.6.20/sound/isa/sb/sb8_main.c.orig 2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/sound/isa/sb/sb8_main.c 2007-03-24 23:30:22.000000000 +0100
@@ -28,6 +28,9 @@
*
* Wed Jul 12 22:02:55 CEST 2000 Uros Bizjak <uros(a)kss-loka.si>
* Cleaned up and rewrote lowlevel routines.
+ *
+ * Sat Mar 24 23:29:20 CEST 2007 Rask Ingemann Lambertsen <rask(a)sygehus.dk>
+ * Added Jazz16 enhancements (ported from sound/oss/sb_common.c).
*/
#include <sound/driver.h>
@@ -73,6 +76,15 @@ static struct snd_ratnum stereo_clocks[]
}
};
+/* For stereo playback and capture, the denominator is divided by two, so it
+ * must be even to get the intended sample rate. */
+static struct snd_ratnum jazz16_stereo_clock = {
+ .num = SB8_CLOCK,
+ .den_min = 2,
+ .den_max = 512,
+ .den_step = 2,
+};
+
static int snd_sb8_hw_constraint_rate_channels(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
@@ -101,14 +113,53 @@ static int snd_sb8_hw_constraint_channel
return 0;
}
+static int snd_jazz16_hw_constraint_rate_channels(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ int err = 0;
+
+ if (c->max > 1) {
+ unsigned int num = 0, den = 0;
+ err = snd_interval_ratnum(r, 1, &jazz16_stereo_clock, &num, &den);
+ if (err >= 0 && den) {
+ params->rate_num = num;
+ params->rate_den = den;
+ }
+ }
+ return err;
+}
+
+static int snd_jazz16_hw_constraint_channels_rate(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ int err = 0;
+
+ /* Force mono mode if the sample rate interval doesn't allow stereo. */
+ if (SB8_DEN(r->min) == SB8_DEN(r->max)
+ && SB8_DEN(r->min) & 1)
+ {
+ struct snd_interval t = { .min = 1, .max = 1 };
+ struct snd_interval *c;
+
+ c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ err = snd_interval_refine(c, &t);
+ }
+ return err;
+}
+
static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
{
unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mixreg, rate, size, count;
+ unsigned int mixreg, rate, size, count, dma;
+ unsigned char stereo, format;
rate = runtime->rate;
+ stereo = runtime->channels > 1;
switch (chip->hardware) {
case SB_HW_PRO:
if (runtime->channels > 1) {
@@ -117,6 +168,7 @@ static int snd_sb8_playback_prepare(stru
break;
}
/* fallthru */
+ case SB_HW_JAZZ16:
case SB_HW_201:
if (rate > 23000) {
chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
@@ -134,8 +186,17 @@ static int snd_sb8_playback_prepare(stru
}
size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
+ if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
+ dma = chip->dma16;
+ format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
+ } else {
+ dma = chip->dma8;
+ format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
+ }
spin_lock_irqsave(&chip->reg_lock, flags);
snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
+ if (chip->hardware >= SB_HW_PRO)
+ snd_sbdsp_command(chip, format);
if (runtime->channels > 1) {
/* set playback stereo mode */
spin_lock(&chip->mixer_lock);
@@ -173,7 +234,7 @@ static int snd_sb8_playback_prepare(stru
snd_sbdsp_command(chip, count >> 8);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_dma_program(chip->dma8, runtime->dma_addr,
+ snd_dma_program(dma, runtime->dma_addr,
size, DMA_MODE_WRITE | DMA_AUTOINIT);
return 0;
}
@@ -232,9 +293,11 @@ static int snd_sb8_capture_prepare(struc
unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mixreg, rate, size, count;
+ unsigned int mixreg, rate, size, count, dma;
+ unsigned char stereo, format;
rate = runtime->rate;
+ stereo = runtime->channels > 1;
switch (chip->hardware) {
case SB_HW_PRO:
if (runtime->channels > 1) {
@@ -242,6 +305,8 @@ static int snd_sb8_capture_prepare(struc
chip->capture_format = SB_DSP_HI_INPUT_AUTO;
break;
}
+ /* fall through */
+ case SB_HW_JAZZ16:
chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO;
break;
case SB_HW_201:
@@ -261,10 +326,17 @@ static int snd_sb8_capture_prepare(struc
}
size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
+ if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
+ dma = chip->dma16;
+ format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
+ } else {
+ dma = chip->dma8;
+ format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
+ }
spin_lock_irqsave(&chip->reg_lock, flags);
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
- if (runtime->channels > 1)
- snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
+ if (chip->hardware >= SB_HW_PRO)
+ snd_sbdsp_command(chip, format);
snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
if (runtime->channels > 1) {
snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
@@ -285,7 +357,7 @@ static int snd_sb8_capture_prepare(struc
snd_sbdsp_command(chip, count >> 8);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_dma_program(chip->dma8, runtime->dma_addr,
+ snd_dma_program(dma, runtime->dma_addr,
size, DMA_MODE_READ | DMA_AUTOINIT);
return 0;
}
@@ -358,10 +430,12 @@ static snd_pcm_uframes_t snd_sb8_playbac
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
size_t ptr;
+ int dma;
if (chip->mode != SB_MODE_PLAYBACK_8)
return 0;
- ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size);
+ dma = (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? chip->dma16 : chip->dma8;
+ ptr = snd_dma_pointer(dma, chip->p_dma_size);
return bytes_to_frames(substream->runtime, ptr);
}
@@ -369,10 +443,12 @@ static snd_pcm_uframes_t snd_sb8_capture
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
size_t ptr;
+ int dma;
if (chip->mode != SB_MODE_CAPTURE_8)
return 0;
- ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size);
+ dma = (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? chip->dma16 : chip->dma8;
+ ptr = snd_dma_pointer(dma, chip->c_dma_size);
return bytes_to_frames(substream->runtime, ptr);
}
@@ -443,6 +519,19 @@ static int snd_sb8_open(struct snd_pcm_s
runtime->hw = snd_sb8_capture;
}
switch (chip->hardware) {
+ case SB_HW_JAZZ16:
+ runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
+ runtime->hw.rates |= SNDRV_PCM_RATE_8000_44100;
+ runtime->hw.rate_max = 45455;
+ runtime->hw.channels_max = 2;
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ snd_jazz16_hw_constraint_rate_channels, NULL,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ snd_jazz16_hw_constraint_channels_rate, NULL,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ break;
case SB_HW_PRO:
runtime->hw.rate_max = 44100;
runtime->hw.channels_max = 2;
--- linux-2.6.20/sound/isa/Kconfig.orig 2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/sound/isa/Kconfig 2007-03-25 21:49:44.000000000 +0200
@@ -248,6 +248,21 @@ config SND_INTERWAVE_STB
To compile this driver as a module, choose M here: the module
will be called snd-interwave-stb.
+config SND_JAZZ16
+ tristate "Media Vision Jazz16"
+ depends on SND
+ select SND_OPL3_LIB
+ select SND_PCM
+ help
+ Say Y here to include support for Media Vision Jazz16 based
+ soundcards.
+
+ You probably want to enable Jazz16 Plug and Play support
+ (CONFIG_JAZZ16PNP) also.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-jazz16.
+
config SND_OPL3SA2
tristate "Yamaha OPL3-SA2/SA3"
depends on SND
--- linux-2.6.20/Documentation/sound/alsa/ALSA-Configuration.txt-orig 2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/Documentation/sound/alsa/ALSA-Configuration.txt 2007-03-25 20:35:31.000000000 +0200
@@ -1120,6 +1120,16 @@ Prior to version 0.9.0rc4 options had a
This module supports multiple cards, autoprobe and ISA PnP.
+ Module snd-jazz16
+ -----------------
+
+ Module for sound cards based on Media Vision Jazz16 chip (PnP only)
+
+ This module supports multiple cards and PnP.
+
+ Note: You will most likely want to enable Jazz16 PnP support
+ (CONFIG_JAZZ16PNP) in the kernel.
+
Module snd-korg1212
-------------------
--- linux-2.6.20/include/sound/sb.h.orig 2007-02-19 20:57:51.000000000 +0100
+++ linux-2.6.20/include/sound/sb.h 2007-03-25 21:37:01.000000000 +0200
@@ -33,6 +33,7 @@ enum sb_hw_type {
SB_HW_20,
SB_HW_201,
SB_HW_PRO,
+ SB_HW_JAZZ16, /* Media Vision Jazz16 chip */
SB_HW_16,
SB_HW_16CSP, /* SB16 with CSP chip */
SB_HW_ALS100, /* Avance Logic ALS100 chip */
@@ -142,6 +143,7 @@ struct snd_sb {
#define SB_DSP_HI_INPUT_AUTO 0x98
#define SB_DSP_IMMED_INT 0xf2
#define SB_DSP_GET_VERSION 0xe1
+#define SB_DSP_GET_JAZZ_VERSION 0xfa
#define SB_DSP_SPEAKER_ON 0xd1
#define SB_DSP_SPEAKER_OFF 0xd3
#define SB_DSP_DMA8_OFF 0xd0
@@ -265,6 +267,9 @@ struct snd_sb {
#define SB_DMASETUP_DMA6 0x40
#define SB_DMASETUP_DMA7 0x80
+/* Check the output of SB_DSP_GET_JAZZ_VERSION. */
+#define SB_VERSION_IS_JAZZ16(x) ((x) == 0x12)
+
/*
*
*/
--
Rask Ingemann Lambertsen