/* * audioixp_chip_init() * * Description: * This routine initializes ATI IXP audio controller and the AC97 * codec. * * Arguments: * audioixp_state_t *state The device's state structure * * Returns: * DDI_SUCCESS The hardware was initialized properly * DDI_FAILURE The hardware couldn't be initialized properly */ static int audioixp_chip_init(audioixp_state_t *statep) { /* * put the audio controller into quiet state, everything off */ CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA); CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA); /* AC97 reset */ if (audioixp_reset_ac97(statep) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "AC97 codec reset failed"); return (DDI_FAILURE); } if (audioixp_codec_ready(statep) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "AC97 codec not ready"); return (DDI_FAILURE); } /* enable interrupts */ PUT32(IXP_AUDIO_INT, 0xffffffff); PUT32( IXP_AUDIO_INT_EN, IXP_AUDIO_INT_EN_IN_DMA_OVERFLOW | IXP_AUDIO_INT_EN_STATUS | IXP_AUDIO_INT_EN_OUT_DMA_UNDERFLOW); return (DDI_SUCCESS); } /* audioixp_chip_init() */
/* * audioixp_stop_port() * * Description: * This routine stops the DMA engine. * * Arguments: * audioixp_port_t *port Port of DMA engine to stop. */ static void audioixp_stop_port(audioixp_port_t *port) { audioixp_state_t *statep = port->statep; ASSERT(mutex_owned(&statep->inst_lock)); /* if suspended, then do nothing else */ if (statep->suspended) { return; } if (port->num == IXP_REC) { CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN); } else { CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT); } }
void radeonfb_i2c_release_bus(void *cookie, int flags) { struct radeonfb_i2c *ric = (struct radeonfb_i2c *)cookie; struct radeonfb_softc *sc = ric->ric_softc; if (ric->ric_register == RADEON_GPIO_DVI_DDC) { /* we no longer "want" I2C, and we're "done" with it */ CLR32(sc, ric->ric_register, RADEON_GPIO_SW_USE); SET32(sc, ric->ric_register, RADEON_GPIO_SW_DONE); } }
/* * audioixp_reset_ac97() * * Description: * Reset AC97 Codec register. * * Arguments: * audioixp_state_t *state The device's state structure * * Returns: * DDI_SUCCESS Reset the codec successfully * DDI_FAILURE Failed to reset the codec */ static int audioixp_reset_ac97(audioixp_state_t *statep) { uint32_t cmd; int i; CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_POWER_DOWN); drv_usecwait(10); /* register reset */ SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_AC_SOFT_RESET); /* force a read to flush caches */ (void) GET32(IXP_AUDIO_CMD); drv_usecwait(10); CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_AC_SOFT_RESET); /* cold reset */ for (i = 0; i < 300; i++) { cmd = GET32(IXP_AUDIO_CMD); if (cmd & IXP_AUDIO_CMD_AC_ACTIVE) { cmd |= IXP_AUDIO_CMD_AC_RESET | IXP_AUDIO_CMD_AC_SYNC; PUT32(IXP_AUDIO_CMD, cmd); return (DDI_SUCCESS); } cmd &= ~IXP_AUDIO_CMD_AC_RESET; cmd |= IXP_AUDIO_CMD_AC_SYNC; PUT32(IXP_AUDIO_CMD, cmd); (void) GET32(IXP_AUDIO_CMD); drv_usecwait(10); cmd |= IXP_AUDIO_CMD_AC_RESET; PUT32(IXP_AUDIO_CMD, cmd); drv_usecwait(10); } audio_dev_warn(statep->adev, "AC'97 reset timed out"); return (DDI_FAILURE); }
/* * audioixp_destroy() * * Description: * This routine releases all resources held by the device instance, * as part of either detach or a failure in attach. * * Arguments: * audioixp_state_t *state The device soft state. */ void audioixp_destroy(audioixp_state_t *statep) { if (!statep->suspended) { PUT32(IXP_AUDIO_INT, GET32(IXP_AUDIO_INT)); PUT32(IXP_AUDIO_INT_EN, 0); /* * put the audio controller into quiet state, everything off */ CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA); CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA); } if (statep->intr_added) { ddi_remove_intr(statep->dip, 0, statep->iblock); } if (statep->ksp) { kstat_delete(statep->ksp); } audioixp_free_port(statep->play_port); audioixp_free_port(statep->rec_port); audioixp_unmap_regs(statep); if (statep->ac97) { ac97_free(statep->ac97); } if (statep->adev) { audio_dev_free(statep->adev); } mutex_destroy(&statep->inst_lock); kmem_free(statep, sizeof (*statep)); }
static void audioixp_stop_dma(audioixp_state_t *statep) { CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA); CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA); }
/* * audio1575_start() * * Description: * This is called by the framework to start a port transferring data. * * Arguments: * void *arg The DMA engine to start * * Returns: * 0 on success (never fails, errno if it did) */ static int audio1575_start(void *arg) { audio1575_port_t *port = arg; audio1575_state_t *statep = port->statep; mutex_enter(&statep->lock); port->offset = 0; if (port->num == M1575_REC) { /* Uli FIFO madness ... */ SET32(M1575_FIFOCR1_REG, M1575_FIFOCR1_PCMIRST); SET32(M1575_DMACR_REG, M1575_DMACR_PCMIPAUSE); PUT8(M1575_PCMICR_REG, 0); PUT8(M1575_PCMICR_REG, M1575_CR_RR); PUT32(M1575_PCMIBDBAR_REG, port->bdl_paddr); PUT8(M1575_PCMILVIV_REG, M1575_BD_NUMS - 1); CLR32(M1575_DMACR_REG, M1575_DMACR_PCMIPAUSE); /* ULi says do fifo resets here */ SET32(M1575_FIFOCR1_REG, M1575_FIFOCR1_PCMIRST); CLR32(M1575_DMACR_REG, M1575_DMACR_PCMIPAUSE); PUT8(M1575_PCMICR_REG, 0); SET32(M1575_DMACR_REG, M1575_DMACR_PCMISTART); } else { uint32_t scr; /* Uli FIFO madness ... */ SET32(M1575_FIFOCR1_REG, M1575_FIFOCR1_PCMORST); SET32(M1575_DMACR_REG, M1575_DMACR_PCMOPAUSE); /* configure the number of channels properly */ scr = GET32(M1575_SCR_REG); scr &= ~(M1575_SCR_6CHL_MASK | M1575_SCR_CHAMOD_MASK); scr |= M1575_SCR_6CHL_2; /* select our proper ordering */ switch (port->nchan) { case 2: scr |= M1575_SCR_CHAMOD_2; break; case 4: scr |= M1575_SCR_CHAMOD_4; break; case 6: scr |= M1575_SCR_CHAMOD_6; break; } PUT32(M1575_SCR_REG, scr); PUT8(M1575_PCMOCR_REG, 0); PUT8(M1575_PCMOCR_REG, M1575_CR_RR); PUT32(M1575_PCMOBDBAR_REG, port->bdl_paddr); PUT8(M1575_PCMOLVIV_REG, M1575_BD_NUMS - 1); CLR32(M1575_DMACR_REG, M1575_DMACR_PCMOPAUSE); PUT8(M1575_PCMOCR_REG, 0); SET32(M1575_DMACR_REG, M1575_DMACR_PCMOSTART); } mutex_exit(&statep->lock); return (0); }