summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-03-12 09:06:12 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-03-12 09:06:12 +0000
commit092fedf8e0695cc819935ddc9205603de47bafb5 (patch)
tree2ed305cfc8371b336da69c53a20a26f90e9ffd35
parent903c1dc4596fa0ccb99ae0f016dccba46740a27a (diff)
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) \