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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }