summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormickey <mickey@openbsd.org>2003-03-12 09:06:11 +0000
committermickey <mickey@openbsd.org>2003-03-12 09:06:11 +0000
commit27b54b8b1962397b8360d287a2e64d85a2f0e1c5 (patch)
treec0de78a65ac92ad1742e8a47db264d37ff66ce44
parentdocument setting ipx frame type; from ianm@cit.uws.edu.au (diff)
downloadwireguard-openbsd-27b54b8b1962397b8360d287a2e64d85a2f0e1c5.tar.xz
wireguard-openbsd-27b54b8b1962397b8360d287a2e64d85a2f0e1c5.zip
reclaim more resources on failures.
test the harmony id to filter out unsupported yet audio types and detect the teleshare. detect input overload and report to userland.
-rw-r--r--sys/arch/hppa/gsc/harmony.c56
-rw-r--r--sys/arch/hppa/gsc/harmonyreg.h4
-rw-r--r--sys/arch/hppa/gsc/harmonyvar.h26
3 files changed, 67 insertions, 19 deletions
diff --git a/sys/arch/hppa/gsc/harmony.c b/sys/arch/hppa/gsc/harmony.c
index 7c00eb75c2c..4d08abb6276 100644
--- a/sys/arch/hppa/gsc/harmony.c
+++ b/sys/arch/hppa/gsc/harmony.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: harmony.c,v 1.16 2003/02/05 19:24:13 jason Exp $ */
+/* $OpenBSD: harmony.c,v 1.17 2003/03/12 09:06:11 mickey Exp $ */
/*
* Copyright (c) 2003 Jason L. Wright (jason@thought.net)
@@ -160,38 +160,55 @@ harmony_attach(parent, self, aux)
return;
}
+ cntl = READ_REG(sc, HARMONY_ID);
+ switch ((cntl & ID_REV_MASK)) {
+ case ID_REV_TS:
+ sc->sc_teleshare = 1;
+ case ID_REV_NOTS:
+ break;
+ default:
+ printf(": unknown id == 0x%02x\n",
+ (cntl & ID_REV_MASK) >> ID_REV_SHIFT);
+ bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
+ return;
+ }
+
if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct harmony_empty),
PAGE_SIZE, 0, &sc->sc_empty_seg, 1, &sc->sc_empty_rseg,
BUS_DMA_NOWAIT) != 0) {
- printf(": couldn't alloc empty memory\n");
+ printf(": couldn't alloc DMA memory\n");
+ bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
return;
}
if (bus_dmamem_map(sc->sc_dmat, &sc->sc_empty_seg, 1,
sizeof(struct harmony_empty), (caddr_t *)&sc->sc_empty_kva,
BUS_DMA_NOWAIT) != 0) {
- printf(": couldn't map empty memory\n");
+ printf(": couldn't map DMA memory\n");
bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
sc->sc_empty_rseg);
+ bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
return;
}
if (bus_dmamap_create(sc->sc_dmat, sizeof(struct harmony_empty), 1,
sizeof(struct harmony_empty), 0, BUS_DMA_NOWAIT,
&sc->sc_empty_map) != 0) {
- printf(": can't create empty dmamap\n");
+ printf(": can't create DMA map\n");
bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_empty_kva,
sizeof(struct harmony_empty));
bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
sc->sc_empty_rseg);
+ bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
return;
}
if (bus_dmamap_load(sc->sc_dmat, sc->sc_empty_map, sc->sc_empty_kva,
sizeof(struct harmony_empty), NULL, BUS_DMA_NOWAIT) != 0) {
- printf(": can't load empty dmamap\n");
+ printf(": can't load DMA map\n");
bus_dmamap_destroy(sc->sc_dmat, sc->sc_empty_map);
bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_empty_kva,
sizeof(struct harmony_empty));
bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
sc->sc_empty_rseg);
+ bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
return;
}
@@ -227,7 +244,11 @@ harmony_attach(parent, self, aux)
cntl = READ_REG(sc, HARMONY_CNTL);
rev = (cntl & CNTL_CODEC_REV_MASK) >> CNTL_CODEC_REV_SHIFT;
- printf(": rev %u\n", rev);
+ printf(": rev %u", rev);
+
+ if (sc->sc_teleshare)
+ printf(", teleshare");
+ printf("\n");
if ((rev & CS4215_REV_VER) >= CS4215_REV_VER_E)
sc->sc_hasulinear8 = 1;
@@ -312,6 +333,12 @@ harmony_intr(vsc)
(*c->c_intr)(c->c_intrarg);
}
+ if (READ_REG(sc, HARMONY_OV) & OV_OV) {
+ sc->sc_ov = 1;
+ WRITE_REG(sc, HARMONY_OV, 0);
+ } else
+ sc->sc_ov = 0;
+
harmony_intr_enable(sc);
return (r);
@@ -728,6 +755,12 @@ harmony_get_port(void *vsc, mixer_ctrl_t *cp)
break;
err = 0;
break;
+ case HARMONY_PORT_INPUT_OV:
+ if (cp->type != AUDIO_MIXER_ENUM)
+ break;
+ cp->un.ord = sc->sc_ov ? 1 : 0;
+ err = 0;
+ break;
case HARMONY_PORT_OUTPUT_LVL:
if (cp->type != AUDIO_MIXER_VALUE)
break;
@@ -788,6 +821,17 @@ harmony_query_devinfo(void *vsc, mixer_devinfo_t *dip)
dip->un.v.num_channels = 2;
strcpy(dip->un.v.units.name, AudioNvolume);
break;
+ case HARMONY_PORT_INPUT_OV:
+ dip->type = AUDIO_MIXER_ENUM;
+ dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
+ dip->prev = dip->next = AUDIO_MIXER_LAST;
+ strcpy(dip->label.name, "overrange");
+ dip->un.e.num_mem = 2;
+ strcpy(dip->un.e.member[0].label.name, AudioNoff);
+ dip->un.e.member[0].ord = 0;
+ strcpy(dip->un.e.member[1].label.name, AudioNon);
+ dip->un.e.member[1].ord = 1;
+ break;
case HARMONY_PORT_OUTPUT_LVL:
dip->type = AUDIO_MIXER_VALUE;
dip->mixer_class = HARMONY_PORT_OUTPUT_CLASS;
diff --git a/sys/arch/hppa/gsc/harmonyreg.h b/sys/arch/hppa/gsc/harmonyreg.h
index 8e9f2d62ad5..5507a7463c1 100644
--- a/sys/arch/hppa/gsc/harmonyreg.h
+++ b/sys/arch/hppa/gsc/harmonyreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: harmonyreg.h,v 1.3 2003/02/05 08:47:05 jason Exp $ */
+/* $OpenBSD: harmonyreg.h,v 1.4 2003/03/12 09:06:11 mickey Exp $ */
/*
* Copyright (c) 2003 Jason L. Wright (jason@thought.net)
@@ -56,9 +56,11 @@
/* HARMONY_ID */
#define ID_REV_MASK 0x00ff0000 /* revision mask: */
+#define ID_REV_SHIFT 16
#define ID_REV_TS 0x00150000 /* teleshare installed */
#define ID_REV_NOTS 0x00140000 /* teleshare not installed */
#define ID_CHIID 0x0000f000 /* CHI identification */
+#define ID_CHIID_SHIFT 12
/* HARMONY_RESET */
#define RESET_RST 0x00000001 /* reset codec */
diff --git a/sys/arch/hppa/gsc/harmonyvar.h b/sys/arch/hppa/gsc/harmonyvar.h
index b747fcdb4d1..38aea2655ae 100644
--- a/sys/arch/hppa/gsc/harmonyvar.h
+++ b/sys/arch/hppa/gsc/harmonyvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: harmonyvar.h,v 1.5 2003/02/05 19:24:13 jason Exp $ */
+/* $OpenBSD: harmonyvar.h,v 1.6 2003/03/12 09:06:11 mickey Exp $ */
/*
* Copyright (c) 2003 Jason L. Wright (jason@thought.net)
@@ -31,16 +31,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#define HARMONY_PORT_INPUT_LVL 0
-#define HARMONY_PORT_OUTPUT_LVL 1
-#define HARMONY_PORT_OUTPUT_GAIN 2
-#define HARMONY_PORT_MONITOR_LVL 3
-#define HARMONY_PORT_RECORD_SOURCE 4
-#define HARMONY_PORT_OUTPUT_SOURCE 5
-#define HARMONY_PORT_INPUT_CLASS 6
-#define HARMONY_PORT_OUTPUT_CLASS 7
-#define HARMONY_PORT_MONITOR_CLASS 8
-#define HARMONY_PORT_RECORD_CLASS 9
+#define HARMONY_PORT_INPUT_LVL 0
+#define HARMONY_PORT_INPUT_OV 1
+#define HARMONY_PORT_OUTPUT_LVL 2
+#define HARMONY_PORT_OUTPUT_GAIN 3
+#define HARMONY_PORT_MONITOR_LVL 4
+#define HARMONY_PORT_RECORD_SOURCE 5
+#define HARMONY_PORT_OUTPUT_SOURCE 6
+#define HARMONY_PORT_INPUT_CLASS 7
+#define HARMONY_PORT_OUTPUT_CLASS 8
+#define HARMONY_PORT_MONITOR_CLASS 9
+#define HARMONY_PORT_RECORD_CLASS 10
#define HARMONY_IN_MIC 0
#define HARMONY_IN_LINE 1
@@ -103,7 +104,8 @@ struct harmony_softc {
struct harmony_channel sc_playback, sc_capture;
struct harmony_volume sc_monitor_lvl, sc_input_lvl, sc_output_lvl;
int sc_in_port, sc_out_port, sc_hasulinear8;
- int sc_micpreamp, sc_outputgain;
+ int sc_micpreamp, sc_ov, sc_outputgain;
+ int sc_teleshare;
};
#define READ_REG(sc, reg) \