diff options
author | Christian Weisgerber <naddy@cvs.openbsd.org> | 2001-09-06 14:47:08 +0000 |
---|---|---|
committer | Christian Weisgerber <naddy@cvs.openbsd.org> | 2001-09-06 14:47:08 +0000 |
commit | 9954eaf1309aad3397247d28ad73ea36ea0e9512 (patch) | |
tree | 1c6ef381529828c48bdb7b6d15ba501ee9ac27f3 /sys/dev | |
parent | e96ae92beea60ed40283f60ad80329c08a1f1431 (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.c | 1065 | ||||
-rw-r--r-- | sys/dev/pci/eapreg.h | 284 |
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 |