From alsa-devel-owner@alsa.jcu.cz  Fri Nov 27 16:43:01 1998
Received: from racine.provincia.ravenna.it (racine.provincia.ravenna.it [193.207.49.1])
	by marvin.jcu.cz (8.9.1a/8.9.1) with ESMTP id QAA06791
	for <alsa-devel@jcu.cz>; Fri, 27 Nov 1998 16:41:57 +0100
Received: from igor.opun.it (gw3-async-9.racine.ravenna.it [193.207.49.75])
	by racine.provincia.ravenna.it (8.8.5/8.8.5/Racine.03) with ESMTP id QAA07572;
	Fri, 27 Nov 1998 16:40:51 +0100 (MET)
Received: from racine.ra.it (localhost [127.0.0.1])
	by igor.opun.it (8.8.8/8.8.8) with ESMTP id QAA02673;
	Fri, 27 Nov 1998 16:36:38 +0100
Message-ID: <365EC706.984266CF@racine.ra.it>
Date: Fri, 27 Nov 1998 16:36:38 +0100
From: Abramo Bagnara <abbagnara@racine.ra.it>
MIME-Version: 1.0
To: alsa-devel@jcu.cz
CC: Christian Fischbach <fishbach@eucmos.sim.ucm.es>
Subject: Re: Es1869 fist running version ...
References: <Pine.OSF.3.96.981124112612.17190B-100000@eucmos.sim.ucm.es> <365D3E04.1CDCFE3E@racine.ra.it>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

I made some work on this first running version:

- Fixed trigger function (patch already sent)
- Fixed a bug in mmap'ed mode
- Added 3d spatializer mixer control
- Reorganized some I/O
- Fixed some minor bugs

This is a patch against es1869.c dated 22 November.
Please let me know if you want a patch against something different (I
don't know which version Jaroslav
has in his hands).

--- alsa-driver-0.2.0-pre10p1-es1869/lowlevel/isa/es1869.c	Sun Nov 22
22:01:55 1998
+++ mine/lowlevel/isa/es1869.c	Fri Nov 27 16:12:57 1998
@@ -45,7 +45,7 @@
 	int i;
 
 	for(i = 1000; i; i--)
-		if(inb(codec->port + 0x0E) & 0x80)
+		if (inb(codec->port + 0x0C) & 0x40)
 			return inb(codec->port + 0x0A);
 	snd_printd("es1869 get byte failed: 0x%x = 0x%x!!!\n", codec->port +
0x0E, inb(codec->port + 0x0E));
 	return -ENODEV;
@@ -113,6 +113,8 @@
 	}
 	/* enable extended mode */
 	snd_es1869_dsp_command(codec, 0xC6);
+	/* Change behaviour of register A1 */
+	snd_es1869_mixer_bits(codec, 0x71, 0x20, 0x00);
 	return 0;
 }
 
@@ -228,22 +230,19 @@
 	else
 		bits = 256 - div1;
 
-	if(dma == 1) {
-		/* Change behaviour of register A1 */
-		snd_es1869_mixer_bits(codec, 0x71, 0x20, 0x00);
-		snd_es1869_write(codec, 0xA1, bits);
-	}
-	else
-		snd_es1869_mixer_write(codec, 0x70, bits);
-
 	/* set filter register */
 	rate = (rate * 9) / 20;
 	div0 = 256 - 7160000 / (rate * 82);
-	if(dma == 1)
+
+	if (dma == 1) {
+		snd_es1869_write(codec, 0xA1, bits);
 		snd_es1869_write(codec, 0xA2, div0);
-	else
+	}
+	else {
+		snd_es1869_mixer_write(codec, 0x70, bits);
 		snd_es1869_mixer_write(codec, 0x72, div0);
 }
+}
 
 static int snd_es1869_playback_ioctl(snd_pcm1_t * pcm1,
 				     unsigned int cmd, unsigned long *arg)
@@ -253,8 +252,8 @@
 		pcm1->playback.real_rate = pcm1->playback.rate;
 		if (pcm1->playback.real_rate < 4000)
 			pcm1->playback.real_rate = 4000;
