Exemple #1
0
int drv_set_dma(u32_t dma, u32_t length, int chan) {
	/* dma length in bytes, 
	   max is 64k long words for es1371 = 256k bytes */
	u32_t page, frame_count_reg, dma_add_reg;

	switch(chan) {
		case ADC1_CHAN: page = ADC_MEM_PAGE;
						frame_count_reg = ADC_BUFFER_SIZE;
						dma_add_reg = ADC_PCI_ADDRESS;
						break;
		case DAC1_CHAN: page = DAC_MEM_PAGE;
						frame_count_reg = DAC1_BUFFER_SIZE;
						dma_add_reg = DAC1_PCI_ADDRESS;
						break;;
		case DAC2_CHAN: page = DAC_MEM_PAGE;
						frame_count_reg = DAC2_BUFFER_SIZE;
						dma_add_reg = DAC2_PCI_ADDRESS;
						break;;    
		default: return EIO;
	}
	pci_outb(reg(MEM_PAGE), page);
	pci_outl(reg(dma_add_reg), dma);

	/* device expects long word count in stead of bytes */
	length /= 4;

	/* It seems that register _CURRENT_COUNT is overwritten, but this is
	 * the way to go. The register frame_count_reg is only longword
	 * addressable.
	 * It expects length -1
	 */
	pci_outl(reg(frame_count_reg), (u32_t) (length - 1));

	return OK;
}
PUBLIC int drv_init_hw (void) {
	u16_t i, j;
	u16_t chip_sel_ctrl_reg;

	/* First, detect the hardware */
	if (detect_hw() != OK) {
		return EIO;
	}

	/* PCI command register 
	 * enable the SERR# driver, PCI bus mastering and I/O access
	 */
	pci_attr_w16 (dev.devind, PCI_CR, SERR_EN|PCI_MASTER|IO_ACCESS);

	/* turn everything off */
	pci_outl(reg(CHIP_SEL_CTRL),  0x0UL);

	/* turn off legacy (legacy control is undocumented) */
	pci_outl(reg(LEGACY), 0x0UL);
	pci_outl(reg(LEGACY+4), 0x0UL);

	/* turn off serial interface */
	pci_outl(reg(SERIAL_INTERFACE_CTRL), 0x0UL);
	/*pci_outl(reg(SERIAL_INTERFACE_CTRL), 0x3UL);*/


	/* enable the codec */
	chip_sel_ctrl_reg = pci_inw(reg(CHIP_SEL_CTRL));
	chip_sel_ctrl_reg |= XCTL0 | CDC_EN; 
	pci_outw(reg(CHIP_SEL_CTRL), chip_sel_ctrl_reg);

	/* initialize the codec */
	if (ak4531_init(reg(CODEC_WRITE_ADDRESS), 
				reg(INTERRUPT_STATUS), CWRIP, reg(0)) < 0) {
		return EINVAL;
	}

	/* clear all the memory */
	for (i = 0; i < 0x10; ++i) {
		pci_outb(reg(MEM_PAGE), i);
		for (j = 0; j < 0x10; j += 4) {
			pci_outl  (reg(MEMORY) + j, 0x0UL);
		}
	}

	/* initialize variables for each sub_device */
	for (i = 0; i < drv.NrOfSubDevices; i++) {
		if(i != MIXER) {
			aud_conf[i].busy = 0;
			aud_conf[i].stereo = DEFAULT_STEREO;
			aud_conf[i].sample_rate = DEFAULT_RATE;
			aud_conf[i].nr_of_bits = DEFAULT_NR_OF_BITS;
			aud_conf[i].sign = DEFAULT_SIGNED;
			aud_conf[i].fragment_size = 
				sub_dev[i].DmaSize / sub_dev[i].NrOfDmaFragments;
		}
	}
	return OK;
}
Exemple #3
0
int drv_init_hw (void) {
	u16_t i, j;

	/* First, detect the hardware */
	if (detect_hw() != OK) {
		return EIO;
	}

	/* PCI command register 
	 * enable the SERR# driver, PCI bus mastering and I/O access
	 */
	pci_attr_w16 (dev.devind, PCI_CR, SERR_EN|PCI_MASTER|IO_ACCESS);

	/* turn everything off */
	pci_outl(reg(CHIP_SEL_CTRL),  0x0UL);

	/* turn off legacy (legacy control is undocumented) */
	pci_outl(reg(LEGACY), 0x0UL);
	pci_outl(reg(LEGACY+4), 0x0UL);

	/* turn off serial interface */
	pci_outl(reg(SERIAL_INTERFACE_CTRL), 0x0UL);
	/*pci_outl(reg(SERIAL_INTERFACE_CTRL), 0x3UL);*/


	/* clear all the memory */
	for (i = 0; i < 0x10; ++i) {
		pci_outb(reg(MEM_PAGE), i);
		for (j = 0; j < 0x10; j += 4) {
			pci_outl  (reg(MEMORY) + j, 0x0UL);
		}
	}

	/* Sample Rate Converter initialization */
	if (src_init(&dev) != OK) {
		return EIO;
	}
	if (AC97_init(&dev) != OK) {
		return EIO;
	}

	/* initialize variables for each sub_device */
	for (i = 0; i < drv.NrOfSubDevices; i++) {
		if(i != MIXER) {
			aud_conf[i].busy = 0;
			aud_conf[i].stereo = DEFAULT_STEREO;
			aud_conf[i].sample_rate = DEFAULT_RATE;
			aud_conf[i].nr_of_bits = DEFAULT_NR_OF_BITS;
			aud_conf[i].sign = DEFAULT_SIGNED;
			aud_conf[i].fragment_size = 
				sub_dev[i].DmaSize / sub_dev[i].NrOfDmaFragments;
		}
	}
	return OK;
}
Exemple #4
0
static int AC97_write_unsynced (const DEV_STRUCT * pCC, u16_t wAddr,
    u16_t wData)
{
    /* wait for WIP to go away */
    if (WaitBitd (pCC->base + CODEC_READ, 30, 0, WIP_TIMEOUT))
        return (AC97_ERR_WIP_TIMEOUT);

    /* write addr and data */
    pci_outl(pCC->base + CODEC_READ, ((u32_t) wAddr << 16) | wData);
    return 0;
}
PRIVATE int set_sample_rate(u32_t rate, int sub_dev) {
	/* currently only 44.1kHz */
	u32_t controlRegister;

	if (rate > MAX_RATE || rate < MIN_RATE) {
		return EINVAL;
	}

	controlRegister = pci_inl(reg(CHIP_SEL_CTRL));
	controlRegister |= FREQ_44K100;
	pci_outl(reg(CHIP_SEL_CTRL), controlRegister);

	aud_conf[sub_dev].sample_rate = rate;

	return OK;
}
Exemple #6
0
int drv_resume(int sub_dev) {
	u32_t pause_bit = 0;

	drv_reenable_int(sub_dev); /* enable interrupts */

	switch(sub_dev) {
		case DAC1_CHAN: pause_bit = P1_PAUSE;break;
		case DAC2_CHAN: pause_bit = P2_PAUSE;break;    
		default: return EINVAL;
	}

	/* clear pause bit */
	pci_outl(reg(SERIAL_INTERFACE_CTRL),
			pci_inl(reg(SERIAL_INTERFACE_CTRL)) & ~pause_bit);

	return OK;
}
Exemple #7
0
int drv_pause(int sub_dev) { 
	u32_t pause_bit;

	disable_int(sub_dev); /* don't send interrupts */

	switch(sub_dev) {
		case DAC1_CHAN: pause_bit = P1_PAUSE;break;
		case DAC2_CHAN: pause_bit = P2_PAUSE;break;    
		default: return EINVAL;
	}

	/* pause */
	pci_outl(reg(SERIAL_INTERFACE_CTRL),
			pci_inl(reg(SERIAL_INTERFACE_CTRL)) | pause_bit);

	return OK;
}
Exemple #8
0
static int AC97_read_unsynced (const DEV_STRUCT * pCC, u16_t wAddr,
    u16_t *data)
{
u32_t dtemp;

    /* wait for WIP to go away */
    if (WaitBitd (pCC->base + CODEC_READ, 30, 0, WIP_TIMEOUT))
        return (AC97_ERR_WIP_TIMEOUT);

    /* write addr w/data=0 and assert read request */
    pci_outl(pCC->base + CODEC_READ, ((u32_t) wAddr << 16) | (1UL << 23));

    /* now wait for the stinkin' data (RDY) */
    if (WaitBitd (pCC->base + CODEC_READ, 31, 1, DRDY_TIMEOUT))
        return (AC97_ERR_DATA_TIMEOUT);

    dtemp = pci_inl(pCC->base + CODEC_READ);

    if (data)
        *data = (u16_t) dtemp;

    return 0;
}
Exemple #9
0
static int AC97_write (const DEV_STRUCT * pCC, u16_t wAddr, u16_t wData)
{
u32_t dtemp, i;
u16_t  wBaseAddr = pCC->base;

    /* wait for WIP bit (Write In Progress) to go away */
    /* remember, register CODEC_READ (0x14) 
       is a pseudo read-write register */
    if (WaitBitd (wBaseAddr + CODEC_READ, 30, 0, WIP_TIMEOUT)){
        printf("AC97_ERR_WIP_TIMEOUT\n");
        return (AC97_ERR_WIP_TIMEOUT);
    }
    if (SRC_UNSYNCED != SrcSyncState)
    {
        /* enable SRC state data in SRC mux */
        if (WaitBitd (wBaseAddr + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
            return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);

        /* todo: why are we writing an undefined register? */
        dtemp = pci_inl(wBaseAddr + SAMPLE_RATE_CONV);
        pci_outl(wBaseAddr + SAMPLE_RATE_CONV, (dtemp & SRC_CTLMASK) |
                0x00010000UL);

        /* wait for a SAFE time to write addr/data and then do it */
        /*_disable(); */
        for( i = 0; i < 0x1000UL; ++i )
            if( (pci_inl(wBaseAddr + SAMPLE_RATE_CONV) & 0x00070000UL) ==
                    SrcSyncState )
            break;

        if (i >= 0x1000UL) {
            /* _enable(); */
            return (AC97_ERR_SRC_SYNC_TIMEOUT);
        }
    }

    /* A test for 5880 - prime the PCI data bus */
    {
        u32_t dat = ((u32_t) wAddr << 16) | wData;
        char page = pci_inb(wBaseAddr + MEM_PAGE);

        pci_outl (wBaseAddr + MEM_PAGE, dat);

        /* write addr and data */
        pci_outl(wBaseAddr + CODEC_READ, dat);

        pci_outb(wBaseAddr + MEM_PAGE, page);  /* restore page reg */
    }

    if (SRC_UNSYNCED != SrcSyncState)
    {
         /* _enable(); */

        /* restore SRC reg */
        if (WaitBitd (wBaseAddr + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
            return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);

        pci_outl(wBaseAddr + SAMPLE_RATE_CONV, dtemp & 0xfff8ffffUL);
    }

    return 0;
}
Exemple #10
0
static int AC97_read (const DEV_STRUCT * pCC, u16_t wAddr, u16_t *data)
{
u32_t dtemp, i;
u16_t  base = pCC->base;

    /* wait for WIP to go away */
    if (WaitBitd (base + CODEC_READ, 30, 0, WIP_TIMEOUT))
        return (AC97_ERR_WIP_TIMEOUT);

    if (SRC_UNSYNCED != SrcSyncState) 
    {
        /* enable SRC state data in SRC mux */
        if (WaitBitd (base + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
            return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);

        dtemp = pci_inl(base + SAMPLE_RATE_CONV);
        pci_outl(base + SAMPLE_RATE_CONV, (dtemp & SRC_CTLMASK) |
                0x00010000UL);

        /* wait for a SAFE time to write a read request and then do it */
        /* todo: how do we solve the lock() problem? */
        /* _disable(); */
        for( i = 0; i < 0x1000UL; ++i )
            if( (pci_inl(base + SAMPLE_RATE_CONV) & 0x00070000UL) ==
                    SrcSyncState )
            break;

        if (i >= 0x1000UL) {
            /*_enable();*/
            return (AC97_ERR_SRC_SYNC_TIMEOUT);
        }
    }

    /* A test for 5880 - prime the PCI data bus */
    { 
        /* set bit 23, this means read in stead of write. */
        u32_t dat = ((u32_t) wAddr << 16) | (1UL << 23);
        char page = pci_inb(base + MEM_PAGE);

        /* todo: why are we putting data in the mem page register??? */
        pci_outl(base + MEM_PAGE, dat);

        /* write addr w/data=0 and assert read request */
        pci_outl(base + CODEC_READ, dat);

        pci_outb(base + MEM_PAGE, page);  /* restore page reg */
    
    }
    if (SRC_UNSYNCED != SrcSyncState) 
    {
    
        /*_enable();*/

        /* restore SRC reg */
        if (WaitBitd (base + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
            return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);

        pci_outl(base + SAMPLE_RATE_CONV, dtemp & 0xfff8ffffUL);
    }

    /* now wait for the stinkin' data (DRDY = data ready) */
    if (WaitBitd (base + CODEC_READ, 31, 1, DRDY_TIMEOUT))
        return (AC97_ERR_DATA_TIMEOUT);

    dtemp = pci_inl(base + CODEC_READ);

    if (data)
        *data = (u16_t) dtemp;

    return 0;
}
void ahi_pci_outl(ULONG value, ULONG addr, APTR dev)
{
  pci_outl(SWAPLONG(value), addr);
}