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