-		if (pcm1->playback.real_rate > 44100)
-			pcm1->playback.real_rate = 44100;
+		if (pcm1->playback.real_rate > 48000)
+			pcm1->playback.real_rate = 48000;
 		return 0;
 	}
 	return -ENXIO;
@@ -268,8 +267,8 @@
 		pcm1->record.real_rate = pcm1->record.rate;
 		if(pcm1->record.real_rate < 4000)
 			pcm1->record.real_rate = 4000;
-		if(pcm1->record.real_rate > 44100)
-			pcm1->record.real_rate = 44100;
+		if (pcm1->record.real_rate > 48000)
+			pcm1->record.real_rate = 48000;
 		return 0;
 	}
 	return -ENXIO;
@@ -434,8 +433,23 @@
 	/* Set DMA controler */
 	snd_dma_program(codec->dma2, buffer, size, DMA_MODE_WRITE |
DMA_MODE_AUTOINIT);
 
-	snd_spin_lock(codec, mixer, &flags);
+	printk("Playback prepare! Voices = 0x%x\n", pchn->voices);
+}
+
+static void snd_es1869_playback_trigger(snd_pcm1_t * pcm1, int up)
+{
+	es1869_t *codec;
+	unsigned long flags;
+
+	codec = (es1869_t *) pcm1->private_data;
+	if (up)
+		codec->trigger_value |= 0x01;
+	else
+		codec->trigger_value &= ~0x01;
+
+	snd_spin_lock(codec, reg, &flags);
 
+	if (up) {
 	/* Start DMA */
 	snd_es1869_mixer_bits(codec, 0x78, 0x03, 0x00);
 	
@@ -444,21 +458,20 @@
 
 	/* Enable Audio 2 (this register is set to 0 by reset) */
 	snd_es1869_mixer_write(codec, 0x7C, codec->audio2_vol);
+	}
+	else {
+	  /* Stop DMA */
+	  snd_es1869_mixer_bits(codec, 0x78, 0x00, 0x03);
 
-	snd_spin_unlock(codec, mixer, &flags);
+	  snd_delay(3);
 
-	printk("Playback prepare! Voices = 0x%x\n", pchn->voices);
+	  /* Disable Audio 2 (this register is set to 0 by reset) */
+	  snd_es1869_mixer_write(codec, 0x7C, 0);
 }
 
-static void snd_es1869_playback_trigger(snd_pcm1_t * pcm1, int up)
-{
-	es1869_t *codec;
+	snd_spin_unlock(codec, reg, &flags);
 
-	codec = (es1869_t *) pcm1->private_data;
-	if(up)
-		codec->trigger_value |= 0x01;
-	else
-		codec->trigger_value &= ~0x01;
+	printk("Playback trigger! Up = %d\n", up);
 }
 
 static void snd_es1869_record_prepare(snd_pcm1_t *pcm1,
@@ -530,25 +543,34 @@
 	/* avoid pops */
 	snd_delay(10);
 
-	snd_spin_lock(codec, reg, &flags);
-
-	/* Start DMA */
-	snd_es1869_bits(codec, 0xB8, 0x01, 0x00);
-
-	snd_spin_unlock(codec, reg, &flags);
-
 	printk("Record prepare! Voices = 0x%x\n", pchn->voices);
 }
 
 static void snd_es1869_record_trigger(snd_pcm1_t *pcm1, int up)
 {
 	es1869_t *codec;
+	unsigned long flags;
 
 	codec = (es1869_t *) pcm1->private_data;
 	if(up)
 		codec->trigger_value |= 0x02;
 	else
 		codec->trigger_value &= ~0x02;
+
+	snd_spin_lock(codec, reg, &flags);
+
+	if (up) {
+	  /* Start DMA */
+	  snd_es1869_bits(codec, 0xB8, 0x01, 0x00);
+	}
+	else {
+	  /* Stop DMA */
+	  snd_es1869_bits(codec, 0xB8, 0x00, 0x01);
+	}
+
+	snd_spin_unlock(codec, reg, &flags);
+
+	printk("Record trigger! Up = %d\n", up);
 }
 
 void snd_es1869_interrupt(snd_pcm_t *pcm)
@@ -564,15 +586,18 @@
 	bits = inb(codec->ctrl_port + 6);
 
 	/* ok.. playback is active */
-	if((bits & 0x02) && (codec->trigger_value & 0x01))
+	if (bits & 0x02) {
+	  if (codec->trigger_value & 0x01)
 		pcm1->playback.ack(pcm1);
+	  snd_es1869_mixer_bits(codec, 0x7A, 0x00, 0x80);
+	}
+
 
 	/* ok.. record is active */
 	if((bits & 0x01) && (codec->trigger_value & 0x02))
 		pcm1->record.ack(pcm1);
 
 	/* ack interrupt */
-	snd_es1869_mixer_bits(codec, 0x7A, 0x00, 0x80);
 	inb(codec->port + 0x0E);
 
 
@@ -634,7 +659,7 @@
 	es1869_t *codec;
 
 	codec = (es1869_t *) pcm1->private_data;
-	if(codec->trigger_value != 0x05)
+	if (!(codec->trigger_value & 0x01))
 		return 0;
 	return used_size - snd_dma_residue(codec->dma2);
 }
