All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][RFT] Adding support for Jazz16 based sound cards
@ 2007-03-11 23:24 Rask Ingemann Lambertsen
  2007-03-12 11:28 ` Takashi Iwai
  2007-03-19  0:32 ` Rene Herman
  0 siblings, 2 replies; 24+ messages in thread
From: Rask Ingemann Lambertsen @ 2007-03-11 23:24 UTC (permalink / raw)
  To: alsa-devel; +Cc: Adam Belay

   Below is a patch against linux-2.6.20 to add support for Jazz16 sound
cards. It consists of changes to ALSA's SoundBlaster support and a new PnP
protocol for detecting the card, setting resources and such. Before
submitting a patch for inclusion into Linux, I would like to have a few
comments and perhaps a test report from someone else.

   The Jazz16 is an SB Pro clone with higher stereo sample rates of upto
45454 Hz and 16-bit sound. As such, I have modified the SoundBlaster code to
make use of the features of the Jazz16.

   In stereo mode, the denominator used for setting the sample rate must be
even. Some silly(?) apps like timidity++ set the playback rate before
seeting the number of channels, which causes needless rounding of the mono
playback rate. E.g. "timidity -s 40000 -osM" results in a playback rate of
38461 Hz (a denominator of 26) even though 40000 Hz (a denominator of 25) is
fine in mono mode. This is not a big problem, but is there an easy way of
fixing it?

   I tried to include u-law support, but it doesn't sound right and playback
speed is about one third of what it should be. I could really use some
documentation here. I'll remove it before submitting a final patch if I
don't get it to work.

   Setting the irq of the MPU-401 port requires the SB part to be active and
even worse, DSP commands need to be sent. Would it be better to just use the
MPU-401 port without an irq and avoid the complexity?

-- 
Rask Ingemann Lambertsen

--- 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-11 19:20:07.000000000 +0100
@@ -0,0 +1,169 @@
+/* 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.
+ * The chip has an MPU-401 interface which is handled by the MPU-401 driver.
+ *
+ * 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@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_DEBUG	KERN_DEBUG 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;
+	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);
+	/* FIXME 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);
+	if ((err = snd_sbdsp_create (card, sbport, sbirq, jazz16_interrupt,
+	                             sbdma8, sbdma16, SB_HW_AUTO, &chip)) < 0) {
+		snd_card_free (card);
+		return (err);
+	}
+	/* FIXME 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);
+	}
+	if ((err = snd_sb8dsp_pcm (chip, 0, NULL)) < 0) {
+		snd_card_free (card);
+		return (err);
+	}
+	if ((err = snd_sbmixer_new (chip)) < 0) {
+		snd_card_free (card);
+		return (err);
+	}
+	if ((err = snd_opl3_create (card, sbport, sbport + 2,
+				    OPL3_HW_AUTO, 1, &opl3)) < 0) {
+		snd_printk (PFX_ERR "No OPL device found, skipping.\n");
+	} else {
+		if ((err = snd_opl3_timer_new (opl3, 1, 2)) < 0) {
+			snd_card_free (card);
+			return (err);
+		}
+		if ((err = snd_opl3_hwdep_new (opl3, 0, 1, NULL)) < 0) {
+			snd_card_free (card);
+			return (err);
+		}
+	}
+	if ((err = snd_card_register (card)) < 0) {
+		snd_card_free (card);
+		return (err);
+	}
+	return (0);
+}
+
+static void __devexit snd_jazz16_pnp_remove(struct pnp_dev *dev)
+{
+	struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);
+
+	snd_card_disconnect(card);
+	snd_card_free_when_closed(card);
+}
+
+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-11 19:07:08.000000000 +0100
@@ -28,6 +28,9 @@
  *
  * Wed Jul 12 22:02:55 CEST 2000 Uros Bizjak <uros@kss-loka.si>
  *   Cleaned up and rewrote lowlevel routines.
+ *
+ * Sun Mar 11 18:45:38 CEST 2007 Rask Ingemann Lambertsen <rask@sygehus.dk>
+ *   Added Jazz16 enhancements.
  */
 
 #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,54 @@ 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);
+  	unsigned int num = 0, den = 0;
+	int err = 0;
+
+	if (c->max > 1)
+		err = snd_interval_ratnum(r, 1, &jazz16_stereo_clock, &num, &den);
+	else
+		err = snd_interval_ratnum(r, 1, &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,12 @@ static int snd_sb8_playback_prepare(stru
 			break;
 		}
 		/* fallthru */
+	case SB_HW_JAZZ16:
+		if (runtime->format == SNDRV_PCM_FORMAT_MU_LAW) {
+			chip->playback_format = SB_DSP_ULAW_OUTPUT_AUTO;
+			break;
+		}
+		/* fall through */
 	case SB_HW_201:
 		if (rate > 23000) {
 			chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
@@ -134,8 +191,26 @@ 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);
+	switch (runtime->format)
+	{
+		case SNDRV_PCM_FORMAT_U8:
+		case SNDRV_PCM_FORMAT_MU_LAW:
+		dma = chip->dma8;
+		format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
+		break;
+
+		case SNDRV_PCM_FORMAT_S16_LE:
+		dma = chip->dma16;
+		format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
+		break;
+
+		default:
+		return -EINVAL;
+	}
 	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 +248,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 +307,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 +319,12 @@ static int snd_sb8_capture_prepare(struc
 			chip->capture_format = SB_DSP_HI_INPUT_AUTO;
 			break;
 		}
+		/* fall through */
+	case SB_HW_JAZZ16:
+		if (runtime->format == SNDRV_PCM_FORMAT_MU_LAW) {
+			chip->capture_format = SB_DSP_ULAW_OUTPUT_AUTO;
+			break;
+		}
 		chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO;
 		break;
 	case SB_HW_201:
@@ -261,10 +344,26 @@ 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);
+	switch (runtime->format)
+	{
+		case SNDRV_PCM_FORMAT_U8:
+		case SNDRV_PCM_FORMAT_MU_LAW:
+		dma = chip->dma8;
+		format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
+		break;
+
+		case SNDRV_PCM_FORMAT_S16_LE:
+		dma = chip->dma16;
+		format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
+		break;
+
+		default:
+		return -EINVAL;
+	}
 	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);
@@ -278,14 +377,14 @@ static int snd_sb8_capture_prepare(struc
 	} else {
 		snd_sbdsp_command(chip, 256 - runtime->rate_den);
 	}
