summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorChristian Weisgerber <naddy@cvs.openbsd.org>2001-09-06 14:47:08 +0000
committerChristian Weisgerber <naddy@cvs.openbsd.org>2001-09-06 14:47:08 +0000
commit9954eaf1309aad3397247d28ad73ea36ea0e9512 (patch)
tree1c6ef381529828c48bdb7b6d15ba501ee9ac27f3 /sys/dev
parente96ae92beea60ed40283f60ad80329c08a1f1431 (diff)
sync up to NetBSD; reviewed by csapuntz@
- better support for more chip revisions - split register definitions into separate header file - KNF
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/eap.c1065
-rw-r--r--sys/dev/pci/eapreg.h284
2 files changed, 666 insertions, 683 deletions
diff --git a/sys/dev/pci/eap.c b/sys/dev/pci/eap.c
index 6d91a585323..6a28b517344 100644
--- a/sys/dev/pci/eap.c
+++ b/sys/dev/pci/eap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: eap.c,v 1.12 2001/08/25 10:13:29 art Exp $ */
-/* $NetBSD: eap.c,v 1.25 1999/02/18 07:59:30 mycroft Exp $ */
+/* $OpenBSD: eap.c,v 1.13 2001/09/06 14:47:07 naddy Exp $ */
+/* $NetBSD: eap.c,v 1.46 2001/09/03 15:07:37 reinoud Exp $ */
/*
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -41,27 +41,26 @@
* Debugging: Andreas Gustafsson <gson@araneus.fi>
* Testing: Chuck Cranor <chuck@maria.wustl.edu>
* Phil Nelson <phil@cs.wwu.edu>
+ *
+ * ES1371/AC97: Ezra Story <ezy@panix.com>
*/
/*
- * Ensoniq AudoiPCI ES1370 + AK4531 driver.
- * Data sheets can be found at
- * http://www.ensoniq.com/multimedia/semi_html/html/es1370.zip
- * and
- * http://www.akm.com/pdf/4531.pdf
+ * Ensoniq ES1370 + AK4531 and ES1371/ES1373 + AC97
*
- * Added Creative Ensoniq support: ES1371 + AC97 = hack city.
- * -- Ezra Story <ezy@panix.com>
- * Check es1371.zip from above, and the Audio Codec 97 spec from
- * intel.com.
+ * Documentation links:
+ *
+ * ftp://ftp.alsa-project.org/pub/manuals/ensoniq/
+ * ftp://ftp.alsa-project.org/pub/manuals/asahi_kasei/4531.pdf
+ * ftp://download.intel.com/ial/scalableplatforms/audio/ac97r21.pdf
*/
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/device.h>
+#include <sys/proc.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/pcivar.h>
@@ -74,226 +73,14 @@
#include <machine/bus.h>
+#include <dev/pci/eapreg.h>
+
struct cfdriver eap_cd = {
NULL, "eap", DV_DULL
};
#define PCI_CBIO 0x10
-#define EAP_ICSC 0x00 /* interrupt / chip select control */
-#define EAP_SERR_DISABLE 0x00000001
-#define EAP_CDC_EN 0x00000002
-#define EAP_JYSTK_EN 0x00000004
-#define EAP_UART_EN 0x00000008
-#define EAP_ADC_EN 0x00000010
-#define EAP_DAC2_EN 0x00000020
-#define EAP_DAC1_EN 0x00000040
-#define EAP_BREQ 0x00000080
-#define EAP_XTCL0 0x00000100
-#define EAP_M_CB 0x00000200
-#define EAP_CCB_INTRM 0x00000400
-#define EAP_DAC_SYNC 0x00000800
-#define EAP_WTSRSEL 0x00003000
-#define EAP_WTSRSEL_5 0x00000000
-#define EAP_WTSRSEL_11 0x00001000
-#define EAP_WTSRSEL_22 0x00002000
-#define EAP_WTSRSEL_44 0x00003000
-#define EAP_M_SBB 0x00004000
-#define EAP_MSFMTSEL 0x00008000
-#define EAP_SET_PCLKDIV(n) (((n)&0x1fff)<<16)
-#define EAP_GET_PCLKDIV(n) (((n)>>16)&0x1fff)
-#define EAP_PCLKBITS 0x1fff0000
-#define EAP_XTCL1 0x40000000
-#define EAP_ADC_STOP 0x80000000
-#define E1371_SYNC_RES (1<<14)
-
-#define EAP_ICSS 0x04 /* interrupt / chip select status */
-#define EAP_I_ADC 0x00000001
-#define EAP_I_DAC2 0x00000002
-#define EAP_I_DAC1 0x00000004
-#define EAP_I_UART 0x00000008
-#define EAP_I_MCCB 0x00000010
-#define EAP_VC 0x00000060
-#define EAP_CWRIP 0x00000100
-#define EAP_CBUSY 0x00000200
-#define EAP_CSTAT 0x00000400
-#define CT5880_AC97_RESET 0x20000000
-#define EAP_INTR 0x80000000
-
-#define EAP_UART_DATA 0x08
-#define EAP_UART_STATUS 0x09
-#define EAP_UART_CONTROL 0x09
-#define EAP_MEMPAGE 0x0c
-#define EAP_CODEC 0x10
-#define EAP_SET_CODEC(a,d) (((a)<<8) | (d))
-
-/* ES1371 Registers */
-#define E1371_CODEC 0x14
-#define E1371_CODEC_WIP (1<<30)
-#define E1371_CODEC_VALID (1<<31)
-#define E1371_CODEC_READ (1<<23)
-#define E1371_SET_CODEC(a,d) (((a)<<16) | (d))
-#define E1371_SRC 0x10
-#define E1371_SRC_RAMWE (1<<24)
-#define E1371_SRC_RBUSY (1<<23)
-#define E1371_SRC_DISABLE (1<<22)
-#define E1371_SRC_DISP1 (1<<21)
-#define E1371_SRC_DISP2 (1<<20)
-#define E1371_SRC_DISREC (1<<19)
-#define E1371_SRC_ADDR(a) ((a)<<25)
-#define E1371_SRC_STATE_MASK 0x870000
-#define E1371_SRC_STATE_OK 0x010000
-#define E1371_SRC_DATA(d) (d)
-#define E1371_SRC_DATAMASK 0xffff
-#define E1371_LEGACY 0x18
-
-/* ES1371 Sample rate converter registers */
-#define ESRC_ADC 0x78
-#define ESRC_DAC1 0x74
-#define ESRC_DAC2 0x70
-#define ESRC_ADC_VOLL 0x6c
-#define ESRC_ADC_VOLR 0x6d
-#define ESRC_DAC1_VOLL 0x7c
-#define ESRC_DAC1_VOLR 0x7d
-#define ESRC_DAC2_VOLL 0x7e
-#define ESRC_DAC2_VOLR 0x7f
-#define ESRC_TRUNC_N 0x00
-#define ESRC_IREGS 0x01
-#define ESRC_ACF 0x02
-#define ESRC_VFF 0x03
-#define ESRC_SET_TRUNC(n) ((n)<<9)
-#define ESRC_SET_N(n) ((n)<<4)
-#define ESRC_SMF 0x8000
-#define ESRC_SET_VFI(n) ((n)<<10)
-#define ESRC_SET_ACI(n) (n)
-#define ESRC_SET_ADC_VOL(n) ((n)<<8)
-#define ESRC_SET_DAC_VOLI(n) ((n)<<12)
-#define ESRC_SET_DAC_VOLF(n) (n)
-#define SRC_MAGIC ((1<15)|(1<<13)|(1<<11)|(1<<9))
-
-
-#define EAP_SIC 0x20
-#define EAP_P1_S_MB 0x00000001
-#define EAP_P1_S_EB 0x00000002
-#define EAP_P2_S_MB 0x00000004
-#define EAP_P2_S_EB 0x00000008
-#define EAP_R1_S_MB 0x00000010
-#define EAP_R1_S_EB 0x00000020
-#define EAP_P2_DAC_SEN 0x00000040
-#define EAP_P1_SCT_RLD 0x00000080
-#define EAP_P1_INTR_EN 0x00000100
-#define EAP_P2_INTR_EN 0x00000200
-#define EAP_R1_INTR_EN 0x00000400
-#define EAP_P1_PAUSE 0x00000800
-#define EAP_P2_PAUSE 0x00001000
-#define EAP_P1_LOOP_SEL 0x00002000
-#define EAP_P2_LOOP_SEL 0x00004000
-#define EAP_R1_LOOP_SEL 0x00008000
-#define EAP_SET_P2_ST_INC(i) ((i) << 16)
-#define EAP_SET_P2_END_INC(i) ((i) << 19)
-#define EAP_INC_BITS 0x003f0000
-
-#define EAP_DAC1_CSR 0x24
-#define EAP_DAC2_CSR 0x28
-#define EAP_ADC_CSR 0x2c
-#define EAP_GET_CURRSAMP(r) ((r) >> 16)
-
-#define EAP_DAC_PAGE 0xc
-#define EAP_ADC_PAGE 0xd
-#define EAP_UART_PAGE1 0xe
-#define EAP_UART_PAGE2 0xf
-
-#define EAP_DAC1_ADDR 0x30
-#define EAP_DAC1_SIZE 0x34
-#define EAP_DAC2_ADDR 0x38
-#define EAP_DAC2_SIZE 0x3c
-#define EAP_ADC_ADDR 0x30
-#define EAP_ADC_SIZE 0x34
-#define EAP_SET_SIZE(c,s) (((c)<<16) | (s))
-
-#define EAP_READ_TIMEOUT 0x1000
-#define EAP_WRITE_TIMEOUT 0x1000
-
-
-#define EAP_XTAL_FREQ 1411200 /* 22.5792 / 16 MHz */
-
-/* AK4531 registers */
-#define AK_MASTER_L 0x00
-#define AK_MASTER_R 0x01
-#define AK_VOICE_L 0x02
-#define AK_VOICE_R 0x03
-#define AK_FM_L 0x04
-#define AK_FM_R 0x05
-#define AK_CD_L 0x06
-#define AK_CD_R 0x07
-#define AK_LINE_L 0x08
-#define AK_LINE_R 0x09
-#define AK_AUX_L 0x0a
-#define AK_AUX_R 0x0b
-#define AK_MONO1 0x0c
-#define AK_MONO2 0x0d
-#define AK_MIC 0x0e
-#define AK_MONO 0x0f
-#define AK_OUT_MIXER1 0x10
-#define AK_M_FM_L 0x40
-#define AK_M_FM_R 0x20
-#define AK_M_LINE_L 0x10
-#define AK_M_LINE_R 0x08
-#define AK_M_CD_L 0x04
-#define AK_M_CD_R 0x02
-#define AK_M_MIC 0x01
-#define AK_OUT_MIXER2 0x11
-#define AK_M_AUX_L 0x20
-#define AK_M_AUX_R 0x10
-#define AK_M_VOICE_L 0x08
-#define AK_M_VOICE_R 0x04
-#define AK_M_MONO2 0x02
-#define AK_M_MONO1 0x01
-#define AK_IN_MIXER1_L 0x12
-#define AK_IN_MIXER1_R 0x13
-#define AK_IN_MIXER2_L 0x14
-#define AK_IN_MIXER2_R 0x15
-#define AK_M_TMIC 0x80
-#define AK_M_TMONO1 0x40
-#define AK_M_TMONO2 0x20
-#define AK_M2_AUX_L 0x10
-#define AK_M2_AUX_R 0x08
-#define AK_M_VOICE 0x04
-#define AK_M2_MONO2 0x02
-#define AK_M2_MONO1 0x01
-#define AK_RESET 0x16
-#define AK_PD 0x02
-#define AK_NRST 0x01
-#define AK_CS 0x17
-#define AK_ADSEL 0x18
-#define AK_MGAIN 0x19
-#define AK_NPORTS 0x20
-
-#define MAX_NPORTS AK_NPORTS
-
-/* Not sensical for AC97? */
-#define VOL_TO_ATT5(v) (0x1f - ((v) >> 3))
-#define VOL_TO_GAIN5(v) VOL_TO_ATT5(v)
-#define ATT5_TO_VOL(v) ((0x1f - (v)) << 3)
-#define GAIN5_TO_VOL(v) ATT5_TO_VOL(v)
-#define VOL_0DB 200
-
-/* Futzable parms */
-#define EAP_MASTER_VOL 0
-#define EAP_VOICE_VOL 1
-#define EAP_FM_VOL 2
-#define EAP_VIDEO_VOL 2 /* ES1371 */
-#define EAP_CD_VOL 3
-#define EAP_LINE_VOL 4
-#define EAP_AUX_VOL 5
-#define EAP_MIC_VOL 6
-#define EAP_RECORD_SOURCE 7
-#define EAP_OUTPUT_SELECT 8
-#define EAP_MIC_PREAMP 9
-#define EAP_OUTPUT_CLASS 10
-#define EAP_RECORD_CLASS 11
-#define EAP_INPUT_CLASS 12
-
/* Debug */
#ifdef AUDIO_DEBUG
#define DPRINTF(x) if (eapdebug) printf x
@@ -304,9 +91,9 @@ int eapdebug = 20;
#define DPRINTFN(n,x)
#endif
-int eap_match __P((struct device *, void *, void *));
-void eap_attach __P((struct device *, struct device *, void *));
-int eap_intr __P((void *));
+int eap_match(struct device *, void *, void *);
+void eap_attach(struct device *, struct device *, void *);
+int eap_intr(void *);
struct eap_dma {
bus_dmamap_t map;
@@ -316,6 +103,7 @@ struct eap_dma {
size_t size;
struct eap_dma *next;
};
+
#define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
#define KERNADDR(p) ((void *)((p)->addr))
@@ -340,18 +128,18 @@ struct eap_softc {
char sc_rrun;
#endif
- u_short sc_port[MAX_NPORTS]; /* mirror of the hardware setting */
+ u_short sc_port[AK_NPORTS]; /* mirror of the hardware setting */
u_int sc_record_source; /* recording source mask */
u_int sc_output_source; /* output source mask */
u_int sc_mic_preamp;
- char sc_1371; /* Using ES1371/AC97 codec */
+ char sc_1371; /* Using ES1371/AC97 codec */
struct ac97_codec_if *codec_if;
struct ac97_host_if host_if;
};
-int eap_allocmem __P((struct eap_softc *, size_t, size_t, struct eap_dma *));
-int eap_freemem __P((struct eap_softc *, struct eap_dma *));
+int eap_allocmem(struct eap_softc *, size_t, size_t, struct eap_dma *);
+int eap_freemem(struct eap_softc *, struct eap_dma *);
#define EWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
#define EWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
@@ -362,43 +150,43 @@ struct cfattach eap_ca = {
sizeof(struct eap_softc), eap_match, eap_attach
};
-int eap_open __P((void *, int));
-void eap_close __P((void *));
-int eap_query_encoding __P((void *, struct audio_encoding *));
-int eap_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
-int eap_round_blocksize __P((void *, int));
-int eap_trigger_output __P((void *, void *, void *, int, void (*)(void *),
- void *, struct audio_params *));
-int eap_trigger_input __P((void *, void *, void *, int, void (*)(void *),
- void *, struct audio_params *));
-int eap_halt_output __P((void *));
-int eap_halt_input __P((void *));
-void eap_write_codec __P((struct eap_softc *, int, int));
-int eap_getdev __P((void *, struct audio_device *));
-int eap_mixer_set_port __P((void *, mixer_ctrl_t *));
-int eap_mixer_get_port __P((void *, mixer_ctrl_t *));
-int eap1371_mixer_set_port __P((void *, mixer_ctrl_t *));
-int eap1371_mixer_get_port __P((void *, mixer_ctrl_t *));
-int eap_query_devinfo __P((void *, mixer_devinfo_t *));
-void *eap_malloc __P((void *, u_long, int, int));
-void eap_free __P((void *, void *, int));
-u_long eap_round_buffersize __P((void *, u_long));
-int eap_mappage __P((void *, void *, int, int));
-int eap_get_props __P((void *));
-void eap_set_mixer __P((struct eap_softc *sc, int a, int d));
-int eap1371_src_wait __P((struct eap_softc *sc));
-void eap1371_set_adc_rate __P((struct eap_softc *sc, int rate));
-void eap1371_set_dac_rate __P((struct eap_softc *sc, int rate, int which));
-int eap1371_src_read __P((struct eap_softc *sc, int a));
-void eap1371_src_write __P((struct eap_softc *sc, int a, int d));
-int eap1371_query_devinfo __P((void *addr, mixer_devinfo_t *dip));
-
-int eap1371_attach_codec __P((void *sc, struct ac97_codec_if *));
-int eap1371_read_codec __P((void *sc, u_int8_t a, u_int16_t *d));
-int eap1371_write_codec __P((void *sc, u_int8_t a, u_int16_t d));
-void eap1371_reset_codec __P((void *sc));
-int eap1371_get_portnum_by_name __P((struct eap_softc *, char *, char *,
- char *));
+int eap_open(void *, int);
+void eap_close(void *);
+int eap_query_encoding(void *, struct audio_encoding *);
+int eap_set_params(void *, int, int, struct audio_params *, struct audio_params *);
+int eap_round_blocksize(void *, int);
+int eap_trigger_output(void *, void *, void *, int, void (*)(void *),
+ void *, struct audio_params *);
+int eap_trigger_input(void *, void *, void *, int, void (*)(void *),
+ void *, struct audio_params *);
+int eap_halt_output(void *);
+int eap_halt_input(void *);
+void eap1370_write_codec(struct eap_softc *, int, int);
+int eap_getdev(void *, struct audio_device *);
+int eap1370_mixer_set_port(void *, mixer_ctrl_t *);
+int eap1370_mixer_get_port(void *, mixer_ctrl_t *);
+int eap1371_mixer_set_port(void *, mixer_ctrl_t *);
+int eap1371_mixer_get_port(void *, mixer_ctrl_t *);
+int eap1370_query_devinfo(void *, mixer_devinfo_t *);
+void *eap_malloc(void *, u_long, int, int);
+void eap_free(void *, void *, int);
+u_long eap_round_buffersize(void *, u_long);
+int eap_mappage(void *, void *, int, int);
+int eap_get_props(void *);
+void eap1370_set_mixer(struct eap_softc *sc, int a, int d);
+u_int32_t eap1371_src_wait(struct eap_softc *sc);
+void eap1371_set_adc_rate(struct eap_softc *sc, int rate);
+void eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which);
+int eap1371_src_read(struct eap_softc *sc, int a);
+void eap1371_src_write(struct eap_softc *sc, int a, int d);
+int eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip);
+
+int eap1371_attach_codec(void *sc, struct ac97_codec_if *);
+int eap1371_read_codec(void *sc, u_int8_t a, u_int16_t *d);
+int eap1371_write_codec(void *sc, u_int8_t a, u_int16_t d);
+void eap1371_reset_codec(void *sc);
+int eap1371_get_portnum_by_name(struct eap_softc *, char *, char *,
+ char *);
struct audio_hw_if eap1370_hw_if = {
eap_open,
@@ -417,9 +205,9 @@ struct audio_hw_if eap1370_hw_if = {
NULL,
eap_getdev,
NULL,
- eap_mixer_set_port,
- eap_mixer_get_port,
- eap_query_devinfo,
+ eap1370_mixer_set_port,
+ eap1370_mixer_get_port,
+ eap1370_query_devinfo,
eap_malloc,
eap_free,
eap_round_buffersize,
@@ -465,302 +253,268 @@ struct audio_device eap_device = {
};
int
-eap_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
+eap_match(struct device *parent, void *match, void *aux)
{
struct pci_attach_args *pa = (struct pci_attach_args *) aux;
- if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_ENSONIQ &&
- PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CREATIVELABS)
- return (0);
-
- if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI ||
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI97 ||
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_CT5880 ||
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_EV1938)
- return (1);
+ switch (PCI_VENDOR(pa->pa_id)) {
+ case PCI_VENDOR_CREATIVELABS:
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_CREATIVELABS_EV1938:
+ return (1);
+ }
+ break;
+ case PCI_VENDOR_ENSONIQ:
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_ENSONIQ_AUDIOPCI:
+ case PCI_PRODUCT_ENSONIQ_AUDIOPCI97:
+ case PCI_PRODUCT_ENSONIQ_CT5880:
+ return (1);
+ }
+ break;
+ }
return (0);
}
void
-eap_write_codec(sc, a, d)
- struct eap_softc *sc;
- int a, d;
+eap1370_write_codec(struct eap_softc *sc, int a, int d)
{
-
int icss, to;
-
+
to = EAP_WRITE_TIMEOUT;
do {
icss = EREAD4(sc, EAP_ICSS);
DPRINTFN(5,("eap: codec %d prog: icss=0x%08x\n", a, icss));
- if (!to--) {
- printf("eap: timeout writing to codec\n");
- return;
- }
+ if (!to--) {
+ printf("eap: timeout writing to codec\n");
+ return;
+ }
} while (icss & EAP_CWRIP); /* XXX could use CSTAT here */
- EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
+ EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
}
+/*
+ * Reading and writing the CODEC is very convoluted. This mimics the
+ * FreeBSD and Linux drivers.
+ */
-int
-eap1371_read_codec(sc_, a, d)
- void *sc_;
- u_int8_t a;
- u_int16_t *d;
+static __inline void
+eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd)
{
- struct eap_softc *sc = sc_;
- int to;
- int cdc, src;
-
- to = EAP_WRITE_TIMEOUT;
- do {
- cdc = EREAD4(sc, E1371_CODEC);
- if (!to--) {
- printf("eap: timeout writing to codec\n");
- return 1;
- }
- } while (cdc & E1371_CODEC_WIP);
-
- /* just do it */
- src = (eap1371_src_wait(sc) & (E1371_SRC_DISABLE | E1371_SRC_DISP1 |
- E1371_SRC_DISP2 | E1371_SRC_DISREC)) ;
-
- EWRITE4(sc, E1371_SRC, src | 0x10000);
-
- for (to = 0; to < EAP_READ_TIMEOUT; to++) {
- if (!(EREAD4(sc, E1371_SRC) & E1371_SRC_STATE_MASK))
- break;
-
- delay(1);
- }
+ int to, s;
+ u_int32_t src, t;
for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
- if ((EREAD4(sc, E1371_SRC) & E1371_SRC_STATE_MASK) ==
- E1371_SRC_STATE_OK)
+ if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP))
break;
-
delay(1);
}
-
- EWRITE4(sc, E1371_CODEC, E1371_SET_CODEC(a, 0) | E1371_CODEC_READ);
+ if (to >= EAP_WRITE_TIMEOUT)
+ printf("%s: eap1371_ready_codec timeout 1\n",
+ sc->sc_dev.dv_xname);
- eap1371_src_wait(sc);
- EWRITE4(sc, E1371_SRC, src);
+ s = splaudio();
+ src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
+ EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
for (to = 0; to < EAP_READ_TIMEOUT; to++) {
- if ((cdc = EREAD4(sc, E1371_CODEC)) & E1371_CODEC_VALID)
+ t = EREAD4(sc, E1371_SRC);
+ if ((t & E1371_SRC_STATE_MASK) == 0)
break;
+ delay(1);
}
+ if (to >= EAP_READ_TIMEOUT)
+ printf("%s: eap1371_ready_codec timeout 2\n",
+ sc->sc_dev.dv_xname);
- if (to == EAP_WRITE_TIMEOUT) {
- DPRINTF(("eap1371: read codec timeout\n"));
+ for (to = 0; to < EAP_READ_TIMEOUT; to++) {
+ t = EREAD4(sc, E1371_SRC);
+ if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
+ break;
+ delay(1);
}
+ if (to >= EAP_READ_TIMEOUT)
+ printf("%s: eap1371_ready_codec timeout 3\n",
+ sc->sc_dev.dv_xname);
- *d = cdc & 0xffff;
+ EWRITE4(sc, E1371_CODEC, wd);
- DPRINTFN(10, ("eap1371: reading codec (%x) = %x\n", a, *d));
+ eap1371_src_wait(sc);
+ EWRITE4(sc, E1371_SRC, src);
- return (0);
+ splx(s);
}
int
-eap1371_write_codec(sc_, a, d)
- void *sc_;
- u_int8_t a;
- u_int16_t d;
+eap1371_read_codec(void *sc_, u_int8_t a, u_int16_t *d)
{
struct eap_softc *sc = sc_;
- int to;
- int cdc, src;
-
- to = EAP_WRITE_TIMEOUT;
- do {
- cdc = EREAD4(sc, E1371_CODEC);
- if (!to--) {
- printf("eap: timeout writing to codec\n");
- return 1;
- }
- } while (cdc & E1371_CODEC_WIP);
+ int to;
+ u_int32_t t;
- /* just do it */
- src = (eap1371_src_wait(sc) & (E1371_SRC_DISABLE | E1371_SRC_DISP1 |
- E1371_SRC_DISP2 | E1371_SRC_DISREC)) ;
-
- EWRITE4(sc, E1371_SRC, src | 0x10000);
+ eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, 0) | E1371_CODEC_READ);
for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
- if (!(EREAD4(sc, E1371_SRC) & E1371_SRC_STATE_MASK))
+ if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP))
break;
-
- delay(1);
}
-
+ if (to > EAP_WRITE_TIMEOUT)
+ printf("%s: eap1371_read_codec timeout 1\n",
+ sc->sc_dev.dv_xname);
+
for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
- if ((EREAD4(sc, E1371_SRC) & E1371_SRC_STATE_MASK) ==
- E1371_SRC_STATE_OK)
+ t = EREAD4(sc, E1371_CODEC);
+ if (t & E1371_CODEC_VALID)
break;
-
- delay(1);
}
+ if (to > EAP_WRITE_TIMEOUT)
+ printf("%s: eap1371_read_codec timeout 2\n",
+ sc->sc_dev.dv_xname);
- EWRITE4(sc, E1371_CODEC, E1371_SET_CODEC(a, d));
+ *d = (u_int16_t)t;
- eap1371_src_wait(sc);
- EWRITE4(sc, E1371_SRC, src);
+ DPRINTFN(10, ("eap1371: reading codec (%x) = %x\n", a, *d));
- DPRINTFN(10, ("eap1371: writing codec %x --> %x\n", d, a));
-
- return (0);
+ return (0);
}
int
-eap1371_src_wait(sc)
- struct eap_softc *sc;
+eap1371_write_codec(void *sc_, u_int8_t a, u_int16_t d)
{
- int to;
- int src;
+ struct eap_softc *sc = sc_;
+
+ eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, d));
+
+ DPRINTFN(10, ("eap1371: writing codec %x --> %x\n", d, a));
+
+ return (0);
+}
+u_int32_t
+eap1371_src_wait(struct eap_softc *sc)
+{
+ int to;
+ u_int32_t src;
+
for (to = 0; to < EAP_READ_TIMEOUT; to++) {
src = EREAD4(sc, E1371_SRC);
if (!(src & E1371_SRC_RBUSY))
- return src;
+ return (src);
delay(1);
}
-
-
- printf("eap: timeout waiting for sample rate"
- "converter\n");
-
- return src;
+ printf("%s: eap1371_src_wait timeout\n", sc->sc_dev.dv_xname);
+ return (src);
}
int
-eap1371_src_read(sc, a)
- struct eap_softc *sc;
- int a;
+eap1371_src_read(struct eap_softc *sc, int a)
{
- int r, to;
- int src;
+ int to;
+ u_int32_t src, t;
- src = eap1371_src_wait(sc);
+ src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
+ src |= E1371_SRC_ADDR(a);
+ EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
- EWRITE4(sc, E1371_SRC,
- (src & (E1371_SRC_DISABLE | E1371_SRC_DISP1 |
- E1371_SRC_DISP2 | E1371_SRC_DISREC)) |
- E1371_SRC_ADDR(a) | 0x10000UL);
-
- r = eap1371_src_wait(sc);
-
- if ((r & E1371_SRC_STATE_MASK) != E1371_SRC_STATE_OK) {
+ if ((eap1371_src_wait(sc) & E1371_SRC_STATE_MASK) != E1371_SRC_STATE_OK) {
for (to = 0; to < EAP_READ_TIMEOUT; to++) {
- r = EREAD4(sc, E1371_SRC);
- if ((r & E1371_SRC_STATE_MASK) ==
- E1371_SRC_STATE_OK) break;
+ t = EREAD4(sc, E1371_SRC);
+ if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
+ break;
+ delay(1);
}
}
- EWRITE4 (sc, E1371_SRC,
- (src & (E1371_SRC_DISABLE | E1371_SRC_DISP1 |
- E1371_SRC_DISP2 | E1371_SRC_DISREC)) |
- E1371_SRC_ADDR(a));
+ EWRITE4(sc, E1371_SRC, src);
- return r;
+ return t & E1371_SRC_DATAMASK;
}
void
-eap1371_src_write(sc, a, d)
- struct eap_softc *sc;
- int a,d;
+eap1371_src_write(struct eap_softc *sc, int a, int d)
{
- int r;
+ u_int32_t r;
- r = eap1371_src_wait(sc);
- r &= (E1371_SRC_DISABLE | E1371_SRC_DISP1 |
- E1371_SRC_DISP2 | E1371_SRC_DISREC);
+ r = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
r |= E1371_SRC_RAMWE | E1371_SRC_ADDR(a) | E1371_SRC_DATA(d);
EWRITE4(sc, E1371_SRC, r);
}
void
-eap1371_set_adc_rate(sc, rate)
- struct eap_softc *sc;
- int rate;
+eap1371_set_adc_rate(struct eap_softc *sc, int rate)
{
int freq, n, truncm;
int out;
-
- /* Whatever, it works, so I'll leave it :) */
-
- if (rate > 48000)
- rate = 48000;
- if (rate < 4000)
- rate = 4000;
- n = rate / 3000;
- if ((1 << n) & SRC_MAGIC)
- n--;
- truncm = ((21 * n) - 1) | 1;
- freq = ((48000 << 15) / rate) * n;
- if (rate >= 24000) {
- if (truncm > 239)
- truncm = 239;
+ int s;
+
+ /* Whatever, it works, so I'll leave it :) */
+
+ if (rate > 48000)
+ rate = 48000;
+ if (rate < 4000)
+ rate = 4000;
+ n = rate / 3000;
+ if ((1 << n) & SRC_MAGIC)
+ n--;
+ truncm = ((21 * n) - 1) | 1;
+ freq = ((48000 << 15) / rate) * n;
+ if (rate >= 24000) {
+ if (truncm > 239)
+ truncm = 239;
out = ESRC_SET_TRUNC((239 - truncm) / 2);
- } else {
- if (truncm > 119)
- truncm = 119;
+ } else {
+ if (truncm > 119)
+ truncm = 119;
out = ESRC_SMF | ESRC_SET_TRUNC((119 - truncm) / 2);
- }
+ }
out |= ESRC_SET_N(n);
- eap1371_src_write(sc, ESRC_ADC+ESRC_TRUNC_N, out);
+ s = splaudio();
+ eap1371_src_write(sc, ESRC_ADC+ESRC_TRUNC_N, out);
- out = eap1371_src_read(sc, ESRC_ADC+ESRC_IREGS) & 0xff;
- eap1371_src_write(sc, ESRC_ADC+ESRC_IREGS, out |
+ out = eap1371_src_read(sc, ESRC_ADC+ESRC_IREGS) & 0xff;
+ eap1371_src_write(sc, ESRC_ADC+ESRC_IREGS, out |
ESRC_SET_VFI(freq >> 15));
- eap1371_src_write(sc, ESRC_ADC+ESRC_VFF, freq & 0x7fff);
- eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(n));
- eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(n));
+ eap1371_src_write(sc, ESRC_ADC+ESRC_VFF, freq & 0x7fff);
+ eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(n));
+ eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(n));
+ splx(s);
}
void
-eap1371_set_dac_rate(sc, rate, which)
- struct eap_softc *sc;
- int rate;
- int which;
+eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which)
{
- int dac = (which == 1) ? ESRC_DAC1 : ESRC_DAC2;
+ int dac = which == 1 ? ESRC_DAC1 : ESRC_DAC2;
int freq, r;
+ int s;
- /* Whatever, it works, so I'll leave it :) */
-
- if (rate > 48000)
- rate = 48000;
- if (rate < 4000)
- rate = 4000;
- freq = ((rate << 15) + 1500) / 3000;
-
- eap1371_src_wait(sc);
- r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE |
- E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
- r |= (which == 1) ? E1371_SRC_DISP1 : E1371_SRC_DISP2;
- EWRITE4(sc, E1371_SRC, r);
- r = eap1371_src_read(sc, dac + ESRC_IREGS) & 0x00ff;
- eap1371_src_write(sc, dac + ESRC_IREGS, r | ((freq >> 5) & 0xfc00));
- eap1371_src_write(sc, dac + ESRC_VFF, freq & 0x7fff);
- r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE |
- E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
- r &= ~((which == 1) ? E1371_SRC_DISP1 : E1371_SRC_DISP2);
- EWRITE4(sc, E1371_SRC, r);
+ /* Whatever, it works, so I'll leave it :) */
+
+ if (rate > 48000)
+ rate = 48000;
+ if (rate < 4000)
+ rate = 4000;
+ freq = ((rate << 15) + 1500) / 3000;
+
+ s = splaudio();
+ eap1371_src_wait(sc);
+ r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE |
+ E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
+ r |= (which == 1) ? E1371_SRC_DISP1 : E1371_SRC_DISP2;
+ EWRITE4(sc, E1371_SRC, r);
+ r = eap1371_src_read(sc, dac + ESRC_IREGS) & 0x00ff;
+ eap1371_src_write(sc, dac + ESRC_IREGS, r | ((freq >> 5) & 0xfc00));
+ eap1371_src_write(sc, dac + ESRC_VFF, freq & 0x7fff);
+ r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE |
+ E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
+ r &= ~(which == 1 ? E1371_SRC_DISP1 : E1371_SRC_DISP2);
+ EWRITE4(sc, E1371_SRC, r);
+ splx(s);
}
void
-eap_attach(parent, self, aux)
- struct device *parent;
- struct device *self;
- void *aux;
+eap_attach(struct device *parent, struct device *self, void *aux)
{
struct eap_softc *sc = (struct eap_softc *)self;
struct pci_attach_args *pa = (struct pci_attach_args *)aux;
@@ -771,11 +525,22 @@ eap_attach(parent, self, aux)
pcireg_t csr;
mixer_ctrl_t ctl;
int i;
- int revision;
+ int revision, ct5880;
+
+ /* Flag if we're "creative" */
+ sc->sc_1371 = !(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI);
- sc->sc_1371 =
- !(PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI);
revision = PCI_REVISION(pa->pa_class);
+ if (sc->sc_1371) {
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ &&
+ ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI97 &&
+ (revision == EAP_ES1373_8 || revision == EAP_CT5880_A)) ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_CT5880))
+ ct5880 = 1;
+ else
+ ct5880 = 0;
+ }
/* Map I/O register */
if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
@@ -818,9 +583,9 @@ eap_attach(parent, self, aux)
/* reset codec */
/* normal operation */
/* select codec clocks */
- eap_write_codec(sc, AK_RESET, AK_PD);
- eap_write_codec(sc, AK_RESET, AK_PD | AK_NRST);
- eap_write_codec(sc, AK_CS, 0x0);
+ eap1370_write_codec(sc, AK_RESET, AK_PD);
+ eap1370_write_codec(sc, AK_RESET, AK_PD | AK_NRST);
+ eap1370_write_codec(sc, AK_CS, 0x0);
eap_hw_if = &eap1370_hw_if;
@@ -850,21 +615,16 @@ eap_attach(parent, self, aux)
ctl.un.mask = 1 << EAP_MIC_VOL;
eap_hw_if->set_port(sc, &ctl);
} else {
- int error;
+ /* clean slate */
- /* clean slate */
EWRITE4(sc, EAP_SIC, 0);
- EWRITE4(sc, EAP_ICSC, 0);
- EWRITE4(sc, E1371_LEGACY, 0);
-
- /* It seems that revision 7 and greater of the AUDIOPCI 97
- are actually CT5880 */
- if ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_CT5880) ||
- ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI97)
- && (revision >= 7))) {
- EWRITE4(sc, EAP_ICSS, CT5880_AC97_RESET);
+ EWRITE4(sc, EAP_ICSC, 0);
+ EWRITE4(sc, E1371_LEGACY, 0);
- delay(20000);
+ if (ct5880) {
+ EWRITE4(sc, EAP_ICSS, EAP_CT5880_AC97_RESET);
+ /* Let codec wake up */
+ tsleep(sc, PRIBIO, "eapcdc", hz / 20);
}
/* Reset from es1371's perspective */
@@ -872,40 +632,40 @@ eap_attach(parent, self, aux)
delay(20);
EWRITE4(sc, EAP_ICSC, 0);
- /* must properly reprogram sample rate converter,
- * or it locks up. Set some defaults for the life of the
- * machine, and set up a sb default sample rate.
- */
- EWRITE4(sc, E1371_SRC, E1371_SRC_DISABLE);
- for (i=0; i<0x80; i++)
- eap1371_src_write(sc, i, 0);
+ /*
+ * Must properly reprogram sample rate converter,
+ * or it locks up. Set some defaults for the life of the
+ * machine, and set up a sb default sample rate.
+ */
+ EWRITE4(sc, E1371_SRC, E1371_SRC_DISABLE);
+ for (i = 0; i < 0x80; i++)
+ eap1371_src_write(sc, i, 0);
eap1371_src_write(sc, ESRC_DAC1+ESRC_TRUNC_N, ESRC_SET_N(16));
eap1371_src_write(sc, ESRC_DAC2+ESRC_TRUNC_N, ESRC_SET_N(16));
- eap1371_src_write(sc, ESRC_DAC1+ESRC_IREGS, ESRC_SET_VFI(16));
- eap1371_src_write(sc, ESRC_DAC2+ESRC_IREGS, ESRC_SET_VFI(16));
- eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(16));
- eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(16));
+ eap1371_src_write(sc, ESRC_DAC1+ESRC_IREGS, ESRC_SET_VFI(16));
+ eap1371_src_write(sc, ESRC_DAC2+ESRC_IREGS, ESRC_SET_VFI(16));
+ eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(16));
+ eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(16));
eap1371_src_write(sc, ESRC_DAC1_VOLL, ESRC_SET_DAC_VOLI(1));
eap1371_src_write(sc, ESRC_DAC1_VOLR, ESRC_SET_DAC_VOLI(1));
eap1371_src_write(sc, ESRC_DAC2_VOLL, ESRC_SET_DAC_VOLI(1));
eap1371_src_write(sc, ESRC_DAC2_VOLR, ESRC_SET_DAC_VOLI(1));
- eap1371_set_adc_rate(sc, 22050);
- eap1371_set_dac_rate(sc, 22050, 1);
- eap1371_set_dac_rate(sc, 22050, 2);
-
- EWRITE4(sc, E1371_SRC, 0);
+ eap1371_set_adc_rate(sc, 22050);
+ eap1371_set_dac_rate(sc, 22050, 1);
+ eap1371_set_dac_rate(sc, 22050, 2);
+
+ EWRITE4(sc, E1371_SRC, 0);
- /* Reset codec */
+ /* Reset codec */
/* Interrupt enable */
sc->host_if.arg = sc;
sc->host_if.attach = eap1371_attach_codec;
sc->host_if.read = eap1371_read_codec;
-
sc->host_if.write = eap1371_write_codec;
sc->host_if.reset = eap1371_reset_codec;
- if ((error = ac97_attach(&sc->host_if)) == 0) {
+ if (ac97_attach(&sc->host_if) == 0) {
/* Interrupt enable */
EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
} else
@@ -926,22 +686,19 @@ eap_attach(parent, self, aux)
AudioNvolume, AudioNmute);
eap1371_mixer_set_port(sc, &ctl);
-
ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord,
AudioNsource, NULL);
ctl.type = AUDIO_MIXER_ENUM;
ctl.un.ord = 0;
eap1371_mixer_set_port(sc, &ctl);
- }
+ }
audio_attach_mi(eap_hw_if, sc, &sc->sc_dev);
}
int
-eap1371_attach_codec(sc_, codec_if)
- void *sc_;
- struct ac97_codec_if *codec_if;
+eap1371_attach_codec(void *sc_, struct ac97_codec_if *codec_if)
{
struct eap_softc *sc = sc_;
@@ -950,22 +707,25 @@ eap1371_attach_codec(sc_, codec_if)
}
void
-eap1371_reset_codec(sc_)
- void *sc_;
+eap1371_reset_codec(void *sc_)
{
struct eap_softc *sc = sc_;
- u_int32_t icsc = EREAD4(sc, EAP_ICSC);
-
+ u_int32_t icsc;
+ int s;
+
+ s = splaudio();
+ icsc = EREAD4(sc, EAP_ICSC);
EWRITE4(sc, EAP_ICSC, icsc | E1371_SYNC_RES);
- delay(100);
+ delay(20);
EWRITE4(sc, EAP_ICSC, icsc & ~E1371_SYNC_RES);
+ delay(1);
+ splx(s);
return;
}
int
-eap_intr(p)
- void *p;
+eap_intr(void *p)
{
struct eap_softc *sc = p;
u_int32_t intr, sic;
@@ -976,6 +736,7 @@ eap_intr(p)
sic = EREAD4(sc, EAP_SIC);
DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic));
if (intr & EAP_I_ADC) {
+#if 0
/*
* XXX This is a hack!
* The EAP chip sometimes generates the recording interrupt
@@ -997,6 +758,7 @@ eap_intr(p)
}
}
/* Continue with normal interrupt handling. */
+#endif
EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
if (sc->sc_rintr)
@@ -1012,11 +774,7 @@ eap_intr(p)
}
int
-eap_allocmem(sc, size, align, p)
- struct eap_softc *sc;
- size_t size;
- size_t align;
- struct eap_dma *p;
+eap_allocmem(struct eap_softc *sc, size_t size, size_t align, struct eap_dma *p)
{
int error;
@@ -1053,9 +811,7 @@ free:
}
int
-eap_freemem(sc, p)
- struct eap_softc *sc;
- struct eap_dma *p;
+eap_freemem(struct eap_softc *sc, struct eap_dma *p)
{
bus_dmamap_unload(sc->sc_dmatag, p->map);
bus_dmamap_destroy(sc->sc_dmatag, p->map);
@@ -1065,9 +821,7 @@ eap_freemem(sc, p)
}
int
-eap_open(addr, flags)
- void *addr;
- int flags;
+eap_open(void *addr, int flags)
{
return (0);
}
@@ -1076,8 +830,7 @@ eap_open(addr, flags)
* Close function is called at splaudio().
*/
void
-eap_close(addr)
- void *addr;
+eap_close(void *addr)
{
struct eap_softc *sc = addr;
@@ -1089,9 +842,7 @@ eap_close(addr)
}
int
-eap_query_encoding(addr, fp)
- void *addr;
- struct audio_encoding *fp;
+eap_query_encoding(void *addr, struct audio_encoding *fp)
{
switch (fp->index) {
case 0:
@@ -1148,10 +899,8 @@ eap_query_encoding(addr, fp)
}
int
-eap_set_params(addr, setmode, usemode, play, rec)
- void *addr;
- int setmode, usemode;
- struct audio_params *play, *rec;
+eap_set_params(void *addr, int setmode, int usemode,
+ struct audio_params *play, struct audio_params *rec)
{
struct eap_softc *sc = addr;
struct audio_params *p;
@@ -1203,26 +952,26 @@ eap_set_params(addr, setmode, usemode, play, rec)
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16) {
if (mode == AUMODE_PLAY)
- p->sw_code = swap_bytes_change_sign16;
+ p->sw_code = swap_bytes_change_sign16_le;
else
- p->sw_code = change_sign16_swap_bytes;
+ p->sw_code = change_sign16_swap_bytes_le;
}
break;
case AUDIO_ENCODING_ULINEAR_LE:
if (p->precision == 16)
- p->sw_code = change_sign16;
+ p->sw_code = change_sign16_le;
break;
case AUDIO_ENCODING_ULAW:
if (mode == AUMODE_PLAY) {
p->factor = 2;
- p->sw_code = mulaw_to_slinear16;
+ p->sw_code = mulaw_to_slinear16_le;
} else
p->sw_code = ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
if (mode == AUMODE_PLAY) {
p->factor = 2;
- p->sw_code = alaw_to_slinear16;
+ p->sw_code = alaw_to_slinear16_le;
} else
p->sw_code = ulinear8_to_alaw;
break;
@@ -1231,57 +980,55 @@ eap_set_params(addr, setmode, usemode, play, rec)
}
}
- if (sc->sc_1371) {
+ if (sc->sc_1371) {
eap1371_set_dac_rate(sc, play->sample_rate, 1);
eap1371_set_dac_rate(sc, play->sample_rate, 2);
eap1371_set_adc_rate(sc, rec->sample_rate);
} else {
- /* Set the speed */
- DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n",
- EREAD4(sc, EAP_ICSC)));
- div = EREAD4(sc, EAP_ICSC) & ~EAP_PCLKBITS;
- /*
- * XXX
- * The -2 isn't documented, but seemed to make the wall
- * time match
- * what I expect. - mycroft
- */
- if (usemode == AUMODE_RECORD)
- div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ /
- rec->sample_rate - 2);
- else
- div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ /
- play->sample_rate - 2);
- div |= EAP_CCB_INTRM;
- EWRITE4(sc, EAP_ICSC, div);
- DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div));
- }
+ /* Set the speed */
+ DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n",
+ EREAD4(sc, EAP_ICSC)));
+ div = EREAD4(sc, EAP_ICSC) & ~EAP_PCLKBITS;
+ /*
+ * XXX
+ * The -2 isn't documented, but seemed to make the wall
+ * time match
+ * what I expect. - mycroft
+ */
+ if (usemode == AUMODE_RECORD)
+ div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ /
+ rec->sample_rate - 2);
+ else
+ div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ /
+ play->sample_rate - 2);
+ div |= EAP_CCB_INTRM;
+ EWRITE4(sc, EAP_ICSC, div);
+ DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div));
+ }
return (0);
}
int
-eap_round_blocksize(addr, blk)
- void *addr;
- int blk;
+eap_round_blocksize(void *addr, int blk)
{
return (blk & -32); /* keep good alignment */
}
int
-eap_trigger_output(addr, start, end, blksize, intr, arg, param)
- void *addr;
- void *start, *end;
- int blksize;
- void (*intr) __P((void *));
- void *arg;
- struct audio_params *param;
+eap_trigger_output(
+ void *addr,
+ void *start,
+ void *end,
+ int blksize,
+ void (*intr)(void *),
+ void *arg,
+ struct audio_params *param)
{
struct eap_softc *sc = addr;
struct eap_dma *p;
u_int32_t icsc, sic;
int sampshift;
- int idx;
#ifdef DIAGNOSTIC
if (sc->sc_prun)
@@ -1290,12 +1037,12 @@ eap_trigger_output(addr, start, end, blksize, intr, arg, param)
#endif
DPRINTFN(1, ("eap_trigger_output: sc=%p start=%p end=%p "
- "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
+ "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
sc->sc_pintr = intr;
sc->sc_parg = arg;
sic = EREAD4(sc, EAP_SIC);
- sic &= ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS | EAP_P2_INTR_EN);
+ sic &= ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS);
sic |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(param->precision * param->factor / 8);
sampshift = 0;
if (param->precision * param->factor == 16) {
@@ -1306,9 +1053,7 @@ eap_trigger_output(addr, start, end, blksize, intr, arg, param)
sic |= EAP_P2_S_MB;
sampshift++;
}
-
- DPRINTFN(1, ("set SIC=0x%08x\n", sic));
- EWRITE4(sc, EAP_SIC, sic);
+ EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN);
EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN);
for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
@@ -1320,45 +1065,34 @@ eap_trigger_output(addr, start, end, blksize, intr, arg, param)
DPRINTF(("eap_trigger_output: DAC2_ADDR=0x%x, DAC2_SIZE=0x%x\n",
(int)DMAADDR(p),
- EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
+ (int)EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE);
EWRITE4(sc, EAP_DAC2_ADDR, DMAADDR(p));
EWRITE4(sc, EAP_DAC2_SIZE,
EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1));
EWRITE4(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1);
- icsc = EREAD4(sc, EAP_ICSC);
if (sc->sc_1371)
EWRITE4(sc, E1371_SRC, 0);
- EWRITE4(sc, EAP_ICSC, icsc | EAP_DAC2_EN);
-
-
- for (idx = 0; idx < 3; idx++) {
- DPRINTFN (1, ("icsc=%08x sic=%08x dac2csr=%08x icss=%08x src=%08x\n",
- EREAD4(sc, EAP_ICSC),
- EREAD4(sc, EAP_SIC),
- EREAD4(sc, EAP_DAC2_CSR),
- EREAD4(sc, EAP_ICSS),
- EREAD4(sc, E1371_SRC)));
+ icsc = EREAD4(sc, EAP_ICSC);
+ EWRITE4(sc, EAP_ICSC, icsc | EAP_DAC2_EN);
- delay(1000);
- }
+ DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", icsc));
return (0);
}
-
-
int
-eap_trigger_input(addr, start, end, blksize, intr, arg, param)
- void *addr;
- void *start, *end;
- int blksize;
- void (*intr) __P((void *));
- void *arg;
- struct audio_params *param;
+eap_trigger_input(
+ void *addr,
+ void *start,
+ void *end,
+ int blksize,
+ void (*intr)(void *),
+ void *arg,
+ struct audio_params *param)
{
struct eap_softc *sc = addr;
struct eap_dma *p;
@@ -1387,9 +1121,8 @@ eap_trigger_input(addr, start, end, blksize, intr, arg, param)
sic |= EAP_R1_S_MB;
sampshift++;
}
- DPRINTFN(1, ("set SIC=0x%08x\n", sic));
-
- EWRITE4(sc, EAP_SIC, sic);
+ EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
+ EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
;
@@ -1400,7 +1133,7 @@ eap_trigger_input(addr, start, end, blksize, intr, arg, param)
DPRINTF(("eap_trigger_input: ADC_ADDR=0x%x, ADC_SIZE=0x%x\n",
(int)DMAADDR(p),
- EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
+ (int)EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
EWRITE4(sc, EAP_ADC_ADDR, DMAADDR(p));
EWRITE4(sc, EAP_ADC_SIZE,
@@ -1420,8 +1153,7 @@ eap_trigger_input(addr, start, end, blksize, intr, arg, param)
}
int
-eap_halt_output(addr)
- void *addr;
+eap_halt_output(void *addr)
{
struct eap_softc *sc = addr;
u_int32_t icsc;
@@ -1436,8 +1168,7 @@ eap_halt_output(addr)
}
int
-eap_halt_input(addr)
- void *addr;
+eap_halt_input(void *addr)
{
struct eap_softc *sc = addr;
u_int32_t icsc;
@@ -1452,70 +1183,55 @@ eap_halt_input(addr)
}
int
-eap_getdev(addr, retp)
- void *addr;
- struct audio_device *retp;
+eap_getdev(void *addr, struct audio_device *retp)
{
*retp = eap_device;
return (0);
}
int
-eap1371_mixer_set_port(addr, cp)
- void *addr;
- mixer_ctrl_t *cp;
+eap1371_mixer_set_port(void *addr, mixer_ctrl_t *cp)
{
struct eap_softc *sc = addr;
- return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if,
- cp));
+ return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp));
}
int
-eap1371_mixer_get_port(addr, cp)
- void *addr;
- mixer_ctrl_t *cp;
+eap1371_mixer_get_port(void *addr, mixer_ctrl_t *cp)
{
struct eap_softc *sc = addr;
- return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if,
- cp));
+ return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
}
int
-eap1371_query_devinfo(addr, dip)
- void *addr;
- mixer_devinfo_t *dip;
+eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip)
{
struct eap_softc *sc = addr;
- return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip));
+ return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
}
int
-eap1371_get_portnum_by_name(sc, class, device, qualifier)
- struct eap_softc *sc;
- char *class, *device, *qualifier;
+eap1371_get_portnum_by_name(struct eap_softc *sc,
+ char *class, char *device, char *qualifier)
{
- return ((sc->codec_if->vtbl->get_portnum_by_name)(sc->codec_if, class,
- device, qualifier));
+ return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class,
+ device, qualifier));
}
void
-eap_set_mixer(sc, a, d)
- struct eap_softc *sc;
- int a, d;
+eap1370_set_mixer(struct eap_softc *sc, int a, int d)
{
- eap_write_codec(sc, a, d);
+ eap1370_write_codec(sc, a, d);
- sc->sc_port[a] = d;
- DPRINTFN(1, ("eap_mixer_set_port port 0x%02x = 0x%02x\n", a, d));
+ sc->sc_port[a] = d;
+ DPRINTFN(1, ("eap1370_mixer_set_port port 0x%02x = 0x%02x\n", a, d));
}
int
-eap_mixer_set_port(addr, cp)
- void *addr;
- mixer_ctrl_t *cp;
+eap1370_mixer_set_port(void *addr, mixer_ctrl_t *cp)
{
struct eap_softc *sc = addr;
int lval, rval, l, r, la, ra;
@@ -1538,10 +1254,10 @@ eap_mixer_set_port(addr, cp)
l2 |= AK_M2_AUX_L, r2 |= AK_M2_AUX_R;
if (m & (1 << EAP_MIC_VOL))
l2 |= AK_M_TMIC, r2 |= AK_M_TMIC;
- eap_set_mixer(sc, AK_IN_MIXER1_L, l1);
- eap_set_mixer(sc, AK_IN_MIXER1_R, r1);
- eap_set_mixer(sc, AK_IN_MIXER2_L, l2);
- eap_set_mixer(sc, AK_IN_MIXER2_R, r2);
+ eap1370_set_mixer(sc, AK_IN_MIXER1_L, l1);
+ eap1370_set_mixer(sc, AK_IN_MIXER1_R, r1);
+ eap1370_set_mixer(sc, AK_IN_MIXER2_L, l2);
+ eap1370_set_mixer(sc, AK_IN_MIXER2_R, r2);
return (0);
}
if (cp->dev == EAP_OUTPUT_SELECT) {
@@ -1561,8 +1277,8 @@ eap_mixer_set_port(addr, cp)
o2 |= AK_M_AUX_L | AK_M_AUX_R;
if (m & (1 << EAP_MIC_VOL))
o1 |= AK_M_MIC;
- eap_set_mixer(sc, AK_OUT_MIXER1, o1);
- eap_set_mixer(sc, AK_OUT_MIXER2, o2);
+ eap1370_set_mixer(sc, AK_OUT_MIXER1, o1);
+ eap1370_set_mixer(sc, AK_OUT_MIXER2, o2);
return (0);
}
if (cp->dev == EAP_MIC_PREAMP) {
@@ -1571,7 +1287,7 @@ eap_mixer_set_port(addr, cp)
if (cp->un.ord != 0 && cp->un.ord != 1)
return (EINVAL);
sc->sc_mic_preamp = cp->un.ord;
- eap_set_mixer(sc, AK_MGAIN, cp->un.ord);
+ eap1370_set_mixer(sc, AK_MGAIN, cp->un.ord);
return (0);
}
if (cp->type != AUDIO_MIXER_VALUE)
@@ -1622,17 +1338,15 @@ eap_mixer_set_port(addr, cp)
default:
return (EINVAL);
}
- eap_set_mixer(sc, la, l);
+ eap1370_set_mixer(sc, la, l);
if (ra >= 0) {
- eap_set_mixer(sc, ra, r);
+ eap1370_set_mixer(sc, ra, r);
}
return (0);
}
int
-eap_mixer_get_port(addr, cp)
- void *addr;
- mixer_ctrl_t *cp;
+eap1370_mixer_get_port(void *addr, mixer_ctrl_t *cp)
{
struct eap_softc *sc = addr;
int la, ra, l, r;
@@ -1699,9 +1413,7 @@ eap_mixer_get_port(addr, cp)
}
int
-eap_query_devinfo(addr, dip)
- void *addr;
- mixer_devinfo_t *dip;
+eap1370_query_devinfo(void *addr, mixer_devinfo_t *dip)
{
switch (dip->index) {
case EAP_MASTER_VOL:
@@ -1839,10 +1551,7 @@ eap_query_devinfo(addr, dip)
}
void *
-eap_malloc(addr, size, pool, flags)
- void *addr;
- u_long size;
- int pool, flags;
+eap_malloc(void *addr, u_long size, int pool, int flags)
{
struct eap_softc *sc = addr;
struct eap_dma *p;
@@ -1862,38 +1571,29 @@ eap_malloc(addr, size, pool, flags)
}
void
-eap_free(addr, ptr, pool)
- void *addr;
- void *ptr;
- int pool;
+eap_free(void *addr, void *ptr, int pool)
{
struct eap_softc *sc = addr;
- struct eap_dma **p;
+ struct eap_dma **pp, *p;
- for (p = &sc->sc_dmas; *p; p = &(*p)->next) {
- if (KERNADDR(*p) == ptr) {
- eap_freemem(sc, *p);
- *p = (*p)->next;
- free(*p, pool);
+ for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
+ if (KERNADDR(p) == ptr) {
+ eap_freemem(sc, p);
+ *pp = p->next;
+ free(p, pool);
return;
}
}
}
u_long
-eap_round_buffersize(addr, size)
- void *addr;
- u_long size;
+eap_round_buffersize(void *addr, u_long size)
{
return (size);
}
int
-eap_mappage(addr, mem, off, prot)
- void *addr;
- void *mem;
- int off;
- int prot;
+eap_mappage(void *addr, void *mem, int off, int prot)
{
struct eap_softc *sc = addr;
struct eap_dma *p;
@@ -1909,9 +1609,8 @@ eap_mappage(addr, mem, off, prot)
}
int
-eap_get_props(addr)
- void *addr;
+eap_get_props(void *addr)
{
return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
- AUDIO_PROP_FULLDUPLEX);
+ AUDIO_PROP_FULLDUPLEX);
}
diff --git a/sys/dev/pci/eapreg.h b/sys/dev/pci/eapreg.h
new file mode 100644
index 00000000000..0997f83e8eb
--- /dev/null
+++ b/sys/dev/pci/eapreg.h
@@ -0,0 +1,284 @@
+/* $OpenBSD: eapreg.h,v 1.1 2001/09/06 14:47:07 naddy Exp $ */
+/* $NetBSD: eapreg.h,v 1.2 2000/04/30 21:59:58 augustss Exp $ */
+
+/*
+ * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson <augustss@netbsd.org> and Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ES1370/ES1371/ES1373 registers
+ */
+
+#define EAP_ICSC 0x00 /* interrupt / chip select control */
+#define EAP_SERR_DISABLE 0x00000001
+#define EAP_CDC_EN 0x00000002
+#define EAP_JYSTK_EN 0x00000004
+#define EAP_UART_EN 0x00000008
+#define EAP_ADC_EN 0x00000010
+#define EAP_DAC2_EN 0x00000020
+#define EAP_DAC1_EN 0x00000040
+#define EAP_BREQ 0x00000080
+#define EAP_XTCL0 0x00000100
+#define EAP_M_CB 0x00000200
+#define EAP_CCB_INTRM 0x00000400
+#define EAP_DAC_SYNC 0x00000800
+#define EAP_WTSRSEL 0x00003000
+#define EAP_WTSRSEL_5 0x00000000
+#define EAP_WTSRSEL_11 0x00001000
+#define EAP_WTSRSEL_22 0x00002000
+#define EAP_WTSRSEL_44 0x00003000
+#define EAP_M_SBB 0x00004000
+#define E1371_SYNC_RES 0x00004000
+#define EAP_MSFMTSEL 0x00008000
+#define EAP_SET_PCLKDIV(n) (((n)&0x1fff)<<16)
+#define EAP_GET_PCLKDIV(n) (((n)>>16)&0x1fff)
+#define EAP_PCLKBITS 0x1fff0000
+#define EAP_XTCL1 0x40000000
+#define EAP_ADC_STOP 0x80000000
+
+#define EAP_ICSS 0x04 /* interrupt / chip select status */
+ /* on the 5880 control / status */
+#define EAP_I_ADC 0x00000001
+#define EAP_I_DAC2 0x00000002
+#define EAP_I_DAC1 0x00000004
+#define EAP_I_UART 0x00000008
+#define EAP_I_MCCB 0x00000010
+#define EAP_VC 0x00000060
+#define EAP_CWRIP 0x00000100
+#define EAP_CBUSY 0x00000200
+#define EAP_CSTAT 0x00000400
+#define EAP_CT5880_AC97_RESET 0x20000000
+#define EAP_INTR 0x80000000
+
+#define EAP_UART_DATA 0x08
+#define EAP_UART_STATUS 0x09
+#define EAP_US_RXRDY 0x01
+#define EAP_US_TXRDY 0x02
+#define EAP_US_TXINT 0x04
+#define EAP_US_RXINT 0x80
+#define EAP_UART_CONTROL 0x09
+#define EAP_UC_CNTRL 0x03
+#define EAP_UC_TXINTEN 0x20
+#define EAP_UC_RXINTEN 0x80
+#define EAP_MEMPAGE 0x0c
+#define EAP_CODEC 0x10
+#define EAP_SET_CODEC(a,d) (((a)<<8) | (d))
+
+/*
+ * ES1371/ES1373 registers
+ */
+
+#define E1371_CODEC 0x14
+#define E1371_CODEC_VALID 0x80000000
+#define E1371_CODEC_WIP 0x40000000
+#define E1371_CODEC_READ 0x00800000
+#define E1371_SET_CODEC(a,d) (((a)<<16) | (d))
+
+#define E1371_SRC 0x10
+#define E1371_SRC_RAMWE 0x01000000
+#define E1371_SRC_RBUSY 0x00800000
+#define E1371_SRC_DISABLE 0x00400000
+#define E1371_SRC_DISP1 0x00200000
+#define E1371_SRC_DISP2 0x00100000
+#define E1371_SRC_DISREC 0x00080000
+#define E1371_SRC_ADDR(a) ((a)<<25)
+#define E1371_SRC_DATA(d) (d)
+#define E1371_SRC_DATAMASK 0x0000ffff
+#define E1371_SRC_CTLMASK (E1371_SRC_DISABLE | E1371_SRC_DISP1 | \
+ E1371_SRC_DISP2 | E1371_SRC_DISREC)
+#define E1371_SRC_STATE_MASK 0x00870000
+#define E1371_SRC_STATE_OK 0x00010000
+
+#define E1371_LEGACY 0x18
+
+/*
+ * ES1371/ES1373 sample rate converter registers
+ */
+
+#define ESRC_ADC 0x78
+#define ESRC_DAC1 0x74
+#define ESRC_DAC2 0x70
+#define ESRC_ADC_VOLL 0x6c
+#define ESRC_ADC_VOLR 0x6d
+#define ESRC_DAC1_VOLL 0x7c
+#define ESRC_DAC1_VOLR 0x7d
+#define ESRC_DAC2_VOLL 0x7e
+#define ESRC_DAC2_VOLR 0x7f
+#define ESRC_TRUNC_N 0x00
+#define ESRC_IREGS 0x01
+#define ESRC_ACF 0x02
+#define ESRC_VFF 0x03
+#define ESRC_SET_TRUNC(n) ((n)<<9)
+#define ESRC_SET_N(n) ((n)<<4)
+#define ESRC_SMF 0x8000
+#define ESRC_SET_VFI(n) ((n)<<10)
+#define ESRC_SET_ACI(n) (n)
+#define ESRC_SET_ADC_VOL(n) ((n)<<8)
+#define ESRC_SET_DAC_VOLI(n) ((n)<<12)
+#define ESRC_SET_DAC_VOLF(n) (n)
+#define SRC_MAGIC ((1<15)|(1<<13)|(1<<11)|(1<<9))
+
+#define EAP_SIC 0x20
+#define EAP_P1_S_MB 0x00000001
+#define EAP_P1_S_EB 0x00000002
+#define EAP_P2_S_MB 0x00000004
+#define EAP_P2_S_EB 0x00000008
+#define EAP_R1_S_MB 0x00000010
+#define EAP_R1_S_EB 0x00000020
+#define EAP_P2_DAC_SEN 0x00000040
+#define EAP_P1_SCT_RLD 0x00000080
+#define EAP_P1_INTR_EN 0x00000100
+#define EAP_P2_INTR_EN 0x00000200
+#define EAP_R1_INTR_EN 0x00000400
+#define EAP_P1_PAUSE 0x00000800
+#define EAP_P2_PAUSE 0x00001000
+#define EAP_P1_LOOP_SEL 0x00002000
+#define EAP_P2_LOOP_SEL 0x00004000
+#define EAP_R1_LOOP_SEL 0x00008000
+#define EAP_SET_P2_ST_INC(i) ((i) << 16)
+#define EAP_SET_P2_END_INC(i) ((i) << 19)
+#define EAP_INC_BITS 0x003f0000
+
+#define EAP_DAC1_CSR 0x24
+#define EAP_DAC2_CSR 0x28
+#define EAP_ADC_CSR 0x2c
+#define EAP_GET_CURRSAMP(r) ((r) >> 16)
+
+#define EAP_DAC_PAGE 0xc
+#define EAP_ADC_PAGE 0xd
+#define EAP_UART_PAGE1 0xe
+#define EAP_UART_PAGE2 0xf
+
+#define EAP_DAC1_ADDR 0x30
+#define EAP_DAC1_SIZE 0x34
+#define EAP_DAC2_ADDR 0x38
+#define EAP_DAC2_SIZE 0x3c
+#define EAP_ADC_ADDR 0x30
+#define EAP_ADC_SIZE 0x34
+#define EAP_SET_SIZE(c,s) (((c)<<16) | (s))
+
+#define EAP_READ_TIMEOUT 5000
+#define EAP_WRITE_TIMEOUT 5000
+
+
+#define EAP_XTAL_FREQ 1411200 /* 22.5792 / 16 MHz */
+
+/* AK4531 registers */
+#define AK_MASTER_L 0x00
+#define AK_MASTER_R 0x01
+#define AK_VOICE_L 0x02
+#define AK_VOICE_R 0x03
+#define AK_FM_L 0x04
+#define AK_FM_R 0x05
+#define AK_CD_L 0x06
+#define AK_CD_R 0x07
+#define AK_LINE_L 0x08
+#define AK_LINE_R 0x09
+#define AK_AUX_L 0x0a
+#define AK_AUX_R 0x0b
+#define AK_MONO1 0x0c
+#define AK_MONO2 0x0d
+#define AK_MIC 0x0e
+#define AK_MONO 0x0f
+#define AK_OUT_MIXER1 0x10
+#define AK_M_FM_L 0x40
+#define AK_M_FM_R 0x20
+#define AK_M_LINE_L 0x10
+#define AK_M_LINE_R 0x08
+#define AK_M_CD_L 0x04
+#define AK_M_CD_R 0x02
+#define AK_M_MIC 0x01
+#define AK_OUT_MIXER2 0x11
+#define AK_M_AUX_L 0x20
+#define AK_M_AUX_R 0x10
+#define AK_M_VOICE_L 0x08
+#define AK_M_VOICE_R 0x04
+#define AK_M_MONO2 0x02
+#define AK_M_MONO1 0x01
+#define AK_IN_MIXER1_L 0x12
+#define AK_IN_MIXER1_R 0x13
+#define AK_IN_MIXER2_L 0x14
+#define AK_IN_MIXER2_R 0x15
+#define AK_M_TMIC 0x80
+#define AK_M_TMONO1 0x40
+#define AK_M_TMONO2 0x20
+#define AK_M2_AUX_L 0x10
+#define AK_M2_AUX_R 0x08
+#define AK_M_VOICE 0x04
+#define AK_M2_MONO2 0x02
+#define AK_M2_MONO1 0x01
+#define AK_RESET 0x16
+#define AK_PD 0x02
+#define AK_NRST 0x01
+#define AK_CS 0x17
+#define AK_ADSEL 0x18
+#define AK_MGAIN 0x19
+#define AK_NPORTS 0x20
+
+/* Not sensical for AC97? */
+#define VOL_TO_ATT5(v) (0x1f - ((v) >> 3))
+#define VOL_TO_GAIN5(v) VOL_TO_ATT5(v)
+#define ATT5_TO_VOL(v) ((0x1f - (v)) << 3)
+#define GAIN5_TO_VOL(v) ATT5_TO_VOL(v)
+#define VOL_0DB 200
+
+/* Futzable parms */
+#define EAP_MASTER_VOL 0
+#define EAP_VOICE_VOL 1
+#define EAP_FM_VOL 2
+#define EAP_VIDEO_VOL 2 /* ES1371 */
+#define EAP_CD_VOL 3
+#define EAP_LINE_VOL 4
+#define EAP_AUX_VOL 5
+#define EAP_MIC_VOL 6
+#define EAP_RECORD_SOURCE 7
+#define EAP_OUTPUT_SELECT 8
+#define EAP_MIC_PREAMP 9
+#define EAP_OUTPUT_CLASS 10
+#define EAP_RECORD_CLASS 11
+#define EAP_INPUT_CLASS 12
+
+#define MIDI_BUSY_WAIT 100
+#define MIDI_BUSY_DELAY 100 /* Delay when UART is busy */
+
+#define EAP_EV1938_A 0x00
+#define EAP_ES1371_A 0x02
+#define EAP_CT5880_C 0x02
+#define EAP_CT5880_D 0x03
+#define EAP_ES1373_A 0x04
+#define EAP_ES1373_B 0x06
+#define EAP_CT5880_A 0x07
+#define EAP_ES1373_8 0x08
+#define EAP_ES1371_B 0x09