@@ -644,7 +669,7 @@
 	es1869_t *codec;
 
 	codec = (es1869_t *) pcm1->private_data;
-	if(codec->trigger_value != 0x0f)
+	if (!(codec->trigger_value & 0x02))
 		return 0;
 	return used_size - snd_dma_residue(codec->dma1);
 }
@@ -840,6 +865,29 @@
 #define ES1869_PRIVATE( reg, left_shift, right_shift ) \
 	  (reg|(left_shift << 12)|(right_shift << 8))
 
+static void snd_es1869_3d_mute(snd_kmixer_t * mixer,
snd_kmixer_channel_t * channel, unsigned int mute)
+{
+	unsigned long flags;
+	es1869_t *codec;
+	codec = (es1869_t *) mixer->private_data;
+	snd_spin_lock(codec, mixer, &flags);
+	if (mute)
+	  snd_es1869_mixer_bits(codec, 0x50, 0x0, 0xc);
+	else
+	  snd_es1869_mixer_bits(codec, 0x50, 0xc, 0x0);
+	snd_spin_unlock(codec, mixer, &flags);
+}
+
+static void snd_es1869_3d_volume(snd_kmixer_t * mixer,
snd_kmixer_channel_t * channel, int left, int right)
+{
+	unsigned long flags;
+	es1869_t *codec;
+	codec = (es1869_t *) mixer->private_data;
+	snd_spin_lock(codec, mixer, &flags);
+	snd_es1869_mixer_write(codec, 0x52, left);
+	snd_spin_unlock(codec, mixer, &flags);
+}
+
 static struct snd_stru_mixer_channel_hw snd_es1869_mixs[] =
 {
 	{
@@ -986,6 +1034,22 @@
 		snd_es1869_volume_level,/* set volume level */
 		NULL,			/* set route */
 	},
+	{
+		SND_MIXER_PRI_3D_SPACE,	/* priority */
+		SND_MIXER_PRI_PARENT,	/* parent priority */
+		SND_MIXER_ID_3D_SPACE,	/* device name */
+		SND_MIXER_OSS_DIGITAL1,	/* OSS device # */
+		0,
+		0, 63,			/* min, max value */
+		0, 0, 0,		/* min, max, step - dB */
+		0,
+		NULL,			/* compute dB -> linear */
+		NULL,			/* compute linear -> dB */
+		NULL,			/* record source */
+		snd_es1869_3d_mute,	/* set mute */
+		snd_es1869_3d_volume,	/* set volume level */
+		NULL,			/* set route */
+	},
 };
 
 snd_kmixer_t *snd_es1869_new_mixer(snd_pcm_t * pcm)

