From 7141bfc1fe0d53aaf356bc0c1add2421cdcfac7f Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 2 Sep 2022 16:53:28 +0000 Subject: [PATCH] Add a callback for setting the TDM slot used by an audio codec. Implement this callback in tascodec(4) such that we can pick the audio channel that it outputs. This will override the default which is to downmix stereo input from TDM channels 0 and 1 to mono output. ok ratchov@ --- sys/dev/fdt/tascodec.c | 32 +++++++++++++++++++++++++++++++- sys/dev/ofw/ofw_misc.h | 3 ++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/sys/dev/fdt/tascodec.c b/sys/dev/fdt/tascodec.c index 12e1466ffe5..a7d5b295715 100644 --- a/sys/dev/fdt/tascodec.c +++ b/sys/dev/fdt/tascodec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tascodec.c,v 1.4 2022/07/25 16:35:41 kettenis Exp $ */ +/* $OpenBSD: tascodec.c,v 1.5 2022/09/02 16:53:28 kettenis Exp $ */ /* * Copyright (c) 2022 Mark Kettenis * @@ -49,7 +49,14 @@ #define TDM_CFG1_RX_EDGE (1 << 0) #define TDM_CFG2 0x0c #define TDM_CFG2_SCFG_MASK (3 << 4) +#define TDM_CFG2_SCFG_MONO_LEFT (1 << 4) +#define TDM_CFG2_SCFG_MONO_RIGHT (2 << 4) #define TDM_CFG2_SCFG_STEREO_DOWNMIX (3 << 4) +#define TDM_CFG3 0x0d +#define TDM_CFG3_RX_SLOT_R_MASK 0xf0 +#define TDM_CFG3_RX_SLOT_R_SHIFT 4 +#define TDM_CFG3_RX_SLOT_L_MASK 0x0f +#define TDM_CFG3_RX_SLOT_L_SHIFT 0 struct tascodec_softc { struct device sc_dev; @@ -74,6 +81,7 @@ struct cfdriver tascodec_cd = { }; int tascodec_set_format(void *, uint32_t, uint32_t, uint32_t); +int tascodec_set_tdm_slot(void *, int); int tascodec_set_port(void *, mixer_ctrl_t *); int tascodec_get_port(void *, mixer_ctrl_t *); @@ -141,6 +149,7 @@ tascodec_attach(struct device *parent, struct device *self, void *aux) sc->sc_dai.dd_cookie = sc; sc->sc_dai.dd_hw_if = &tascodec_hw_if; sc->sc_dai.dd_set_format = tascodec_set_format; + sc->sc_dai.dd_set_tdm_slot = tascodec_set_tdm_slot; dai_register(&sc->sc_dai); } @@ -205,6 +214,27 @@ tascodec_set_format(void *cookie, uint32_t fmt, uint32_t pol, return 0; } +int +tascodec_set_tdm_slot(void *cookie, int slot) +{ + struct tascodec_softc *sc = cookie; + uint8_t cfg2, cfg3; + + if (slot < 0 || slot >= 16) + return EINVAL; + + cfg2 = tascodec_read(sc, TDM_CFG2); + cfg3 = tascodec_read(sc, TDM_CFG3); + cfg2 &= ~TDM_CFG2_SCFG_MASK; + cfg2 |= TDM_CFG2_SCFG_MONO_LEFT; + cfg3 &= ~TDM_CFG3_RX_SLOT_L_MASK; + cfg3 |= slot << TDM_CFG3_RX_SLOT_L_SHIFT; + tascodec_write(sc, TDM_CFG2, cfg2); + tascodec_write(sc, TDM_CFG3, cfg3); + + return 0; +} + /* * Mixer controls; the gain of the TAS2770 is determined by the * amplifier gain and digital volume control setting, but we only diff --git a/sys/dev/ofw/ofw_misc.h b/sys/dev/ofw/ofw_misc.h index 9aee48a0f22..831cc40a946 100644 --- a/sys/dev/ofw/ofw_misc.h +++ b/sys/dev/ofw/ofw_misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_misc.h,v 1.24 2022/03/21 19:22:40 miod Exp $ */ +/* $OpenBSD: ofw_misc.h,v 1.25 2022/09/02 16:53:28 kettenis Exp $ */ /* * Copyright (c) 2017-2021 Mark Kettenis * @@ -194,6 +194,7 @@ struct dai_device { const void *dd_hw_if; int (*dd_set_format)(void *, uint32_t, uint32_t, uint32_t); int (*dd_set_sysclk)(void *, uint32_t); + int (*dd_set_tdm_slot)(void *, int); LIST_ENTRY(dai_device) dd_list; uint32_t dd_phandle; -- 2.20.1