Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Add support for ES1371. From OpenBSD and Ezra S...



details:   https://anonhg.NetBSD.org/src/rev/a7af3ac97af3
branches:  trunk
changeset: 477676:a7af3ac97af3
user:      augustss <augustss%NetBSD.org@localhost>
date:      Wed Oct 27 13:20:34 1999 +0000

description:
Add support for ES1371.  From OpenBSD and Ezra Story <ezy%panix.com@localhost>.

diffstat:

 sys/dev/pci/eap.c     |  596 +++++++++++++++++++++++++++++++++++++++++++------
 sys/dev/pci/files.pci |    4 +-
 2 files changed, 519 insertions(+), 81 deletions(-)

diffs (truncated from 837 to 300 lines):

diff -r fe716492fc4b -r a7af3ac97af3 sys/dev/pci/eap.c
--- a/sys/dev/pci/eap.c Wed Oct 27 13:18:02 1999 +0000
+++ b/sys/dev/pci/eap.c Wed Oct 27 13:20:34 1999 +0000
@@ -1,4 +1,5 @@
-/*     $NetBSD: eap.c,v 1.27 1999/09/01 07:32:31 kleink Exp $  */
+/*     $NetBSD: eap.c,v 1.28 1999/10/27 13:20:34 augustss Exp $        */
+/*      $OpenBSD: eap.c,v 1.6 1999/10/05 19:24:42 csapuntz Exp $ */
 
 /*
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -48,7 +49,13 @@
  * http://www.ensoniq.com/multimedia/semi_html/html/es1370.zip
  * and
  * http://206.214.38.151/pdf/4531.pdf
+ *
+ * Added Creative Ensoniq support: ES1371 + AC97 = hack city.
+ * -- Ezra Story <ezy%panix.com@localhost>
+ * Check es1371.zip from above, and the Audio Codec 97 spec from
+ * intel.com.
  */
+ 
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -63,6 +70,7 @@
 #include <dev/audio_if.h>
 #include <dev/mulaw.h>
 #include <dev/auconv.h>
+#include <dev/ic/ac97.h>
 
 #include <machine/bus.h>
 
@@ -93,6 +101,7 @@
 #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
@@ -113,6 +122,49 @@
 #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_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
@@ -152,6 +204,10 @@
 #define EAP_ADC_SIZE           0x34
 #define  EAP_SET_SIZE(c,s)     (((c)<<16) | (s))
 
+#define EAP_READ_TIMEOUT       5000000
+#define EAP_WRITE_TIMEOUT      5000000
+
+
 #define EAP_XTAL_FREQ 1411200 /* 22.5792 / 16 MHz */
 
 /* AK4531 registers */
@@ -204,29 +260,34 @@
 #define AK_CS                  0x17
 #define AK_ADSEL               0x18
 #define AK_MGAIN               0x19
+#define AK_NPORTS               0x20
 
-#define AK_NPORTS 16
+#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_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_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
 #define DPRINTFN(n,x)  if (eapdebug>(n)) printf x
@@ -272,10 +333,14 @@
        char    sc_rrun;
 #endif
 
-       u_char  sc_port[AK_NPORTS];     /* mirror of the hardware setting */
+       u_short sc_port[MAX_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 */
+
+       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 *));
@@ -301,17 +366,32 @@
            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 *, int, size_t, int, int));
 void   eap_free __P((void *, void *, int));
 size_t eap_round_buffersize __P((void *, int, size_t));
 int    eap_mappage __P((void *, void *, int, int));
 int    eap_get_props __P((void *));
-void   eap_write_codec __P((struct eap_softc *sc, int a, int d));
 void   eap_set_mixer __P((struct eap_softc *sc, int a, int d));
+void   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 *));
 
 struct audio_hw_if eap_hw_if = {
        eap_open,
@@ -358,10 +438,12 @@
 
        if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_ENSONIQ)
                return (0);
-       if (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_ENSONIQ_AUDIOPCI)
-               return (0);
+       if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI ||
+           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI97) {
+               return (1);
+        }
 
-       return (1);
+       return (0);
 }
 
 void
@@ -369,13 +451,204 @@
        struct eap_softc *sc;
        int a, d;
 {
-       int icss;
+
+       int icss, to = EAP_WRITE_TIMEOUT;
 
        do {
                icss = EREAD4(sc, EAP_ICSS);
                DPRINTFN(5,("eap: codec %d prog: icss=0x%08x\n", a, icss));
-       } while(icss & EAP_CWRIP);
-       EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
+                if (!to--) {
+                        printf("eap: timeout writing to codec\n");
+                        return;
+                }
+       } while(to && icss & EAP_CWRIP);  /* XXX could use CSTAT here */
+        EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
+}
+
+
+int
+eap1371_read_codec(sc_, a, d)
+        void *sc_;
+       u_int8_t a;
+       u_int16_t *d;
+{
+       struct eap_softc *sc = sc_;
+        int to;
+        int cdc;
+
+        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 */
+       eap1371_src_wait(sc);
+        EWRITE4(sc, E1371_CODEC, E1371_SET_CODEC(a, 0) | E1371_CODEC_READ);
+
+       for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
+               if ((cdc = EREAD4(sc, E1371_CODEC)) & E1371_CODEC_VALID)
+                       break;
+       }
+
+       if (to == EAP_WRITE_TIMEOUT) {
+               DPRINTF(("eap1371: read codec timeout\n"));
+       }
+
+       *d = cdc & 0xffff;
+
+        DPRINTFN(10, ("eap1371: reading codec (%x) = %x\n", a, *d));        
+
+       return (0);
+}
+
+int
+eap1371_write_codec(sc_, a, d)
+        void *sc_;
+       u_int8_t a;
+       u_int16_t d;
+{
+       struct eap_softc *sc = sc_;
+        int to;
+        int cdc;
+
+        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 */
+       eap1371_src_wait(sc);
+        EWRITE4(sc, E1371_CODEC, E1371_SET_CODEC(a, d));
+        DPRINTFN(10, ("eap1371: writing codec %x --> %x\n", d, a));
+
+        return (0);
+}
+
+void
+eap1371_src_wait(sc)
+       struct eap_softc *sc;
+{
+        int to;
+        int src;
+



Home | Main Index | Thread Index | Old Index