aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@suse.cz>2004-04-24 19:56:24 +0200
committerJaroslav Kysela <perex@suse.cz>2004-04-24 19:56:24 +0200
commit9f6ccec9fe5e3173df9c27182907e661b249d1d6 (patch)
tree47b3b2b3da84664fd7a1d722bced5b6dfb058750 /sound
parent17ef74c1d3b650bd172c002da46dd227fcb0b5e1 (diff)
downloadhistory-9f6ccec9fe5e3173df9c27182907e661b249d1d6.tar.gz
ALSA CVS update - Takashi Iwai <tiwai@suse.de>
PCI drivers,au88x0 driver bugfixes and VIA/AMD chipset automatic workaround by Manuel Jander <manuel.jander@mat.utfsm.cl>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/Kconfig8
-rw-r--r--sound/pci/au88x0/au8810.h106
-rw-r--r--sound/pci/au88x0/au8820.h4
-rw-r--r--sound/pci/au88x0/au8830.h8
-rw-r--r--sound/pci/au88x0/au88x0.c98
-rw-r--r--sound/pci/au88x0/au88x0.h16
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c6
-rw-r--r--sound/pci/au88x0/au88x0_core.c61
-rw-r--r--sound/pci/au88x0/au88x0_eq.c4
-rw-r--r--sound/pci/au88x0/au88x0_game.c12
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c23
-rw-r--r--sound/pci/au88x0/au88x0_synth.c24
12 files changed, 204 insertions, 166 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 269720128f1eaa..3476f73c59ef9b 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -29,6 +29,9 @@ config SND_AU8810
select SND_AC97_CODEC
help
Say 'Y' or 'M' to include support for Aureal Advantage soundcards.
+ Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
+ 3D support code is in place, but not yet useable. For more info,
+ email the ALSA developer list, or mjander@users.sourceforge.net.
config SND_AU8820
tristate "Aureal Vortex"
@@ -37,6 +40,8 @@ config SND_AU8820
select SND_AC97_CODEC
help
Say 'Y' or 'M' to include support for Aureal Vortex soundcards.
+ Supported features: Hardware Mixer and SRC. For more info, email
+ the ALSA developer list, or mjander@users.sourceforge.net.
config SND_AU8830
tristate "Aureal Vortex 2"
@@ -45,6 +50,9 @@ config SND_AU8830
select SND_AC97_CODEC
help
Say 'Y' or 'M' to include support for Aureal Vortex 2 soundcards.
+ Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
+ 3D support code is in place, but not yet useable. For more info,
+ email the ALSA developer list, or mjander@users.sourceforge.net.
config SND_AZT3328
tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)"
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index e75300845758f2..3837d2ba5e673d 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -7,7 +7,7 @@
#define CARD_NAME "Aureal Advantage 3D Sound Processor"
#define CARD_NAME_SHORT "au8810"
-#define NR_ADB 0x20
+#define NR_ADB 0x10
#define NR_WT 0x00
#define NR_SRC 0x10
#define NR_A3D 0x10
@@ -51,13 +51,14 @@
/* ADB */
#define VORTEX_ADB_SR 0x28400 /* Samplerates enable/disable */
#define VORTEX_ADB_RTBASE 0x28000
-#define VORTEX_ADB_RTBASE_SIZE (VORTEX_ADB_CHNBASE - VORTEX_ADB_RTBASE)
+#define VORTEX_ADB_RTBASE_COUNT 173
#define VORTEX_ADB_CHNBASE 0x282b4
-#define VORTEX_ADB_CHNBASE_SIZE (ADB_MASK - VORTEX_ADB_RTBASE_SIZE)
+#define VORTEX_ADB_CHNBASE_COUNT 24
#define ROUTE_MASK 0xffff
#define SOURCE_MASK 0xff00
#define ADB_MASK 0xff
#define ADB_SHIFT 0x8
+
/* ADB address */
#define OFFSET_ADBDMA 0x00
#define OFFSET_SRCIN 0x40
@@ -69,10 +70,12 @@
#define OFFSET_SPORTIN 0x78 /* ch 0x13 */
#define OFFSET_SPORTOUT 0x90
#define OFFSET_SPDIFOUT 0x92 /* ch 0x14 check this! */
-#define OFFSET_EQIN 0xa0
+#define OFFSET_EQIN 0xa0
#define OFFSET_EQOUT 0x7e /* 2 routes on ch 0x11 */
#define OFFSET_XTALKOUT 0x66 /* crosstalk canceller (source) */
#define OFFSET_XTALKIN 0x96 /* crosstalk canceller (sink) */
+#define OFFSET_A3DIN 0x70 /* ADB sink. */
+#define OFFSET_A3DOUT 0xA6 /* ADB source. 2 routes per slice = 8 */
#define OFFSET_EFXIN 0x80 /* ADB sink. */
#define OFFSET_EFXOUT 0x68 /* ADB source. */
@@ -89,8 +92,8 @@
#define ADB_SPDIFOUT(x) (x + OFFSET_SPDIFOUT)
#define ADB_EQIN(x) (x + OFFSET_EQIN)
#define ADB_EQOUT(x) (x + OFFSET_EQOUT)
-#define ADB_A3DOUT(x) (x + 0x50) /* A3D blocks */
-#define ADB_A3DIN(x) (x + 0x70)
+#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 0x10 A3D blocks */
+#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
#define ADB_XTALKIN(x) (x + OFFSET_XTALKIN)
#define ADB_XTALKOUT(x) (x + OFFSET_XTALKOUT)
@@ -120,20 +123,31 @@
#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
/* SRC */
-#define VORTEX_SRCBLOCK_SR 0x26cc0
-#define VORTEX_SRC_CHNBASE 0x26c40
-#define VORTEX_SRC_RTBASE 0x26c00
-#define VORTEX_SRC_SOURCE 0x26cc4
-#define VORTEX_SRC_SOURCESIZE 0x26cc8
-#define VORTEX_SRC_CONVRATIO 0x26e40
-#define VORTEX_SRC_DRIFT0 0x26e80
-#define VORTEX_SRC_DRIFT1 0x26ec0
-#define VORTEX_SRC_DRIFT2 0x26f40
-#define VORTEX_SRC_U0 0x26e00
-#define VORTEX_SRC_U1 0x26f00
-#define VORTEX_SRC_U2 0x26f80
-#define VORTEX_SRC_DATA 0x26800 /* 0xc800 */
-#define VORTEX_SRC_DATA0 0x26000
+#define VORTEX_SRC_CHNBASE 0x26c40
+#define VORTEX_SRC_RTBASE 0x26c00
+#define VORTEX_SRCBLOCK_SR 0x26cc0
+#define VORTEX_SRC_SOURCE 0x26cc4
+#define VORTEX_SRC_SOURCESIZE 0x26cc8
+/* Params
+ 0x26e00 : 1 U0
+ 0x26e40 : 2 CR
+ 0x26e80 : 3 U3
+ 0x26ec0 : 4 DRIFT1
+ 0x26f00 : 5 U1
+ 0x26f40 : 6 DRIFT2
+ 0x26f80 : 7 U2 : Target rate, direction
+*/
+
+#define VORTEX_SRC_CONVRATIO 0x26e40
+#define VORTEX_SRC_DRIFT0 0x26e80
+#define VORTEX_SRC_DRIFT1 0x26ec0
+#define VORTEX_SRC_DRIFT2 0x26f40
+#define VORTEX_SRC_U0 0x26e00
+#define U0_SLOWLOCK 0x200
+#define VORTEX_SRC_U1 0x26f00
+#define VORTEX_SRC_U2 0x26f80
+#define VORTEX_SRC_DATA 0x26800 /* 0xc800 */
+#define VORTEX_SRC_DATA0 0x26000
/* FIFO */
#define VORTEX_FIFO_ADBCTRL 0x16100 /* Control bits. */
@@ -150,33 +164,37 @@
//#define FIFO_MASK 0x1f /* at shift left 0xb */
//#define FIFO_SIZE 0x20
#define FIFO_BITS 0x03880000
-#define VORTEX_FIFO_ADBDATA 0x14000
-#define VORTEX_FIFO_WTDATA 0x10000
+#define VORTEX_FIFO_ADBDATA 0x14000
+#define VORTEX_FIFO_WTDATA 0x10000
/* CODEC */
-#define VORTEX_CODEC_CTRL 0x29184
-#define VORTEX_CODEC_EN 0x29190
+#define VORTEX_CODEC_CTRL 0x29184
+#define VORTEX_CODEC_EN 0x29190
#define EN_CODEC0 0x00000300
+#define EN_AC98 0x00000c00 /* Modem AC98 slots. */
#define EN_CODEC1 0x00003000
#define EN_CODEC (EN_CODEC0 | EN_CODEC1)
#define EN_SPORT 0x00030000
#define EN_SPDIF 0x000c0000
-#define VORTEX_CODEC_CHN 0x29080
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
-#define VORTEX_CODEC_IO 0x29188
+
+#define VORTEX_CODEC_CHN 0x29080
+#define VORTEX_CODEC_WRITE 0x00800000
+#define VORTEX_CODEC_ADDSHIFT 16
+#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
+#define VORTEX_CODEC_DATSHIFT 0
+#define VORTEX_CODEC_DATMASK 0xffff
+#define VORTEX_CODEC_IO 0x29188
/* SPDIF */
-#define VORTEX_SPDIF_FLAGS 0x2205c
-#define VORTEX_SPDIF_CFG0 0x291D0
-#define VORTEX_SPDIF_CFG1 0x291D4
+#define VORTEX_SPDIF_FLAGS 0x2205c
+#define VORTEX_SPDIF_CFG0 0x291D0
+#define VORTEX_SPDIF_CFG1 0x291D4
#define VORTEX_SPDIF_SMPRATE 0x29194
/* Sample timer */
-#define VORTEX_SMP_TIME 0x29198
+#define VORTEX_SMP_TIME 0x29198
+
+#define VORTEX_MODEM_CTRL 0x291ac
/* IRQ */
#define VORTEX_IRQ_SOURCE 0x2a000 /* Interrupt source flags. */
@@ -193,19 +211,19 @@
#define CTRL_IRQ_ENABLE 0x00004000
/* write: Timer period config / read: TIMER IRQ ack. */
-#define VORTEX_IRQ_STAT 0x2919c
+#define VORTEX_IRQ_STAT 0x2919c
/* DMA */
-#define VORTEX_ENGINE_CTRL 0x27ae8
-#define ENGINE_INIT 0x1380000
+#define VORTEX_ENGINE_CTRL 0x27ae8
+#define ENGINE_INIT 0x1380000
- /* MIDI *//* GAME. */
-#define VORTEX_MIDI_DATA 0x28800
-#define VORTEX_MIDI_CMD 0x28804 /* Write command / Read status */
+/* MIDI *//* GAME. */
+#define VORTEX_MIDI_DATA 0x28800
+#define VORTEX_MIDI_CMD 0x28804 /* Write command / Read status */
-#define VORTEX_CTRL2 0x2880c
+#define VORTEX_CTRL2 0x2880c
#define CTRL2_GAME_ADCMODE 0x40
-#define VORTEX_GAME_LEGACY 0x28808
-#define VORTEX_GAME_AXIS 0x28810
+#define VORTEX_GAME_LEGACY 0x28808
+#define VORTEX_GAME_AXIS 0x28810
#define AXIS_SIZE 4
#define AXIS_RANGE 0x1fff
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index bd7d76c6a65ede..be8022e78714bf 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -48,9 +48,9 @@
/* ADB */
#define VORTEX_ADB_SR 0x10a00 /* Samplerates enable/disable */
#define VORTEX_ADB_RTBASE 0x10800
-#define VORTEX_ADB_RTBASE_SIZE (VORTEX_ADB_CHNBASE - VORTEX_ADB_RTBASE)
+#define VORTEX_ADB_RTBASE_COUNT 103
#define VORTEX_ADB_CHNBASE 0x1099c
-#define VORTEX_ADB_CHNBASE_SIZE (ADB_MASK - VORTEX_ADB_RTBASE_SIZE)
+#define VORTEX_ADB_CHNBASE_COUNT 22
#define ROUTE_MASK 0x3fff
#define ADB_MASK 0x7f
#define ADB_SHIFT 0x7
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 293df0650c342d..aa77826b5e59f1 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -45,7 +45,7 @@
#define VORTEX_ADBDMA_START 0x27c00 /* Which subbuffer starts */
#define VORTEX_ADBDMA_STATUS 0x27A90 /* stored at AdbDma->this_10 / 2 DWORD in size. */
-/* Starting at MSB, each pair seem to be the current DMA page. */
+/* Starting at the MSB, each pair of bits seem to be the current DMA page. */
/* This current page bits are consistent (same value) with VORTEX_ADBDMA_STAT) */
/* DMA */
@@ -65,9 +65,9 @@
/* ADB */
#define VORTEX_ADB_SR 0x28400 /* Samplerates enable/disable */
#define VORTEX_ADB_RTBASE 0x28000
-#define VORTEX_ADB_RTBASE_SIZE (VORTEX_ADB_CHNBASE - VORTEX_ADB_RTBASE)
+#define VORTEX_ADB_RTBASE_COUNT 173
#define VORTEX_ADB_CHNBASE 0x282b4
-#define VORTEX_ADB_CHNBASE_SIZE (ADB_MASK - VORTEX_ADB_RTBASE_SIZE)
+#define VORTEX_ADB_CHNBASE_COUNT 24
#define ROUTE_MASK 0xffff
#define SOURCE_MASK 0xff00
#define ADB_MASK 0xff
@@ -147,7 +147,7 @@
#define VORTEX_SRC_RTBASE 0x26c00
#define VORTEX_SRCBLOCK_SR 0x26cc0
#define VORTEX_SRC_SOURCE 0x26cc4
-#define VORTEX_SRC_SOURCESIZE 0x26cc4
+#define VORTEX_SRC_SOURCESIZE 0x26cc8
/* Params
0x26e00 : 1 U0
0x26e40 : 2 CR
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index fe2377fdbf560c..5c6a78b9823134 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -51,60 +51,70 @@ MODULE_DEVICES("{{Aureal Semiconductor Inc., Aureal Vortex Sound Processor}}");
MODULE_DEVICE_TABLE(pci, snd_vortex_ids);
-static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
+static void vortex_fix_latency(struct pci_dev *vortex)
{
- struct pci_dev *via = NULL;
int rc;
-
- /* autodetect if workarounds are required */
- while ((via = pci_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8365_1, via))) {
- if (fix == 255) {
- printk(KERN_INFO CARD_NAME
- ": detected VIA KT133/KM133. activating workaround...\n");
- fix = 3; // do latency and via bridge workaround
- }
- break;
- }
-
- /* do not do anything if autodetection was enabled and found no VIA */
- if (fix == 255)
- return;
-
- /* fix vortex latency */
- if (fix & 0x01) {
- if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) {
+ if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) {
printk(KERN_INFO CARD_NAME
": vortex latency is 0xff\n");
- } else {
- printk(KERN_WARNING CARD_NAME
- ": could not set vortex latency: pci error 0x%x\n",
- rc);
- }
+ } else {
+ printk(KERN_WARNING CARD_NAME
+ ": could not set vortex latency: pci error 0x%x\n", rc);
}
+}
+
+static void vortex_fix_agp_bridge(struct pci_dev *via)
+{
+ int rc;
+ u8 value;
- /* fix via agp bridge */
- if (via && (fix & 0x02)) {
- u8 value;
+ /*
+ * only set the bit (Extend PCI#2 Internal Master for
+ * Efficient Handling of Dummy Requests) if the can
+ * read the config and it is not already set
+ */
- /*
- * only set the bit (Extend PCI#2 Internal Master for
- * Efficient Handling of Dummy Requests) if the can
- * read the config and it is not already set
- */
+ if (!(rc = pci_read_config_byte(via, 0x42, &value))
+ && ((value & 0x10)
+ || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) {
+ printk(KERN_INFO CARD_NAME
+ ": bridge config is 0x%x\n", value | 0x10);
+ } else {
+ printk(KERN_WARNING CARD_NAME
+ ": could not set vortex latency: pci error 0x%x\n", rc);
+ }
+}
- if (!(rc = pci_read_config_byte(via, 0x42, &value))
- && ((value & 0x10)
- || !(rc =
- pci_write_config_byte(via, 0x42, value | 0x10)))) {
+static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
+{
+ struct pci_dev *via;
- printk(KERN_INFO CARD_NAME
- ": bridge config is 0x%x\n", value | 0x10);
- } else {
- printk(KERN_WARNING CARD_NAME
- ": could not set vortex latency: pci error 0x%x\n",
- rc);
+ /* autodetect if workarounds are required */
+ if (fix == 255) {
+ /* VIA KT133 */
+ via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL);
+ /* VIA Apollo */
+ if (via == NULL) {
+ via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL);
}
+ /* AMD Irongate */
+ if (via == NULL) {
+ via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
+ }
+ if (via) {
+ printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n");
+ vortex_fix_latency(vortex);
+ vortex_fix_agp_bridge(via);
+ }
+ } else {
+ if (fix & 0x1)
+ vortex_fix_latency(vortex);
+ if ((fix & 0x2) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL)))
+ vortex_fix_agp_bridge(via);
+ if ((fix & 0x4) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL)))
+ vortex_fix_agp_bridge(via);
+ if ((fix & 0x8) && (via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
+ vortex_fix_agp_bridge(via);
}
}
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index 028612afd3135d..815de180c7a3b8 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -17,6 +17,7 @@
#ifndef __SOUND_AU88X0_H
#define __SOUND_AU88X0_H
+#ifdef __KERNEL__
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/pci.h>
@@ -28,6 +29,8 @@
#include <sound/hwdep.h>
#include <sound/ac97_codec.h>
+#endif
+
#ifndef CHIP_AU8820
#include "au88x0_eq.h"
#include "au88x0_a3d.h"
@@ -69,20 +72,19 @@
#define IRQ_MODEM 0x4000
/* ADB Resource */
-#define VORTEX_RESOURCE_DMA 0x00000000
-#define VORTEX_RESOURCE_SRC 0x00000001
+#define VORTEX_RESOURCE_DMA 0x00000000
+#define VORTEX_RESOURCE_SRC 0x00000001
#define VORTEX_RESOURCE_MIXIN 0x00000002
#define VORTEX_RESOURCE_MIXOUT 0x00000003
-#define VORTEX_RESOURCE_A3D 0x00000004
+#define VORTEX_RESOURCE_A3D 0x00000004
#define VORTEX_RESOURCE_LAST 0x00000005
/* Check for SDAC bit in "Extended audio ID" AC97 register */
-#define VORTEX_IS_QUAD(x) ((x->codec == NULL) ? 0 : (x->codec->ext_id|0x80))
+#define VORTEX_IS_QUAD(x) ((x->codec == NULL) ? 0 : (x->codec->ext_id&0x80))
/* Check if chip has bug. */
#define IS_BAD_CHIP(x) (\
- (x->rev < 3 && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_1) || \
- (x->rev < 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \
- (x->rev < 0xfe && x->device == PCI_DEVICE_ID_AUREAL_ADVANTAGE))
+ (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \
+ (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_ADVANTAGE))
/* PCM devices */
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 2ca30511025240..dd85d947bde856 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -617,6 +617,12 @@ static void vortex_Vort3D(vortex_t * v, int en)
static void vortex_Vort3D_connect(vortex_t * v, int en)
{
int i;
+
+// Disable AU8810 routes, since they seem to be wrong (in au8810.h).
+#ifdef CHIP_AU8810
+ return;
+#endif
+
#if 1
/* Alloc Xtalk mixin resources */
v->mixxtlk[0] =
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 5239c24268d21b..d8fccffbe80db4 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -72,6 +72,7 @@
into au88x0_pcm.c .
06-06-2003 Buffer shifter bugfix. Mixer volume fix.
07-12-2003 A3D routing finally fixed. Believed to be OK.
+ 25-03-2004 Many thanks to Claudia, for such valuable bug reports.
*/
@@ -772,7 +773,9 @@ vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
return 1;
}
- /*FIFO*/ static void
+ /*FIFO*/
+
+static void
vortex_fifo_clearadbdata(vortex_t * vortex, int fifo, int x)
{
for (x--; x >= 0; x--)
@@ -1345,31 +1348,29 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
dma->nr_periods = count;
dma->sgbuf = sgbuf;
- psize--;
-
dma->cfg0 = 0;
dma->cfg1 = 0;
switch (count) {
/* Four or more pages */
default:
case 4:
- dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | psize;
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
+ dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
+ hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
snd_sgbuf_get_addr(sgbuf, psize * 3));
/* 3 pages */
case 3:
dma->cfg0 |= 0x12000000;
- dma->cfg1 |= 0x80000000 | 0x40000000 | (psize << 0xc);
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
+ dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
+ hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
snd_sgbuf_get_addr(sgbuf, psize * 2));
/* 2 pages */
case 2:
- dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | psize;
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
+ dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
+ hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
snd_sgbuf_get_addr(sgbuf, psize));
/* 1 page */
case 1:
- dma->cfg0 |= 0x80000000 | 0x40000000 | (psize << 0xc);
+ dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
snd_sgbuf_get_addr(sgbuf, 0));
break;
@@ -1575,11 +1576,11 @@ static void vortex_adb_init(vortex_t * vortex)
/* it looks like we are writing more than we need to...
* if we write what we are supposed to it breaks things... */
hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);
- for (i = 0; i < VORTEX_ADB_RTBASE_SIZE; i++)
+ for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)
hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),
hwread(vortex->mmio,
VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);
- for (i = 0; i < VORTEX_ADB_CHNBASE_SIZE; i++) {
+ for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {
hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),
hwread(vortex->mmio,
VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);
@@ -1922,6 +1923,9 @@ vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[])
// Connect front channels through EQ.
vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));
vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));
+ /* Lower volume, since EQ has some gain. */
+ vortex_mix_setvolumebyte(vortex, mixers[0], 0);
+ vortex_mix_setvolumebyte(vortex, mixers[1], 0);
vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));
vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));
@@ -2007,9 +2011,11 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
}
/* Default Connections */
+static int
+vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
+
static void vortex_connect_default(vortex_t * vortex, int en)
{
- // FIXME: check if checkout was succesful.
// Connect AC97 codec.
vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
VORTEX_RESOURCE_MIXOUT);
@@ -2044,7 +2050,7 @@ static void vortex_connect_default(vortex_t * vortex, int en)
#ifndef CHIP_AU8810
vortex_wt_connect(vortex, en);
#endif
- // A3D (crosstalk canceler and A3D slices).
+ // A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.
#ifndef CHIP_AU8820
vortex_Vort3D_connect(vortex, en);
#endif
@@ -2053,18 +2059,7 @@ static void vortex_connect_default(vortex_t * vortex, int en)
// Connect DSP interface for SQ3500 turbo (not here i think...)
// Connect AC98 modem codec
-
- /* Fast Play Workaround. Revision 0xFE does not seem to need it. */
- printk(KERN_INFO "vortex: revision = 0x%x, device = %d\n", vortex->rev, vortex->device);
- if (IS_BAD_CHIP(vortex)) {
- printk(KERN_INFO "vortex: Erratum workaround enabled.\n");
- #ifndef CHIP_AU8820
- vortex->fixed_res[VORTEX_RESOURCE_DMA] = 0x00000001;
- #endif
- // Channel swapping workaround. We are nuking registers somewhere, or
- // its a hardware bug.
- vortex->fixed_res[VORTEX_RESOURCE_SRC] = 0x00000001;
- }
+
}
/*
@@ -2081,7 +2076,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
{
stream_t *stream;
int i, en;
-
+
if ((nr_ch == 3)
|| ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
return -EBUSY;
@@ -2105,7 +2100,6 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
stream->dir = dir;
stream->type = type;
- // FIXME: check for success of checkout or checkin.
/* PLAYBACK ROUTES. */
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
int src[4], mix[4], ch_top;
@@ -2165,8 +2159,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
for (i = 0; i < nr_ch; i++) {
if (stream->type == VORTEX_PCM_ADB) {
vortex_connection_adbdma_src(vortex, en,
- src[nr_ch - 1],
- //src[0],
+ src[nr_ch - 1],
dma,
src[i]);
vortex_connection_src_mixin(vortex, en,
@@ -2188,7 +2181,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
#ifndef CHIP_AU8820
if (stream->type == VORTEX_PCM_A3D) {
vortex_connection_adbdma_src(vortex, en,
- src[0],
+ src[nr_ch - 1],
dma,
src[i]);
vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));
@@ -2237,7 +2230,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
ADB_SPDIFOUT(1));
}
#endif
- /* CAPTURE ROUTES. */
+ /* CAPTURE ROUTES. */
} else {
int src[2], mix[2];
@@ -2271,7 +2264,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
vortex_connection_mixin_mix(vortex, en,
MIX_CAPT(1), mix[0], 0);
vortex_connection_src_adbdma(vortex, en,
- src[nr_ch - 1],
+ src[0],
src[0], dma);
} else {
vortex_connection_mixin_mix(vortex, en,
@@ -2279,7 +2272,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
vortex_connection_mix_src(vortex, en, 0x11, mix[1],
src[1]);
vortex_connection_src_src_adbdma(vortex, en,
- src[0], src[0],
+ src[1], src[0],
src[1], dma);
}
}
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index b9fba01899f9c5..fdf0014f03758e 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -710,11 +710,13 @@ static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex)
static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp)
{
eqlzr_t *eq = &(vortex->eq);
-
+
if ((eq->this28) && (bp == 0)) {
+ /* EQ enabled */
vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08);
} else {
+ /* EQ disabled. */
vortex_EqHw_SetLeftGainsTarget(vortex, (u16 *) (eq->this14));
vortex_EqHw_SetRightGainsTarget(vortex, (u16 *) (eq->this14));
vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c);
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
index 7e7443d3b2b576..ad65c39c2de323 100644
--- a/sound/pci/au88x0/au88x0_game.c
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -41,8 +41,6 @@
#define VORTEX_GAME_DWAIT 20 /* 20 ms */
-static struct gameport gameport;
-
static unsigned char vortex_game_read(struct gameport *gameport)
{
vortex_t *vortex = gameport->driver;
@@ -97,8 +95,10 @@ static int vortex_game_open(struct gameport *gameport, int mode)
static int vortex_gameport_register(vortex_t * vortex)
{
- vortex->gameport = &gameport;
-
+ if ((vortex->gameport = snd_kcalloc(sizeof(struct gameport), GFP_KERNEL)) == NULL) {
+ return -1;
+ };
+
vortex->gameport->driver = vortex;
vortex->gameport->fuzz = 64;
@@ -117,8 +117,10 @@ static int vortex_gameport_register(vortex_t * vortex)
static int vortex_gameport_unregister(vortex_t * vortex)
{
- if (vortex->gameport != NULL)
+ if (vortex->gameport != NULL) {
gameport_unregister_port(vortex->gameport);
+ kfree(vortex->gameport);
+ }
return 0;
}
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 686ca8ff75103b..6df634ebc129d0 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -18,8 +18,7 @@
* Vortex PCM ALSA driver.
*
* Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
- * It remains stuck,and DMA transfers do not happen.
- *
+ * It remains stuck,and DMA transfers do not happen.
*/
#include <sound/driver.h>
@@ -124,7 +123,7 @@ static int snd_vortex_pcm_open(snd_pcm_substream_t * substream)
vortex_t *vortex = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
-
+
/* Force equal size periods */
if ((err =
snd_pcm_hw_constraint_integer(runtime,
@@ -232,12 +231,13 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
}
#ifndef CHIP_AU8810
else {
- /*if (stream != NULL)
+ /* if (stream != NULL)
vortex_wt_allocroute(chip, substream->number, 0); */
vortex_wt_allocroute(chip, substream->number,
params_channels(hw_params));
stream = substream->runtime->private_data =
&chip->dma_wt[substream->number];
+ stream->dma = substream->number;
stream->substream = substream;
vortex_wtdma_setbuffers(chip, substream->number, sgbuf,
params_period_bytes(hw_params),
@@ -325,7 +325,7 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
break;
case SNDRV_PCM_TRIGGER_STOP:
// do something to stop the PCM engine
- //printk(KERN_INFO "vortex: stop %d\n", dma)
+ //printk(KERN_INFO "vortex: stop %d\n", dma);
stream->fifo_enabled = 0;
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
vortex_adbdma_pausefifo(chip, dma);
@@ -502,18 +502,13 @@ static int __devinit snd_vortex_new_pcm(vortex_t * chip, int idx, int nr)
if (idx == VORTEX_PCM_ADB)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
&snd_vortex_playback_ops);
-
+
/* pre-allocation of Scatter-Gather buffers */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci_dev),
- 0x10000, 0x10000);
-
- // The above should be used, as soon as ALSA gets updated.
- /*
- snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci_dev, pcm,
- 0x10000, 0x10000);
- */
+ snd_dma_pci_data(chip->pci_dev),
+ 0x10000, 0x10000);
+
if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
snd_kcontrol_t *kcontrol;
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
index 186721869f580d..400417d34609b5 100644
--- a/sound/pci/au88x0/au88x0_synth.c
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -36,6 +36,7 @@ static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
/* WT */
+/* Put 2 WT channels together for one stereo interlaced channel. */
static void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo)
{
int temp;
@@ -47,6 +48,7 @@ static void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo)
hwwrite(vortex->mmio, WT_STEREO(wt), temp);
}
+/* Join to mixdown route. */
static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en)
{
int temp;
@@ -60,7 +62,7 @@ static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en)
hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp);
}
-// WT routing is still a mistery.
+/* Setup WT route. */
static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
{
wt_voice_t *voice = &(vortex->wt_voice[wt]);
@@ -68,13 +70,15 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
//FIXME: WT audio routing.
if (nr_ch) {
- vortex_fifo_wtinitialize(vortex, wt, 2);
+ vortex_fifo_wtinitialize(vortex, wt, 1);
vortex_fifo_setwtvalid(vortex, wt, 1);
vortex_wt_setstereo(vortex, wt, nr_ch - 1);
} else
vortex_fifo_setwtvalid(vortex, wt, 0);
-
- vortex_wt_setdsout(vortex, wt, 0);
+
+ /* Set mixdown mode. */
+ vortex_wt_setdsout(vortex, wt, 1);
+ /* Set other parameter registers. */
hwwrite(vortex->mmio, WT_SRAMP(0), 0x880000);
//hwwrite(vortex->mmio, WT_GMODE(0), 0xffffffff);
#ifdef CHIP_AU8830
@@ -87,7 +91,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
temp = hwread(vortex->mmio, WT_PARM(wt, 3));
printk("vortex: WT PARM3: %x\n", temp);
- hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
+ //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
hwwrite(vortex->mmio, WT_DELAY(wt, 1), 0);
@@ -106,6 +110,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
return 0;
}
+
static void vortex_wt_connect(vortex_t * vortex, int en)
{
int i, ii, mix;
@@ -129,15 +134,12 @@ static void vortex_wt_connect(vortex_t * vortex, int en)
ADB_WTOUT(i, ii + 0x20), ADB_MIXIN(mix));
vortex_connection_mixin_mix(vortex, en, mix,
- vortex->mixplayb[ii %
- 2], 0);
+ vortex->mixplayb[ii % 2], 0);
if (VORTEX_IS_QUAD(vortex))
vortex_connection_mixin_mix(vortex, en,
mix,
- vortex->
- mixplayb[2 +
- (ii %
- 2)], 0);
+ vortex->mixplayb[2 +
+ (ii % 2)], 0);
}
}
for (i = 0; i < NR_WT; i++) {