Esempio n. 1
0
/*
 * 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() */
Esempio n. 2
0
/*
 * 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);
	}
}
Esempio n. 4
0
/*
 * 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);
}
Esempio n. 5
0
/*
 * 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));
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
/*
 * 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);
}