summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-02-20 16:45:29 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-02-20 16:45:29 +0000
commit58b653139bc72f8a79d8f7ef5e719681a84e10c6 (patch)
tree6aa0ef6284678b93946d6325539f5732ab3e5ae0 /sys
parent23daeb00a48c6987fb72d950455a8f9ada914c1d (diff)
Add necessary bits to support AC97 codecs in envy and add support
for the VIA Tremor 5.1 card. From Alexandr Shadchin <alexandr.shadchin at gmail.com>, thanks! help from oga@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/envy.c151
-rw-r--r--sys/dev/pci/envyreg.h10
-rw-r--r--sys/dev/pci/envyvar.h6
-rw-r--r--sys/dev/pci/files.pci4
4 files changed, 165 insertions, 6 deletions
diff --git a/sys/dev/pci/envy.c b/sys/dev/pci/envy.c
index 37079b0c769..490c224a466 100644
--- a/sys/dev/pci/envy.c
+++ b/sys/dev/pci/envy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: envy.c,v 1.31 2009/11/02 05:54:16 ratchov Exp $ */
+/* $OpenBSD: envy.c,v 1.32 2010/02/20 16:45:28 ratchov Exp $ */
/*
* Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org>
*
@@ -32,11 +32,12 @@
#include <sys/ioctl.h>
#include <sys/audioio.h>
#include <sys/malloc.h>
+#include <dev/audio_if.h>
+#include <dev/ic/ac97.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/envyvar.h>
#include <dev/pci/envyreg.h>
-#include <dev/audio_if.h>
#include <machine/bus.h>
#ifdef ENVY_DEBUG
@@ -103,12 +104,21 @@ int envy_get_port(void *, struct mixer_ctrl *);
int envy_set_port(void *, struct mixer_ctrl *);
int envy_get_props(void *);
+int envy_ac97_wait(struct envy_softc *);
+int envy_ac97_attach_codec(void *, struct ac97_codec_if *);
+int envy_ac97_read_codec(void *, u_int8_t, u_int16_t *);
+int envy_ac97_write_codec(void *, u_int8_t, u_int16_t);
+void envy_ac97_reset_codec(void *);
+enum ac97_host_flags envy_ac97_flags_codec(void *);
+
void delta_init(struct envy_softc *);
void delta_codec_write(struct envy_softc *, int, int, int);
void revo51_init(struct envy_softc *);
void revo51_codec_write(struct envy_softc *, int, int, int);
+void tremor51_init(struct envy_softc *);
+
void julia_init(struct envy_softc *);
void julia_codec_write(struct envy_softc *, int, int, int);
@@ -275,6 +285,12 @@ struct envy_card envy_cards[] = {
revo51_init,
revo51_codec_write
}, {
+ PCI_ID_CODE(0x1412, 0x2403),
+ "VIA Tremor 5.1",
+ 2, &unkenvy_codec, 6, &unkenvy_codec,
+ tremor51_init,
+ unkenvy_codec_write
+ }, {
0,
"unknown 1724-based card",
2, &unkenvy_codec, 8, &unkenvy_codec,
@@ -437,6 +453,26 @@ revo51_codec_write(struct envy_softc *sc, int dev, int addr, int data)
}
/*
+ * via tremor 5.1 specific code
+ */
+
+void
+tremor51_init(struct envy_softc *sc)
+{
+ sc->isac97 = 1;
+ sc->host_if.arg = sc;
+ sc->host_if.attach = envy_ac97_attach_codec;
+ sc->host_if.read = envy_ac97_read_codec;
+ sc->host_if.write = envy_ac97_write_codec;
+ sc->host_if.reset = envy_ac97_reset_codec;
+ sc->host_if.flags = envy_ac97_flags_codec;
+ sc->codec_flags = 0;
+
+ if (ac97_attach(&sc->host_if) != 0)
+ printf("%s: can't attach ac97\n", DEVNAME(sc));
+}
+
+/*
* esi julia specific code
*/
@@ -951,6 +987,108 @@ envy_eeprom_gpioxxx(struct envy_softc *sc, int addr)
return val;
}
+int
+envy_ac97_wait(struct envy_softc *sc)
+{
+ int timeout = 50, st;
+
+ for (;;) {
+ st = bus_space_read_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_CMD);
+ if ((st & ENVY_MT_AC97_READY) && !(st & ENVY_MT_AC97_CMD_MASK)) {
+ st = 0;
+ break;
+ }
+ if (timeout == 0) {
+ st = -1;
+ break;
+ }
+ delay(50);
+ timeout--;
+ }
+
+ return (st);
+}
+
+int
+envy_ac97_attach_codec(void *hdl, struct ac97_codec_if *codec_if)
+{
+ struct envy_softc *sc = hdl;
+
+ sc->codec_if = codec_if;
+
+ return (0);
+}
+
+int
+envy_ac97_read_codec(void *hdl, u_int8_t reg, u_int16_t *result)
+{
+ struct envy_softc *sc = hdl;
+
+ if (envy_ac97_wait(sc)) {
+ printf("%s: envy_ac97_read_codec: timed out\n", DEVNAME(sc));
+ return (-1);
+ }
+
+ bus_space_write_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_IDX, reg & 0x7f);
+ bus_space_write_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_CMD,
+ ENVY_MT_AC97_CMD_RD);
+ delay(50);
+
+ if (envy_ac97_wait(sc)) {
+ printf("%s: envy_ac97_read_codec: timed out\n", DEVNAME(sc));
+ return (-1);
+ }
+
+ *result = bus_space_read_2(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_DATA);
+
+ return (0);
+}
+
+int
+envy_ac97_write_codec(void *hdl, u_int8_t reg, u_int16_t data)
+{
+ struct envy_softc *sc = hdl;
+
+ if (envy_ac97_wait(sc)) {
+ printf("%s: envy_ac97_write_codec: timed out\n", DEVNAME(sc));
+ return (-1);
+ }
+
+ bus_space_write_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_IDX, reg & 0x7f);
+ bus_space_write_2(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_DATA, data);
+ bus_space_write_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_CMD,
+ ENVY_MT_AC97_CMD_WR);
+ delay(50);
+
+ return (0);
+}
+
+void
+envy_ac97_reset_codec(void *hdl)
+{
+ struct envy_softc *sc = hdl;
+
+ bus_space_write_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_CMD,
+ ENVY_MT_AC97_CMD_RST);
+ delay(50);
+ bus_space_write_1(sc->mt_iot, sc->mt_ioh, ENVY_MT_AC97_CMD, 0);
+ delay(50);
+
+ if (envy_ac97_wait(sc)) {
+ printf("%s: envy_ac97_reset_codec: timed out\n", DEVNAME(sc));
+ }
+
+ return;
+}
+
+enum ac97_host_flags
+envy_ac97_flags_codec(void *hdl)
+{
+ struct envy_softc *sc = hdl;
+
+ return (sc->codec_flags);
+}
+
void
envy_reset(struct envy_softc *sc)
{
@@ -1617,6 +1755,9 @@ envy_query_devinfo(void *self, struct mixer_devinfo *dev)
AudioCinputs, AudioCoutputs, AudioCmonitor
};
+ if (sc->isac97)
+ return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dev));
+
if (dev->index < 0)
return ENXIO;
@@ -1706,6 +1847,9 @@ envy_get_port(void *self, struct mixer_ctrl *ctl)
struct envy_softc *sc = (struct envy_softc *)self;
int val, idx, ndev;
+ if (sc->isac97)
+ return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, ctl));
+
if (ctl->dev < ENVY_MIX_NCLASS) {
return EINVAL;
}
@@ -1747,6 +1891,9 @@ envy_set_port(void *self, struct mixer_ctrl *ctl)
struct envy_softc *sc = (struct envy_softc *)self;
int maxsrc, val, idx, ndev;
+ if (sc->isac97)
+ return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, ctl));
+
if (ctl->dev < ENVY_MIX_NCLASS) {
return EINVAL;
}
diff --git a/sys/dev/pci/envyreg.h b/sys/dev/pci/envyreg.h
index 02ce615cc7a..427bd853eb3 100644
--- a/sys/dev/pci/envyreg.h
+++ b/sys/dev/pci/envyreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: envyreg.h,v 1.11 2009/11/02 05:54:16 ratchov Exp $ */
+/* $OpenBSD: envyreg.h,v 1.12 2010/02/20 16:45:28 ratchov Exp $ */
/*
* Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org>
*
@@ -107,6 +107,14 @@
#define ENVY_MT_IMASK 3 /* HT only */
#define ENVY_MT_IMASK_PDMA0 0x1
#define ENVY_MT_IMASK_RDMA0 0x2
+#define ENVY_MT_AC97_IDX 4
+#define ENVY_MT_AC97_CMD 5
+#define ENVY_MT_AC97_READY 0x08
+#define ENVY_MT_AC97_CMD_MASK 0x30
+#define ENVY_MT_AC97_CMD_RD 0x10
+#define ENVY_MT_AC97_CMD_WR 0x20
+#define ENVY_MT_AC97_CMD_RST 0x80
+#define ENVY_MT_AC97_DATA 6
#define ENVY_MT_PADDR 0x10
#define ENVY_MT_PBUFSZ 0x14
#define ENVY_MT_PBLKSZ(s) ((s)->isht ? 0x1c : 0x16)
diff --git a/sys/dev/pci/envyvar.h b/sys/dev/pci/envyvar.h
index ed23eb70a02..ecd9fe1a013 100644
--- a/sys/dev/pci/envyvar.h
+++ b/sys/dev/pci/envyvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: envyvar.h,v 1.12 2009/05/08 16:53:45 ratchov Exp $ */
+/* $OpenBSD: envyvar.h,v 1.13 2010/02/20 16:45:28 ratchov Exp $ */
/*
* Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org>
*
@@ -55,6 +55,7 @@ struct envy_softc {
struct device dev;
struct device *audio;
int isht; /* is a Envy24HT ? */
+ int isac97; /* is a Envy24HT AC97 ? */
struct envy_buf ibuf, obuf;
pcitag_t pci_tag;
pci_chipset_tag_t pci_pc;
@@ -70,6 +71,9 @@ struct envy_softc {
unsigned char shadow[4][16];
#define ENVY_EEPROM_MAXSZ 32
unsigned char eeprom[ENVY_EEPROM_MAXSZ];
+ struct ac97_codec_if *codec_if;
+ struct ac97_host_if host_if;
+ enum ac97_host_flags codec_flags;
void (*iintr)(void *);
void *iarg;
void (*ointr)(void *);
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 629f508eca3..d4fe0bad56d 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.268 2010/02/19 15:00:15 miod Exp $
+# $OpenBSD: files.pci,v 1.269 2010/02/20 16:45:28 ratchov Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -136,7 +136,7 @@ file dev/pci/azalia.c azalia
file dev/pci/azalia_codec.c azalia
# VIA Envy24 (aka ICE1712)
-device envy: audio, auconv, mulaw
+device envy: audio, auconv, mulaw, ac97
attach envy at pci
file dev/pci/envy.c envy