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 VIA VT8233/VT8235. The patch wa...



details:   https://anonhg.NetBSD.org/src/rev/cff0f1d103f1
branches:  trunk
changeset: 537783:cff0f1d103f1
user:      kent <kent%NetBSD.org@localhost>
date:      Sat Oct 05 18:08:30 2002 +0000

description:
Add support for VIA VT8233/VT8235.  The patch was provided by Ola Eriksson
<ola at mreriksson dot net> in PR kern/18375.  It is based on auvia of
OpenBSD.

diffstat:

 sys/dev/pci/auvia.c    |  233 +++++++++++++++++++++++++++++++++---------------
 sys/dev/pci/auviavar.h |    5 +-
 2 files changed, 164 insertions(+), 74 deletions(-)

diffs (truncated from 474 to 300 lines):

diff -r d23eea753469 -r cff0f1d103f1 sys/dev/pci/auvia.c
--- a/sys/dev/pci/auvia.c       Sat Oct 05 17:52:31 2002 +0000
+++ b/sys/dev/pci/auvia.c       Sat Oct 05 18:08:30 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: auvia.c,v 1.21 2002/10/02 16:51:03 thorpej Exp $       */
+/*     $NetBSD: auvia.c,v 1.22 2002/10/05 18:08:30 kent Exp $  */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 /*
- * VIA Technologies VT82C686A Southbridge Audio Driver
+ * VIA Technologies VT82C686A / VT8233 / VT8235 Southbridge Audio Driver
  *
  * Documentation links:
  *
@@ -47,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.21 2002/10/02 16:51:03 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.22 2002/10/05 18:08:30 kent Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -87,7 +87,7 @@
 };
 
 /* rev. H and later seem to support only fixed rate 48 kHz */
-#define        AUVIA_FIXED_RATE        48000   
+#define        AUVIA_FIXED_RATE        48000
 
 int    auvia_match(struct device *, struct cfdata *, void *);
 void   auvia_attach(struct device *, struct device *, void *);
@@ -130,22 +130,35 @@
 #define                AUVIA_PCICONF_ACFM       0x00000200     /* FM enab */
 #define                AUVIA_PCICONF_ACSB       0x00000100     /* SB enab */
 
-#define AUVIA_PLAY_STAT                        0x00
-#define AUVIA_RECORD_STAT              0x10
+#define                AUVIA_PLAY_BASE                 0x00
+#define                AUVIA_RECORD_BASE               0x10
+
+#define                AUVIA_RP_STAT                   0x00
 #define                AUVIA_RPSTAT_INTR               0x03
-#define AUVIA_PLAY_CONTROL             0x01
-#define AUVIA_RECORD_CONTROL           0x11
+#define                AUVIA_RP_CONTROL                0x01
 #define                AUVIA_RPCTRL_START              0x80
 #define                AUVIA_RPCTRL_TERMINATE          0x40
-#define AUVIA_PLAY_MODE                        0x02
-#define AUVIA_RECORD_MODE              0x12
+#define                AUVIA_RPCTRL_AUTOSTART          0x20
+/* The following are 8233 specific */
+#define                AUVIA_RPCTRL_STOP               0x04
+#define                AUVIA_RPCTRL_EOL                0x02
+#define                AUVIA_RPCTRL_FLAG               0x01
+#define                AUVIA_RP_MODE                   0x02
 #define                AUVIA_RPMODE_INTR_FLAG          0x01
 #define                AUVIA_RPMODE_INTR_EOL           0x02
 #define                AUVIA_RPMODE_STEREO             0x10
 #define                AUVIA_RPMODE_16BIT              0x20
 #define                AUVIA_RPMODE_AUTOSTART          0x80