-	if (chip->capture_format != SB_DSP_OUTPUT) {
+	if (chip->capture_format != SB_DSP_INPUT) {
 		count--;
 		snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
 		snd_sbdsp_command(chip, count & 0xff);
 		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 +457,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 +470,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 +546,20 @@ 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_U8 | SNDRV_PCM_FMTBIT_S16_LE
+				    | SNDRV_PCM_FMTBIT_MU_LAW;
+		runtime->hw.rates = SNDRV_PCM_RATE_CONTINUOUS | 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;
@@ -463,6 +580,8 @@ static int snd_sb8_open(struct snd_pcm_s
 	default:
 		break;
 	}
+	if (chip->hardware == SB_HW_JAZZ16)
+		return 0;
 	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 				      &hw_constraints_clock);
 	return 0;	
--- 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-03 12:31:36.000000000 +0100
@@ -38,6 +38,7 @@ enum sb_hw_type {
 	SB_HW_ALS100,		/* Avance Logic ALS100 chip */
 	SB_HW_ALS4000,		/* Avance Logic ALS4000 chip */
 	SB_HW_DT019X,		/* Diamond Tech. DT-019X / Avance Logic ALS-007 */
+	SB_HW_JAZZ16,		/* Media Vision Jazz16 chip */
 };
 
 #define SB_OPEN_PCM			0x01
@@ -140,8 +141,11 @@ struct snd_sb {
 #define SB_DSP_LO_INPUT_AUTO	0x2c
 #define SB_DSP_HI_OUTPUT_AUTO	0x90
 #define SB_DSP_HI_INPUT_AUTO	0x98
+#define SB_DSP_ULAW_OUTPUT_AUTO	0x7f
+#define SB_DSP_ULAW_INPUT_AUTO	0x8f
 #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 +269,14 @@ struct snd_sb {
 #define SB_DMASETUP_DMA6	0x40
 #define SB_DMASETUP_DMA7	0x80
 
+/* Jazz16 configuration. */
+#define SB_JAZZ16_CONFIG_PORT	0x201
+#define SB_JAZZ16_WAKEUP	0xaf
+#define SB_JAZZ16_SET_PORTS	0x50
+
+/* Check the output of SB_DSP_GET_JAZZ_VERSION. */
+#define SB_VERSION_IS_JAZZ16(x)	((x) == 0x12)
+
 /*
  *
  */
--- 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-02 23:12:56.000000000 +0100
@@ -248,6 +248,14 @@ 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' or 'M' to include support for Media Vision 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-11 20:11:08.000000000 +0100
@@ -1120,6 +1120,13 @@ 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 Media Vision Jazz16 chip (PnP only)
+
+    This module supports multiple cards and PnP.
+
   Module snd-korg1212
   -------------------
 
--- linux-2.6.20/drivers/pnp/Makefile-orig	2007-02-19 23:24:22.000000000 +0100
+++ linux-2.6.20/drivers/pnp/Makefile	2007-02-19 23:24:22.000000000 +0100
@@ -7,2 +7,3 @@ obj-$(CONFIG_PNPACPI)		+= pnpacpi/
 obj-$(CONFIG_PNPBIOS)		+= pnpbios/
 obj-$(CONFIG_ISAPNP)		+= isapnp/
+obj-$(CONFIG_JAZZ16PNP)		+= jazz16pnp.o
--- linux-2.6.20/drivers/pnp/Kconfig-orig	2007-02-19 23:23:26.000000000 +0100
+++ linux-2.6.20/drivers/pnp/Kconfig	2007-02-19 23:26:22.000000000 +0100
@@ -37,5 +37,17 @@ source "drivers/pnp/pnpacpi/Kconfig"
 
 source "drivers/pnp/pnpacpi/Kconfig"
 
+#
+# Jazz16 Plug and Play configuration
+#
+config JAZZ16PNP
+	bool "Jazz16 sound card Plug and Play support"
+	depends on PNP && ISA
+	help
+	  Say Y here if you would like support for automatic configuration
+          of I/O ports, DMA channels and IRQ lines of Jazz16 sound cards.
+
+	  If unsure, say N.
+
 endmenu
 
--- linux-2.6.20/drivers/pnp/jazz16pnp.c-orig	2007-03-11 22:11:58.000000000 +0100
+++ linux-2.6.20/drivers/pnp/jazz16pnp.c	2007-03-11 20:21:22.000000000 +0100
@@ -0,0 +1,562 @@
+/*  Media Vision Jazz16 Plug & Play support.
+ *
+ *  Copyright (c) 2007 Rask Ingemann Lambertsen <rask@sygehus.dk>
+ *
+ *   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 detection and setup was ported from the OSS/Free SoundBlaster
+ *  driver. Three devices are added to the PnP layer:
+ *
+ *  Device 0: The game port.
+ *  Device 1: The SoundBlaster look-alike part.
+ *  Device 2: The MPU-401 port.
+ *
+ *  BUGS: Setting the MPU-401 IRQ requires the SB part to be active.
+ */
+
+#include <linux/types.h>
+#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>
+
+MODULE_AUTHOR ("Rask Ingemann Lambertsen <rask@sygehus.dk>");
+MODULE_DESCRIPTION ("Jazz16 Plug & Play support");
+MODULE_LICENSE("GPL");
+
+uint jazz16pnp_disable = 0;	/* Disable Jazz16 PnP. */
+module_param_named (disable, jazz16pnp_disable, uint, 0);
+MODULE_PARM_DESC (disable, "Jazz16 Plug & Play disable switch");
+
+uint jazz16pnp_verbose = 0;	/* Verbosity level. */
+module_param_named (verbose, jazz16pnp_verbose, uint, 0);
+MODULE_PARM_DESC (verbose, "Jazz16 Plug & Play verbosity level");
+
+#define PFX		"jazz16pnp: "
+#define PFX_DEBUG	KERN_DEBUG PFX
+#define PFX_INFO	KERN_INFO PFX
+#define PFX_ERR		KERN_ERR PFX
+
+#define JAZZ16_SET_DMAINTR      0xFB
+
+extern void *pnp_alloc(long size);
+
+static struct pnp_dev *jazz16_gameport_dev = NULL;
+static struct pnp_dev *jazz16_sb_dev = NULL;
+static struct pnp_dev *jazz16_mpu401_dev = NULL;
+
+static uint jazz16_sb_port = 0, jazz16_sb_irq = 0;
+static uint jazz16_sb_dma1 = 0, jazz16_sb_dma2 = 0;
+static uint jazz16_mpu401_port = 0, jazz16_mpu401_irq = 0;
+
+static uint jazz16pnp_count = 0;
+
+static struct pnp_protocol jazz16pnp_protocol;
+
+static int __init jazz16pnp_add_gameport (void)
+{
+	struct pnp_dev *dev;
+	struct pnp_id *dev_id;
+	struct pnp_port *port;
+	struct pnp_option *option;
+
+	if (! (dev = pnp_alloc (sizeof (struct pnp_dev))))
+		goto out_no_dev;
+	if (! (dev_id = pnp_alloc (sizeof (struct pnp_id))))
+		goto out_no_id;
+	if (! (port = pnp_alloc (sizeof (struct pnp_port))))
+		goto out_no_port;
+	if (! (option = pnp_register_independent_option (dev)))
+		goto out_no_option;
+
+	dev->protocol = &jazz16pnp_protocol;
+	dev->capabilities = PNP_READ;
+	dev->active = 1;
+	dev->number = 0;
+
+	pnp_init_resource_table (&dev->res);
+	dev->res.port_resource[0].start = SB_JAZZ16_CONFIG_PORT;
+	dev->res.port_resource[0].end   = SB_JAZZ16_CONFIG_PORT;
+	dev->res.port_resource[0].flags	= IORESOURCE_IO;
+
+	port->min = SB_JAZZ16_CONFIG_PORT;
+	port->max = SB_JAZZ16_CONFIG_PORT;
+	port->size = 1;
+	port->align = 0;
+	pnp_register_port_resource (option, port);
+	
+	memcpy (dev_id->id, "PNPb02f", PNP_ID_LEN);
+	pnp_add_id (dev_id, dev);
+
+	jazz16_gameport_dev = dev;
+	pnp_add_device (dev);
+	return (0);
+
+out_no_option:
+	kfree (port);
+out_no_port:
+	kfree (dev_id);
+out_no_id:
+	kfree (dev);
+out_no_dev:
+	return (-ENOMEM);
+};
+
+static int __init jazz16pnp_add_sb (void)
+{
+	struct pnp_dev *sbdev;
+	struct pnp_port *sbport;
+	struct pnp_irq *sbirq;
+	struct pnp_dma *sbdma1;
+	struct pnp_dma *sbdma2;
+	struct pnp_id *sbid;
+	struct pnp_option *sboption;
+	unsigned long irq_map;
+
+	if (! (sbdev = pnp_alloc (sizeof (struct pnp_dev))))
+		goto out_no_sbdev;
+	if (! (sbport = pnp_alloc (sizeof (struct pnp_port))))
+		goto out_no_sbport;
+	if (! (sbirq = pnp_alloc (sizeof (struct pnp_irq))))
+		goto out_no_sbirq;
+	if (! (sbdma1 = pnp_alloc (sizeof (struct pnp_dma))))
+		goto out_no_sbdma1;
+	if (! (sbdma2 = pnp_alloc (sizeof (struct pnp_dma))))
+		goto out_no_sbdma2;
+	if (! (sbid = pnp_alloc (sizeof (struct pnp_id))))
+		goto out_no_sbid;
+	if (! (sboption = pnp_register_independent_option (sbdev)))
+		goto out_no_sboption;
+
+	pnp_init_resource_table (&sbdev->res);
+	sbdev->capabilities = PNP_READ | PNP_WRITE | PNP_CONFIGURABLE | PNP_DISABLE;
+	sbdev->protocol = &jazz16pnp_protocol;
+	sbdev->number = 1;
+
+	sbport->min = 0x220;
+	sbport->max = 0x260;
+	sbport->size = 0x10;
+	sbport->align = 0x20;
+	sbport->flags = PNP_PORT_FLAG_16BITADDR;
+	pnp_register_port_resource (sboption, sbport);
+
+	irq_map = (1 << 3) | (1 << 5) | (1 << 7) |
+		  (1 << 9) | (1 << 10) | (1 << 15);
+	bitmap_copy (sbirq->map, &irq_map, BITS_PER_LONG);
+	sbirq->flags  = IORESOURCE_IRQ_HIGHEDGE;
+	pnp_register_irq_resource (sboption, sbirq);
+
+	sbdma1->map = (1 << 1) | (1 << 3);
+	pnp_register_dma_resource (sboption, sbdma1);
+
+	sbdma2->map = (1 << 5) | (1 << 7);
+	pnp_register_dma_resource (sboption, sbdma2);
+
+	memcpy (sbid->id, "PNPb00f", PNP_ID_LEN);
+	pnp_add_id (sbid, sbdev);
+
+	jazz16_sb_dev = sbdev;
+	pnp_add_device (sbdev);
+	return (0);
+
+out_no_sboption:
+	kfree (sbid);
+out_no_sbid:
+	kfree (sbdma2);
+out_no_sbdma2:
+	kfree (sbdma1);
+out_no_sbdma1:
+	kfree (sbirq);
+out_no_sbirq:
+	kfree (sbport);
+out_no_sbport:
+	kfree (sbdev);
+out_no_sbdev:
+	return (-ENOMEM);
+}
+
+static int __init jazz16pnp_add_mpu401 (void)
+{
+	struct pnp_dev *mpudev;
+	struct pnp_port *mpuport;
+	struct pnp_irq *mpuirq;
+	struct pnp_id *mpuid;
+	struct pnp_option *mpuoption;
+	unsigned long irq_map;
+
+	if (! (mpudev = pnp_alloc (sizeof (struct pnp_dev))))
+		goto out_no_mpudev;
+	if (! (mpuport = pnp_alloc (sizeof (struct pnp_port))))
+		goto out_no_mpuport;
+	if (! (mpuirq = pnp_alloc (sizeof (struct pnp_irq))))
+		goto out_no_mpuirq;
+	if (! (mpuid = pnp_alloc (sizeof (struct pnp_id))))
+		goto out_no_mpuid;
+	if (! (mpuoption = pnp_register_independent_option (mpudev)))
+		goto out_no_mpuoption;
+
+	pnp_init_resource_table (&mpudev->res);
+	mpudev->capabilities = PNP_READ | PNP_WRITE | PNP_CONFIGURABLE | PNP_DISABLE;
+	mpudev->protocol = &jazz16pnp_protocol;
+	mpudev->number = 2;
+
+	mpuport->min = 0x310;
+	mpuport->max = 0x330;
+	mpuport->size = 0x2;
+	mpuport->align = 0x10;
+	mpuport->flags = PNP_PORT_FLAG_16BITADDR;
+	pnp_register_port_resource (mpuoption, mpuport);
+
+	irq_map = (1 << 3) | (1 << 5) | (1 << 7) |
+		  (1 << 9) | (1 << 10) | (1 << 15);
+	bitmap_copy (mpuirq->map, &irq_map, BITS_PER_LONG);
+	mpuirq->flags = IORESOURCE_IRQ_HIGHEDGE;
+	pnp_register_irq_resource (mpuoption, mpuirq);
+
+	memcpy (mpuid->id, "PNPb006", PNP_ID_LEN);
+	pnp_add_id (mpuid, mpudev);
+
+	jazz16_mpu401_dev = mpudev;
+	pnp_add_device (mpudev);
+	return (0);
+
+	kfree (mpuoption);
+out_no_mpuoption:
+	kfree (mpuid);
+out_no_mpuid:
+	kfree (mpuirq);
+out_no_mpuirq:
+	kfree (mpuport);
+out_no_mpuport:
+	kfree (mpudev);
+out_no_mpudev:
+	return (-ENOMEM);
+}
+
+/* Configure the SB and MPU ports. Passing 0 for both disables the Jazz16. */
+static void jazz16_port_setup (const uint sbport, const uint mpuport)
+{
+	u8 config;
+
+	switch (sbport) {
+		case 0x220:
+		case 0x240:
+		case 0x260:
+		config = sbport & 0x70;
+		jazz16_sb_port = sbport;
+		break;
+
+		default:
+		config = 0;
+		jazz16_sb_port = 0;
+		break;
+	}
+	switch (mpuport) {
+		case 0x310:
+		case 0x320:
+		case 0x330:
+		config |= (mpuport >> 4) & 0x07;
+		jazz16_mpu401_port = mpuport;
+		break;
+
+		default:
+		config |= 0;
+		jazz16_mpu401_port = 0;
+		break;
+	}
+	if (jazz16pnp_verbose)
+		printk (PFX_DEBUG "Setting SB port = 0x%x, MPU port = 0x%x.\n",
+			jazz16_sb_port, jazz16_mpu401_port);
+	outb (SB_JAZZ16_WAKEUP,		SB_JAZZ16_CONFIG_PORT);
+	outb (SB_JAZZ16_SET_PORTS,	SB_JAZZ16_CONFIG_PORT);
+	outb (config,			SB_JAZZ16_CONFIG_PORT);
+}
+
+static u8 jazz16_irq_config (uint irq)
+{
+	switch (irq) {
+		case  3: return (3);
+		case  5: return (1);
+		case  7: return (4);
+		case  9: return (2);
+		case 10: return (5);
+		case 15: return (6);
+		default: return (0);
+	}
+}
+
+static u8 jazz16_dma_config (uint dma)
+{
+	switch (dma) {
+		case  1: return (1);
+		case  3: return (2);
+		case  5: return (3);
+		case  7: return (4);
+		default: return (0);
+	}
+}
+
+/* The my_sbdsp_xxx functions were ripped from sound/isa/sb/sb_common.c. */
+#define BUSY_LOOPS 100000
+
+int my_sbdsp_command(unsigned int base, unsigned char val)
+{
+	int i;
+	for (i = BUSY_LOOPS; i; i--)
+		if ((inb(SBP1(base, STATUS)) & 0x80) == 0) {
+			outb(val, SBP1(base, COMMAND));
+			return 1;
+		}
+	return 0;
+}
+
+int my_sbdsp_get_byte(unsigned int base)
+{
+	int val;
+	int i;
+	for (i = BUSY_LOOPS; i; i--) {
+		if (inb(SBP1(base, DATA_AVAIL)) & 0x80) {
+			val = inb(SBP1(base, READ));
+			return val;
+		}
+	}
+	return -ENODEV;
+}
+
+int my_sbdsp_reset (unsigned int base)
+{
+	int i;
+
+	outb(1, SBP1(base, RESET));
+	udelay(10);
+	outb(0, SBP1(base, RESET));
+	udelay(30);
+	for (i = BUSY_LOOPS; i; i--)
+		if (inb(SBP1(base, DATA_AVAIL)) & 0x80) {
+			if (inb(SBP1(base, READ)) == 0xaa)
+				return 0;
+			else
+				break;
+		}
+	return -ENODEV;
+}
+
+static int jazz16_irq_dma_setup (unsigned int base, uint sbirq, uint mpuirq, uint dma8, uint dma16)
+{
+	u8 dma_config, irq_config;
+
+	if (jazz16pnp_verbose)
+		printk (PFX_DEBUG "Setting SB irq %u, dma %u&%u, MPU irq %u.\n",
+			sbirq, dma8, dma16, mpuirq);
+	irq_config = jazz16_irq_config (sbirq) | jazz16_irq_config (mpuirq) << 4;
+	dma_config = jazz16_dma_config (dma8)  | jazz16_dma_config (dma16)  << 4;
+	if (! my_sbdsp_command (base, JAZZ16_SET_DMAINTR))
+		return (0);
+
+	if (! my_sbdsp_command (base, dma_config))
+		return (0);
+	jazz16_sb_dma1 = dma8;
+	jazz16_sb_dma2 = dma16;
+
+	if (! my_sbdsp_command (base, irq_config))
+		return (0);
+	jazz16_sb_irq = sbirq;
+	jazz16_mpu401_irq = mpuirq;
+	return (1);
+}
+
+static int jazz16pnp_get_resources (struct pnp_dev *dev, struct pnp_resource_table *res)
+{
+	pnp_init_resource_table(res);
+	if (dev == jazz16_gameport_dev) {
+		res->port_resource[0].start = res->port_resource[0].end = SB_JAZZ16_CONFIG_PORT;
+		res->port_resource[0].flags = IORESOURCE_IO;
+	}
+	else if (dev == jazz16_sb_dev) {
+		if (!jazz16_sb_port)
+			return (0);
+		res->port_resource[0].start = jazz16_sb_port;
+		res->port_resource[0].end = jazz16_sb_port + 0x10 - 1;
+		res->port_resource[0].flags = IORESOURCE_IO;
+
+		res->irq_resource[0].start = res->irq_resource[0].end = jazz16_sb_irq;
+		res->irq_resource[0].flags = IORESOURCE_IRQ;
+
+		res->dma_resource[0].start = res->dma_resource[0].end = jazz16_sb_dma1;
+		res->dma_resource[0].flags = IORESOURCE_DMA;
+		res->dma_resource[1].start = res->dma_resource[1].end = jazz16_sb_dma2;
+		res->dma_resource[1].flags = IORESOURCE_DMA;
+	}
+	else if (dev == jazz16_mpu401_dev) {
+		if (!jazz16_mpu401_port)
+			return (0);
+		res->port_resource[0].start = jazz16_mpu401_port;
+		res->port_resource[0].end = jazz16_mpu401_port + 2 - 1;
+		res->port_resource[0].flags = IORESOURCE_IO;
+
+		res->irq_resource[0].start = res->irq_resource[0].end = jazz16_mpu401_irq;
+		res->irq_resource[0].flags = IORESOURCE_IRQ;
+	}
+	else
+		return (-EINVAL);
+	return (0);
+}
+
+static int jazz16pnp_set_resources (struct pnp_dev *dev, struct pnp_resource_table *res)
+{
+	unsigned int irq, dma1, dma2;
+
+	if (dev == jazz16_gameport_dev)
+		return (-ENOSYS);
+
+	else if (dev == jazz16_sb_dev) {
+		if ((res->port_resource[0].flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO)
+			jazz16_port_setup (res->port_resource[0].start, jazz16_mpu401_port);
+		if ((res->dma_resource[0].flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA)
+			dma1 = res->dma_resource[0].start;
+		else
+			dma1 = jazz16_sb_dma1;
+		if ((res->dma_resource[1].flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA)
+			dma2 = res->dma_resource[1].start;
+		else
+			dma2 = jazz16_sb_dma2;
+		if ((res->irq_resource[0].flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ)
+			irq = res->irq_resource[0].start;
+		else
+			irq = jazz16_sb_irq;
+		if (jazz16_sb_port)
+			jazz16_irq_dma_setup (jazz16_sb_port, irq, jazz16_mpu401_irq, dma1, dma2);
+		else
+			return (-EBUSY);
+		return (0);
+	}
+	else if (dev == jazz16_mpu401_dev) {
+		if ((res->port_resource[0].flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO)
+			jazz16_port_setup (jazz16_sb_port, res->port_resource[0].start);
+		if ((res->irq_resource[0].flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ)
+			irq = res->irq_resource[0].start;
+		else
+			irq = jazz16_mpu401_irq;
+		if (jazz16_sb_port)
+			jazz16_irq_dma_setup (jazz16_sb_port, jazz16_sb_irq, irq, jazz16_sb_dma1, jazz16_sb_dma2);
+		else
+			return (-EBUSY);
+		return (0);
+	}
+	else
+		return (-EINVAL);
+}
+
+static int jazz16pnp_disable_resources (struct pnp_dev *dev)
+{
+	if (dev == jazz16_gameport_dev) {
+		return (-ENOSYS);
+	}
+	else if (dev == jazz16_sb_dev) {
+		jazz16_port_setup (0, jazz16_mpu401_port);
+		return (0);
+	}
+	else if (dev == jazz16_mpu401_dev) {
+		jazz16_port_setup (jazz16_sb_port, 0);
+		return (0);
+	}
+	else {
+		BUG();
+		return (-EINVAL);
+	}
+}
+
+static struct pnp_protocol jazz16pnp_protocol = {
+	.name	 = "Jazz16 PnP",
+	.get	 = jazz16pnp_get_resources,
+	.set	 = jazz16pnp_set_resources,
+	.disable = jazz16pnp_disable_resources,
+};
+
+static uint __init jazz16_check (unsigned int base)
+{
+	if (my_sbdsp_reset (base))
+		return (0);
+	if (! (my_sbdsp_command (base, SB_DSP_GET_JAZZ_VERSION)))
+ 		return (0);
+	return (SB_VERSION_IS_JAZZ16 (my_sbdsp_get_byte (base)));
+}
+
+static int __init jazz16pnp_init (void)
+{
+	int err = 0;
+	unsigned int base;
+
+	if (jazz16pnp_disable == 1) {
+		printk (PFX_INFO "Jazz16 Plug & Play support disabled.\n");
+		return (0);
+	}
+
+	if (pnp_register_protocol (&jazz16pnp_protocol) < 0)
+		return (-EBUSY);
+
+	if (! request_region (SB_JAZZ16_CONFIG_PORT, 1, "Jazz16 PnP probe")) {
+		pnp_unregister_protocol (&jazz16pnp_protocol);
+		return (-EBUSY);
+	}
+	if (jazz16pnp_verbose)
+		printk (PFX_DEBUG "Scanning for Jazz16 cards...\n");
+
+	for (base = 0x220; base <= 0x260; base += 0x20) {
+		if (! request_region (base, 16, "Jazz16 PnP probe"))
+			continue;
+		if (jazz16pnp_verbose)
+			printk (PFX_DEBUG "Probing at 0x%x.\n", base);
+		jazz16_port_setup (base, 0);
+		if (jazz16_check (base))
+			jazz16pnp_count ++;
+		jazz16_port_setup (0, 0);
+		release_region (base, 16);
+		if (jazz16pnp_count)
+			break;
+	}
+	release_region (SB_JAZZ16_CONFIG_PORT, 1);
+	if (!jazz16pnp_count) {
+		err = -ENODEV;
+	} else {
+		if (!(jazz16pnp_disable & 2))
+			if (jazz16pnp_add_gameport ())
+				printk (PFX_ERR "Failed to add game port.\n");
+		if (!(jazz16pnp_disable & 4))
+			if (jazz16pnp_add_sb ())
+				printk (PFX_ERR "Failed to add SB port.\n");
+		if (!(jazz16pnp_disable & 8))
+			if (jazz16pnp_add_mpu401 ())
+				printk (PFX_ERR "Failed to add MPU-401 port.\n");
+	}
+	printk (PFX_INFO "%u Jazz16 card%s detected.\n", jazz16pnp_count, jazz16pnp_count == 1 ? "" : "s");
+	return (err);
+}
+module_init (jazz16pnp_init);
+
+static void __exit jazz16pnp_exit (void)
+{
+	pnp_unregister_protocol (&jazz16pnp_protocol);
+}
+module_exit (jazz16pnp_exit);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-11 23:24 [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
@ 2007-03-12 11:28 ` Takashi Iwai
  2007-03-12 23:23   ` Rask Ingemann Lambertsen
  2007-03-19  0:32 ` Rene Herman
  1 sibling, 1 reply; 24+ messages in thread
From: Takashi Iwai @ 2007-03-12 11:28 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: Adam Belay, alsa-devel

At Mon, 12 Mar 2007 00:24:36 +0100,
Rask Ingemann Lambertsen wrote:
> 
>    Below is a patch against linux-2.6.20 to add support for Jazz16 sound
> cards. It consists of changes to ALSA's SoundBlaster support and a new PnP
> protocol for detecting the card, setting resources and such. Before
> submitting a patch for inclusion into Linux, I would like to have a few
> comments and perhaps a test report from someone else.

At a quick review, it's mostly OK.  There are small coding-style
issues (see below), but the code itself looks fine.

And congrats, the jazz16 pnp driver seems to be the first one that
uses struct pnp_protocol except for pnp-core ;)  I'll wait for Adam's
review wrt this part.


>    The Jazz16 is an SB Pro clone with higher stereo sample rates of upto
> 45454 Hz and 16-bit sound. As such, I have modified the SoundBlaster code to
> make use of the features of the Jazz16.
> 
>    In stereo mode, the denominator used for setting the sample rate must be
> even. Some silly(?) apps

Or a silly hardware? ;)

> like timidity++ set the playback rate before
> seeting the number of channels, which causes needless rounding of the mono
> playback rate. E.g. "timidity -s 40000 -osM" results in a playback rate of
> 38461 Hz (a denominator of 26) even though 40000 Hz (a denominator of 25) is
> fine in mono mode. This is not a big problem, but is there an easy way of
> fixing it?

Very unlikely, so far.  We wanted to have a "one-short" configuration
for such cases, but it's not implemented yet.

>    I tried to include u-law support, but it doesn't sound right and playback
> speed is about one third of what it should be. I could really use some
> documentation here. I'll remove it before submitting a final patch if I
> don't get it to work.

OK.

>    Setting the irq of the MPU-401 port requires the SB part to be active and
> even worse, DSP commands need to be sent. Would it be better to just use the
> MPU-401 port without an irq and avoid the complexity?

Isn't SB part already active?  It's fine with non-irq version (which
uses timer) if the code gets too complicated, of course.

Some review comments below:

> +static irqreturn_t jazz16_interrupt(int irq, void *dev_id)
> +{
> +	struct snd_sb *chip = (struct snd_sb *) dev_id;
> +	return (snd_sb8dsp_interrupt(chip));
> +}

You don't need parentheses for return here.

> +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;
> +	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);
> +	/* FIXME 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);
> +	if ((err = snd_sbdsp_create (card, sbport, sbirq, jazz16_interrupt,
> +	                             sbdma8, sbdma16, SB_HW_AUTO, &chip)) < 0) {

Try to avoid if ((err = foo()) < 0) style.  Rather split to two lines, 
	err = foo();
	if (err < 0)
		...
> +static void __devexit snd_jazz16_pnp_remove(struct pnp_dev *dev)
> +{
> +	struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);

No need for cast, but...

> +
> +	snd_card_disconnect(card);
> +	snd_card_free_when_closed(card);
> +}

This should be simply:
	snd_card_free(pnp_get_drvdata(dev));
	pnp_set_drvdata(dev, NULL);

> @@ -134,8 +191,26 @@ 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);
> +	switch (runtime->format)
> +	{
> +		case SNDRV_PCM_FORMAT_U8:
> +		case SNDRV_PCM_FORMAT_MU_LAW:

"case" should be at the same indent level as '{'.

> @@ -278,14 +377,14 @@ static int snd_sb8_capture_prepare(struc
>  	} else {
>  		snd_sbdsp_command(chip, 256 - runtime->rate_den);
>  	}
> -	if (chip->capture_format != SB_DSP_OUTPUT) {
> +	if (chip->capture_format != SB_DSP_INPUT) {

Is this a bug in the current code?


Thanks,

Takashi

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-12 11:28 ` Takashi Iwai
@ 2007-03-12 23:23   ` Rask Ingemann Lambertsen
  2007-03-13  9:34     ` Takashi Iwai
  0 siblings, 1 reply; 24+ messages in thread
From: Rask Ingemann Lambertsen @ 2007-03-12 23:23 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Adam Belay, alsa-devel

On Mon, Mar 12, 2007 at 12:28:00PM +0100, Takashi Iwai wrote:
> At Mon, 12 Mar 2007 00:24:36 +0100,
> Rask Ingemann Lambertsen wrote:
> > 
> >    Below is a patch against linux-2.6.20 to add support for Jazz16 sound
> > cards. It consists of changes to ALSA's SoundBlaster support and a new PnP
> > protocol for detecting the card, setting resources and such. Before
> > submitting a patch for inclusion into Linux, I would like to have a few
> > comments and perhaps a test report from someone else.
> 
> At a quick review, it's mostly OK.  There are small coding-style
> issues (see below), but the code itself looks fine.

   Will be fixed.

> >    Setting the irq of the MPU-401 port requires the SB part to be active and
> > even worse, DSP commands need to be sent. Would it be better to just use the
> > MPU-401 port without an irq and avoid the complexity?
> 
> Isn't SB part already active?

   Not the way it is right now, because the MPU-401 port is a separate PnP
device. I'm not sure that is right, but it is consistent with the only
example of a PNPb00f-device I have, which is the one at
<URL:http://www.garbled.net/tmp/residual/residual.6015-2>.

> It's fine with non-irq version (which
> uses timer) if the code gets too complicated, of course.


> > @@ -278,14 +377,14 @@ static int snd_sb8_capture_prepare(struc
> >  	} else {
> >  		snd_sbdsp_command(chip, 256 - runtime->rate_den);
> >  	}
> > -	if (chip->capture_format != SB_DSP_OUTPUT) {
> > +	if (chip->capture_format != SB_DSP_INPUT) {
> 
> Is this a bug in the current code?

   I believe it is a bug, and if it is, will cause capture to fail on SB 1.0
hardware. This should have been in a separate patch.

-- 
Rask Ingemann Lambertsen

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-12 23:23   ` Rask Ingemann Lambertsen
@ 2007-03-13  9:34     ` Takashi Iwai
  0 siblings, 0 replies; 24+ messages in thread
From: Takashi Iwai @ 2007-03-13  9:34 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: Adam Belay, alsa-devel

At Tue, 13 Mar 2007 00:23:57 +0100,
Rask Ingemann Lambertsen wrote:
> 
> On Mon, Mar 12, 2007 at 12:28:00PM +0100, Takashi Iwai wrote:
> > At Mon, 12 Mar 2007 00:24:36 +0100,
> > Rask Ingemann Lambertsen wrote:
> > > 
> > >    Below is a patch against linux-2.6.20 to add support for Jazz16 sound
> > > cards. It consists of changes to ALSA's SoundBlaster support and a new PnP
> > > protocol for detecting the card, setting resources and such. Before
> > > submitting a patch for inclusion into Linux, I would like to have a few
> > > comments and perhaps a test report from someone else.
> > 
> > At a quick review, it's mostly OK.  There are small coding-style
> > issues (see below), but the code itself looks fine.
> 
>    Will be fixed.
> 
> > >    Setting the irq of the MPU-401 port requires the SB part to be active and
> > > even worse, DSP commands need to be sent. Would it be better to just use the
> > > MPU-401 port without an irq and avoid the complexity?
> > 
> > Isn't SB part already active?
> 
>    Not the way it is right now, because the MPU-401 port is a separate PnP
> device. I'm not sure that is right, but it is consistent with the only
> example of a PNPb00f-device I have, which is the one at
> <URL:http://www.garbled.net/tmp/residual/residual.6015-2>.

Ah, then it's a bit touch as there are no strong link and ordering
between two PNP devices...


> > It's fine with non-irq version (which
> > uses timer) if the code gets too complicated, of course.
> 
> 
> > > @@ -278,14 +377,14 @@ static int snd_sb8_capture_prepare(struc
> > >  	} else {
> > >  		snd_sbdsp_command(chip, 256 - runtime->rate_den);
> > >  	}
> > > -	if (chip->capture_format != SB_DSP_OUTPUT) {
> > > +	if (chip->capture_format != SB_DSP_INPUT) {
> > 
> > Is this a bug in the current code?
> 
>    I believe it is a bug, and if it is, will cause capture to fail on SB 1.0
> hardware. This should have been in a separate patch.

Yes, a separate patch is appreciated.


thanks,

Takashi

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-11 23:24 [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
  2007-03-12 11:28 ` Takashi Iwai
@ 2007-03-19  0:32 ` Rene Herman
  2007-03-19 20:52   ` Rene Herman
                     ` (2 more replies)
  1 sibling, 3 replies; 24+ messages in thread
From: Rene Herman @ 2007-03-19  0:32 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: Adam Belay, alsa-devel

On 03/12/2007 12:24 AM, Rask Ingemann Lambertsen wrote:

> Below is a patch against linux-2.6.20 to add support for Jazz16 sound
> cards. It consists of changes to ALSA's SoundBlaster support and a
> new PnP protocol for detecting the card, setting resources and such.
> Before submitting a patch for inclusion into Linux, I would like to
> have a few comments and perhaps a test report from someone else.

I just now tested this on a standalone Jazz16 and it seems to be working 
fine for me. I once had ogg123 segfault on me at the end of playback but 
was unsuccesful in reproducing -- may have been a fluke.

As to the comments...

The changes to the SB code to support the Jazz16 I ofcourse agree with. 
Supporting a new card is great. I am however not a huge fan of the new 
PnP protocol. It's cute, but I feel it's a little over-engineered and 
could just as well live directly in snd-jazz16.

Currently you have jazz16 specific code in drivers/pnp. It's not code 
that can be more generally used so snd-jazz16 is the correct place for 
it I feel. Right now you've essentially just split one driver into two 
pieces and placed the pieces in different corners of the tree.

In snd-jazz16, you'd take port= as a parameter (or autoprobe 220-260 as 
you do now; not a fan of autoprobing but that's not the issue now) same 
as other alsa drivers do and take irq/dma8/dma16 parameters as requests 
to use those specified resources and program the card for it. sgalaxy 
does this as well for irq and dma for example.

This setup also shares that same problem with the BIOS generally not 
having reserved/routed the resources -- on a general PCI/ISA system the 
user needs to go into the BIOS setup and reserve the resources the card 
is (or will be, in this case) set to. So now the user really needs to 
know what resources are going to be assigned, destroying the plug and 
play idea...

A while ago when I was doing the isa_bus thing I also looked into 
integrating plain old ISA with PnP and ran into those same issues. 
Basically, there are no practical advantages, and a few disadvantages 
(user needing to have reserved the resources, not being able to keep all 
code specific to one piece of hardware in one place, needing to invent 
PnP IDs).

Yes, the setup is sort of nice conceptually, so I hope you don't too 
much mind me not liking it in practice.

Rene.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19  0:32 ` Rene Herman
@ 2007-03-19 20:52   ` Rene Herman
  2007-03-19 21:06   ` Rene Herman
  2007-03-19 22:46   ` [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
  2 siblings, 0 replies; 24+ messages in thread
From: Rene Herman @ 2007-03-19 20:52 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: Adam Belay, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 1187 bytes --]

On 03/19/2007 01:32 AM, Rene Herman wrote:

> In snd-jazz16, you'd take port= as a parameter (or autoprobe 220-260
> as you do now; not a fan of autoprobing but that's not the issue now)
> same as other alsa drivers do and take irq/dma8/dma16 parameters as
> requests to use those specified resources and program the card for
> it.

That is, I'd so something like the attached which just keeps it all in 
the driver.

This version also doesn't autoprobe anything; none of the resources 
exist before being programmed into the card and given that BIOS setup 
issue I've gone on about a couple of times you can't just pick any free 
resource or anything but need the user to tell you which ones it has 
reserved for the card. Only probing for "port" would be okay...

The hardware fundamentally supports just one card per system due to the 
fixed SB_JAZZ16_CONFIG_PORT so the driver does as well. Has been tested 
and works okay. It's rather more straightforward then with the new PnP 
protocol.

(if anyone is following along; this is only the top-level driver module 
and still needs Rask's SB code changes applied. Full patch at

http://members.home.nl/rene.herman/jazz16.diff)

Rene.


[-- Attachment #2: jazz16.c --]
[-- Type: text/plain, Size: 7515 bytes --]

/* 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.
 * The chip has an MPU-401 interface which is handled by the MPU-401 driver.
 *
 * The IBM PPS Model 6015 has a Jazz16 chip on board. Please tell me if it
 * works with this driver or not.
 */

#include <sound/driver.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/isa.h>
#include <linux/ioport.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <sound/core.h>
#include <sound/sb.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
#include <sound/initval.h>

#define CRD_NAME "Media Vision Jazz16"
#define DEV_NAME "jazz16"

MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Rask Ingemann Lambertsen <rask@sygehus.dk>");
MODULE_LICENSE("GPL");

static int index = SNDRV_DEFAULT_IDX1;		/* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1;		/* ID for this card */
static int enable = SNDRV_DEFAULT_ENABLE1;	/* Enable this card */
static long port = SNDRV_DEFAULT_PORT1;		/* 0x220,0x240,0x260 */
static long mpu_port = SNDRV_DEFAULT_PORT1;	/* 0x310,0x320,0x330 */
static int irq = SNDRV_DEFAULT_IRQ1;		/* 5,9,3,7,10,15 */
static int mpu_irq = SNDRV_DEFAULT_IRQ1;	/* 5,9,3,7,10,15 */
static int dma8 = SNDRV_DEFAULT_DMA1;		/* 1,3 */
static int dma16 = SNDRV_DEFAULT_DMA1;		/* 5,7 */

module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param(port, long, 0444);
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param(mpu_port, long, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
module_param(irq, int, 0444);
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param(mpu_irq, int, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param(dma8, int, 0444);
MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
module_param(dma16, int, 0444);
MODULE_PARM_DESC(dma16, "16-bit DMA # for " CRD_NAME " driver.");

static int __devinit snd_jazz16_match(struct device *dev, unsigned int n)
{
	if (!enable)
		return 0;

	if (port == SNDRV_AUTO_PORT) {
		snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
		return 0;
	}
	if (irq == SNDRV_AUTO_IRQ) {
		snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
		return 0;
	}
	if (dma8 == SNDRV_AUTO_DMA) {
		snd_printk(KERN_ERR "%s: please specify dma8\n", dev->bus_id);
		return 0;
	}
	if (dma16 == SNDRV_AUTO_DMA) {
		snd_printk(KERN_ERR "%s: please specify dma16\n", dev->bus_id);
		return 0;
	}
	return 1;
}

static void __devinit snd_jazz16_set_ports(u8 value)
{
        outb(SB_JAZZ16_WAKEUP, SB_JAZZ16_CONFIG_PORT);
        outb(SB_JAZZ16_SET_PORTS, SB_JAZZ16_CONFIG_PORT);
        outb(value, SB_JAZZ16_CONFIG_PORT);
}

#define BUSY_LOOPS 100000

static int __devinit snd_jazz16_sbdsp_command(u8 value)
{
        int i;

        for (i = BUSY_LOOPS; i; i--)
                if ((inb(SBP1(port, STATUS)) & 0x80) == 0) {
                        outb(value, SBP1(port, COMMAND));
                        return 0;
                }
        return -EIO;
}

#define JAZZ16_SET_DMAINTR 0xfb

static int __devinit snd_jazz16_enable(struct device *dev)
{
	static u8 irq_config[] = {0,0,2,3,0,1,0,4,0,2,5,0,0,0,0,6};
	static u8 dma_config[] = {0,1,0,2,0,3,0,4};
	u8 config = 0;

	int error;

	if (port == 0x220 || port == 0x240 || port == 0x260)
		config = port & 0x70;

	if (mpu_port == 0x310 || mpu_port == 0x320 || mpu_port == 0x330)
		config |= (mpu_port >> 4) & 0x07;

	snd_printd("%s: setting SB port = %#lx, MPU port = %#lx.\n",
		dev->bus_id, port, mpu_port);

	snd_jazz16_set_ports(config);

	snd_printd("%s: setting SB irq %d, dma %d&%d, MPU irq %d.\n",
		dev->bus_id, irq, dma8, dma16, mpu_irq);

	error = snd_jazz16_sbdsp_command(JAZZ16_SET_DMAINTR);
	if (error < 0)
		return error;

	config = dma_config[dma8] | dma_config[dma16] << 4;

	error = snd_jazz16_sbdsp_command(config);
	if (error < 0)
		return error;

	config = irq_config[irq] | irq_config[mpu_irq] << 4;

	return snd_jazz16_sbdsp_command(config);
}

static irqreturn_t snd_jazz16_interrupt(int irq, void *dev_id)
{
	return snd_sb8dsp_interrupt(dev_id);
}

static void snd_jazz16_free(struct snd_card *card)
{
	snd_jazz16_set_ports(0);
}

static int __devinit snd_jazz16_probe(struct device *dev, unsigned int n)
{
	struct snd_sb *chip;
	struct snd_card *card;
	struct snd_opl3 *opl3;
	int error;

	card = snd_card_new(index, id, THIS_MODULE, 0);
	if (!card)
		return -EINVAL;

	card->private_free = snd_jazz16_free;

	error = snd_jazz16_enable(dev);
	if (error < 0)
		goto out;

	error = snd_sbdsp_create(card, port, irq, snd_jazz16_interrupt,
			dma8, dma16, SB_HW_AUTO, &chip);
	if (error < 0) 
		goto out;

	if (chip->hardware != SB_HW_JAZZ16) {
		snd_printk(KERN_ERR "%s: not a Jazz16 chip at %#lx.\n",
			dev->bus_id, chip->port);
		error = -ENODEV;
		goto out;
	}

	strcpy(card->driver, "Jazz16");
	strcpy(card->shortname, "Media Vision Jazz16");
	sprintf(card->longname, "%s at %#lx, irq %d, dma8 %d, dma16 %d",
	         chip->name, chip->port, chip->irq, chip->dma8, chip->dma16);

	error = snd_sb8dsp_pcm(chip, 0, NULL);
	if (error < 0)
		goto out;

	error = snd_sbmixer_new(chip);
	if (error < 0)
		goto out;

	error = snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_AUTO,
			1, &opl3);
	if (error < 0)
		snd_printk(KERN_WARNING "%s: no OPL device found, skipping.\n",
			dev->bus_id);
	else {
		error = snd_opl3_timer_new(opl3, 1, 2);
		if (error < 0)
			goto out;

		error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
		if (error < 0)
			goto out;
	}

	snd_card_set_dev(card, dev);

	error = snd_card_register(card);
	if (error < 0)
		goto out;

	dev_set_drvdata(dev, card);
	return 0;

out:	snd_card_free(card);
	return error;
}

static int __devexit snd_jazz16_remove(struct device *dev, unsigned int n)
{
	snd_card_free(dev_get_drvdata(dev));
	dev_set_drvdata(dev, NULL);
	return 0;
}

static struct isa_driver snd_jazz16_driver = {
	.match		= snd_jazz16_match,
	.probe		= snd_jazz16_probe,
	.remove		= __devexit_p(snd_jazz16_remove),

	.driver		= {
		.name	= DEV_NAME
	}
};

static int __devinit alsa_card_jazz16_init(void)
{
	return isa_register_driver(&snd_jazz16_driver, 1);
}

static void __devexit alsa_card_jazz16_exit(void)
{
	isa_unregister_driver(&snd_jazz16_driver);
}

module_init (alsa_card_jazz16_init);
module_exit (alsa_card_jazz16_exit);

[-- Attachment #3: Type: text/plain, Size: 345 bytes --]

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19  0:32 ` Rene Herman
  2007-03-19 20:52   ` Rene Herman
@ 2007-03-19 21:06   ` Rene Herman
  2007-03-19 21:22     ` Rene Herman
  2007-03-19 22:46   ` [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
  2 siblings, 1 reply; 24+ messages in thread
From: Rene Herman @ 2007-03-19 21:06 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: Adam Belay, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]

On 03/19/2007 01:32 AM, Rene Herman wrote:

[ 2nd copy; something went wrong in the alsa-devel moderation queue ]

> In snd-jazz16, you'd take port= as a parameter (or autoprobe 220-260
> as you do now; not a fan of autoprobing but that's not the issue now)
> same as other alsa drivers do and take irq/dma8/dma16 parameters as
> requests to use those specified resources and program the card for
> it.

That is, I'd so something like the attached which just keeps it all in
the driver.

This version also doesn't autoprobe anything; none of the resources
exist before being programmed into the card and given that BIOS setup
issue I've gone on about a couple of times you can't just pick any free
resource or anything but need the user to tell you which ones it has
reserved for the card. Only probing for "port" would be okay...

The hardware fundamentally supports just one card per system due to the
fixed SB_JAZZ16_CONFIG_PORT so the driver does as well. Has been tested
and works okay. It's rather more straightforward then with the new PnP
protocol.

(if anyone is following along; this is only the top-level driver module
and still needs Rask's SB code changes applied. Full patch at

http://members.home.nl/rene.herman/jazz16.diff)

Rene.


[-- Attachment #2: jazz16.c --]
[-- Type: text/plain, Size: 7516 bytes --]

/* 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.
 * The chip has an MPU-401 interface which is handled by the MPU-401 driver.
 *
 * The IBM PPS Model 6015 has a Jazz16 chip on board. Please tell me if it
 * works with this driver or not.
 */

#include <sound/driver.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/isa.h>
#include <linux/ioport.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <sound/core.h>
#include <sound/sb.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
#include <sound/initval.h>

#define CRD_NAME "Media Vision Jazz16"
#define DEV_NAME "jazz16"

MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Rask Ingemann Lambertsen <rask@sygehus.dk>");
MODULE_LICENSE("GPL");

static int index = SNDRV_DEFAULT_IDX1;		/* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1;		/* ID for this card */
static int enable = SNDRV_DEFAULT_ENABLE1;	/* Enable this card */
static long port = SNDRV_DEFAULT_PORT1;		/* 0x220,0x240,0x260 */
static long mpu_port = SNDRV_DEFAULT_PORT1;	/* 0x310,0x320,0x330 */
static int irq = SNDRV_DEFAULT_IRQ1;		/* 5,9,3,7,10,15 */
static int mpu_irq = SNDRV_DEFAULT_IRQ1;	/* 5,9,3,7,10,15 */
static int dma8 = SNDRV_DEFAULT_DMA1;		/* 1,3 */
static int dma16 = SNDRV_DEFAULT_DMA1;		/* 5,7 */

module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param(port, long, 0444);
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param(mpu_port, long, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
module_param(irq, int, 0444);
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param(mpu_irq, int, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param(dma8, int, 0444);
MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
module_param(dma16, int, 0444);
MODULE_PARM_DESC(dma16, "16-bit DMA # for " CRD_NAME " driver.");

static int __devinit snd_jazz16_match(struct device *dev, unsigned int n)
{
	if (!enable)
		return 0;

	if (port == SNDRV_AUTO_PORT) {
		snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
		return 0;
	}
	if (irq == SNDRV_AUTO_IRQ) {
		snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
		return 0;
	}
	if (dma8 == SNDRV_AUTO_DMA) {
		snd_printk(KERN_ERR "%s: please specify dma8\n", dev->bus_id);
		return 0;
	}
	if (dma16 == SNDRV_AUTO_DMA) {
		snd_printk(KERN_ERR "%s: please specify dma16\n", dev->bus_id);
		return 0;
	}
	return 1;
}

static void __devinit snd_jazz16_set_ports(u8 value)
{
        outb(SB_JAZZ16_WAKEUP, SB_JAZZ16_CONFIG_PORT);
        outb(SB_JAZZ16_SET_PORTS, SB_JAZZ16_CONFIG_PORT);
        outb(value, SB_JAZZ16_CONFIG_PORT);
}

#define BUSY_LOOPS 100000

static int __devinit snd_jazz16_sbdsp_command(u8 value)
{
        int i;

        for (i = BUSY_LOOPS; i; i--)
                if ((inb(SBP1(port, STATUS)) & 0x80) == 0) {
                        outb(value, SBP1(port, COMMAND));
                        return 0;
                }
        return -EIO;
}

#define JAZZ16_SET_DMAINTR 0xfb

static int __devinit snd_jazz16_enable(struct device *dev)
{
	static u8 irq_config[] = {0,0,2,3,0,1,0,4,0,2,5,0,0,0,0,6};
	static u8 dma_config[] = {0,1,0,2,0,3,0,4};
	u8 config = 0;

	int error;

	if (port == 0x220 || port == 0x240 || port == 0x260)
		config = port & 0x70;

	if (mpu_port == 0x310 || mpu_port == 0x320 || mpu_port == 0x330)
		config |= (mpu_port >> 4) & 0x07;

	snd_printd("%s: setting SB port = %#lx, MPU port = %#lx.\n",
		dev->bus_id, port, mpu_port);

	snd_jazz16_set_ports(config);

	snd_printd("%s: setting SB irq %d, dma %d&%d, MPU irq %d.\n",
		dev->bus_id, irq, dma8, dma16, mpu_irq);

	error = snd_jazz16_sbdsp_command(JAZZ16_SET_DMAINTR);
	if (error < 0)
		return error;

	config = dma_config[dma8] | dma_config[dma16] << 4;

	error = snd_jazz16_sbdsp_command(config);
	if (error < 0)
		return error;

	config = irq_config[irq] | irq_config[mpu_irq] << 4;

	return snd_jazz16_sbdsp_command(config);
}

static irqreturn_t snd_jazz16_interrupt(int irq, void *dev_id)
{
	return snd_sb8dsp_interrupt(dev_id);
}

static void snd_jazz16_free(struct snd_card *card)
{
	snd_jazz16_set_ports(0);
}

static int __devinit snd_jazz16_probe(struct device *dev, unsigned int n)
{
	struct snd_sb *chip;
	struct snd_card *card;
	struct snd_opl3 *opl3;
	int error;

	card = snd_card_new(index, id, THIS_MODULE, 0);
	if (!card)
		return -EINVAL;

	card->private_free = snd_jazz16_free;

	error = snd_jazz16_enable(dev);
	if (error < 0)
		goto out;

	error = snd_sbdsp_create(card, port, irq, snd_jazz16_interrupt,
			dma8, dma16, SB_HW_AUTO, &chip);
	if (error < 0) 
		goto out;

	if (chip->hardware != SB_HW_JAZZ16) {
		snd_printk(KERN_ERR "%s: not a Jazz16 chip at %#lx.\n",
			dev->bus_id, chip->port);
		error = -ENODEV;
		goto out;
	}

	strcpy(card->driver, "Jazz16");
	strcpy(card->shortname, "Media Vision Jazz16");
	sprintf(card->longname, "%s at %#lx, irq %d, dma8 %d, dma16 %d",
	         chip->name, chip->port, chip->irq, chip->dma8, chip->dma16);

	error = snd_sb8dsp_pcm(chip, 0, NULL);
	if (error < 0)
		goto out;

	error = snd_sbmixer_new(chip);
	if (error < 0)
		goto out;

	error = snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_AUTO,
			1, &opl3);
	if (error < 0)
		snd_printk(KERN_WARNING "%s: no OPL device found, skipping.\n",
			dev->bus_id);
	else {
		error = snd_opl3_timer_new(opl3, 1, 2);
		if (error < 0)
			goto out;

		error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
		if (error < 0)
			goto out;
	}

	snd_card_set_dev(card, dev);

	error = snd_card_register(card);
	if (error < 0)
		goto out;

	dev_set_drvdata(dev, card);
	return 0;

out:	snd_card_free(card);
	return error;
}

static int __devexit snd_jazz16_remove(struct device *dev, unsigned int n)
{
	snd_card_free(dev_get_drvdata(dev));
	dev_set_drvdata(dev, NULL);
	return 0;
}

static struct isa_driver snd_jazz16_driver = {
	.match		= snd_jazz16_match,
	.probe		= snd_jazz16_probe,
	.remove		= __devexit_p(snd_jazz16_remove),

	.driver		= {
		.name	= DEV_NAME
	}
};

static int __devinit alsa_card_jazz16_init(void)
{
	return isa_register_driver(&snd_jazz16_driver, 1);
}

static void __devexit alsa_card_jazz16_exit(void)
{
	isa_unregister_driver(&snd_jazz16_driver);
}

module_init (alsa_card_jazz16_init);
module_exit (alsa_card_jazz16_exit);


[-- Attachment #3: Type: text/plain, Size: 345 bytes --]

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19 21:06   ` Rene Herman
@ 2007-03-19 21:22     ` Rene Herman
  2007-03-19 21:40       ` Rene Herman
  0 siblings, 1 reply; 24+ messages in thread
From: Rene Herman @ 2007-03-19 21:22 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: Adam Belay, alsa-devel

On 03/19/2007 10:06 PM, Rene Herman wrote:

> static void __devinit snd_jazz16_set_ports(u8 value)
> {
>         outb(SB_JAZZ16_WAKEUP, SB_JAZZ16_CONFIG_PORT);
>         outb(SB_JAZZ16_SET_PORTS, SB_JAZZ16_CONFIG_PORT);
>         outb(value, SB_JAZZ16_CONFIG_PORT);
> }

bug -- can't be __devinit, since called from snd_jazz16_free.

Rene.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19 21:22     ` Rene Herman
@ 2007-03-19 21:40       ` Rene Herman
  2007-03-20 12:12         ` Takashi Iwai
  0 siblings, 1 reply; 24+ messages in thread
From: Rene Herman @ 2007-03-19 21:40 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: alsa-devel

On 03/19/2007 10:22 PM, Rene Herman wrote:

Something definitely fishy with that sourceforge moderation interface. 
I'm obviously approving my own messages, but some still aren't making it:

> On 03/19/2007 10:06 PM, Rene Herman wrote:
> 
>> static void __devinit snd_jazz16_set_ports(u8 value)
>> {
>>         outb(SB_JAZZ16_WAKEUP, SB_JAZZ16_CONFIG_PORT);
>>         outb(SB_JAZZ16_SET_PORTS, SB_JAZZ16_CONFIG_PORT);
>>         outb(value, SB_JAZZ16_CONFIG_PORT);
>> }
> 
> bug -- can't be __devinit, since called from snd_jazz16_free.

Rene.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19  0:32 ` Rene Herman
  2007-03-19 20:52   ` Rene Herman
  2007-03-19 21:06   ` Rene Herman
@ 2007-03-19 22:46   ` Rask Ingemann Lambertsen
  2007-03-20 21:23     ` [Alsa-devel] " Rene Herman
  2 siblings, 1 reply; 24+ messages in thread
From: Rask Ingemann Lambertsen @ 2007-03-19 22:46 UTC (permalink / raw)
  To: Rene Herman; +Cc: Adam Belay, alsa-devel

On Mon, Mar 19, 2007 at 01:32:15AM +0100, Rene Herman wrote:
> 
> I just now tested this on a standalone Jazz16 and it seems to be working 
> fine for me. I once had ogg123 segfault on me at the end of playback but 
> was unsuccesful in reproducing -- may have been a fluke.

   Thanks. I'll try out ogg123.

> As to the comments...
> 
> The changes to the SB code to support the Jazz16 I ofcourse agree with. 
> Supporting a new card is great. I am however not a huge fan of the new 
> PnP protocol. It's cute, but I feel it's a little over-engineered and 
> could just as well live directly in snd-jazz16.

   See below.

> This setup also shares that same problem with the BIOS generally not 
> having reserved/routed the resources -- on a general PCI/ISA system the 
> user needs to go into the BIOS setup and reserve the resources the card 
> is (or will be, in this case) set to. So now the user really needs to 
> know what resources are going to be assigned, destroying the plug and 
> play idea...

   Not really. A standards compliant PnPBIOS set up with "PnP aware OS =
YES" will use only enough resources to boot the system, which should leave
enough irqs and dmas for the Linux PnP layer to do its work.

   I think there are three good reasons to use the PnP layer:

   1) The PnP layer informs the PCI layer of irqs to try to avoid - please
see pnp_register_irq_resource() in drivers/pnp/resource.c.
   2) The PnP layer knows which resources are used by active devices, even
if they have not been allocated using e.g. request_region(). This
happens in practice. For example:

$ cat /sys/bus/pnp/devices/01\:02.00/resources
state = active
io 0x2a0-0x2af
io 0x390-0x393
io 0x500-0x50f
irq 5
dma 0
dma 1
$ cat /proc/ioports
[...]
0200-0200 : ns558-pnp
0201-0201 : ns558-pnp
0208-020f : ns558-pnp
0213-0213 : ISAPnP
0280-028f : ES18xx
0356-0356 : ide2
0360-0361 : MPU401 UART
0376-0376 : 0000:00:07.1
  0376-0376 : ide1
0390-0391 : OPL2/3 (left)
0392-0393 : OPL2/3 (right)
03c0-03df : vga+
03e8-03ef : serial
03f6-03f6 : 0000:00:07.1
  03f6-03f6 : ide0
03f8-03ff : serial
0500-050f : AD1816A
0800-0807 : ES18xx - CTRL
[...]

Notice that 0x2a0-0x2af is missing from /proc/ioports. The PnP layer will
avoid using that port range because it knows a device is using it.
   3) Knowing which resources a card can utilize, the PnP layer can try to
stay away from those resources when configuring other cards. The PnP layer
doesn't do that yet in a stock kernel, but I've patched it to do so. I'll
try to get those patches into the kernel.

   An advantage of autoprobing in a PnP protocol driver (as opposed to doing
so in a sound card driver) is that it happens before any file systems have
been mounted, so if the autoprobe happens to find one of those #%!$@ NE2000
cards and lock up the system, it won't corrupt your disks.

-- 
Rask Ingemann Lambertsen

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19 21:40       ` Rene Herman
@ 2007-03-20 12:12         ` Takashi Iwai
  2007-03-20 12:28           ` Broken moderation Takashi Iwai
  0 siblings, 1 reply; 24+ messages in thread
From: Takashi Iwai @ 2007-03-20 12:12 UTC (permalink / raw)
  To: Rene Herman; +Cc: alsa-devel

At Mon, 19 Mar 2007 22:40:48 +0100,
Rene Herman wrote:
> 
> On 03/19/2007 10:22 PM, Rene Herman wrote:
> 
> Something definitely fishy with that sourceforge moderation interface. 
> I'm obviously approving my own messages, but some still aren't making it:

Which one?  I see the following in your threads:
	<45FDDA0F.7050503@gmail.com>
	<45FEFB4D.20108@gmail.com>
	<45FEFF19.4000805@gmail.com>
	<45FF0360.9010006@gmail.com>

I agree that SF's moderation does weird things, though.  There is no
reason to moderate your own post...


Takashi

> 
> > On 03/19/2007 10:06 PM, Rene Herman wrote:
> > 
> >> static void __devinit snd_jazz16_set_ports(u8 value)
> >> {
> >>         outb(SB_JAZZ16_WAKEUP, SB_JAZZ16_CONFIG_PORT);
> >>         outb(SB_JAZZ16_SET_PORTS, SB_JAZZ16_CONFIG_PORT);
> >>         outb(value, SB_JAZZ16_CONFIG_PORT);
> >> }
> > 
> > bug -- can't be __devinit, since called from snd_jazz16_free.
> 
> Rene.
> 
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys-and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/alsa-devel
> 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Broken moderation
  2007-03-20 12:12         ` Takashi Iwai
@ 2007-03-20 12:28           ` Takashi Iwai
  2007-03-20 12:35             ` Takashi Iwai
  0 siblings, 1 reply; 24+ messages in thread
From: Takashi Iwai @ 2007-03-20 12:28 UTC (permalink / raw)
  To: perex; +Cc: alsa-devel, Rene Herman

At Tue, 20 Mar 2007 13:12:09 +0100,
I wrote:
> 
> At Mon, 19 Mar 2007 22:40:48 +0100,
> Rene Herman wrote:
> > 
> > On 03/19/2007 10:22 PM, Rene Herman wrote:
> > 
> > Something definitely fishy with that sourceforge moderation interface. 
> > I'm obviously approving my own messages, but some still aren't making it:
> 
> Which one?  I see the following in your threads:
> 	<45FDDA0F.7050503@gmail.com>
> 	<45FEFB4D.20108@gmail.com>
> 	<45FEFF19.4000805@gmail.com>
> 	<45FF0360.9010006@gmail.com>
> 
> I agree that SF's moderation does weird things, though.  There is no
> reason to moderate your own post...

The moderation is really BROKEN.  At least, as it is now.
I had to approve my own post again.

We have to either fix or stop it soon.
alsa-users ML works fine, so why not alsa-devel?  Just puzzling.

If it's still difficult to fix this immediately, we should move to
another better ML server like vger, _and_ stop forwarding from
alsa-project.org.


Takashi

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Broken moderation
  2007-03-20 12:28           ` Broken moderation Takashi Iwai
@ 2007-03-20 12:35             ` Takashi Iwai
  2007-03-20 12:57               ` Rene Herman
  0 siblings, 1 reply; 24+ messages in thread
From: Takashi Iwai @ 2007-03-20 12:35 UTC (permalink / raw)
  To: perex; +Cc: alsa-devel, Rene Herman

At Tue, 20 Mar 2007 13:28:03 +0100,
I wrote:
> 
> At Tue, 20 Mar 2007 13:12:09 +0100,
> I wrote:
> > 
> > At Mon, 19 Mar 2007 22:40:48 +0100,
> > Rene Herman wrote:
> > > 
> > > On 03/19/2007 10:22 PM, Rene Herman wrote:
> > > 
> > > Something definitely fishy with that sourceforge moderation interface. 
> > > I'm obviously approving my own messages, but some still aren't making it:
> > 
> > Which one?  I see the following in your threads:
> > 	<45FDDA0F.7050503@gmail.com>
> > 	<45FEFB4D.20108@gmail.com>
> > 	<45FEFF19.4000805@gmail.com>
> > 	<45FF0360.9010006@gmail.com>
> > 
> > I agree that SF's moderation does weird things, though.  There is no
> > reason to moderate your own post...
> 
> The moderation is really BROKEN.  At least, as it is now.
> I had to approve my own post again.
> 
> We have to either fix or stop it soon.
> alsa-users ML works fine, so why not alsa-devel?  Just puzzling.

The last post went through without moderation.
Really puzzling.  Did someone approve manually?


Takashi

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Broken moderation
  2007-03-20 12:35             ` Takashi Iwai
@ 2007-03-20 12:57               ` Rene Herman
  2007-03-20 14:58                 ` RESUBSCRIBE - New alsa-devel mailing list Jaroslav Kysela
  0 siblings, 1 reply; 24+ messages in thread
From: Rene Herman @ 2007-03-20 12:57 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, perex

On 03/20/2007 01:35 PM, Takashi Iwai wrote:

> The last post went through without moderation.
> Really puzzling.  Did someone approve manually?

That last one, not me. This one I'm now replying to (from within my 
inbox), yes, me. But yes, something is rotten here. As I said in a later 
message (which you hadn't seen at the time you wrote this due to the 
massive delay of some messages showing up on list even after manual 
moderator acceptance) I even have a message in my inbox from yesterday 
that hasn't made it yet.

My conclusion for the time being -- sourceforge sucks so bad that things 
are unsalvageable as long as the list is on there. linux-kernel is an 
open list and almost completely spam-free, so if vger is willing to host 
the list(s) I don't believe the alsa-project.org forwards would need to 
be disabled (although having a functional spamfilter on alsa-project.org 
directly will ofcourse also be good).

As to the difference with alsa-user -- as far as I'm aware, alsa-user is 
a subscriber-only list which makes all the difference. Personally I 
wouldn't terribly mind having alsa-devel subscriber-only as well but the 
list would then recieve major flack from linux-kernel posters who want 
to cross-post without needing to subscribe. I've personally long since 
concluded that although subscriber only lists may suck, the spam problem 
is just too big if you don't have a few full-time admins to throw at it 
and thereby sucks worse (vger does have those full-time admins).

Rene.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 12:57               ` Rene Herman
@ 2007-03-20 14:58                 ` Jaroslav Kysela
  2007-03-20 15:09                   ` Benoit Fouet
                                     ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Jaroslav Kysela @ 2007-03-20 14:58 UTC (permalink / raw)
  To: Rene Herman; +Cc: Takashi Iwai, ALSA development, alsa-devel

Hello everyone,

	because never ending story with SF services, I quickly setup new 
mailman alsa-devel list on new ALSA server (we'll get working list archive 
as bonus). Because I don't want to move automatically all subscribers, 
please, subscribe yourself to new list:

http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

	New list is available as alsa-devel@alsa-project.org while old on 
SF is available as alsa-devel@lists.sourceforge.net .

	The archive for new alsa-devel mailing list is here:

http://mailman.alsa-project.org/pipermail/alsa-devel/

	The posts from non-members are moderated now!

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 14:58                 ` RESUBSCRIBE - New alsa-devel mailing list Jaroslav Kysela
@ 2007-03-20 15:09                   ` Benoit Fouet
  2007-03-20 15:38                     ` Jaroslav Kysela
  2007-03-20 15:21                   ` Tobin Davis
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Benoit Fouet @ 2007-03-20 15:09 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: Takashi Iwai, ALSA development, alsa-devel, Rene Herman

Hi Jaroslav,

Jaroslav Kysela wrote:
> Hello everyone,
>
> 	because never ending story with SF services, I quickly setup new 
> mailman alsa-devel list on new ALSA server (we'll get working list archive 
> as bonus). Because I don't want to move automatically all subscribers, 
> please, subscribe yourself to new list:
>
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
> 	New list is available as alsa-devel@alsa-project.org while old on 
> SF is available as alsa-devel@lists.sourceforge.net .
>
> 	The archive for new alsa-devel mailing list is here:
>
> http://mailman.alsa-project.org/pipermail/alsa-devel/
>
> 	The posts from non-members are moderated now!
>
>   
does that mean we also have to unsubscribe from SF list ?

Ben


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 14:58                 ` RESUBSCRIBE - New alsa-devel mailing list Jaroslav Kysela
  2007-03-20 15:09                   ` Benoit Fouet
@ 2007-03-20 15:21                   ` Tobin Davis
  2007-03-20 15:35                     ` Ingo Müller
  2007-03-20 16:18                   ` Rene Herman
  2007-03-21  0:49                   ` [Alsa-devel] " Ed Wright
  3 siblings, 1 reply; 24+ messages in thread
From: Tobin Davis @ 2007-03-20 15:21 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: Takashi Iwai, ALSA development, alsa-devel, Rene Herman

Don't forget links to return the user to the main alsa-project page.  It
would be somewhat helpful.

Tobin

On Tue, 2007-03-20 at 15:58 +0100, Jaroslav Kysela wrote:

> Hello everyone,
> 
> 	because never ending story with SF services, I quickly setup new 
> mailman alsa-devel list on new ALSA server (we'll get working list archive 
> as bonus). Because I don't want to move automatically all subscribers, 
> please, subscribe yourself to new list:
> 
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 
> 	New list is available as alsa-devel@alsa-project.org while old on 
> SF is available as alsa-devel@lists.sourceforge.net .
> 
> 	The archive for new alsa-devel mailing list is here:
> 
> http://mailman.alsa-project.org/pipermail/alsa-devel/
> 
> 	The posts from non-members are moderated now!
> 
> 						Jaroslav
> 
> -----
> Jaroslav Kysela <perex@suse.cz>
> Linux Kernel Sound Maintainer
> ALSA Project, SUSE Labs
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys-and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/alsa-devel

-- 
Tobin Davis <tdavis@dsl-only.net>
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 15:21                   ` Tobin Davis
@ 2007-03-20 15:35                     ` Ingo Müller
  0 siblings, 0 replies; 24+ messages in thread
From: Ingo Müller @ 2007-03-20 15:35 UTC (permalink / raw)
  Cc: ALSA development, alsa-devel

Also please don't forget to update the links on 
http://www.alsa-project.org/mailing-lists.php. I already updated the 
corresponding article on the wiki on http://alsa.opensrc.org/ALSA_resources.

Thanks in advance, Ingo


Tobin Davis schrieb:
> Don't forget links to return the user to the main alsa-project page.  It
> would be somewhat helpful.
> 
> Tobin
> 
> On Tue, 2007-03-20 at 15:58 +0100, Jaroslav Kysela wrote:
> 
>> Hello everyone,
>>
>> 	because never ending story with SF services, I quickly setup new 
>> mailman alsa-devel list on new ALSA server (we'll get working list archive 
>> as bonus). Because I don't want to move automatically all subscribers, 
>> please, subscribe yourself to new list:
>>
>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>>
>> 	New list is available as alsa-devel@alsa-project.org while old on 
>> SF is available as alsa-devel@lists.sourceforge.net .
>>
>> 	The archive for new alsa-devel mailing list is here:
>>
>> http://mailman.alsa-project.org/pipermail/alsa-devel/
>>
>> 	The posts from non-members are moderated now!
>>
>> 						Jaroslav
>>
>> -----
>> Jaroslav Kysela <perex@suse.cz>
>> Linux Kernel Sound Maintainer
>> ALSA Project, SUSE Labs
>>
>> -------------------------------------------------------------------------
>> Take Surveys. Earn Cash. Influence the Future of IT
>> Join SourceForge.net's Techsay panel and you'll get the chance to share your
>> opinions on IT & business topics through brief surveys-and earn cash
>> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
>> _______________________________________________
>> Alsa-devel mailing list
>> Alsa-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/alsa-devel
> 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 15:09                   ` Benoit Fouet
@ 2007-03-20 15:38                     ` Jaroslav Kysela
  0 siblings, 0 replies; 24+ messages in thread
From: Jaroslav Kysela @ 2007-03-20 15:38 UTC (permalink / raw)
  To: Benoit Fouet; +Cc: Takashi Iwai, ALSA development, alsa-devel, Rene Herman

On Tue, 20 Mar 2007, Benoit Fouet wrote:

> Hi Jaroslav,
> 
> Jaroslav Kysela wrote:
> > Hello everyone,
> >
> > 	because never ending story with SF services, I quickly setup new 
> > mailman alsa-devel list on new ALSA server (we'll get working list archive 
> > as bonus). Because I don't want to move automatically all subscribers, 
> > please, subscribe yourself to new list:
> >
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >
> > 	New list is available as alsa-devel@alsa-project.org while old on 
> > SF is available as alsa-devel@lists.sourceforge.net .
> >
> > 	The archive for new alsa-devel mailing list is here:
> >
> > http://mailman.alsa-project.org/pipermail/alsa-devel/
> >
> > 	The posts from non-members are moderated now!
> >
> >   
> does that mean we also have to unsubscribe from SF list ?

I would stop using the SF mailing list immediately. I'm asking all 
moderators to stop accepting new posting on SourceForge and redirect 
people to new list. So, unsubscription is not required.

					Thanks,
						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 14:58                 ` RESUBSCRIBE - New alsa-devel mailing list Jaroslav Kysela
  2007-03-20 15:09                   ` Benoit Fouet
  2007-03-20 15:21                   ` Tobin Davis
@ 2007-03-20 16:18                   ` Rene Herman
  2007-03-20 17:25                     ` Jaroslav Kysela
  2007-03-21  0:49                   ` [Alsa-devel] " Ed Wright
  3 siblings, 1 reply; 24+ messages in thread
From: Rene Herman @ 2007-03-20 16:18 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: ALSA development

On 03/20/2007 03:58 PM, Jaroslav Kysela wrote:

> because never ending story with SF services, I quickly setup new 
> mailman alsa-devel list on new ALSA server (we'll get working list
> archive as bonus).

[ ... ]

> The posts from non-members are moderated now!

Thank you, that should improve things. I suppose a non-subcriber doesn't 
get a message they're in a moderation queue? I already have a few spam 
messages in my "moderation requests folder" so I guess this would amount 
to sending hundreds of replies to spammers...

The spam that currently entered my moderation request folder says things 
like:

   Content preview:  Spam detection software, running on the system
   "alsa0.alsa-project.org", has identified this incoming email as
   possible spam.

    [ ... ]

    Content analysis details:   (10.4 points, 5.0 required)

and everything it so marked is quite obvious spam. To quickly moderate 
I'd believe these might as well just be discarded automatically, with 
only the ones that were refused just because of non-subscriber put on 
the moderation queue. I don't know mailman, but I suppose it should be 
able to do that?

If then after a while the spam filtering on alsa-project.org grows more 
effective and we see that we only/mostly get valid postings in the 
moderation queue, we can advice to open up again.

Rene.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 16:18                   ` Rene Herman
@ 2007-03-20 17:25                     ` Jaroslav Kysela
  0 siblings, 0 replies; 24+ messages in thread
From: Jaroslav Kysela @ 2007-03-20 17:25 UTC (permalink / raw)
  To: Rene Herman; +Cc: ALSA development

On Tue, 20 Mar 2007, Rene Herman wrote:

> On 03/20/2007 03:58 PM, Jaroslav Kysela wrote:
> 
> > because never ending story with SF services, I quickly setup new 
> > mailman alsa-devel list on new ALSA server (we'll get working list
> > archive as bonus).
> 
> [ ... ]
> 
> > The posts from non-members are moderated now!
> 
> Thank you, that should improve things. I suppose a non-subcriber doesn't 
> get a message they're in a moderation queue? I already have a few spam 

No, they don't. Messages are on hold until moderator process them.

> messages in my "moderation requests folder" so I guess this would amount 
> to sending hundreds of replies to spammers...
> 
> The spam that currently entered my moderation request folder says things 
> like:
> 
>    Content preview:  Spam detection software, running on the system
>    "alsa0.alsa-project.org", has identified this incoming email as
>    possible spam.
> 
>     [ ... ]
> 
>     Content analysis details:   (10.4 points, 5.0 required)
> 
> and everything it so marked is quite obvious spam. To quickly moderate 
> I'd believe these might as well just be discarded automatically, with 
> only the ones that were refused just because of non-subscriber put on 
> the moderation queue. I don't know mailman, but I suppose it should be 
> able to do that?

I already figured what to set for mailman, so these messages are already 
discarded automatically (I hope). If it's not true (for 
mailman.alsa-project.org), please, notify me.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Alsa-devel] [RFC][RFT] Adding support for Jazz16 based sound cards
  2007-03-19 22:46   ` [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
@ 2007-03-20 21:23     ` Rene Herman
  0 siblings, 0 replies; 24+ messages in thread
From: Rene Herman @ 2007-03-20 21:23 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: alsa-devel, Adam Belay

[-- Attachment #1: Type: text/plain, Size: 4183 bytes --]

On 03/19/2007 11:46 PM, Rask Ingemann Lambertsen wrote:

>> This setup also shares that same problem with the BIOS generally
>> not having reserved/routed the resources -- on a general PCI/ISA
>> system the user needs to go into the BIOS setup and reserve the
>> resources the card is (or will be, in this case) set to. So now the
>> user really needs to know what resources are going to be assigned,
>> destroying the plug and play idea...
> 
> Not really. A standards compliant PnPBIOS set up with "PnP aware OS =
> YES" will use only enough resources to boot the system, which should
> leave enough irqs and dmas for the Linux PnP layer to do its work.

There's also the "routed" bit though. I actually ran into this recently 
when I was playing with snd-sgalaxy (which is why I'm harping on it).

An sgalaxy is also a (partly) software configurable card and when not 
given explicit parameters the driver just searches for an unrequested 
IRQ and DMA and then programs the card for it. Over here  it grabbed IRQ 
10 but then didn't work anyway, and only started working when I set IRQ 
10 to "Legacy ISA" in the BIOS setup. It seems the IRQ simply was not 
available to ISA without having done that (no, no PCI cards were using 
IRQ 10 or anything).

I must say though that my comment above was partly based on a somewhat 
foggy understanding of how things get assigned. Yes, _if_ this "routing" 
problem I seemed to be experiencing is not a serious problem in practice 
(Adam? Are you able to comment?) then the fact that the PnP layer will 
be handing out the resources taking into account the other (known) cards 
is indeed a practical advantage of using that layer.

>    I think there are three good reasons to use the PnP layer:
> 
>    1) The PnP layer informs the PCI layer of irqs to try to avoid - please
> see pnp_register_irq_resource() in drivers/pnp/resource.c.

How does that help? On my systems (one AMI, all others Award BIOses) all 
PCI cards get assigned their IRQ before the OS ever boots. That "PnP OS: 
Yes/No" switch only effects whether or not the BIOS will fully configure 
all ISA-PnP cards.

>    2) The PnP layer knows which resources are used by active devices, even
> if they have not been allocated using e.g. request_region(). This
> happens in practice. For example:

Yes, this is an advantage. It does miss all the resources used by old 
ISA cards for which no (normal or pnp protocol as in this one) drivers 
have been loaded but I guess that's not much of a difference with a 
regular ISA driver...

>    3) Knowing which resources a card can utilize, the PnP layer can try to
> stay away from those resources when configuring other cards. The PnP layer
> doesn't do that yet in a stock kernel, but I've patched it to do so. I'll
> try to get those patches into the kernel.

I guess that could be an advantage.

When I was looking at pnp/isa integration a while ago myself I was 
looking at it from the angle of generic old ISA (ie, hardwired non 
settable resources) and concluded that for these there wasn't any point. 
Having looked a little closer at the resource assigment being done in 
the PnP layer now, I now feel there's some point, but still little for 
those.

But with software settable devices such as this Jazz16, there ofcourse 
is rather more point. I believe the routing issue I refferred to above 
is the most important thing to have answered.

I also still don't really like "splitting the one driver into the two 
pieces" like that but well, we don't actually have all that many 
software settable ISA devices and I guess it's not _too_ bad to have a 
few of these "front-ends" run as a protocol driver at boot as long as it 
stays "a few".

Hey, I already said I like the concept...

By the way; in the "straightforward version" I posted yesterday I 
neglected to reserve the SB_JAZZ16_CONFIG_PORT and the SB range before 
poking at it during setup. Attached version corrects that. Updated patch 
including your SB changes still at

http://members.home.nl/rene.herman/jazz16.diff

Looks more involved now, but posted mainly for completeness; correcting 
yesterday's post. Has been tested and found working again.

Rene.


[-- Attachment #2: jazz16.diff --]
[-- Type: text/plain, Size: 22548 bytes --]

diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 9fef210..b60690a 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1120,6 +1120,13 @@ 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 Media Vision Jazz16 chip
+
+    This module supports multiple cards.
+
   Module snd-korg1212
   -------------------
 
diff --git a/include/sound/sb.h b/include/sound/sb.h
index 2dd5c8e..9594f89 100644
--- a/include/sound/sb.h
+++ b/include/sound/sb.h
@@ -38,6 +38,7 @@ enum sb_hw_type {
 	SB_HW_ALS100,		/* Avance Logic ALS100 chip */
 	SB_HW_ALS4000,		/* Avance Logic ALS4000 chip */
 	SB_HW_DT019X,		/* Diamond Tech. DT-019X / Avance Logic ALS-007 */
+	SB_HW_JAZZ16,		/* Media Vision Jazz16 chip */
 };
 
 #define SB_OPEN_PCM			0x01
@@ -140,8 +141,11 @@ #define SB_DSP_LO_OUTPUT_AUTO	0x1c
 #define SB_DSP_LO_INPUT_AUTO	0x2c
 #define SB_DSP_HI_OUTPUT_AUTO	0x90
 #define SB_DSP_HI_INPUT_AUTO	0x98
+#define SB_DSP_ULAW_OUTPUT_AUTO	0x7f
+#define SB_DSP_ULAW_INPUT_AUTO	0x8f
 #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 +269,14 @@ #define SB_DMASETUP_DMA5	0x20
 #define SB_DMASETUP_DMA6	0x40
 #define SB_DMASETUP_DMA7	0x80
 
+/* Jazz16 configuration. */
+#define SB_JAZZ16_CONFIG_PORT	0x201
+#define SB_JAZZ16_WAKEUP	0xaf
+#define SB_JAZZ16_SET_PORTS	0x50
+
+/* Check the output of SB_DSP_GET_JAZZ_VERSION. */
+#define SB_VERSION_IS_JAZZ16(x)	((x) == 0x12)
+
 /*
  *
  */
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index a629b52..450255f 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -258,6 +258,14 @@ config SND_SW60XG
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-sw60xg.
 
+config SND_JAZZ16
+	tristate "Media Vision Jazz16"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_PCM
+	help
+	  Say 'Y' or 'M' to include support for Media Vision Jazz16.
+
 config SND_OPL3SA2
 	tristate "Yamaha OPL3-SA2/SA3"
 	depends on SND
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index fd9d9c5..745e1c1 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -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
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
new file mode 100644
index 0000000..988a5e9
--- /dev/null
+++ b/sound/isa/sb/jazz16.c
@@ -0,0 +1,334 @@
+/* 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.
+ * The chip has an MPU-401 interface which is handled by the MPU-401 driver.
+ *
+ * The IBM PPS Model 6015 has a Jazz16 chip on board. Please tell me if it
+ * works with this driver or not.
+ */
+
+#include <sound/driver.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/isa.h>
+#include <linux/ioport.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <sound/core.h>
+#include <sound/sb.h>
+#include <sound/mpu401.h>
+#include <sound/opl3.h>
+#include <sound/initval.h>
+
+#define CRD_NAME "Media Vision Jazz16"
+#define DEV_NAME "jazz16"
+
+MODULE_DESCRIPTION(CRD_NAME);
+MODULE_AUTHOR("Rask Ingemann Lambertsen <rask@sygehus.dk>");
+MODULE_LICENSE("GPL");
+
+static int index = SNDRV_DEFAULT_IDX1;		/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;		/* ID for this card */
+static int enable = SNDRV_DEFAULT_ENABLE1;	/* Enable this card */
+static long port = SNDRV_DEFAULT_PORT1;		/* 0x220,0x240,0x260 */
+static long mpu_port = SNDRV_DEFAULT_PORT1;	/* 0x310,0x320,0x330 */
+static int irq = SNDRV_DEFAULT_IRQ1;		/* 5,9,3,7,10,15 */
+static int mpu_irq = SNDRV_DEFAULT_IRQ1;	/* 5,9,3,7,10,15 */
+static int dma8 = SNDRV_DEFAULT_DMA1;		/* 1,3 */
+static int dma16 = SNDRV_DEFAULT_DMA1;		/* 5,7 */
+
+module_param(index, int, 0444);
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
+module_param(id, charp, 0444);
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
+module_param(enable, bool, 0444);
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
+module_param(port, long, 0444);
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
+module_param(mpu_port, long, 0444);
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
+module_param(irq, int, 0444);
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
+module_param(mpu_irq, int, 0444);
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
+module_param(dma8, int, 0444);
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
+module_param(dma16, int, 0444);
+MODULE_PARM_DESC(dma16, "16-bit DMA # for " CRD_NAME " driver.");
+
+static int __devinit snd_jazz16_match(struct device *dev, unsigned int n)
+{
+	if (!enable)
+		return 0;
+
+	if (port == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+		return 0;
+	}
+	if (irq == SNDRV_AUTO_IRQ) {
+		snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+		return 0;
+	}
+	if (dma8 == SNDRV_AUTO_DMA) {
+		snd_printk(KERN_ERR "%s: please specify dma8\n", dev->bus_id);
+		return 0;
+	}
+	if (dma16 == SNDRV_AUTO_DMA) {
+		snd_printk(KERN_ERR "%s: please specify dma16\n", dev->bus_id);
+		return 0;
+	}
+	return 1;
+}
+
+#define BUSY_LOOPS 100000
+
+static int __devinit jazz16_sbdsp_command(u8 value)
+{
+        int i;
+
+        for (i = BUSY_LOOPS; i; i--)
+                if ((inb(SBP1(port, STATUS)) & 0x80) == 0) {
+                        outb(value, SBP1(port, COMMAND));
+                        return 0;
+                }
+        return -EIO;
+}
+
+static int __devinit jazz16_sbdsp_get_byte(void)
+{
+        int i;
+
+        for (i = BUSY_LOOPS; i; i--) 
+                if (inb(SBP1(port, DATA_AVAIL)) & 0x80) 
+                        return inb(SBP1(port, READ));
+
+        return -EIO;
+}
+
+static int __devinit jazz16_sbdsp_reset(void)
+{
+        int error;
+
+        outb(1, SBP1(port, RESET));
+        udelay(10);
+        outb(0, SBP1(port, RESET));
+        udelay(30);
+
+	error = jazz16_sbdsp_get_byte();
+	if (error < 0)
+		return error;
+
+        return error == 0xaa ? 0 : -ENODEV;
+}
+
+static void jazz16_set_ports(u8 value)
+{
+        outb(SB_JAZZ16_WAKEUP, SB_JAZZ16_CONFIG_PORT);
+        outb(SB_JAZZ16_SET_PORTS, SB_JAZZ16_CONFIG_PORT);
+        outb(value, SB_JAZZ16_CONFIG_PORT);
+}
+
+#define JAZZ16_SET_DMAINTR 0xfb
+
+static int __devinit jazz16_enable(struct device *dev)
+{
+	static u8 irq_config[] = {0,0,2,3,0,1,0,4,0,2,5,0,0,0,0,6};
+	static u8 dma_config[] = {0,1,0,2,0,3,0,4};
+	u8 config = 0;
+
+	int error;
+
+	if (port != 0x220 && port != 0x240 && port != 0x260)
+		port = 0;
+
+	if (mpu_port != 0x310 && mpu_port != 0x320 && mpu_port != 0x330)
+		mpu_port = 0;
+
+	config = (port & 0x70) | ((mpu_port >> 4) & 0x07);
+
+	snd_printd("%s: setting SB port = %#lx, MPU port = %#lx.\n",
+		dev->bus_id, port, mpu_port);
+
+	jazz16_set_ports(config);
+	
+	snd_printd("%s: setting SB irq %d, dma %d&%d, MPU irq %d.\n",
+		dev->bus_id, irq, dma8, dma16, mpu_irq);
+
+	if (!request_region(port, 16, "Jazz16")) 
+		return  -EBUSY;
+
+	error = jazz16_sbdsp_command(JAZZ16_SET_DMAINTR);
+	if (error < 0)
+		goto out;
+
+	config = dma_config[dma8] | dma_config[dma16] << 4;
+
+	error = jazz16_sbdsp_command(config);
+	if (error < 0)
+		goto out;
+
+	config = irq_config[irq] | irq_config[mpu_irq] << 4;
+
+	error = jazz16_sbdsp_command(config);
+	if (error < 0)
+		goto out;
+
+        error = jazz16_sbdsp_reset();
+	if (error < 0)
+		goto out;
+
+        error = jazz16_sbdsp_command(SB_DSP_GET_JAZZ_VERSION);
+	if (error < 0)
+		goto out;
+
+	error = jazz16_sbdsp_get_byte();
+	if (error < 0)
+		goto out;
+
+	error = SB_VERSION_IS_JAZZ16(error) ? 0 : -ENODEV;
+		
+out:	release_region(port, 16);	
+	return error;	
+}
+
+static irqreturn_t snd_jazz16_interrupt(int irq, void *dev_id)
+{
+	return snd_sb8dsp_interrupt(dev_id);
+}
+
+static void snd_jazz16_free(struct snd_card *card)
+{
+	jazz16_set_ports(0);
+	release_and_free_resource(card->private_data);
+}
+
+static int __devinit snd_jazz16_probe(struct device *dev, unsigned int n)
+{
+	struct snd_sb *chip;
+	struct snd_card *card;
+	struct snd_opl3 *opl3;
+	int error;
+
+	card = snd_card_new(index, id, THIS_MODULE, 0);
+	if (!card)
+		return -EINVAL;
+
+	card->private_data = request_region(SB_JAZZ16_CONFIG_PORT, 1,
+				"Jazz16 Config");
+	if (!card->private_data) {
+		error = -EBUSY;
+		goto out;
+	}
+	card->private_free = snd_jazz16_free;
+
+	if (mpu_port == SNDRV_AUTO_PORT)
+		mpu_port = 0;
+
+	if (mpu_irq == SNDRV_AUTO_IRQ)
+		mpu_irq = 0;
+
+	error = jazz16_enable(dev);
+	if (error < 0)
+		goto out;
+
+	error = snd_sbdsp_create(card, port, irq, snd_jazz16_interrupt,
+			dma8, dma16, SB_HW_AUTO, &chip);
+	if (error < 0)
+		goto out;
+
+	if (chip->hardware != SB_HW_JAZZ16) {
+		snd_printk(KERN_ERR "%s: not a Jazz16 chip at %#lx.\n",
+			dev->bus_id, chip->port);
+		error = -ENODEV;
+		goto out;
+	}
+
+	strcpy(card->driver, "Jazz16");
+	strcpy(card->shortname, "Media Vision Jazz16");
+	sprintf(card->longname, "%s at %#lx, irq %d, dma8 %d, dma16 %d",
+	         chip->name, chip->port, chip->irq, chip->dma8, chip->dma16);
+
+	error = snd_sb8dsp_pcm(chip, 0, NULL);
+	if (error < 0)
+		goto out;
+
+	error = snd_sbmixer_new(chip);
+	if (error < 0)
+		goto out;
+
+	error = snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_AUTO,
+			1, &opl3);
+	if (error < 0)
+		snd_printk(KERN_WARNING "%s: no OPL device found, skipping.\n",
+			dev->bus_id);
+	else {
+		error = snd_opl3_timer_new(opl3, 1, 2);
+		if (error < 0)
+			goto out;
+
+		error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+		if (error < 0)
+			goto out;
+	}
+
+	snd_card_set_dev(card, dev);
+
+	error = snd_card_register(card);
+	if (error < 0)
+		goto out;
+
+	dev_set_drvdata(dev, card);
+	return 0;
+
+out:	snd_card_free(card);
+	return error;
+}
+
+static int __devexit snd_jazz16_remove(struct device *dev, unsigned int n)
+{
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
+	return 0;
+}
+
+static struct isa_driver snd_jazz16_driver = {
+	.match		= snd_jazz16_match,
+	.probe		= snd_jazz16_probe,
+	.remove		= __devexit_p(snd_jazz16_remove),
+
+	.driver		= {
+		.name	= DEV_NAME
+	}
+};
+
+static int __devinit alsa_card_jazz16_init(void)
+{
+	return isa_register_driver(&snd_jazz16_driver, 1);
+}
+
+static void __devexit alsa_card_jazz16_exit(void)
+{
+	isa_unregister_driver(&snd_jazz16_driver);
+}
+
+module_init (alsa_card_jazz16_init);
+module_exit (alsa_card_jazz16_exit);
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index aea9e5e..70cd031 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -28,6 +28,9 @@
  *
  * Wed Jul 12 22:02:55 CEST 2000 Uros Bizjak <uros@kss-loka.si>
  *   Cleaned up and rewrote lowlevel routines.
+ *
+ * Sun Mar 11 18:45:38 CEST 2007 Rask Ingemann Lambertsen <rask@sygehus.dk>
+ *   Added Jazz16 enhancements.
  */
 
 #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,54 @@ 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);
+  	unsigned int num = 0, den = 0;
+	int err = 0;
+
+	if (c->max > 1)
+		err = snd_interval_ratnum(r, 1, &jazz16_stereo_clock, &num, &den);
+	else
+		err = snd_interval_ratnum(r, 1, &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 +169,12 @@ static int snd_sb8_playback_prepare(stru
 			break;
 		}
 		/* fallthru */
+	case SB_HW_JAZZ16:
+		if (runtime->format == SNDRV_PCM_FORMAT_MU_LAW) {
+			chip->playback_format = SB_DSP_ULAW_OUTPUT_AUTO;
+			break;
+		}
+		/* fall through */
 	case SB_HW_201:
 		if (rate > 23000) {
 			chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
@@ -134,8 +192,26 @@ 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);
+	switch (runtime->format)
+	{
+		case SNDRV_PCM_FORMAT_U8:
+		case SNDRV_PCM_FORMAT_MU_LAW:
+		dma = chip->dma8;
+		format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
+		break;
+
+		case SNDRV_PCM_FORMAT_S16_LE:
+		dma = chip->dma16;
+		format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
+		break;
+
+		default:
+		return -EINVAL;
+	}
 	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 +249,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 +308,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 +320,12 @@ static int snd_sb8_capture_prepare(struc
 			chip->capture_format = SB_DSP_HI_INPUT_AUTO;
 			break;
 		}
+		/* fall through */
+	case SB_HW_JAZZ16:
+		if (runtime->format == SNDRV_PCM_FORMAT_MU_LAW) {
+			chip->capture_format = SB_DSP_ULAW_OUTPUT_AUTO;
+			break;
+		}
 		chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO;
 		break;
 	case SB_HW_201:
@@ -261,10 +345,26 @@ 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);
+	switch (runtime->format)
+	{
+		case SNDRV_PCM_FORMAT_U8:
+		case SNDRV_PCM_FORMAT_MU_LAW:
+		dma = chip->dma8;
+		format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
+		break;
+
+		case SNDRV_PCM_FORMAT_S16_LE:
+		dma = chip->dma16;
+		format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
+		break;
+
+		default:
+		return -EINVAL;
+	}
 	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);
@@ -278,14 +378,14 @@ static int snd_sb8_capture_prepare(struc
 	} else {
 		snd_sbdsp_command(chip, 256 - runtime->rate_den);
 	}
-	if (chip->capture_format != SB_DSP_OUTPUT) {
+	if (chip->capture_format != SB_DSP_INPUT) {
 		count--;
 		snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
 		snd_sbdsp_command(chip, count & 0xff);
 		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 +458,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 +471,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 +547,20 @@ 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_U8 | SNDRV_PCM_FMTBIT_S16_LE
+				    | SNDRV_PCM_FMTBIT_MU_LAW;
+		runtime->hw.rates = SNDRV_PCM_RATE_CONTINUOUS | 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;
@@ -463,9 +581,11 @@ static int snd_sb8_open(struct snd_pcm_s
 	default:
 		break;
 	}
+	if (chip->hardware == SB_HW_JAZZ16)
+		return 0;
 	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 				      &hw_constraints_clock);
-	return 0;	
+	return 0;
 }
 
 static int snd_sb8_close(struct snd_pcm_substream *substream)
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 3094f38..69e72b5 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -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;
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 490b1ca..b16b592 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -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:

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [Alsa-devel] RESUBSCRIBE - New alsa-devel mailing list
  2007-03-20 14:58                 ` RESUBSCRIBE - New alsa-devel mailing list Jaroslav Kysela
                                     ` (2 preceding siblings ...)
  2007-03-20 16:18                   ` Rene Herman
@ 2007-03-21  0:49                   ` Ed Wright
  2007-03-21  9:10                     ` Rene Herman
  3 siblings, 1 reply; 24+ messages in thread
From: Ed Wright @ 2007-03-21  0:49 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel, alsa-devel

On 2007-03-20 23:58, Jaroslav Kysela wrote:
> Hello everyone,
> 
> 	because never ending story with SF services, I quickly setup new 
> mailman alsa-devel list on new ALSA server (we'll get working list archive 
> as bonus). Because I don't want to move automatically all subscribers, 
> please, subscribe yourself to new list:
> 
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 
> 	New list is available as alsa-devel@alsa-project.org while old on 
> SF is available as alsa-devel@lists.sourceforge.net .
> 
> 	The archive for new alsa-devel mailing list is here:
> 
> http://mailman.alsa-project.org/pipermail/alsa-devel/
> 
> 	The posts from non-members are moderated now!
> 
> 						Jaroslav

Using a threaded email client, I nearly didn't see this post because 
it's buried inside the "[Alsa-devel] [RFC][RFT] Adding support for 
Jazz16 based sound cards" thread.

Thread-hijacking??

Ed

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Alsa-devel] RESUBSCRIBE - New alsa-devel mailing list
  2007-03-21  0:49                   ` [Alsa-devel] " Ed Wright
@ 2007-03-21  9:10                     ` Rene Herman
  0 siblings, 0 replies; 24+ messages in thread
From: Rene Herman @ 2007-03-21  9:10 UTC (permalink / raw)
  To: Ed Wright; +Cc: alsa-devel, Jaroslav Kysela

On 03/21/2007 01:49 AM, Ed Wright wrote:

> Using a threaded email client, I nearly didn't see this post because
> it's buried inside the "[Alsa-devel] [RFC][RFT] Adding support for 
> Jazz16 based sound cards" thread.
> 
> Thread-hijacking??

Thank you. I just reposted Jaroslav's message on the old list using a 
new thread (the old list is closed for all other traffic).

Rene.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2007-03-21  9:11 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-11 23:24 [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
2007-03-12 11:28 ` Takashi Iwai
2007-03-12 23:23   ` Rask Ingemann Lambertsen
2007-03-13  9:34     ` Takashi Iwai
2007-03-19  0:32 ` Rene Herman
2007-03-19 20:52   ` Rene Herman
2007-03-19 21:06   ` Rene Herman
2007-03-19 21:22     ` Rene Herman
2007-03-19 21:40       ` Rene Herman
2007-03-20 12:12         ` Takashi Iwai
2007-03-20 12:28           ` Broken moderation Takashi Iwai
2007-03-20 12:35             ` Takashi Iwai
2007-03-20 12:57               ` Rene Herman
2007-03-20 14:58                 ` RESUBSCRIBE - New alsa-devel mailing list Jaroslav Kysela
2007-03-20 15:09                   ` Benoit Fouet
2007-03-20 15:38                     ` Jaroslav Kysela
2007-03-20 15:21                   ` Tobin Davis
2007-03-20 15:35                     ` Ingo Müller
2007-03-20 16:18                   ` Rene Herman
2007-03-20 17:25                     ` Jaroslav Kysela
2007-03-21  0:49                   ` [Alsa-devel] " Ed Wright
2007-03-21  9:10                     ` Rene Herman
2007-03-19 22:46   ` [RFC][RFT] Adding support for Jazz16 based sound cards Rask Ingemann Lambertsen
2007-03-20 21:23     ` [Alsa-devel] " Rene Herman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.