diff options
| author | jmcneill <jmcneill@NetBSD.org> | 2019-11-16 13:10:07 +0000 |
|---|---|---|
| committer | jmcneill <jmcneill@NetBSD.org> | 2019-11-16 13:10:07 +0000 |
| commit | a346ca7d317fb87da3f435d495272ca08dcf5934 (patch) | |
| tree | f7981104d6092f4f1c4cf7246e87bd7ca6eefa45 /sys/dev/ic | |
| parent | 794acfe49897036dc053b3729f658f827e535ebd (diff) | |
Add software volume controls.
Diffstat (limited to 'sys/dev/ic')
| -rw-r--r-- | sys/dev/ic/dw_hdmi.c | 60 | ||||
| -rw-r--r-- | sys/dev/ic/dw_hdmi.h | 3 |
2 files changed, 52 insertions, 11 deletions
diff --git a/sys/dev/ic/dw_hdmi.c b/sys/dev/ic/dw_hdmi.c index 905d29d594e..d38cdb838a0 100644 --- a/sys/dev/ic/dw_hdmi.c +++ b/sys/dev/ic/dw_hdmi.c @@ -1,4 +1,4 @@ -/* $NetBSD: dw_hdmi.c,v 1.3 2019/11/16 12:50:08 jmcneill Exp $ */ +/* $NetBSD: dw_hdmi.c,v 1.4 2019/11/16 13:10:07 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dw_hdmi.c,v 1.3 2019/11/16 12:50:08 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dw_hdmi.c,v 1.4 2019/11/16 13:10:07 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -752,12 +752,47 @@ dwhdmi_dai_add_device(audio_dai_tag_t dai, audio_dai_tag_t aux) return 0; } +static void +dwhdmi_audio_swvol_codec(audio_filter_arg_t *arg) +{ + struct dwhdmi_softc * const sc = arg->context; + const aint_t *src; + aint_t *dst; + u_int sample_count; + u_int i; + + src = arg->src; + dst = arg->dst; + sample_count = arg->count * arg->srcfmt->channels; + for (i = 0; i < sample_count; i++) { + aint2_t v = (aint2_t)(*src++); + v = v * sc->sc_swvol / 255; + *dst++ = (aint_t)v; + } +} + +static int +dwhdmi_audio_set_format(void *priv, int setmode, + const audio_params_t *play, const audio_params_t *rec, + audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) +{ + struct dwhdmi_softc * const sc = priv; + + pfil->codec = dwhdmi_audio_swvol_codec; + pfil->context = sc; + + return 0; +} + static int -dwhdmi_dai_set_port(void *priv, mixer_ctrl_t *mc) +dwhdmi_audio_set_port(void *priv, mixer_ctrl_t *mc) { + struct dwhdmi_softc * const sc = priv; + switch (mc->dev) { case DWHDMI_DAI_OUTPUT_MASTER_VOLUME: case DWHDMI_DAI_INPUT_DAC_VOLUME: + sc->sc_swvol = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; return 0; default: return ENXIO; @@ -765,13 +800,15 @@ dwhdmi_dai_set_port(void *priv, mixer_ctrl_t *mc) } static int -dwhdmi_dai_get_port(void *priv, mixer_ctrl_t *mc) +dwhdmi_audio_get_port(void *priv, mixer_ctrl_t *mc) { + struct dwhdmi_softc * const sc = priv; + switch (mc->dev) { case DWHDMI_DAI_OUTPUT_MASTER_VOLUME: case DWHDMI_DAI_INPUT_DAC_VOLUME: - mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 255; - mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 255; + mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_swvol; + mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_swvol; return 0; default: return ENXIO; @@ -779,7 +816,7 @@ dwhdmi_dai_get_port(void *priv, mixer_ctrl_t *mc) } static int -dwhdmi_dai_query_devinfo(void *priv, mixer_devinfo_t *di) +dwhdmi_audio_query_devinfo(void *priv, mixer_devinfo_t *di) { switch (di->index) { case DWHDMI_DAI_OUTPUT_CLASS: @@ -822,9 +859,10 @@ dwhdmi_dai_query_devinfo(void *priv, mixer_devinfo_t *di) } static const struct audio_hw_if dwhdmi_dai_hw_if = { - .set_port = dwhdmi_dai_set_port, - .get_port = dwhdmi_dai_get_port, - .query_devinfo = dwhdmi_dai_query_devinfo, + .set_format = dwhdmi_audio_set_format, + .set_port = dwhdmi_audio_set_port, + .get_port = dwhdmi_audio_get_port, + .query_devinfo = dwhdmi_audio_query_devinfo, }; int @@ -849,6 +887,8 @@ dwhdmi_attach(struct dwhdmi_softc *sc) sc->sc_version >> 12, sc->sc_version & 0xfff, sc->sc_phytype); + sc->sc_swvol = 255; + /* * If a DDC i2c bus tag is provided by the caller, use it. Otherwise, * use the I2C master built-in to DWC HDMI. diff --git a/sys/dev/ic/dw_hdmi.h b/sys/dev/ic/dw_hdmi.h index 58317ad8d8e..73477e05165 100644 --- a/sys/dev/ic/dw_hdmi.h +++ b/sys/dev/ic/dw_hdmi.h @@ -1,4 +1,4 @@ -/* $NetBSD: dw_hdmi.h,v 1.3 2019/11/16 12:50:08 jmcneill Exp $ */ +/* $NetBSD: dw_hdmi.h,v 1.4 2019/11/16 13:10:07 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> @@ -76,6 +76,7 @@ struct dwhdmi_softc { struct i2c_controller sc_ic_builtin; struct audio_dai_device sc_dai; + uint8_t sc_swvol; struct dwhdmi_connector sc_connector; struct drm_bridge sc_bridge; |