-#define        AUVIA_PLAY_DMAOPS_BASE          0x04
-#define        AUVIA_RECORD_DMAOPS_BASE        0x14
+#define                AUVIA_RP_DMAOPS_BASE            0x04
+
+#define                VIA8233_RP_DXS_LVOL             0x02
+#define                VIA8233_RP_DXS_RVOL             0x03
+#define                VIA8233_RP_RATEFMT              0x08
+#define                VIA8233_RATEFMT_48K             0xfffff
+#define                VIA8233_RATEFMT_STEREO          0x00100000
+#define                VIA8233_RATEFMT_16BIT           0x00200000
+
+#define                VIA_RP_DMAOPS_COUNT             0x0c
 
 #define        AUVIA_CODEC_CTL                 0x80
 #define                AUVIA_CODEC_READ                0x00800000
@@ -202,6 +215,7 @@
                return 0;
        switch (PCI_PRODUCT(pa->pa_id)) {
        case PCI_PRODUCT_VIATECH_VT82C686A_AC97:
+       case PCI_PRODUCT_VIATECH_VT8233_AC97:
                break;
        default:
                return 0;
@@ -216,30 +230,56 @@
 {
        struct pci_attach_args *pa = aux;
        struct auvia_softc *sc = (struct auvia_softc *) self;
-        const char *intrstr = NULL;
+       const char *intrstr = NULL;
        struct mixer_ctrl ctl;
        pci_chipset_tag_t pc = pa->pa_pc;
-        pcitag_t pt = pa->pa_tag;
-        pci_intr_handle_t ih;
+       pcitag_t pt = pa->pa_tag;
+       pci_intr_handle_t ih;
+       bus_size_t iosize;
        pcireg_t pr;
        u_int16_t v;
-        int r, i;
+       int r, i;
+
+       if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT8233_AC97)
+               sc->sc_flags |= AUVIA_FLAGS_VT8233;
+
+       if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot,
+               &sc->sc_ioh, NULL, &iosize)) {
+               printf(": can't map i/o space\n");
+               return;
+       }
+
+       sc->sc_dmat = pa->pa_dmat;
+       sc->sc_pc = pc;
+       sc->sc_pt = pt;
 
        r = PCI_REVISION(pa->pa_class);
-       sc->sc_revision[1] = '\0';
-       if (r == 0x20) {
-               sc->sc_revision[0] = 'H';
-       } else if ((r >= 0x10) && (r <= 0x14)) {
-               sc->sc_revision[0] = 'A' + (r - 0x10);
+       if (sc->sc_flags & AUVIA_FLAGS_VT8233) {
+               sprintf(sc->sc_revision, "0x%02X", r);
+               if (r < 0x50) {
+                       printf(": VIA VT8233 AC'97 Audio (rev %s)\n",
+                              sc->sc_revision);
+               } else {
+                       printf(": VIA VT8235 AC'97 Audio (rev %s)\n",
+                              sc->sc_revision);
+               }
        } else {
-               sprintf(sc->sc_revision, "0x%02X", r);
+               sc->sc_revision[1] = '\0';
+               if (r == 0x20) {
+                       sc->sc_revision[0] = 'H';
+               } else if ((r >= 0x10) && (r <= 0x14)) {
+                       sc->sc_revision[0] = 'A' + (r - 0x10);
+               } else {
+                       sprintf(sc->sc_revision, "0x%02X", r);
+               }
+
+               printf(": VIA VT82C686A AC'97 Audio (rev %s)\n",
+                      sc->sc_revision);
        }
 
-       printf(": VIA VT82C686A AC'97 Audio (rev %s)\n",
-               sc->sc_revision);
-
        if (pci_intr_map(pa, &ih)) {
-               printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
+               printf(": couldn't map interrupt\n");
+               bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
                return;
        }
        intrstr = pci_intr_string(pc, ih);
@@ -250,21 +290,12 @@
                if (intrstr != NULL)
                        printf(" at %s", intrstr);
                printf("\n");
+               bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
                return;
        }
 
-       sc->sc_dmat = pa->pa_dmat;
-       sc->sc_pc = pc;
-       sc->sc_pt = pt;
-
        printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
 
-       if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot,
-                           &sc->sc_ioh, &sc->sc_ioaddr, &sc->sc_iosize)) {
-               printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
-               return;
-       }
-
        /* disable SBPro compat & others */
        pr = pci_conf_read(pc, pt, AUVIA_PCICONF_JUNK);
 
