int drv_int(int sub_dev) { u32_t int_status; u32_t bit; /* return status of interrupt bit of specified channel*/ switch (sub_dev) { case DAC1_CHAN: bit = DAC1;break; case DAC2_CHAN: bit = DAC2;break; case ADC1_CHAN: bit = ADC;break; default: return EINVAL; } int_status = pci_inl(reg(INTERRUPT_STATUS)) & bit; return int_status; }
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; }
/* return status of the interrupt summary bit */ int drv_int_sum(void) { return pci_inl(reg(INTERRUPT_STATUS)) & INTR; }
ULONG ahi_pci_inl(ULONG addr, APTR dev) { return SWAPLONG(pci_inl(addr)); }