1 1.2 rkujawa /* $NetBSD: mpc5200_ac97.c,v 1.2 2026/07/01 00:03:18 rkujawa Exp $ */ 2 1.1 rkujawa 3 1.1 rkujawa /*- 4 1.1 rkujawa * Copyright (c) 2026 The NetBSD Foundation, Inc. 5 1.1 rkujawa * All rights reserved. 6 1.1 rkujawa * 7 1.1 rkujawa * This code is derived from software contributed to The NetBSD Foundation 8 1.1 rkujawa * by Radoslaw Kujawa. 9 1.1 rkujawa * 10 1.1 rkujawa * Redistribution and use in source and binary forms, with or without 11 1.1 rkujawa * modification, are permitted provided that the following conditions 12 1.1 rkujawa * are met: 13 1.1 rkujawa * 1. Redistributions of source code must retain the above copyright 14 1.1 rkujawa * notice, this list of conditions and the following disclaimer. 15 1.1 rkujawa * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 rkujawa * notice, this list of conditions and the following disclaimer in the 17 1.1 rkujawa * documentation and/or other materials provided with the distribution. 18 1.1 rkujawa * 19 1.1 rkujawa * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 rkujawa * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 rkujawa * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 rkujawa * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 rkujawa * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 rkujawa * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 rkujawa * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 rkujawa * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 rkujawa * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 rkujawa * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 rkujawa * POSSIBILITY OF SUCH DAMAGE. 30 1.1 rkujawa */ 31 1.1 rkujawa 32 1.1 rkujawa /* 33 1.1 rkujawa * Driver for the Freescale MPC5200B on-chip AC97 controller (a PSC in AC97 34 1.1 rkujawa * mode), written with the assumption that it's connected to a codec that 35 1.1 rkujawa * can be driver through the ac97(4) interface. 36 1.1 rkujawa */ 37 1.1 rkujawa 38 1.1 rkujawa #include <sys/cdefs.h> 39 1.2 rkujawa __KERNEL_RCSID(0, "$NetBSD: mpc5200_ac97.c,v 1.2 2026/07/01 00:03:18 rkujawa Exp $"); 40 1.1 rkujawa 41 1.1 rkujawa #include <sys/param.h> 42 1.1 rkujawa #include <sys/systm.h> 43 1.1 rkujawa #include <sys/device.h> 44 1.1 rkujawa #include <sys/bus.h> 45 1.1 rkujawa #include <sys/mutex.h> 46 1.1 rkujawa #include <sys/audioio.h> 47 1.1 rkujawa 48 1.1 rkujawa #include <dev/audio/audio_if.h> 49 1.1 rkujawa 50 1.1 rkujawa #include <dev/ic/ac97var.h> 51 1.1 rkujawa 52 1.1 rkujawa #include <dev/ofw/openfirm.h> 53 1.1 rkujawa 54 1.1 rkujawa #include <machine/intr.h> 55 1.1 rkujawa 56 1.1 rkujawa #include <powerpc/mpc5200/obiovar.h> 57 1.1 rkujawa #include <powerpc/mpc5200/mpc5200reg.h> 58 1.1 rkujawa #include <powerpc/mpc5200/pscreg.h> 59 1.1 rkujawa #include <powerpc/mpc5200/mpc5200_ac97reg.h> 60 1.1 rkujawa #include <powerpc/mpc5200/mpc5200_ac97var.h> 61 1.1 rkujawa #include <powerpc/mpc5200/bestcommvar.h> 62 1.1 rkujawa 63 1.1 rkujawa /* 64 1.1 rkujawa * BestComm wiring for the PSC2 transmit path. 65 1.1 rkujawa */ 66 1.1 rkujawa #define MPCAC97_TX_TASK 12 67 1.1 rkujawa #define MPCAC97_TX_INITIATOR 12 68 1.1 rkujawa #define MPCAC97_TX_PRIO 5 /* SDMA initiator priority (0-7) */ 69 1.1 rkujawa #define AC97_FIFO_TX PSC_TB /* DMA target: Tx Buffer (0x0c) */ 70 1.1 rkujawa 71 1.1 rkujawa #define MPCAC97_RATE 48000 /* AC97 fixed sample rate */ 72 1.1 rkujawa #define MPCAC97_FRAME_SIZE 8 /* 2 ch * 32-bit slot word */ 73 1.1 rkujawa #define MPCAC97_MAX_NBLK 256 /* SDMA descriptor-ring sanity cap */ 74 1.1 rkujawa 75 1.1 rkujawa /* 76 1.1 rkujawa * Tx FIFO "almost empty" threshold 77 1.1 rkujawa */ 78 1.1 rkujawa #define MPCAC97_TFALARM 0x100 79 1.1 rkujawa #define MPCAC97_TFGRAN 0x04 80 1.1 rkujawa 81 1.1 rkujawa /* Codec register-access poll limits. */ 82 1.1 rkujawa #define AC97_CMD_TIMEOUT 1000 /* x10us = 10ms for a command frame */ 83 1.1 rkujawa #define AC97_READY_TIMEOUT 1000 /* x1ms = 1s for codec power-up */ 84 1.1 rkujawa 85 1.1 rkujawa #define AC97_REG_POWERDOWN 0x26 /* powerdown ctrl/status (AC97_REG_POWER) */ 86 1.1 rkujawa #define AC97_POWER_READY 0x000f /* ADC+DAC+ANL+REF ready bits */ 87 1.1 rkujawa 88 1.1 rkujawa static int mpcac97_match(device_t, cfdata_t, void *); 89 1.1 rkujawa static void mpcac97_attach(device_t, device_t, void *); 90 1.1 rkujawa 91 1.1 rkujawa static void mpcac97_init_psc(struct mpcac97_softc *); 92 1.1 rkujawa static int mpcac97_intr(void *); 93 1.1 rkujawa 94 1.1 rkujawa /* ac97(4) host interface. */ 95 1.1 rkujawa static int mpcac97_ac97_attach(void *, struct ac97_codec_if *); 96 1.1 rkujawa static int mpcac97_ac97_read(void *, uint8_t, uint16_t *); 97 1.1 rkujawa static int mpcac97_ac97_write(void *, uint8_t, uint16_t); 98 1.1 rkujawa static int mpcac97_ac97_reset(void *); 99 1.1 rkujawa static enum ac97_host_flags mpcac97_ac97_flags(void *); 100 1.1 rkujawa 101 1.1 rkujawa /* audio(4) hardware interface. */ 102 1.1 rkujawa static int mpcac97_open(void *, int); 103 1.1 rkujawa static void mpcac97_close(void *); 104 1.1 rkujawa static int mpcac97_query_format(void *, audio_format_query_t *); 105 1.1 rkujawa static int mpcac97_set_format(void *, int, const audio_params_t *, 106 1.1 rkujawa const audio_params_t *, audio_filter_reg_t *, 107 1.1 rkujawa audio_filter_reg_t *); 108 1.1 rkujawa static int mpcac97_round_blocksize(void *, int, int, 109 1.1 rkujawa const audio_params_t *); 110 1.1 rkujawa static size_t mpcac97_round_buffersize(void *, int, size_t); 111 1.1 rkujawa static void *mpcac97_allocm(void *, int, size_t); 112 1.1 rkujawa static void mpcac97_freem(void *, void *, size_t); 113 1.1 rkujawa static int mpcac97_get_props(void *); 114 1.1 rkujawa static int mpcac97_trigger_output(void *, void *, void *, int, 115 1.1 rkujawa void (*)(void *), void *, const audio_params_t *); 116 1.1 rkujawa static int mpcac97_halt_output(void *); 117 1.1 rkujawa static int mpcac97_getdev(void *, struct audio_device *); 118 1.1 rkujawa static int mpcac97_set_port(void *, mixer_ctrl_t *); 119 1.1 rkujawa static int mpcac97_get_port(void *, mixer_ctrl_t *); 120 1.1 rkujawa static int mpcac97_query_devinfo(void *, mixer_devinfo_t *); 121 1.1 rkujawa static void mpcac97_get_locks(void *, kmutex_t **, kmutex_t **); 122 1.1 rkujawa 123 1.1 rkujawa CFATTACH_DECL_NEW(mpcaudio, sizeof(struct mpcac97_softc), 124 1.1 rkujawa mpcac97_match, mpcac97_attach, NULL, NULL); 125 1.1 rkujawa 126 1.1 rkujawa static const struct bestcomm_bd_layout mpcac97_tx_layout = 127 1.1 rkujawa BESTCOMM_LAYOUT_GEN_TX; 128 1.1 rkujawa 129 1.1 rkujawa /* 130 1.1 rkujawa * Data-routing-descriptor offsets 131 1.1 rkujawa */ 132 1.1 rkujawa static const uint16_t mpcac97_tx_drd[] = { 133 1.1 rkujawa 0x04, 0x0c, 0x10, 0x14, 0x20, 0x28, 0x30, 0x34 134 1.1 rkujawa }; 135 1.1 rkujawa 136 1.1 rkujawa static const struct audio_format mpcac97_formats[] = { 137 1.1 rkujawa { 138 1.1 rkujawa .mode = AUMODE_PLAY, 139 1.1 rkujawa .encoding = AUDIO_ENCODING_SLINEAR_BE, 140 1.1 rkujawa .validbits = 16, 141 1.1 rkujawa .precision = 32, 142 1.1 rkujawa .channels = 2, 143 1.1 rkujawa .channel_mask = AUFMT_STEREO, 144 1.1 rkujawa .frequency_type = 1, 145 1.1 rkujawa .frequency = { MPCAC97_RATE }, 146 1.1 rkujawa }, 147 1.1 rkujawa }; 148 1.1 rkujawa 149 1.1 rkujawa static const struct audio_hw_if mpcac97_hw_if = { 150 1.1 rkujawa .open = mpcac97_open, 151 1.1 rkujawa .close = mpcac97_close, 152 1.1 rkujawa .query_format = mpcac97_query_format, 153 1.1 rkujawa .set_format = mpcac97_set_format, 154 1.1 rkujawa .round_blocksize = mpcac97_round_blocksize, 155 1.1 rkujawa .round_buffersize = mpcac97_round_buffersize, 156 1.1 rkujawa .allocm = mpcac97_allocm, 157 1.1 rkujawa .freem = mpcac97_freem, 158 1.1 rkujawa .get_props = mpcac97_get_props, 159 1.1 rkujawa .trigger_output = mpcac97_trigger_output, 160 1.1 rkujawa .halt_output = mpcac97_halt_output, 161 1.1 rkujawa .getdev = mpcac97_getdev, 162 1.1 rkujawa .set_port = mpcac97_set_port, 163 1.1 rkujawa .get_port = mpcac97_get_port, 164 1.1 rkujawa .query_devinfo = mpcac97_query_devinfo, 165 1.1 rkujawa .get_locks = mpcac97_get_locks, 166 1.1 rkujawa }; 167 1.1 rkujawa 168 1.1 rkujawa /* Register accessors over the big-endian SoC bus_space tag. */ 169 1.1 rkujawa static inline uint8_t 170 1.1 rkujawa RD1(struct mpcac97_softc *sc, bus_size_t o) 171 1.1 rkujawa { 172 1.1 rkujawa return bus_space_read_1(sc->sc_iot, sc->sc_ioh, o); 173 1.1 rkujawa } 174 1.1 rkujawa static inline uint16_t 175 1.1 rkujawa RD2(struct mpcac97_softc *sc, bus_size_t o) 176 1.1 rkujawa { 177 1.1 rkujawa return bus_space_read_2(sc->sc_iot, sc->sc_ioh, o); 178 1.1 rkujawa } 179 1.1 rkujawa static inline uint32_t 180 1.1 rkujawa RD4(struct mpcac97_softc *sc, bus_size_t o) 181 1.1 rkujawa { 182 1.1 rkujawa return bus_space_read_4(sc->sc_iot, sc->sc_ioh, o); 183 1.1 rkujawa } 184 1.1 rkujawa static inline void 185 1.1 rkujawa WR1(struct mpcac97_softc *sc, bus_size_t o, uint8_t v) 186 1.1 rkujawa { 187 1.1 rkujawa bus_space_write_1(sc->sc_iot, sc->sc_ioh, o, v); 188 1.1 rkujawa } 189 1.1 rkujawa static inline void 190 1.1 rkujawa WR2(struct mpcac97_softc *sc, bus_size_t o, uint16_t v) 191 1.1 rkujawa { 192 1.1 rkujawa bus_space_write_2(sc->sc_iot, sc->sc_ioh, o, v); 193 1.1 rkujawa } 194 1.1 rkujawa static inline void 195 1.1 rkujawa WR4(struct mpcac97_softc *sc, bus_size_t o, uint32_t v) 196 1.1 rkujawa { 197 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, o, v); 198 1.1 rkujawa } 199 1.1 rkujawa 200 1.1 rkujawa static int 201 1.1 rkujawa mpcac97_match(device_t parent, cfdata_t cf, void *aux) 202 1.1 rkujawa { 203 1.1 rkujawa struct obio_attach_args *oba = aux; 204 1.1 rkujawa char compat[40]; 205 1.1 rkujawa int len; 206 1.1 rkujawa 207 1.1 rkujawa if (strcmp(oba->obio_name, "sound") == 0) 208 1.1 rkujawa return 1; 209 1.1 rkujawa 210 1.1 rkujawa len = OF_getprop(oba->obio_node, "compatible", compat, sizeof(compat)); 211 1.1 rkujawa if (len > 0 && 212 1.1 rkujawa (strcmp(compat, "mpc5200-psc-ac97") == 0 || 213 1.1 rkujawa strcmp(compat, "mpc5200b-psc-ac97") == 0)) 214 1.1 rkujawa return 1; 215 1.1 rkujawa 216 1.1 rkujawa return 0; 217 1.1 rkujawa } 218 1.1 rkujawa 219 1.1 rkujawa static void 220 1.1 rkujawa mpcac97_attach(device_t parent, device_t self, void *aux) 221 1.1 rkujawa { 222 1.1 rkujawa struct mpcac97_softc *sc = device_private(self); 223 1.1 rkujawa struct obio_attach_args *oba = aux; 224 1.1 rkujawa bus_addr_t addr; 225 1.1 rkujawa bus_size_t size; 226 1.1 rkujawa 227 1.1 rkujawa sc->sc_dev = self; 228 1.1 rkujawa sc->sc_iot = oba->obio_bst; 229 1.1 rkujawa sc->sc_dmat = oba->obio_dmat; 230 1.1 rkujawa 231 1.1 rkujawa aprint_naive("\n"); 232 1.1 rkujawa aprint_normal(": MPC5200 AC97 controller\n"); 233 1.1 rkujawa 234 1.1 rkujawa if (!bestcomm_available()) { 235 1.1 rkujawa aprint_error_dev(self, "BestComm SDMA not available\n"); 236 1.1 rkujawa return; 237 1.1 rkujawa } 238 1.1 rkujawa 239 1.1 rkujawa /* 240 1.1 rkujawa * XXX: we should not depend on the firmware here? 241 1.1 rkujawa */ 242 1.1 rkujawa addr = oba->obio_addr != 0 ? oba->obio_addr : 243 1.1 rkujawa (MPC5200_MBAR_DEFAULT + MPC5200_REG_PSC2); 244 1.1 rkujawa size = oba->obio_size != 0 ? oba->obio_size : MPC5200_PSC_SIZE; 245 1.1 rkujawa sc->sc_pa = addr; 246 1.1 rkujawa if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { 247 1.1 rkujawa aprint_error_dev(self, "can't map registers\n"); 248 1.1 rkujawa return; 249 1.1 rkujawa } 250 1.1 rkujawa 251 1.1 rkujawa mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 252 1.1 rkujawa /* 253 1.1 rkujawa * XXX: The hardware interrupt lock is at IPL_NET, not usual IPL_AUDIO! 254 1.1 rkujawa * The completion interrupt is a leaf on the shared BestComm SDMA cascade 255 1.1 rkujawa * (along with FEC), and every leaf on that cascade MUST run at the 256 1.1 rkujawa * cascade's own IPL!!! Otherwise, enjoy hard lockups. 257 1.1 rkujawa */ 258 1.1 rkujawa mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NET); 259 1.1 rkujawa 260 1.1 rkujawa /* Put PSC2 into normal AC97 mode and enable the transceiver. */ 261 1.1 rkujawa mpcac97_init_psc(sc); 262 1.1 rkujawa 263 1.1 rkujawa /* 264 1.1 rkujawa * Attach the codec-independent AC97 layer. 265 1.1 rkujawa */ 266 1.1 rkujawa sc->sc_host_if.arg = sc; 267 1.1 rkujawa sc->sc_host_if.attach = mpcac97_ac97_attach; 268 1.1 rkujawa sc->sc_host_if.read = mpcac97_ac97_read; 269 1.1 rkujawa sc->sc_host_if.write = mpcac97_ac97_write; 270 1.1 rkujawa sc->sc_host_if.reset = mpcac97_ac97_reset; 271 1.1 rkujawa sc->sc_host_if.flags = mpcac97_ac97_flags; 272 1.2 rkujawa aprint_debug_dev(self, "calling ac97_attach\n"); 273 1.1 rkujawa if (ac97_attach(&sc->sc_host_if, self, &sc->sc_lock) != 0) { 274 1.1 rkujawa aprint_error_dev(self, "no AC97 codec found\n"); 275 1.1 rkujawa goto fail; 276 1.1 rkujawa } 277 1.2 rkujawa aprint_debug_dev(self, "ac97_attach returned ok\n"); 278 1.1 rkujawa 279 1.1 rkujawa /* 280 1.1 rkujawa * The codec's SPDIF control is lock-gated 281 1.1 rkujawa */ 282 1.1 rkujawa mutex_enter(&sc->sc_lock); 283 1.1 rkujawa sc->sc_codec->vtbl->unlock(sc->sc_codec); 284 1.1 rkujawa mutex_exit(&sc->sc_lock); 285 1.2 rkujawa aprint_debug_dev(self, "spdif unlocked\n"); 286 1.1 rkujawa 287 1.1 rkujawa /* 288 1.1 rkujawa * Route the BestComm transmit-task completion event to our block 289 1.1 rkujawa * handler. 290 1.1 rkujawa */ 291 1.1 rkujawa sc->sc_txih = intr_establish(bestcomm_task_irq(MPCAC97_TX_TASK), 292 1.1 rkujawa IST_LEVEL, IPL_NET, mpcac97_intr, sc); 293 1.1 rkujawa if (sc->sc_txih == NULL) { 294 1.1 rkujawa aprint_error_dev(self, "can't establish SDMA interrupt\n"); 295 1.1 rkujawa goto fail; 296 1.1 rkujawa } 297 1.2 rkujawa aprint_debug_dev(self, "SDMA intr established\n"); 298 1.1 rkujawa 299 1.1 rkujawa sc->sc_audiodev = audio_attach_mi(&mpcac97_hw_if, sc, self); 300 1.2 rkujawa aprint_debug_dev(self, "audio_attach_mi done\n"); 301 1.1 rkujawa return; 302 1.1 rkujawa 303 1.1 rkujawa fail: 304 1.1 rkujawa if (sc->sc_txih != NULL) 305 1.1 rkujawa intr_disestablish(sc->sc_txih); 306 1.1 rkujawa mutex_destroy(&sc->sc_lock); 307 1.1 rkujawa mutex_destroy(&sc->sc_intr_lock); 308 1.1 rkujawa bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); 309 1.1 rkujawa } 310 1.1 rkujawa 311 1.1 rkujawa /* 312 1.1 rkujawa * Configure PSC2 for "normal" AC97 mode. 313 1.1 rkujawa */ 314 1.1 rkujawa static void 315 1.1 rkujawa mpcac97_init_psc(struct mpcac97_softc *sc) 316 1.1 rkujawa { 317 1.1 rkujawa 318 1.1 rkujawa WR1(sc, PSC_CR, CMD_RESET_RX); 319 1.1 rkujawa WR1(sc, PSC_CR, CMD_RESET_TX); 320 1.1 rkujawa WR1(sc, PSC_CR, CMD_RESET_ERR); 321 1.1 rkujawa WR1(sc, PSC_CR, CMD_RESET_MR); 322 1.1 rkujawa 323 1.1 rkujawa WR4(sc, PSC_SICR, SICR_NORMAL_AC97); 324 1.1 rkujawa WR4(sc, PSC_AC97SLOTS, AC97SLOTS_TX_STEREO); 325 1.1 rkujawa 326 1.1 rkujawa WR2(sc, PSC_TFALARM, MPCAC97_TFALARM); 327 1.1 rkujawa WR1(sc, PSC_TFCNTL, MPCAC97_TFGRAN); 328 1.1 rkujawa 329 1.1 rkujawa WR2(sc, PSC_IMR, 0); /* no PSC interrupts; BestComm drives playback */ 330 1.1 rkujawa } 331 1.1 rkujawa 332 1.1 rkujawa /* 333 1.1 rkujawa * BestComm transmit-task completion handler. 334 1.1 rkujawa */ 335 1.1 rkujawa static int 336 1.1 rkujawa mpcac97_intr(void *arg) 337 1.1 rkujawa { 338 1.1 rkujawa struct mpcac97_softc *sc = arg; 339 1.1 rkujawa int handled = 0; 340 1.1 rkujawa 341 1.1 rkujawa mutex_enter(&sc->sc_intr_lock); 342 1.1 rkujawa if (!sc->sc_txon) { 343 1.1 rkujawa mutex_exit(&sc->sc_intr_lock); 344 1.1 rkujawa return 0; 345 1.1 rkujawa } 346 1.1 rkujawa 347 1.1 rkujawa while ((bestcomm_bd_status(&sc->sc_txring, sc->sc_curblk) & 348 1.1 rkujawa BESTCOMM_BD_READY) == 0) { 349 1.1 rkujawa u_int blk = sc->sc_curblk; 350 1.1 rkujawa 351 1.1 rkujawa bestcomm_bd_post(&sc->sc_txring, blk, 352 1.1 rkujawa sc->sc_blkbase + blk * sc->sc_blksize, sc->sc_blksize, 0); 353 1.1 rkujawa sc->sc_curblk = (blk + 1) % sc->sc_nblk; 354 1.1 rkujawa if (sc->sc_pintr != NULL) 355 1.1 rkujawa (*sc->sc_pintr)(sc->sc_pintrarg); 356 1.1 rkujawa handled = 1; 357 1.1 rkujawa } 358 1.1 rkujawa 359 1.1 rkujawa /* Restart the task if it ran the ring dry between completions. */ 360 1.1 rkujawa if (handled) 361 1.1 rkujawa bestcomm_task_start(MPCAC97_TX_TASK); 362 1.1 rkujawa 363 1.1 rkujawa mutex_exit(&sc->sc_intr_lock); 364 1.1 rkujawa return handled; 365 1.1 rkujawa } 366 1.1 rkujawa 367 1.1 rkujawa /* 368 1.1 rkujawa * ac97(4) host interface. 369 1.1 rkujawa */ 370 1.1 rkujawa static int 371 1.1 rkujawa mpcac97_ac97_attach(void *arg, struct ac97_codec_if *codec) 372 1.1 rkujawa { 373 1.1 rkujawa struct mpcac97_softc *sc = arg; 374 1.1 rkujawa 375 1.1 rkujawa sc->sc_codec = codec; 376 1.1 rkujawa return 0; 377 1.1 rkujawa } 378 1.1 rkujawa 379 1.1 rkujawa static int 380 1.1 rkujawa mpcac97_ac97_read(void *arg, uint8_t reg, uint16_t *valp) 381 1.1 rkujawa { 382 1.1 rkujawa struct mpcac97_softc *sc = arg; 383 1.1 rkujawa int i; 384 1.1 rkujawa 385 1.1 rkujawa /* Drop any stale response, then issue the read command. */ 386 1.1 rkujawa (void)RD4(sc, PSC_AC97DATA); 387 1.1 rkujawa WR4(sc, PSC_AC97CMD, AC97CMD_READ | AC97CMD_INDEX(reg)); 388 1.1 rkujawa 389 1.1 rkujawa for (i = 0; i < AC97_CMD_TIMEOUT; i++) { 390 1.1 rkujawa if (RD2(sc, PSC_SR) & AC97_SR_DATA_VALID) { 391 1.1 rkujawa *valp = AC97DATA_VALUE(RD4(sc, PSC_AC97DATA)); 392 1.1 rkujawa return 0; 393 1.1 rkujawa } 394 1.1 rkujawa DELAY(10); 395 1.1 rkujawa } 396 1.1 rkujawa 397 1.1 rkujawa *valp = 0xffff; 398 1.1 rkujawa return ETIMEDOUT; 399 1.1 rkujawa } 400 1.1 rkujawa 401 1.1 rkujawa static int 402 1.1 rkujawa mpcac97_ac97_write(void *arg, uint8_t reg, uint16_t val) 403 1.1 rkujawa { 404 1.1 rkujawa struct mpcac97_softc *sc = arg; 405 1.1 rkujawa int i; 406 1.1 rkujawa 407 1.1 rkujawa WR4(sc, PSC_AC97CMD, AC97CMD_WRITE(reg, val)); 408 1.1 rkujawa 409 1.1 rkujawa /* CMD_SEND is set by the write and cleared once the frame is sent. */ 410 1.1 rkujawa for (i = 0; i < AC97_CMD_TIMEOUT; i++) { 411 1.1 rkujawa if ((RD2(sc, PSC_SR) & AC97_SR_CMD_SEND) == 0) 412 1.1 rkujawa return 0; 413 1.1 rkujawa DELAY(10); 414 1.1 rkujawa } 415 1.1 rkujawa 416 1.1 rkujawa return ETIMEDOUT; 417 1.1 rkujawa } 418 1.1 rkujawa 419 1.1 rkujawa static int 420 1.1 rkujawa mpcac97_ac97_reset(void *arg) 421 1.1 rkujawa { 422 1.1 rkujawa struct mpcac97_softc *sc = arg; 423 1.2 rkujawa uint16_t val = 0xffff; 424 1.2 rkujawa int i, rderr = ETIMEDOUT; 425 1.1 rkujawa 426 1.1 rkujawa /* 427 1.1 rkujawa * Cold-reset the external codec by pulsing RES low then high 428 1.1 rkujawa */ 429 1.1 rkujawa WR1(sc, PSC_CR, CMD_TX_DISABLE | CMD_RX_DISABLE); 430 1.1 rkujawa WR1(sc, PSC_OP1, AC97_OP_RES); /* RES -> low */ 431 1.1 rkujawa DELAY(1000); 432 1.1 rkujawa WR1(sc, PSC_OP0, AC97_OP_RES); /* RES -> high */ 433 1.1 rkujawa DELAY(1000); 434 1.1 rkujawa WR1(sc, PSC_CR, CMD_TX_ENABLE | CMD_RX_ENABLE); 435 1.1 rkujawa 436 1.1 rkujawa /* Wait for the codec's analog/digital subsections to power up. */ 437 1.1 rkujawa for (i = 0; i < AC97_READY_TIMEOUT; i++) { 438 1.2 rkujawa rderr = mpcac97_ac97_read(sc, AC97_REG_POWERDOWN, &val); 439 1.2 rkujawa if (rderr == 0 && 440 1.2 rkujawa (val & AC97_POWER_READY) == AC97_POWER_READY) { 441 1.2 rkujawa aprint_debug_dev(sc->sc_dev, 442 1.2 rkujawa "codec ready after ~%dms (powerdown=0x%04x)\n", 443 1.2 rkujawa i, val); 444 1.1 rkujawa return 0; 445 1.2 rkujawa } 446 1.1 rkujawa DELAY(1000); 447 1.1 rkujawa } 448 1.1 rkujawa 449 1.2 rkujawa /* 450 1.2 rkujawa * Rare, not-reliably-reproducible cold-boot race: the STAC9766 is 451 1.2 rkujawa * occasionally not ready within AC97_READY_TIMEOUT. Try to hunt this 452 1.2 rkujawa * down. 453 1.2 rkujawa */ 454 1.2 rkujawa aprint_error_dev(sc->sc_dev, 455 1.2 rkujawa "codec not ready after reset: last read %s, powerdown=0x%04x, " 456 1.2 rkujawa "sr=0x%04x\n", 457 1.2 rkujawa rderr ? "TIMED OUT (AC-link silent)" : "ok-but-not-ready", 458 1.2 rkujawa val, RD2(sc, PSC_SR)); 459 1.1 rkujawa return 0; /* best effort: let ac97_attach probe the codec ID */ 460 1.1 rkujawa } 461 1.1 rkujawa 462 1.1 rkujawa static enum ac97_host_flags 463 1.1 rkujawa mpcac97_ac97_flags(void *arg) 464 1.1 rkujawa { 465 1.1 rkujawa 466 1.1 rkujawa return 0; 467 1.1 rkujawa } 468 1.1 rkujawa 469 1.1 rkujawa /* 470 1.1 rkujawa * audio(4) hardware interface. 471 1.1 rkujawa */ 472 1.1 rkujawa static int 473 1.1 rkujawa mpcac97_open(void *v, int flags) 474 1.1 rkujawa { 475 1.1 rkujawa struct mpcac97_softc *sc = v; 476 1.1 rkujawa 477 1.1 rkujawa /* 478 1.1 rkujawa * Lock the codec's SPDIF control for the duration the device is open 479 1.1 rkujawa */ 480 1.1 rkujawa sc->sc_codec->vtbl->lock(sc->sc_codec); 481 1.1 rkujawa return 0; 482 1.1 rkujawa } 483 1.1 rkujawa 484 1.1 rkujawa static void 485 1.1 rkujawa mpcac97_close(void *v) 486 1.1 rkujawa { 487 1.1 rkujawa struct mpcac97_softc *sc = v; 488 1.1 rkujawa 489 1.1 rkujawa sc->sc_codec->vtbl->unlock(sc->sc_codec); 490 1.1 rkujawa } 491 1.1 rkujawa 492 1.1 rkujawa static int 493 1.1 rkujawa mpcac97_query_format(void *v, audio_format_query_t *afp) 494 1.1 rkujawa { 495 1.1 rkujawa 496 1.1 rkujawa return audio_query_format(mpcac97_formats, 497 1.1 rkujawa __arraycount(mpcac97_formats), afp); 498 1.1 rkujawa } 499 1.1 rkujawa 500 1.1 rkujawa static int 501 1.1 rkujawa mpcac97_set_format(void *v, int setmode, 502 1.1 rkujawa const audio_params_t *play, const audio_params_t *rec, 503 1.1 rkujawa audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 504 1.1 rkujawa { 505 1.1 rkujawa 506 1.1 rkujawa /* 507 1.1 rkujawa * Only the single advertised hardware format is offered 508 1.1 rkujawa */ 509 1.1 rkujawa return 0; 510 1.1 rkujawa } 511 1.1 rkujawa 512 1.1 rkujawa static int 513 1.1 rkujawa mpcac97_round_blocksize(void *v, int bs, int mode, const audio_params_t *p) 514 1.1 rkujawa { 515 1.1 rkujawa 516 1.1 rkujawa /* Keep a block a whole number of 8-byte stereo DMA frames. */ 517 1.1 rkujawa bs &= ~(MPCAC97_FRAME_SIZE - 1); 518 1.1 rkujawa if (bs < MPCAC97_FRAME_SIZE) 519 1.1 rkujawa bs = MPCAC97_FRAME_SIZE; 520 1.1 rkujawa return bs; 521 1.1 rkujawa } 522 1.1 rkujawa 523 1.1 rkujawa static size_t 524 1.1 rkujawa mpcac97_round_buffersize(void *v, int mode, size_t size) 525 1.1 rkujawa { 526 1.1 rkujawa 527 1.1 rkujawa /* 528 1.1 rkujawa * The audio layer sizes the hardware buffer as a whole number of 529 1.1 rkujawa * blocks; keep it intact. 530 1.1 rkujawa */ 531 1.1 rkujawa return size; 532 1.1 rkujawa } 533 1.1 rkujawa 534 1.1 rkujawa static void * 535 1.1 rkujawa mpcac97_allocm(void *v, int direction, size_t size) 536 1.1 rkujawa { 537 1.1 rkujawa struct mpcac97_softc *sc = v; 538 1.1 rkujawa int rseg; 539 1.1 rkujawa 540 1.1 rkujawa if (direction != AUMODE_PLAY) /* playback only */ 541 1.1 rkujawa return NULL; 542 1.1 rkujawa if (sc->sc_dmakva != NULL) /* one play buffer */ 543 1.1 rkujawa return NULL; 544 1.1 rkujawa 545 1.1 rkujawa if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &sc->sc_dmaseg, 546 1.1 rkujawa 1, &rseg, BUS_DMA_WAITOK) != 0) 547 1.1 rkujawa return NULL; 548 1.1 rkujawa sc->sc_dmanseg = rseg; 549 1.1 rkujawa if (bus_dmamem_map(sc->sc_dmat, &sc->sc_dmaseg, rseg, size, 550 1.1 rkujawa &sc->sc_dmakva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0) 551 1.1 rkujawa goto free; 552 1.1 rkujawa if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, BUS_DMA_WAITOK, 553 1.1 rkujawa &sc->sc_dmamap) != 0) 554 1.1 rkujawa goto unmap; 555 1.1 rkujawa if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_dmakva, size, 556 1.1 rkujawa NULL, BUS_DMA_WAITOK) != 0) 557 1.1 rkujawa goto destroy; 558 1.1 rkujawa 559 1.1 rkujawa sc->sc_dmaphys = sc->sc_dmamap->dm_segs[0].ds_addr; 560 1.1 rkujawa sc->sc_dmasize = size; 561 1.1 rkujawa return sc->sc_dmakva; 562 1.1 rkujawa 563 1.1 rkujawa destroy: 564 1.1 rkujawa bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); 565 1.1 rkujawa sc->sc_dmamap = NULL; 566 1.1 rkujawa unmap: 567 1.1 rkujawa bus_dmamem_unmap(sc->sc_dmat, sc->sc_dmakva, size); 568 1.1 rkujawa sc->sc_dmakva = NULL; 569 1.1 rkujawa free: 570 1.1 rkujawa bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, rseg); 571 1.1 rkujawa return NULL; 572 1.1 rkujawa } 573 1.1 rkujawa 574 1.1 rkujawa static void 575 1.1 rkujawa mpcac97_freem(void *v, void *ptr, size_t size) 576 1.1 rkujawa { 577 1.1 rkujawa struct mpcac97_softc *sc = v; 578 1.1 rkujawa 579 1.1 rkujawa if (ptr != sc->sc_dmakva) 580 1.1 rkujawa return; 581 1.1 rkujawa 582 1.1 rkujawa bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap); 583 1.1 rkujawa bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); 584 1.1 rkujawa bus_dmamem_unmap(sc->sc_dmat, sc->sc_dmakva, size); 585 1.1 rkujawa bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, sc->sc_dmanseg); 586 1.1 rkujawa sc->sc_dmamap = NULL; 587 1.1 rkujawa sc->sc_dmakva = NULL; 588 1.1 rkujawa sc->sc_dmasize = 0; 589 1.1 rkujawa } 590 1.1 rkujawa 591 1.1 rkujawa static int 592 1.1 rkujawa mpcac97_get_props(void *v) 593 1.1 rkujawa { 594 1.1 rkujawa 595 1.1 rkujawa return AUDIO_PROP_PLAYBACK; 596 1.1 rkujawa } 597 1.1 rkujawa 598 1.1 rkujawa static int 599 1.1 rkujawa mpcac97_trigger_output(void *v, void *start, void *end, int blksize, 600 1.1 rkujawa void (*intr)(void *), void *arg, const audio_params_t *param) 601 1.1 rkujawa { 602 1.1 rkujawa struct mpcac97_softc *sc = v; 603 1.1 rkujawa bus_addr_t base; 604 1.1 rkujawa u_int i, nblk; 605 1.1 rkujawa 606 1.1 rkujawa nblk = ((char *)end - (char *)start) / blksize; 607 1.1 rkujawa if (nblk == 0 || nblk > MPCAC97_MAX_NBLK) 608 1.1 rkujawa return EINVAL; 609 1.1 rkujawa if ((char *)start < (char *)sc->sc_dmakva || 610 1.1 rkujawa (char *)start + nblk * blksize > 611 1.1 rkujawa (char *)sc->sc_dmakva + sc->sc_dmasize) 612 1.1 rkujawa return EINVAL; 613 1.1 rkujawa 614 1.1 rkujawa base = sc->sc_dmaphys + ((char *)start - (char *)sc->sc_dmakva); 615 1.1 rkujawa 616 1.1 rkujawa /* (Re)build the BD ring: one descriptor per audio block. */ 617 1.1 rkujawa bestcomm_bd_teardown(&sc->sc_txring); 618 1.1 rkujawa if (bestcomm_bd_setup(&sc->sc_txring, MPCAC97_TX_TASK, 619 1.1 rkujawa &mpcac97_tx_layout, sc->sc_pa + AC97_FIFO_TX, nblk, blksize, 620 1.1 rkujawa sizeof(uint32_t), MPCAC97_TX_INITIATOR, MPCAC97_TX_PRIO) != 0) 621 1.1 rkujawa return ENOMEM; 622 1.1 rkujawa 623 1.1 rkujawa /* 624 1.1 rkujawa * GEN_TX_BD is a runtime-configurable task 625 1.1 rkujawa */ 626 1.1 rkujawa bestcomm_task_set_initiator(MPCAC97_TX_TASK, MPCAC97_TX_INITIATOR, 627 1.1 rkujawa mpcac97_tx_drd, __arraycount(mpcac97_tx_drd)); 628 1.1 rkujawa 629 1.1 rkujawa sc->sc_blkbase = base; 630 1.1 rkujawa sc->sc_blksize = blksize; 631 1.1 rkujawa sc->sc_nblk = nblk; 632 1.1 rkujawa sc->sc_curblk = 0; 633 1.1 rkujawa sc->sc_pintr = intr; 634 1.1 rkujawa sc->sc_pintrarg = arg; 635 1.1 rkujawa sc->sc_txon = true; 636 1.1 rkujawa 637 1.1 rkujawa for (i = 0; i < nblk; i++) 638 1.1 rkujawa bestcomm_bd_post(&sc->sc_txring, i, base + i * blksize, 639 1.1 rkujawa blksize, 0); 640 1.1 rkujawa 641 1.1 rkujawa bestcomm_task_start(MPCAC97_TX_TASK); 642 1.1 rkujawa return 0; 643 1.1 rkujawa } 644 1.1 rkujawa 645 1.1 rkujawa static int 646 1.1 rkujawa mpcac97_halt_output(void *v) 647 1.1 rkujawa { 648 1.1 rkujawa struct mpcac97_softc *sc = v; 649 1.1 rkujawa 650 1.1 rkujawa sc->sc_txon = false; 651 1.1 rkujawa sc->sc_pintr = NULL; 652 1.1 rkujawa sc->sc_pintrarg = NULL; 653 1.1 rkujawa bestcomm_bd_teardown(&sc->sc_txring); 654 1.1 rkujawa return 0; 655 1.1 rkujawa } 656 1.1 rkujawa 657 1.1 rkujawa static int 658 1.1 rkujawa mpcac97_getdev(void *v, struct audio_device *adp) 659 1.1 rkujawa { 660 1.1 rkujawa 661 1.1 rkujawa strlcpy(adp->name, "MPC5200 AC97", sizeof(adp->name)); 662 1.1 rkujawa strlcpy(adp->version, "", sizeof(adp->version)); 663 1.1 rkujawa strlcpy(adp->config, "mpcac97", sizeof(adp->config)); 664 1.1 rkujawa return 0; 665 1.1 rkujawa } 666 1.1 rkujawa 667 1.1 rkujawa static int 668 1.1 rkujawa mpcac97_set_port(void *v, mixer_ctrl_t *mc) 669 1.1 rkujawa { 670 1.1 rkujawa struct mpcac97_softc *sc = v; 671 1.1 rkujawa 672 1.1 rkujawa return sc->sc_codec->vtbl->mixer_set_port(sc->sc_codec, mc); 673 1.1 rkujawa } 674 1.1 rkujawa 675 1.1 rkujawa static int 676 1.1 rkujawa mpcac97_get_port(void *v, mixer_ctrl_t *mc) 677 1.1 rkujawa { 678 1.1 rkujawa struct mpcac97_softc *sc = v; 679 1.1 rkujawa 680 1.1 rkujawa return sc->sc_codec->vtbl->mixer_get_port(sc->sc_codec, mc); 681 1.1 rkujawa } 682 1.1 rkujawa 683 1.1 rkujawa static int 684 1.1 rkujawa mpcac97_query_devinfo(void *v, mixer_devinfo_t *di) 685 1.1 rkujawa { 686 1.1 rkujawa struct mpcac97_softc *sc = v; 687 1.1 rkujawa 688 1.1 rkujawa return sc->sc_codec->vtbl->query_devinfo(sc->sc_codec, di); 689 1.1 rkujawa } 690 1.1 rkujawa 691 1.1 rkujawa static void 692 1.1 rkujawa mpcac97_get_locks(void *v, kmutex_t **intr, kmutex_t **thread) 693 1.1 rkujawa { 694 1.1 rkujawa struct mpcac97_softc *sc = v; 695 1.1 rkujawa 696 1.1 rkujawa *intr = &sc->sc_intr_lock; 697 1.1 rkujawa *thread = &sc->sc_lock; 698 1.1 rkujawa } 699