diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2010-02-20 16:45:29 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2010-02-20 16:45:29 +0000 |
commit | 58b653139bc72f8a79d8f7ef5e719681a84e10c6 (patch) | |
tree | 6aa0ef6284678b93946d6325539f5732ab3e5ae0 /sys/dev/pci | |
parent | 23daeb00a48c6987fb72d950455a8f9ada914c1d (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/dev/pci')
-rw-r--r-- | sys/dev/pci/envy.c | 151 | ||||
-rw-r--r-- | sys/dev/pci/envyreg.h | 10 | ||||
-rw-r--r-- | sys/dev/pci/envyvar.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/files.pci | 4 |
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 |