@@ -287,6 +318,8 @@
        if ((r = ac97_attach(&sc->host_if)) != 0) {
                printf("%s: can't attach codec (error 0x%X)\n",
                        sc->sc_dev.dv_xname, r);
+               pci_intr_disestablish(pc, sc->sc_ih);
+               bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
                return;
        }
 
@@ -317,7 +350,7 @@
                        { AudioCinputs, AudioNline},
                        { AudioCrecord, AudioNvolume},
                };
-               
+
                ctl.type = AUDIO_MIXER_ENUM;
                ctl.un.ord = 0;
 
@@ -336,8 +369,8 @@
        ctl.dev = sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if,
                AudioCoutputs, AudioNmaster, NULL);
        auvia_set_port(sc, &ctl);
-       
-        audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev);
+
+       audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev);
 }
 
 
@@ -367,7 +400,7 @@
        pci_conf_write(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK, r);
        delay(2);
 
-       r |= AUVIA_PCICONF_ACNOTRST;            /* disable RESET (inactive high) */
+       r |= AUVIA_PCICONF_ACNOTRST;    /* disable RESET (inactive high) */
        pci_conf_write(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK, r);
        delay(200);
 
@@ -461,7 +494,7 @@
 auvia_close(void *addr)
 {
        struct auvia_softc *sc = addr;
-    
+
        auvia_halt_output(sc);
        auvia_halt_input(sc);
 
@@ -535,15 +568,38 @@
        struct auvia_softc *sc = addr;
        struct audio_params *p;
        u_int16_t regval;
-       int reg, mode;
+       int reg, mode, base;
 
        /* for mode in (RECORD, PLAY) */
-       for (mode = AUMODE_RECORD; mode != -1; 
+       for (mode = AUMODE_RECORD; mode != -1;
             mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
                if ((setmode & mode) == 0)
                        continue;
 
-               p = mode == AUMODE_PLAY ? play : rec;
+               if (mode == AUMODE_PLAY ) {
+                       p = play;
+                       base = AUVIA_PLAY_BASE;
+               } else {
+                       p = rec;
+                       base = AUVIA_RECORD_BASE;
+               }
+
+               if (sc->sc_flags & AUVIA_FLAGS_VT8233) {
+                       u_int32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+                               base + VIA8233_RP_RATEFMT) & ~(VIA8233_RATEFMT_48K
+                               | VIA8233_RATEFMT_STEREO | VIA8233_RATEFMT_16BIT);
+
+                       v |= VIA8233_RATEFMT_48K *
+                               (p->sample_rate / 20) / (48000 / 20);
+
+                       if (p->channels == 2)
+                               v |= VIA8233_RATEFMT_STEREO;
+                       if( p->precision == 16)
+                               v |= VIA8233_RATEFMT_16BIT;
+
+                       bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+                               base + VIA8233_RP_RATEFMT, v);
+               }
 
                if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
                    (p->precision != 8 && p->precision != 16) ||
@@ -630,10 +686,10 @@
 int
 auvia_halt_output(void *addr)
 {
-        struct auvia_softc *sc = addr;
+       struct auvia_softc *sc = addr;
 
-       bus_space_write_1(sc->sc_iot, sc->sc_ioh, AUVIA_PLAY_CONTROL,
-               AUVIA_RPCTRL_TERMINATE);
+       bus_space_write_1(sc->sc_iot, sc->sc_ioh,
+               AUVIA_PLAY_BASE + AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE);
 
        return 0;
 }
@@ -642,10 +698,10 @@
 int
 auvia_halt_input(void *addr)
 {
-        struct auvia_softc *sc = addr;
+       struct auvia_softc *sc = addr;
 
-       bus_space_write_1(sc->sc_iot, sc->sc_ioh, AUVIA_RECORD_CONTROL,
-               AUVIA_RPCTRL_TERMINATE);
+       bus_space_write_1(sc->sc_iot, sc->sc_ioh,
+               AUVIA_PLAY_BASE + AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE);
 
        return 0;
 }
@@ -654,10 +710,16 @@



Home | Main Index | Thread Index | Old Index