1 1.61 andvar /* $NetBSD: cs4281.c,v 1.61 2025/01/07 18:27:26 andvar Exp $ */ 2 1.1 augustss 3 1.1 augustss /* 4 1.1 augustss * Copyright (c) 2000 Tatoku Ogaito. All rights reserved. 5 1.1 augustss * 6 1.1 augustss * Redistribution and use in source and binary forms, with or without 7 1.1 augustss * modification, are permitted provided that the following conditions 8 1.1 augustss * are met: 9 1.1 augustss * 1. Redistributions of source code must retain the above copyright 10 1.1 augustss * notice, this list of conditions and the following disclaimer. 11 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 augustss * notice, this list of conditions and the following disclaimer in the 13 1.1 augustss * documentation and/or other materials provided with the distribution. 14 1.1 augustss * 3. All advertising materials mentioning features or use of this software 15 1.1 augustss * must display the following acknowledgement: 16 1.1 augustss * This product includes software developed by Tatoku Ogaito 17 1.1 augustss * for the NetBSD Project. 18 1.1 augustss * 4. The name of the author may not be used to endorse or promote products 19 1.1 augustss * derived from this software without specific prior written permission 20 1.1 augustss * 21 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.1 augustss * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.1 augustss * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.1 augustss * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.1 augustss * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.1 augustss * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.1 augustss * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 augustss * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.1 augustss * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 1.1 augustss * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 augustss */ 32 1.1 augustss 33 1.1 augustss /* 34 1.1 augustss * Cirrus Logic CS4281 driver. 35 1.1 augustss * Data sheets can be found 36 1.1 augustss * http://www.cirrus.com/ftp/pub/4281.pdf 37 1.1 augustss * ftp://ftp.alsa-project.org/pub/manuals/cirrus/cs4281tm.pdf 38 1.1 augustss * 39 1.1 augustss * TODO: 40 1.3 tacha * 1: midi and FM support 41 1.3 tacha * 2: ... 42 1.1 augustss * 43 1.1 augustss */ 44 1.7 lukem 45 1.7 lukem #include <sys/cdefs.h> 46 1.61 andvar __KERNEL_RCSID(0, "$NetBSD: cs4281.c,v 1.61 2025/01/07 18:27:26 andvar Exp $"); 47 1.1 augustss 48 1.1 augustss #include <sys/param.h> 49 1.1 augustss #include <sys/systm.h> 50 1.1 augustss #include <sys/kernel.h> 51 1.1 augustss #include <sys/fcntl.h> 52 1.1 augustss #include <sys/device.h> 53 1.1 augustss #include <sys/systm.h> 54 1.1 augustss 55 1.1 augustss #include <dev/pci/pcidevs.h> 56 1.1 augustss #include <dev/pci/pcivar.h> 57 1.1 augustss #include <dev/pci/cs4281reg.h> 58 1.1 augustss #include <dev/pci/cs428xreg.h> 59 1.1 augustss 60 1.1 augustss #include <sys/audioio.h> 61 1.55 isaki #include <dev/audio/audio_if.h> 62 1.1 augustss #include <dev/midi_if.h> 63 1.1 augustss 64 1.1 augustss #include <dev/ic/ac97reg.h> 65 1.1 augustss #include <dev/ic/ac97var.h> 66 1.1 augustss 67 1.1 augustss #include <dev/pci/cs428x.h> 68 1.1 augustss 69 1.35 ad #include <sys/bus.h> 70 1.1 augustss 71 1.1 augustss #if defined(ENABLE_SECONDARY_CODEC) 72 1.1 augustss #define MAX_CHANNELS (4) 73 1.1 augustss #define MAX_FIFO_SIZE 32 /* 128/4channels */ 74 1.1 augustss #else 75 1.1 augustss #define MAX_CHANNELS (2) 76 1.1 augustss #define MAX_FIFO_SIZE 64 /* 128/2channels */ 77 1.1 augustss #endif 78 1.1 augustss 79 1.1 augustss /* IF functions for audio driver */ 80 1.41 cegger static int cs4281_match(device_t, cfdata_t, void *); 81 1.41 cegger static void cs4281_attach(device_t, device_t, void *); 82 1.26 thorpej static int cs4281_intr(void *); 83 1.55 isaki static int cs4281_query_format(void *, audio_format_query_t *); 84 1.55 isaki static int cs4281_set_format(void *, int, 85 1.55 isaki const audio_params_t *, const audio_params_t *, 86 1.55 isaki audio_filter_reg_t *, audio_filter_reg_t *); 87 1.26 thorpej static int cs4281_halt_output(void *); 88 1.26 thorpej static int cs4281_halt_input(void *); 89 1.26 thorpej static int cs4281_getdev(void *, struct audio_device *); 90 1.26 thorpej static int cs4281_trigger_output(void *, void *, void *, int, 91 1.26 thorpej void (*)(void *), void *, 92 1.26 thorpej const audio_params_t *); 93 1.26 thorpej static int cs4281_trigger_input(void *, void *, void *, int, 94 1.26 thorpej void (*)(void *), void *, 95 1.26 thorpej const audio_params_t *); 96 1.1 augustss 97 1.52 msaitoh static int cs4281_reset_codec(void *); 98 1.3 tacha 99 1.1 augustss /* Internal functions */ 100 1.52 msaitoh static uint8_t cs4281_sr2regval(int); 101 1.52 msaitoh static void cs4281_set_dac_rate(struct cs428x_softc *, int); 102 1.52 msaitoh static void cs4281_set_adc_rate(struct cs428x_softc *, int); 103 1.26 thorpej static int cs4281_init(struct cs428x_softc *, int); 104 1.1 augustss 105 1.1 augustss /* Power Management */ 106 1.52 msaitoh static bool cs4281_suspend(device_t, const pmf_qual_t *); 107 1.52 msaitoh static bool cs4281_resume(device_t, const pmf_qual_t *); 108 1.1 augustss 109 1.26 thorpej static const struct audio_hw_if cs4281_hw_if = { 110 1.55 isaki .query_format = cs4281_query_format, 111 1.55 isaki .set_format = cs4281_set_format, 112 1.54 isaki .round_blocksize = cs428x_round_blocksize, 113 1.54 isaki .halt_output = cs4281_halt_output, 114 1.54 isaki .halt_input = cs4281_halt_input, 115 1.54 isaki .getdev = cs4281_getdev, 116 1.54 isaki .set_port = cs428x_mixer_set_port, 117 1.54 isaki .get_port = cs428x_mixer_get_port, 118 1.54 isaki .query_devinfo = cs428x_query_devinfo, 119 1.54 isaki .allocm = cs428x_malloc, 120 1.54 isaki .freem = cs428x_free, 121 1.54 isaki .round_buffersize = cs428x_round_buffersize, 122 1.54 isaki .get_props = cs428x_get_props, 123 1.54 isaki .trigger_output = cs4281_trigger_output, 124 1.54 isaki .trigger_input = cs4281_trigger_input, 125 1.54 isaki .get_locks = cs428x_get_locks, 126 1.1 augustss }; 127 1.1 augustss 128 1.2 augustss #if NMIDI > 0 && 0 129 1.1 augustss /* Midi Interface */ 130 1.26 thorpej static void cs4281_midi_close(void*); 131 1.26 thorpej static void cs4281_midi_getinfo(void *, struct midi_info *); 132 1.26 thorpej static int cs4281_midi_open(void *, int, void (*)(void *, int), 133 1.23 kent void (*)(void *), void *); 134 1.26 thorpej static int cs4281_midi_output(void *, int); 135 1.1 augustss 136 1.26 thorpej static const struct midi_hw_if cs4281_midi_hw_if = { 137 1.1 augustss cs4281_midi_open, 138 1.1 augustss cs4281_midi_close, 139 1.1 augustss cs4281_midi_output, 140 1.1 augustss cs4281_midi_getinfo, 141 1.1 augustss 0, 142 1.45 jmcneill cs428x_get_locks, 143 1.1 augustss }; 144 1.1 augustss #endif 145 1.1 augustss 146 1.48 chs CFATTACH_DECL_NEW(clct, sizeof(struct cs428x_softc), 147 1.13 thorpej cs4281_match, cs4281_attach, NULL, NULL); 148 1.1 augustss 149 1.26 thorpej static struct audio_device cs4281_device = { 150 1.1 augustss "CS4281", 151 1.1 augustss "", 152 1.1 augustss "cs4281" 153 1.1 augustss }; 154 1.1 augustss 155 1.55 isaki static const struct audio_format cs4281_formats[] = { 156 1.55 isaki { 157 1.55 isaki .mode = AUMODE_PLAY | AUMODE_RECORD, 158 1.55 isaki .encoding = AUDIO_ENCODING_SLINEAR_NE, 159 1.55 isaki .validbits = 16, 160 1.55 isaki .precision = 16, 161 1.55 isaki .channels = 2, 162 1.55 isaki .channel_mask = AUFMT_STEREO, 163 1.55 isaki .frequency_type = 6, 164 1.55 isaki .frequency = { 8000, 11025, 16000, 22050, 44100, 48000 }, 165 1.55 isaki }, 166 1.55 isaki }; 167 1.55 isaki #define CS4281_NFORMATS __arraycount(cs4281_formats) 168 1.1 augustss 169 1.26 thorpej static int 170 1.41 cegger cs4281_match(device_t parent, cfdata_t match, void *aux) 171 1.1 augustss { 172 1.23 kent struct pci_attach_args *pa; 173 1.23 kent 174 1.23 kent pa = (struct pci_attach_args *)aux; 175 1.1 augustss if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CIRRUS) 176 1.1 augustss return 0; 177 1.1 augustss if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CIRRUS_CS4281) 178 1.1 augustss return 1; 179 1.1 augustss return 0; 180 1.1 augustss } 181 1.1 augustss 182 1.26 thorpej static void 183 1.41 cegger cs4281_attach(device_t parent, device_t self, void *aux) 184 1.1 augustss { 185 1.23 kent struct cs428x_softc *sc; 186 1.23 kent struct pci_attach_args *pa; 187 1.23 kent pci_chipset_tag_t pc; 188 1.1 augustss char const *intrstr; 189 1.3 tacha pcireg_t reg; 190 1.29 christos int error; 191 1.51 christos char intrbuf[PCI_INTRSTR_LEN]; 192 1.1 augustss 193 1.42 cegger sc = device_private(self); 194 1.48 chs sc->sc_dev = self; 195 1.23 kent pa = (struct pci_attach_args *)aux; 196 1.23 kent pc = pa->pa_pc; 197 1.15 thorpej 198 1.47 drochner pci_aprint_devinfo(pa, "Audio controller"); 199 1.1 augustss 200 1.34 joerg sc->sc_pc = pa->pa_pc; 201 1.34 joerg sc->sc_pt = pa->pa_tag; 202 1.34 joerg 203 1.1 augustss /* Map I/O register */ 204 1.1 augustss if (pci_mapreg_map(pa, PCI_BA0, 205 1.1 augustss PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, 206 1.1 augustss &sc->ba0t, &sc->ba0h, NULL, NULL)) { 207 1.48 chs aprint_error_dev(sc->sc_dev, "can't map BA0 space\n"); 208 1.1 augustss return; 209 1.1 augustss } 210 1.1 augustss if (pci_mapreg_map(pa, PCI_BA1, 211 1.1 augustss PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, 212 1.1 augustss &sc->ba1t, &sc->ba1h, NULL, NULL)) { 213 1.48 chs aprint_error_dev(sc->sc_dev, "can't map BA1 space\n"); 214 1.1 augustss return; 215 1.1 augustss } 216 1.1 augustss 217 1.1 augustss sc->sc_dmatag = pa->pa_dmat; 218 1.1 augustss 219 1.29 christos /* power up chip */ 220 1.38 dyoung if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self, 221 1.29 christos pci_activate_null)) && error != EOPNOTSUPP) { 222 1.48 chs aprint_error_dev(sc->sc_dev, "cannot activate %d\n", error); 223 1.29 christos return; 224 1.3 tacha } 225 1.3 tacha 226 1.1 augustss /* Enable the device (set bus master flag) */ 227 1.3 tacha reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 228 1.1 augustss pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 229 1.3 tacha reg | PCI_COMMAND_MASTER_ENABLE); 230 1.1 augustss 231 1.1 augustss #if 0 232 1.1 augustss /* LATENCY_TIMER setting */ 233 1.1 augustss temp1 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); 234 1.10 simonb if (PCI_LATTIMER(temp1) < 32) { 235 1.1 augustss temp1 &= 0xffff00ff; 236 1.1 augustss temp1 |= 0x00002000; 237 1.1 augustss pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, temp1); 238 1.1 augustss } 239 1.1 augustss #endif 240 1.22 kent 241 1.1 augustss /* Map and establish the interrupt. */ 242 1.34 joerg if (pci_intr_map(pa, &sc->intrh)) { 243 1.48 chs aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n"); 244 1.1 augustss return; 245 1.1 augustss } 246 1.51 christos intrstr = pci_intr_string(pc, sc->intrh, intrbuf, sizeof(intrbuf)); 247 1.1 augustss 248 1.45 jmcneill mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 249 1.46 mrg mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 250 1.45 jmcneill 251 1.53 jdolecek sc->sc_ih = pci_intr_establish_xname(sc->sc_pc, sc->intrh, IPL_AUDIO, 252 1.53 jdolecek cs4281_intr, sc, device_xname(self)); 253 1.1 augustss if (sc->sc_ih == NULL) { 254 1.48 chs aprint_error_dev(sc->sc_dev, "couldn't establish interrupt"); 255 1.1 augustss if (intrstr != NULL) 256 1.39 dyoung aprint_error(" at %s", intrstr); 257 1.39 dyoung aprint_error("\n"); 258 1.45 jmcneill mutex_destroy(&sc->sc_lock); 259 1.45 jmcneill mutex_destroy(&sc->sc_intr_lock); 260 1.1 augustss return; 261 1.1 augustss } 262 1.48 chs aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); 263 1.1 augustss 264 1.1 augustss /* 265 1.1 augustss * Sound System start-up 266 1.1 augustss */ 267 1.45 jmcneill if (cs4281_init(sc, 1) != 0) { 268 1.45 jmcneill mutex_destroy(&sc->sc_lock); 269 1.45 jmcneill mutex_destroy(&sc->sc_intr_lock); 270 1.1 augustss return; 271 1.45 jmcneill } 272 1.1 augustss 273 1.1 augustss sc->type = TYPE_CS4281; 274 1.1 augustss 275 1.1 augustss sc->dma_size = CS4281_BUFFER_SIZE / MAX_CHANNELS; 276 1.1 augustss sc->dma_align = 0x10; 277 1.1 augustss sc->hw_blocksize = sc->dma_size / 2; 278 1.22 kent 279 1.1 augustss /* AC 97 attachment */ 280 1.1 augustss sc->host_if.arg = sc; 281 1.3 tacha sc->host_if.attach = cs428x_attach_codec; 282 1.3 tacha sc->host_if.read = cs428x_read_codec; 283 1.3 tacha sc->host_if.write = cs428x_write_codec; 284 1.1 augustss sc->host_if.reset = cs4281_reset_codec; 285 1.45 jmcneill if (ac97_attach(&sc->host_if, self, &sc->sc_lock) != 0) { 286 1.48 chs aprint_error_dev(sc->sc_dev, "ac97_attach failed\n"); 287 1.45 jmcneill mutex_destroy(&sc->sc_lock); 288 1.45 jmcneill mutex_destroy(&sc->sc_intr_lock); 289 1.1 augustss return; 290 1.1 augustss } 291 1.48 chs audio_attach_mi(&cs4281_hw_if, sc, sc->sc_dev); 292 1.1 augustss 293 1.2 augustss #if NMIDI > 0 && 0 294 1.48 chs midi_attach_mi(&cs4281_midi_hw_if, sc, sc->sc_dev); 295 1.1 augustss #endif 296 1.1 augustss 297 1.36 jmcneill if (!pmf_device_register(self, cs4281_suspend, cs4281_resume)) 298 1.36 jmcneill aprint_error_dev(self, "couldn't establish power handler\n"); 299 1.1 augustss } 300 1.1 augustss 301 1.26 thorpej static int 302 1.23 kent cs4281_intr(void *p) 303 1.1 augustss { 304 1.23 kent struct cs428x_softc *sc; 305 1.23 kent uint32_t intr, hdsr0, hdsr1; 306 1.1 augustss char *empty_dma; 307 1.23 kent int handled; 308 1.1 augustss 309 1.23 kent sc = p; 310 1.23 kent handled = 0; 311 1.1 augustss hdsr0 = 0; 312 1.1 augustss hdsr1 = 0; 313 1.23 kent 314 1.45 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 315 1.45 jmcneill 316 1.1 augustss /* grab interrupt register */ 317 1.1 augustss intr = BA0READ4(sc, CS4281_HISR); 318 1.1 augustss 319 1.1 augustss DPRINTF(("cs4281_intr:")); 320 1.1 augustss /* not for me */ 321 1.1 augustss if ((intr & HISR_INTENA) == 0) { 322 1.1 augustss /* clear the interrupt register */ 323 1.1 augustss BA0WRITE4(sc, CS4281_HICR, HICR_CHGM | HICR_IEV); 324 1.45 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 325 1.1 augustss return 0; 326 1.1 augustss } 327 1.1 augustss 328 1.1 augustss if (intr & HISR_DMA0) 329 1.1 augustss hdsr0 = BA0READ4(sc, CS4281_HDSR0); /* clear intr condition */ 330 1.1 augustss if (intr & HISR_DMA1) 331 1.1 augustss hdsr1 = BA0READ4(sc, CS4281_HDSR1); /* clear intr condition */ 332 1.1 augustss /* clear the interrupt register */ 333 1.1 augustss BA0WRITE4(sc, CS4281_HICR, HICR_CHGM | HICR_IEV); 334 1.23 kent 335 1.49 christos #ifdef CS4280_DEBUG 336 1.1 augustss DPRINTF(("intr = 0x%08x, hdsr0 = 0x%08x hdsr1 = 0x%08x\n", 337 1.1 augustss intr, hdsr0, hdsr1)); 338 1.49 christos #else 339 1.50 christos __USE(hdsr0); 340 1.50 christos __USE(hdsr1); 341 1.49 christos #endif 342 1.23 kent 343 1.1 augustss /* Playback Interrupt */ 344 1.1 augustss if (intr & HISR_DMA0) { 345 1.3 tacha handled = 1; 346 1.18 mycroft if (sc->sc_prun) { 347 1.28 jmcneill DPRINTF((" PB DMA 0x%x(%d)", 348 1.28 jmcneill (int)BA0READ4(sc, CS4281_DCA0), 349 1.28 jmcneill (int)BA0READ4(sc, CS4281_DCC0))); 350 1.1 augustss if ((sc->sc_pi%sc->sc_pcount) == 0) 351 1.1 augustss sc->sc_pintr(sc->sc_parg); 352 1.28 jmcneill /* copy buffer */ 353 1.28 jmcneill ++sc->sc_pi; 354 1.28 jmcneill empty_dma = sc->sc_pdma->addr; 355 1.28 jmcneill if (sc->sc_pi&1) 356 1.28 jmcneill empty_dma += sc->hw_blocksize; 357 1.28 jmcneill memcpy(empty_dma, sc->sc_pn, sc->hw_blocksize); 358 1.28 jmcneill sc->sc_pn += sc->hw_blocksize; 359 1.28 jmcneill if (sc->sc_pn >= sc->sc_pe) 360 1.28 jmcneill sc->sc_pn = sc->sc_ps; 361 1.1 augustss } else { 362 1.48 chs aprint_error_dev(sc->sc_dev, "unexpected play intr\n"); 363 1.1 augustss } 364 1.1 augustss } 365 1.1 augustss if (intr & HISR_DMA1) { 366 1.3 tacha handled = 1; 367 1.18 mycroft if (sc->sc_rrun) { 368 1.28 jmcneill /* copy from DMA */ 369 1.28 jmcneill DPRINTF((" CP DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA1), 370 1.28 jmcneill (int)BA0READ4(sc, CS4281_DCC1))); 371 1.28 jmcneill ++sc->sc_ri; 372 1.28 jmcneill empty_dma = sc->sc_rdma->addr; 373 1.28 jmcneill if ((sc->sc_ri & 1) == 0) 374 1.28 jmcneill empty_dma += sc->hw_blocksize; 375 1.28 jmcneill memcpy(sc->sc_rn, empty_dma, sc->hw_blocksize); 376 1.28 jmcneill sc->sc_rn += sc->hw_blocksize; 377 1.28 jmcneill if (sc->sc_rn >= sc->sc_re) 378 1.28 jmcneill sc->sc_rn = sc->sc_rs; 379 1.1 augustss if ((sc->sc_ri % sc->sc_rcount) == 0) 380 1.1 augustss sc->sc_rintr(sc->sc_rarg); 381 1.1 augustss } else { 382 1.48 chs aprint_error_dev(sc->sc_dev, 383 1.39 dyoung "unexpected record intr\n"); 384 1.1 augustss } 385 1.1 augustss } 386 1.1 augustss DPRINTF(("\n")); 387 1.3 tacha 388 1.45 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 389 1.45 jmcneill 390 1.3 tacha return handled; 391 1.1 augustss } 392 1.1 augustss 393 1.26 thorpej static int 394 1.55 isaki cs4281_query_format(void *addr, audio_format_query_t *afp) 395 1.1 augustss { 396 1.10 simonb 397 1.55 isaki return audio_query_format(cs4281_formats, CS4281_NFORMATS, afp); 398 1.1 augustss } 399 1.1 augustss 400 1.26 thorpej static int 401 1.55 isaki cs4281_set_format(void *addr, int setmode, 402 1.55 isaki const audio_params_t *play, const audio_params_t *rec, 403 1.55 isaki audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 404 1.1 augustss { 405 1.23 kent struct cs428x_softc *sc; 406 1.1 augustss 407 1.23 kent sc = addr; 408 1.1 augustss /* set sample rate */ 409 1.1 augustss cs4281_set_dac_rate(sc, play->sample_rate); 410 1.1 augustss cs4281_set_adc_rate(sc, rec->sample_rate); 411 1.1 augustss return 0; 412 1.1 augustss } 413 1.1 augustss 414 1.26 thorpej static int 415 1.23 kent cs4281_halt_output(void *addr) 416 1.1 augustss { 417 1.23 kent struct cs428x_softc *sc; 418 1.23 kent 419 1.23 kent sc = addr; 420 1.1 augustss BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK); 421 1.1 augustss sc->sc_prun = 0; 422 1.1 augustss return 0; 423 1.1 augustss } 424 1.1 augustss 425 1.26 thorpej static int 426 1.23 kent cs4281_halt_input(void *addr) 427 1.1 augustss { 428 1.23 kent struct cs428x_softc *sc; 429 1.1 augustss 430 1.23 kent sc = addr; 431 1.1 augustss BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK); 432 1.1 augustss sc->sc_rrun = 0; 433 1.1 augustss return 0; 434 1.1 augustss } 435 1.1 augustss 436 1.26 thorpej static int 437 1.33 christos cs4281_getdev(void *addr, struct audio_device *retp) 438 1.1 augustss { 439 1.10 simonb 440 1.1 augustss *retp = cs4281_device; 441 1.1 augustss return 0; 442 1.1 augustss } 443 1.1 augustss 444 1.26 thorpej static int 445 1.23 kent cs4281_trigger_output(void *addr, void *start, void *end, int blksize, 446 1.23 kent void (*intr)(void *), void *arg, 447 1.23 kent const audio_params_t *param) 448 1.1 augustss { 449 1.23 kent struct cs428x_softc *sc; 450 1.23 kent uint32_t fmt; 451 1.1 augustss struct cs428x_dma *p; 452 1.1 augustss int dma_count; 453 1.1 augustss 454 1.23 kent sc = addr; 455 1.23 kent fmt = 0; 456 1.1 augustss #ifdef DIAGNOSTIC 457 1.1 augustss if (sc->sc_prun) 458 1.1 augustss printf("cs4281_trigger_output: already running\n"); 459 1.4 tacha #endif 460 1.1 augustss sc->sc_prun = 1; 461 1.1 augustss 462 1.1 augustss DPRINTF(("cs4281_trigger_output: sc=%p start=%p end=%p " 463 1.1 augustss "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 464 1.1 augustss sc->sc_pintr = intr; 465 1.1 augustss sc->sc_parg = arg; 466 1.1 augustss 467 1.1 augustss /* stop playback DMA */ 468 1.1 augustss BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK); 469 1.1 augustss 470 1.22 kent DPRINTF(("param: precision=%d channels=%d encoding=%d\n", 471 1.22 kent param->precision, param->channels, param->encoding)); 472 1.1 augustss for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next) 473 1.23 kent continue; 474 1.1 augustss if (p == NULL) { 475 1.1 augustss printf("cs4281_trigger_output: bad addr %p\n", start); 476 1.23 kent return EINVAL; 477 1.1 augustss } 478 1.1 augustss 479 1.1 augustss sc->sc_pcount = blksize / sc->hw_blocksize; 480 1.1 augustss sc->sc_ps = (char *)start; 481 1.1 augustss sc->sc_pe = (char *)end; 482 1.1 augustss sc->sc_pdma = p; 483 1.1 augustss sc->sc_pbuf = KERNADDR(p); 484 1.1 augustss sc->sc_pi = 0; 485 1.1 augustss sc->sc_pn = sc->sc_ps; 486 1.1 augustss if (blksize >= sc->dma_size) { 487 1.1 augustss sc->sc_pn = sc->sc_ps + sc->dma_size; 488 1.1 augustss memcpy(sc->sc_pbuf, start, sc->dma_size); 489 1.1 augustss ++sc->sc_pi; 490 1.1 augustss } else { 491 1.1 augustss sc->sc_pn = sc->sc_ps + sc->hw_blocksize; 492 1.1 augustss memcpy(sc->sc_pbuf, start, sc->hw_blocksize); 493 1.1 augustss } 494 1.1 augustss 495 1.1 augustss dma_count = sc->dma_size; 496 1.22 kent if (param->precision != 8) 497 1.1 augustss dma_count /= 2; /* 16 bit */ 498 1.1 augustss if (param->channels > 1) 499 1.1 augustss dma_count /= 2; /* Stereo */ 500 1.1 augustss 501 1.1 augustss DPRINTF(("cs4281_trigger_output: DMAADDR(p)=0x%x count=%d\n", 502 1.1 augustss (int)DMAADDR(p), dma_count)); 503 1.1 augustss BA0WRITE4(sc, CS4281_DBA0, DMAADDR(p)); 504 1.1 augustss BA0WRITE4(sc, CS4281_DBC0, dma_count-1); 505 1.1 augustss 506 1.1 augustss /* set playback format */ 507 1.1 augustss fmt = BA0READ4(sc, CS4281_DMR0) & ~DMRn_FMTMSK; 508 1.55 isaki if (param->encoding == AUDIO_ENCODING_SLINEAR_BE) 509 1.1 augustss fmt |= DMRn_BEND; 510 1.1 augustss BA0WRITE4(sc, CS4281_DMR0, fmt); 511 1.1 augustss 512 1.1 augustss /* set sample rate */ 513 1.4 tacha sc->sc_prate = param->sample_rate; 514 1.1 augustss cs4281_set_dac_rate(sc, param->sample_rate); 515 1.1 augustss 516 1.1 augustss /* start DMA */ 517 1.1 augustss BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) & ~DCRn_MSK); 518 1.1 augustss /* Enable interrupts */ 519 1.1 augustss BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 520 1.1 augustss 521 1.1 augustss DPRINTF(("HICR =0x%08x(expected 0x00000001)\n", BA0READ4(sc, CS4281_HICR))); 522 1.1 augustss DPRINTF(("HIMR =0x%08x(expected 0x00f0fc3f)\n", BA0READ4(sc, CS4281_HIMR))); 523 1.1 augustss DPRINTF(("DMR0 =0x%08x(expected 0x2???0018)\n", BA0READ4(sc, CS4281_DMR0))); 524 1.1 augustss DPRINTF(("DCR0 =0x%08x(expected 0x00030000)\n", BA0READ4(sc, CS4281_DCR0))); 525 1.1 augustss DPRINTF(("FCR0 =0x%08x(expected 0x81000f00)\n", BA0READ4(sc, CS4281_FCR0))); 526 1.1 augustss DPRINTF(("DACSR=0x%08x(expected 1 for 44kHz 5 for 8kHz)\n", 527 1.1 augustss BA0READ4(sc, CS4281_DACSR))); 528 1.1 augustss DPRINTF(("SRCSA=0x%08x(expected 0x0b0a0100)\n", BA0READ4(sc, CS4281_SRCSA))); 529 1.1 augustss DPRINTF(("SSPM&SSPM_PSRCEN =0x%08x(expected 0x00000010)\n", 530 1.1 augustss BA0READ4(sc, CS4281_SSPM) & SSPM_PSRCEN)); 531 1.1 augustss 532 1.1 augustss return 0; 533 1.1 augustss } 534 1.1 augustss 535 1.26 thorpej static int 536 1.23 kent cs4281_trigger_input(void *addr, void *start, void *end, int blksize, 537 1.23 kent void (*intr)(void *), void *arg, 538 1.23 kent const audio_params_t *param) 539 1.1 augustss { 540 1.23 kent struct cs428x_softc *sc; 541 1.1 augustss struct cs428x_dma *p; 542 1.23 kent uint32_t fmt; 543 1.1 augustss int dma_count; 544 1.1 augustss 545 1.23 kent sc = addr; 546 1.23 kent fmt = 0; 547 1.1 augustss #ifdef DIAGNOSTIC 548 1.1 augustss if (sc->sc_rrun) 549 1.1 augustss printf("cs4281_trigger_input: already running\n"); 550 1.4 tacha #endif 551 1.1 augustss sc->sc_rrun = 1; 552 1.1 augustss DPRINTF(("cs4281_trigger_input: sc=%p start=%p end=%p " 553 1.1 augustss "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 554 1.1 augustss sc->sc_rintr = intr; 555 1.1 augustss sc->sc_rarg = arg; 556 1.1 augustss 557 1.1 augustss /* stop recording DMA */ 558 1.1 augustss BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK); 559 1.1 augustss 560 1.1 augustss for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next) 561 1.23 kent continue; 562 1.1 augustss if (!p) { 563 1.1 augustss printf("cs4281_trigger_input: bad addr %p\n", start); 564 1.23 kent return EINVAL; 565 1.1 augustss } 566 1.1 augustss 567 1.1 augustss sc->sc_rcount = blksize / sc->hw_blocksize; 568 1.1 augustss sc->sc_rs = (char *)start; 569 1.1 augustss sc->sc_re = (char *)end; 570 1.1 augustss sc->sc_rdma = p; 571 1.1 augustss sc->sc_rbuf = KERNADDR(p); 572 1.1 augustss sc->sc_ri = 0; 573 1.1 augustss sc->sc_rn = sc->sc_rs; 574 1.1 augustss 575 1.1 augustss dma_count = sc->dma_size; 576 1.22 kent if (param->precision != 8) 577 1.1 augustss dma_count /= 2; 578 1.1 augustss if (param->channels > 1) 579 1.1 augustss dma_count /= 2; 580 1.1 augustss 581 1.1 augustss DPRINTF(("cs4281_trigger_input: DMAADDR(p)=0x%x count=%d\n", 582 1.1 augustss (int)DMAADDR(p), dma_count)); 583 1.1 augustss BA0WRITE4(sc, CS4281_DBA1, DMAADDR(p)); 584 1.1 augustss BA0WRITE4(sc, CS4281_DBC1, dma_count-1); 585 1.1 augustss 586 1.1 augustss /* set recording format */ 587 1.1 augustss fmt = BA0READ4(sc, CS4281_DMR1) & ~DMRn_FMTMSK; 588 1.55 isaki if (param->encoding == AUDIO_ENCODING_SLINEAR_BE) 589 1.1 augustss fmt |= DMRn_BEND; 590 1.1 augustss BA0WRITE4(sc, CS4281_DMR1, fmt); 591 1.1 augustss 592 1.1 augustss /* set sample rate */ 593 1.4 tacha sc->sc_rrate = param->sample_rate; 594 1.1 augustss cs4281_set_adc_rate(sc, param->sample_rate); 595 1.1 augustss 596 1.1 augustss /* Start DMA */ 597 1.1 augustss BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) & ~DCRn_MSK); 598 1.1 augustss /* Enable interrupts */ 599 1.1 augustss BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 600 1.1 augustss 601 1.1 augustss DPRINTF(("HICR=0x%08x\n", BA0READ4(sc, CS4281_HICR))); 602 1.1 augustss DPRINTF(("HIMR=0x%08x\n", BA0READ4(sc, CS4281_HIMR))); 603 1.1 augustss DPRINTF(("DMR1=0x%08x\n", BA0READ4(sc, CS4281_DMR1))); 604 1.1 augustss DPRINTF(("DCR1=0x%08x\n", BA0READ4(sc, CS4281_DCR1))); 605 1.1 augustss 606 1.1 augustss return 0; 607 1.1 augustss } 608 1.1 augustss 609 1.36 jmcneill static bool 610 1.44 dyoung cs4281_suspend(device_t dv, const pmf_qual_t *qual) 611 1.3 tacha { 612 1.36 jmcneill struct cs428x_softc *sc = device_private(dv); 613 1.3 tacha 614 1.45 jmcneill mutex_enter(&sc->sc_lock); 615 1.58 riastrad mutex_spin_enter(&sc->sc_intr_lock); 616 1.45 jmcneill 617 1.36 jmcneill /* save current playback status */ 618 1.36 jmcneill if (sc->sc_prun) { 619 1.36 jmcneill sc->sc_suspend_state.cs4281.dcr0 = BA0READ4(sc, CS4281_DCR0); 620 1.36 jmcneill sc->sc_suspend_state.cs4281.dmr0 = BA0READ4(sc, CS4281_DMR0); 621 1.36 jmcneill sc->sc_suspend_state.cs4281.dbc0 = BA0READ4(sc, CS4281_DBC0); 622 1.36 jmcneill sc->sc_suspend_state.cs4281.dba0 = BA0READ4(sc, CS4281_DBA0); 623 1.36 jmcneill } 624 1.36 jmcneill 625 1.36 jmcneill /* save current capture status */ 626 1.36 jmcneill if (sc->sc_rrun) { 627 1.36 jmcneill sc->sc_suspend_state.cs4281.dcr1 = BA0READ4(sc, CS4281_DCR1); 628 1.36 jmcneill sc->sc_suspend_state.cs4281.dmr1 = BA0READ4(sc, CS4281_DMR1); 629 1.36 jmcneill sc->sc_suspend_state.cs4281.dbc1 = BA0READ4(sc, CS4281_DBC1); 630 1.36 jmcneill sc->sc_suspend_state.cs4281.dba1 = BA0READ4(sc, CS4281_DBA1); 631 1.36 jmcneill } 632 1.36 jmcneill /* Stop DMA */ 633 1.36 jmcneill BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK); 634 1.36 jmcneill BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK); 635 1.3 tacha 636 1.45 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 637 1.45 jmcneill mutex_exit(&sc->sc_lock); 638 1.45 jmcneill 639 1.36 jmcneill return true; 640 1.36 jmcneill } 641 1.4 tacha 642 1.36 jmcneill static bool 643 1.44 dyoung cs4281_resume(device_t dv, const pmf_qual_t *qual) 644 1.36 jmcneill { 645 1.36 jmcneill struct cs428x_softc *sc = device_private(dv); 646 1.34 joerg 647 1.45 jmcneill mutex_enter(&sc->sc_lock); 648 1.45 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 649 1.45 jmcneill 650 1.36 jmcneill cs4281_init(sc, 0); 651 1.36 jmcneill cs4281_reset_codec(sc); 652 1.34 joerg 653 1.36 jmcneill /* restore ac97 registers */ 654 1.45 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 655 1.36 jmcneill (*sc->codec_if->vtbl->restore_ports)(sc->codec_if); 656 1.45 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 657 1.3 tacha 658 1.36 jmcneill /* restore DMA related status */ 659 1.36 jmcneill if (sc->sc_prun) { 660 1.36 jmcneill cs4281_set_dac_rate(sc, sc->sc_prate); 661 1.36 jmcneill BA0WRITE4(sc, CS4281_DBA0, sc->sc_suspend_state.cs4281.dba0); 662 1.36 jmcneill BA0WRITE4(sc, CS4281_DBC0, sc->sc_suspend_state.cs4281.dbc0); 663 1.36 jmcneill BA0WRITE4(sc, CS4281_DMR0, sc->sc_suspend_state.cs4281.dmr0); 664 1.36 jmcneill BA0WRITE4(sc, CS4281_DCR0, sc->sc_suspend_state.cs4281.dcr0); 665 1.36 jmcneill } 666 1.36 jmcneill if (sc->sc_rrun) { 667 1.36 jmcneill cs4281_set_adc_rate(sc, sc->sc_rrate); 668 1.36 jmcneill BA0WRITE4(sc, CS4281_DBA1, sc->sc_suspend_state.cs4281.dba1); 669 1.36 jmcneill BA0WRITE4(sc, CS4281_DBC1, sc->sc_suspend_state.cs4281.dbc1); 670 1.36 jmcneill BA0WRITE4(sc, CS4281_DMR1, sc->sc_suspend_state.cs4281.dmr1); 671 1.36 jmcneill BA0WRITE4(sc, CS4281_DCR1, sc->sc_suspend_state.cs4281.dcr1); 672 1.36 jmcneill } 673 1.60 andvar /* enable interrupts */ 674 1.36 jmcneill if (sc->sc_prun || sc->sc_rrun) 675 1.36 jmcneill BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 676 1.4 tacha 677 1.45 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 678 1.45 jmcneill mutex_exit(&sc->sc_lock); 679 1.45 jmcneill 680 1.36 jmcneill return true; 681 1.3 tacha } 682 1.3 tacha 683 1.3 tacha /* control AC97 codec */ 684 1.26 thorpej static int 685 1.3 tacha cs4281_reset_codec(void *addr) 686 1.3 tacha { 687 1.3 tacha struct cs428x_softc *sc; 688 1.23 kent uint16_t data; 689 1.23 kent uint32_t dat32; 690 1.3 tacha int n; 691 1.3 tacha 692 1.3 tacha sc = addr; 693 1.3 tacha 694 1.10 simonb DPRINTFN(3, ("cs4281_reset_codec\n")); 695 1.3 tacha 696 1.3 tacha /* Reset codec */ 697 1.3 tacha BA0WRITE4(sc, CS428X_ACCTL, 0); 698 1.3 tacha delay(50); /* delay 50us */ 699 1.3 tacha 700 1.3 tacha BA0WRITE4(sc, CS4281_SPMC, 0); 701 1.3 tacha delay(100); /* delay 100us */ 702 1.3 tacha BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN); 703 1.3 tacha #if defined(ENABLE_SECONDARY_CODEC) 704 1.3 tacha BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E); 705 1.3 tacha BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID); 706 1.3 tacha #endif 707 1.3 tacha delay(50000); /* XXX: delay 50ms */ 708 1.3 tacha 709 1.3 tacha /* Enable ASYNC generation */ 710 1.3 tacha BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN); 711 1.3 tacha 712 1.10 simonb /* Wait for codec ready. Linux driver waits 50ms here */ 713 1.3 tacha n = 0; 714 1.10 simonb while ((BA0READ4(sc, CS428X_ACSTS) & ACSTS_CRDY) == 0) { 715 1.3 tacha delay(100); 716 1.3 tacha if (++n > 1000) { 717 1.3 tacha printf("reset_codec: AC97 codec ready timeout\n"); 718 1.19 kent return ETIMEDOUT; 719 1.3 tacha } 720 1.3 tacha } 721 1.3 tacha #if defined(ENABLE_SECONDARY_CODEC) 722 1.3 tacha /* secondary codec ready*/ 723 1.3 tacha n = 0; 724 1.10 simonb while ((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) { 725 1.3 tacha delay(100); 726 1.3 tacha if (++n > 1000) 727 1.19 kent return 0; 728 1.3 tacha } 729 1.3 tacha #endif 730 1.3 tacha /* Set the serial timing configuration */ 731 1.3 tacha /* XXX: undocumented but the Linux driver do this */ 732 1.3 tacha BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 733 1.23 kent 734 1.10 simonb /* Wait for codec ready signal */ 735 1.3 tacha n = 0; 736 1.3 tacha do { 737 1.3 tacha delay(1000); 738 1.3 tacha if (++n > 1000) { 739 1.48 chs aprint_error_dev(sc->sc_dev, 740 1.39 dyoung "timeout waiting for codec ready\n"); 741 1.19 kent return ETIMEDOUT; 742 1.3 tacha } 743 1.3 tacha dat32 = BA0READ4(sc, CS428X_ACSTS) & ACSTS_CRDY; 744 1.3 tacha } while (dat32 == 0); 745 1.3 tacha 746 1.3 tacha /* Enable Valid Frame output on ASDOUT */ 747 1.3 tacha BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN | ACCTL_VFRM); 748 1.23 kent 749 1.10 simonb /* Wait until codec calibration is finished. Codec register 26h */ 750 1.3 tacha n = 0; 751 1.3 tacha do { 752 1.3 tacha delay(1); 753 1.3 tacha if (++n > 1000) { 754 1.48 chs aprint_error_dev(sc->sc_dev, 755 1.39 dyoung "timeout waiting for codec calibration\n"); 756 1.19 kent return ETIMEDOUT; 757 1.3 tacha } 758 1.3 tacha cs428x_read_codec(sc, AC97_REG_POWER, &data); 759 1.3 tacha } while ((data & 0x0f) != 0x0f); 760 1.3 tacha 761 1.3 tacha /* Set the serial timing configuration again */ 762 1.3 tacha /* XXX: undocumented but the Linux driver do this */ 763 1.3 tacha BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 764 1.3 tacha 765 1.3 tacha /* Wait until we've sampled input slots 3 & 4 as valid */ 766 1.3 tacha n = 0; 767 1.3 tacha do { 768 1.3 tacha delay(1000); 769 1.3 tacha if (++n > 1000) { 770 1.48 chs aprint_error_dev(sc->sc_dev, "timeout waiting for " 771 1.39 dyoung "sampled input slots as valid\n"); 772 1.19 kent return ETIMEDOUT; 773 1.3 tacha } 774 1.3 tacha dat32 = BA0READ4(sc, CS428X_ACISV) & (ACISV_ISV3 | ACISV_ISV4) ; 775 1.3 tacha } while (dat32 != (ACISV_ISV3 | ACISV_ISV4)); 776 1.23 kent 777 1.3 tacha /* Start digital data transfer of audio data to the codec */ 778 1.3 tacha BA0WRITE4(sc, CS428X_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4)); 779 1.19 kent return 0; 780 1.3 tacha } 781 1.3 tacha 782 1.3 tacha 783 1.3 tacha /* Internal functions */ 784 1.3 tacha 785 1.1 augustss /* convert sample rate to register value */ 786 1.26 thorpej static uint8_t 787 1.23 kent cs4281_sr2regval(int rate) 788 1.1 augustss { 789 1.23 kent uint8_t retval; 790 1.1 augustss 791 1.1 augustss /* We don't have to change here. but anyway ... */ 792 1.1 augustss if (rate > 48000) 793 1.1 augustss rate = 48000; 794 1.1 augustss if (rate < 6023) 795 1.1 augustss rate = 6023; 796 1.1 augustss 797 1.1 augustss switch (rate) { 798 1.1 augustss case 8000: 799 1.1 augustss retval = 5; 800 1.1 augustss break; 801 1.1 augustss case 11025: 802 1.1 augustss retval = 4; 803 1.1 augustss break; 804 1.1 augustss case 16000: 805 1.1 augustss retval = 3; 806 1.1 augustss break; 807 1.1 augustss case 22050: 808 1.1 augustss retval = 2; 809 1.1 augustss break; 810 1.1 augustss case 44100: 811 1.1 augustss retval = 1; 812 1.1 augustss break; 813 1.1 augustss case 48000: 814 1.1 augustss retval = 0; 815 1.1 augustss break; 816 1.1 augustss default: 817 1.1 augustss retval = 1536000/rate; /* == 24576000/(rate*16) */ 818 1.1 augustss } 819 1.1 augustss return retval; 820 1.1 augustss } 821 1.1 augustss 822 1.26 thorpej static void 823 1.23 kent cs4281_set_adc_rate(struct cs428x_softc *sc, int rate) 824 1.1 augustss { 825 1.10 simonb 826 1.3 tacha BA0WRITE4(sc, CS4281_ADCSR, cs4281_sr2regval(rate)); 827 1.1 augustss } 828 1.1 augustss 829 1.26 thorpej static void 830 1.23 kent cs4281_set_dac_rate(struct cs428x_softc *sc, int rate) 831 1.1 augustss { 832 1.10 simonb 833 1.3 tacha BA0WRITE4(sc, CS4281_DACSR, cs4281_sr2regval(rate)); 834 1.1 augustss } 835 1.1 augustss 836 1.26 thorpej static int 837 1.23 kent cs4281_init(struct cs428x_softc *sc, int init) 838 1.1 augustss { 839 1.1 augustss int n; 840 1.23 kent uint16_t data; 841 1.23 kent uint32_t dat32; 842 1.1 augustss 843 1.1 augustss /* set "Configuration Write Protect" register to 844 1.1 augustss * 0x4281 to allow to write */ 845 1.1 augustss BA0WRITE4(sc, CS4281_CWPR, 0x4281); 846 1.1 augustss 847 1.3 tacha /* 848 1.3 tacha * Unset "Full Power-Down bit of Extended PCI Power Management 849 1.3 tacha * Control" register to release the reset state. 850 1.3 tacha */ 851 1.3 tacha dat32 = BA0READ4(sc, CS4281_EPPMC); 852 1.3 tacha if (dat32 & EPPMC_FPDN) { 853 1.3 tacha BA0WRITE4(sc, CS4281_EPPMC, dat32 & ~EPPMC_FPDN); 854 1.3 tacha } 855 1.3 tacha 856 1.1 augustss /* Start PLL out in known state */ 857 1.1 augustss BA0WRITE4(sc, CS4281_CLKCR1, 0); 858 1.1 augustss /* Start serial ports out in known state */ 859 1.1 augustss BA0WRITE4(sc, CS4281_SERMC, 0); 860 1.23 kent 861 1.1 augustss /* Reset codec */ 862 1.1 augustss BA0WRITE4(sc, CS428X_ACCTL, 0); 863 1.1 augustss delay(50); /* delay 50us */ 864 1.1 augustss 865 1.1 augustss BA0WRITE4(sc, CS4281_SPMC, 0); 866 1.1 augustss delay(100); /* delay 100us */ 867 1.1 augustss BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN); 868 1.1 augustss #if defined(ENABLE_SECONDARY_CODEC) 869 1.1 augustss BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E); 870 1.1 augustss BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID); 871 1.1 augustss #endif 872 1.1 augustss delay(50000); /* XXX: delay 50ms */ 873 1.1 augustss 874 1.1 augustss /* Turn on Sound System clocks based on ABITCLK */ 875 1.1 augustss BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_DLLP); 876 1.1 augustss delay(50000); /* XXX: delay 50ms */ 877 1.1 augustss BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_SWCE | CLKCR1_DLLP); 878 1.1 augustss 879 1.1 augustss /* Set enables for sections that are needed in the SSPM registers */ 880 1.1 augustss BA0WRITE4(sc, CS4281_SSPM, 881 1.1 augustss SSPM_MIXEN | /* Mixer */ 882 1.1 augustss SSPM_CSRCEN | /* Capture SRC */ 883 1.1 augustss SSPM_PSRCEN | /* Playback SRC */ 884 1.1 augustss SSPM_JSEN | /* Joystick */ 885 1.1 augustss SSPM_ACLEN | /* AC LINK */ 886 1.1 augustss SSPM_FMEN /* FM */ 887 1.1 augustss ); 888 1.1 augustss 889 1.1 augustss /* Wait for clock stabilization */ 890 1.1 augustss n = 0; 891 1.1 augustss #if 1 892 1.1 augustss /* what document says */ 893 1.56 simonb while ((BA0READ4(sc, CS4281_CLKCR1) & (CLKCR1_DLLRDY | CLKCR1_CLKON)) 894 1.10 simonb != (CLKCR1_DLLRDY | CLKCR1_CLKON)) { 895 1.1 augustss delay(100); 896 1.10 simonb if (++n > 1000) { 897 1.48 chs aprint_error_dev(sc->sc_dev, 898 1.39 dyoung "timeout waiting for clock stabilization\n"); 899 1.1 augustss return -1; 900 1.10 simonb } 901 1.1 augustss } 902 1.1 augustss #else 903 1.1 augustss /* Cirrus driver for Linux does */ 904 1.10 simonb while (!(BA0READ4(sc, CS4281_CLKCR1) & CLKCR1_DLLRDY)) { 905 1.1 augustss delay(1000); 906 1.10 simonb if (++n > 1000) { 907 1.48 chs aprint_error_dev(sc->sc_dev, 908 1.39 dyoung "timeout waiting for clock stabilization\n"); 909 1.1 augustss return -1; 910 1.10 simonb } 911 1.1 augustss } 912 1.1 augustss #endif 913 1.1 augustss 914 1.1 augustss /* Enable ASYNC generation */ 915 1.1 augustss BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN); 916 1.1 augustss 917 1.10 simonb /* Wait for codec ready. Linux driver waits 50ms here */ 918 1.1 augustss n = 0; 919 1.10 simonb while ((BA0READ4(sc, CS428X_ACSTS) & ACSTS_CRDY) == 0) { 920 1.1 augustss delay(100); 921 1.10 simonb if (++n > 1000) { 922 1.48 chs aprint_error_dev(sc->sc_dev, 923 1.39 dyoung "timeout waiting for codec ready\n"); 924 1.1 augustss return -1; 925 1.10 simonb } 926 1.1 augustss } 927 1.1 augustss 928 1.1 augustss #if defined(ENABLE_SECONDARY_CODEC) 929 1.1 augustss /* secondary codec ready*/ 930 1.1 augustss n = 0; 931 1.10 simonb while ((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) { 932 1.1 augustss delay(100); 933 1.10 simonb if (++n > 1000) { 934 1.48 chs aprint_error_dev(sc->sc_dev, 935 1.39 dyoung "timeout waiting for secondary codec ready\n"); 936 1.1 augustss return -1; 937 1.10 simonb } 938 1.1 augustss } 939 1.1 augustss #endif 940 1.1 augustss 941 1.1 augustss /* Set the serial timing configuration */ 942 1.1 augustss /* XXX: undocumented but the Linux driver do this */ 943 1.1 augustss BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 944 1.23 kent 945 1.10 simonb /* Wait for codec ready signal */ 946 1.1 augustss n = 0; 947 1.1 augustss do { 948 1.1 augustss delay(1000); 949 1.1 augustss if (++n > 1000) { 950 1.48 chs aprint_error_dev(sc->sc_dev, 951 1.39 dyoung "timeout waiting for codec ready\n"); 952 1.1 augustss return -1; 953 1.1 augustss } 954 1.1 augustss dat32 = BA0READ4(sc, CS428X_ACSTS) & ACSTS_CRDY; 955 1.1 augustss } while (dat32 == 0); 956 1.1 augustss 957 1.1 augustss /* Enable Valid Frame output on ASDOUT */ 958 1.1 augustss BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN | ACCTL_VFRM); 959 1.23 kent 960 1.10 simonb /* Wait until codec calibration is finished. codec register 26h */ 961 1.1 augustss n = 0; 962 1.1 augustss do { 963 1.1 augustss delay(1); 964 1.1 augustss if (++n > 1000) { 965 1.48 chs aprint_error_dev(sc->sc_dev, 966 1.39 dyoung "timeout waiting for codec calibration\n"); 967 1.1 augustss return -1; 968 1.1 augustss } 969 1.3 tacha cs428x_read_codec(sc, AC97_REG_POWER, &data); 970 1.1 augustss } while ((data & 0x0f) != 0x0f); 971 1.1 augustss 972 1.1 augustss /* Set the serial timing configuration again */ 973 1.1 augustss /* XXX: undocumented but the Linux driver do this */ 974 1.1 augustss BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 975 1.1 augustss 976 1.1 augustss /* Wait until we've sampled input slots 3 & 4 as valid */ 977 1.1 augustss n = 0; 978 1.1 augustss do { 979 1.1 augustss delay(1000); 980 1.1 augustss if (++n > 1000) { 981 1.48 chs aprint_error_dev(sc->sc_dev, "timeout waiting for " 982 1.39 dyoung "sampled input slots as valid\n"); 983 1.1 augustss return -1; 984 1.1 augustss } 985 1.1 augustss dat32 = BA0READ4(sc, CS428X_ACISV) & (ACISV_ISV3 | ACISV_ISV4); 986 1.1 augustss } while (dat32 != (ACISV_ISV3 | ACISV_ISV4)); 987 1.23 kent 988 1.1 augustss /* Start digital data transfer of audio data to the codec */ 989 1.1 augustss BA0WRITE4(sc, CS428X_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4)); 990 1.23 kent 991 1.3 tacha cs428x_write_codec(sc, AC97_REG_HEADPHONE_VOLUME, 0); 992 1.3 tacha cs428x_write_codec(sc, AC97_REG_MASTER_VOLUME, 0); 993 1.23 kent 994 1.1 augustss /* Power on the DAC */ 995 1.3 tacha cs428x_read_codec(sc, AC97_REG_POWER, &data); 996 1.3 tacha cs428x_write_codec(sc, AC97_REG_POWER, data & 0xfdff); 997 1.1 augustss 998 1.1 augustss /* Wait until we sample a DAC ready state. 999 1.1 augustss * Not documented, but Linux driver does. 1000 1.1 augustss */ 1001 1.1 augustss for (n = 0; n < 32; ++n) { 1002 1.1 augustss delay(1000); 1003 1.3 tacha cs428x_read_codec(sc, AC97_REG_POWER, &data); 1004 1.1 augustss if (data & 0x02) 1005 1.1 augustss break; 1006 1.1 augustss } 1007 1.23 kent 1008 1.1 augustss /* Power on the ADC */ 1009 1.3 tacha cs428x_read_codec(sc, AC97_REG_POWER, &data); 1010 1.3 tacha cs428x_write_codec(sc, AC97_REG_POWER, data & 0xfeff); 1011 1.1 augustss 1012 1.1 augustss /* Wait until we sample ADC ready state. 1013 1.1 augustss * Not documented, but Linux driver does. 1014 1.1 augustss */ 1015 1.1 augustss for (n = 0; n < 32; ++n) { 1016 1.1 augustss delay(1000); 1017 1.3 tacha cs428x_read_codec(sc, AC97_REG_POWER, &data); 1018 1.1 augustss if (data & 0x01) 1019 1.1 augustss break; 1020 1.1 augustss } 1021 1.23 kent 1022 1.1 augustss #if 0 1023 1.1 augustss /* Initialize AC-Link features */ 1024 1.1 augustss /* variable sample-rate support */ 1025 1.1 augustss mem = BA0READ4(sc, CS4281_SERMC); 1026 1.1 augustss mem |= (SERMC_ODSEN1 | SERMC_ODSEN2); 1027 1.1 augustss BA0WRITE4(sc, CS4281_SERMC, mem); 1028 1.1 augustss /* XXX: more... */ 1029 1.23 kent 1030 1.1 augustss /* Initialize SSCR register features */ 1031 1.1 augustss /* XXX: hardware volume setting */ 1032 1.1 augustss BA0WRITE4(sc, CS4281_SSCR, ~SSCR_HVC); /* disable HW volume setting */ 1033 1.1 augustss #endif 1034 1.1 augustss 1035 1.1 augustss /* disable Sound Blaster Pro emulation */ 1036 1.24 perry /* XXX: 1037 1.1 augustss * Cannot set since the documents does not describe which bit is 1038 1.1 augustss * correspond to SSCR_SB. Since the reset value of SSCR is 0, 1039 1.1 augustss * we can ignore it.*/ 1040 1.1 augustss #if 0 1041 1.1 augustss BA0WRITE4(sc, CS4281_SSCR, SSCR_SB); 1042 1.1 augustss #endif 1043 1.1 augustss 1044 1.1 augustss /* map AC97 PCM playback to DMA Channel 0 */ 1045 1.1 augustss /* Reset FEN bit to setup first */ 1046 1.10 simonb BA0WRITE4(sc, CS4281_FCR0, (BA0READ4(sc, CS4281_FCR0) & ~FCRn_FEN)); 1047 1.1 augustss /* 1048 1.1 augustss *| RS[4:0]/| | 1049 1.1 augustss *| LS[4:0] | AC97 | Slot Function 1050 1.1 augustss *|---------+--------+-------------------- 1051 1.1 augustss *| 0 | 3 | Left PCM Playback 1052 1.1 augustss *| 1 | 4 | Right PCM Playback 1053 1.1 augustss *| 2 | 5 | Phone Line 1 DAC 1054 1.1 augustss *| 3 | 6 | Center PCM Playback 1055 1.1 augustss *.... 1056 1.1 augustss * quoted from Table 29(p109) 1057 1.1 augustss */ 1058 1.1 augustss dat32 = 0x01 << 24 | /* RS[4:0] = 1 see above */ 1059 1.1 augustss 0x00 << 16 | /* LS[4:0] = 0 see above */ 1060 1.1 augustss 0x0f << 8 | /* SZ[6:0] = 15 size of buffer */ 1061 1.1 augustss 0x00 << 0 ; /* OF[6:0] = 0 offset */ 1062 1.1 augustss BA0WRITE4(sc, CS4281_FCR0, dat32); 1063 1.1 augustss BA0WRITE4(sc, CS4281_FCR0, dat32 | FCRn_FEN); 1064 1.1 augustss 1065 1.1 augustss /* map AC97 PCM record to DMA Channel 1 */ 1066 1.1 augustss /* Reset FEN bit to setup first */ 1067 1.10 simonb BA0WRITE4(sc, CS4281_FCR1, (BA0READ4(sc, CS4281_FCR1) & ~FCRn_FEN)); 1068 1.1 augustss /* 1069 1.1 augustss *| RS[4:0]/| 1070 1.1 augustss *| LS[4:0] | AC97 | Slot Function 1071 1.1 augustss *|---------+------+------------------- 1072 1.1 augustss *| 10 | 3 | Left PCM Record 1073 1.1 augustss *| 11 | 4 | Right PCM Record 1074 1.1 augustss *| 12 | 5 | Phone Line 1 ADC 1075 1.1 augustss *| 13 | 6 | Mic ADC 1076 1.1 augustss *.... 1077 1.1 augustss * quoted from Table 30(p109) 1078 1.1 augustss */ 1079 1.1 augustss dat32 = 0x0b << 24 | /* RS[4:0] = 11 See above */ 1080 1.1 augustss 0x0a << 16 | /* LS[4:0] = 10 See above */ 1081 1.1 augustss 0x0f << 8 | /* SZ[6:0] = 15 Size of buffer */ 1082 1.1 augustss 0x10 << 0 ; /* OF[6:0] = 16 offset */ 1083 1.1 augustss 1084 1.1 augustss /* XXX: I cannot understand why FCRn_PSH is needed here. */ 1085 1.1 augustss BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_PSH); 1086 1.1 augustss BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_FEN); 1087 1.1 augustss 1088 1.1 augustss #if 0 1089 1.1 augustss /* Disable DMA Channel 2, 3 */ 1090 1.10 simonb BA0WRITE4(sc, CS4281_FCR2, (BA0READ4(sc, CS4281_FCR2) & ~FCRn_FEN)); 1091 1.10 simonb BA0WRITE4(sc, CS4281_FCR3, (BA0READ4(sc, CS4281_FCR3) & ~FCRn_FEN)); 1092 1.1 augustss #endif 1093 1.1 augustss 1094 1.1 augustss /* Set the SRC Slot Assignment accordingly */ 1095 1.1 augustss /*| PLSS[4:0]/ 1096 1.1 augustss *| PRSS[4:0] | AC97 | Slot Function 1097 1.1 augustss *|-----------+------+---------------- 1098 1.1 augustss *| 0 | 3 | Left PCM Playback 1099 1.1 augustss *| 1 | 4 | Right PCM Playback 1100 1.1 augustss *| 2 | 5 | phone line 1 DAC 1101 1.1 augustss *| 3 | 6 | Center PCM Playback 1102 1.1 augustss *| 4 | 7 | Left Surround PCM Playback 1103 1.1 augustss *| 5 | 8 | Right Surround PCM Playback 1104 1.1 augustss *...... 1105 1.1 augustss * 1106 1.1 augustss *| CLSS[4:0]/ 1107 1.1 augustss *| CRSS[4:0] | AC97 | Codec |Slot Function 1108 1.1 augustss *|-----------+------+-------+----------------- 1109 1.1 augustss *| 10 | 3 |Primary| Left PCM Record 1110 1.1 augustss *| 11 | 4 |Primary| Right PCM Record 1111 1.1 augustss *| 12 | 5 |Primary| Phone Line 1 ADC 1112 1.1 augustss *| 13 | 6 |Primary| Mic ADC 1113 1.1 augustss *|..... 1114 1.1 augustss *| 20 | 3 | Sec. | Left PCM Record 1115 1.1 augustss *| 21 | 4 | Sec. | Right PCM Record 1116 1.1 augustss *| 22 | 5 | Sec. | Phone Line 1 ADC 1117 1.1 augustss *| 23 | 6 | Sec. | Mic ADC 1118 1.1 augustss */ 1119 1.1 augustss dat32 = 0x0b << 24 | /* CRSS[4:0] Right PCM Record(primary) */ 1120 1.1 augustss 0x0a << 16 | /* CLSS[4:0] Left PCM Record(primary) */ 1121 1.1 augustss 0x01 << 8 | /* PRSS[4:0] Right PCM Playback */ 1122 1.1 augustss 0x00 << 0; /* PLSS[4:0] Left PCM Playback */ 1123 1.1 augustss BA0WRITE4(sc, CS4281_SRCSA, dat32); 1124 1.23 kent 1125 1.5 wiz /* Set interrupt to occurred at Half and Full terminal 1126 1.1 augustss * count interrupt enable for DMA channel 0 and 1. 1127 1.1 augustss * To keep DMA stop, set MSK. 1128 1.1 augustss */ 1129 1.1 augustss dat32 = DCRn_HTCIE | DCRn_TCIE | DCRn_MSK; 1130 1.1 augustss BA0WRITE4(sc, CS4281_DCR0, dat32); 1131 1.1 augustss BA0WRITE4(sc, CS4281_DCR1, dat32); 1132 1.23 kent 1133 1.61 andvar /* Set Auto-Initialize Control enable */ 1134 1.1 augustss BA0WRITE4(sc, CS4281_DMR0, 1135 1.1 augustss DMRn_DMA | DMRn_AUTO | DMRn_TR_READ); 1136 1.1 augustss BA0WRITE4(sc, CS4281_DMR1, 1137 1.1 augustss DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); 1138 1.1 augustss 1139 1.1 augustss /* Clear DMA Mask in HIMR */ 1140 1.1 augustss dat32 = ~HIMR_DMAIM & ~HIMR_D1IM & ~HIMR_D0IM; 1141 1.1 augustss BA0WRITE4(sc, CS4281_HIMR, 1142 1.1 augustss BA0READ4(sc, CS4281_HIMR) & dat32); 1143 1.4 tacha 1144 1.4 tacha /* set current status */ 1145 1.4 tacha if (init != 0) { 1146 1.4 tacha sc->sc_prun = 0; 1147 1.4 tacha sc->sc_rrun = 0; 1148 1.4 tacha } 1149 1.4 tacha 1150 1.4 tacha /* setup playback volume */ 1151 1.4 tacha BA0WRITE4(sc, CS4281_PPRVC, 7); 1152 1.4 tacha BA0WRITE4(sc, CS4281_PPLVC, 7); 1153 1.4 tacha 1154 1.1 augustss return 0; 1155 1.1 augustss } 1156