static int iga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fb_info) { /* * Set a single color register. The values supplied are * already rounded down to the hardware's capabilities * (according to the entries in the `var' structure). Return * != 0 for invalid regno. */ struct fb_info_iga *info = (struct fb_info_iga*) fb_info; if (regno >= info->video_cmap_len) return 1; info->palette[regno].red = red; info->palette[regno].green = green; info->palette[regno].blue = blue; pci_outb(info, regno, DAC_W_INDEX); pci_outb(info, red, DAC_DATA); pci_outb(info, green, DAC_DATA); pci_outb(info, blue, DAC_DATA); if (regno < 16) { switch (default_var.bits_per_pixel) { #ifdef FBCON_HAS_CFB16 case 16: info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno; break; #endif #ifdef FBCON_HAS_CFB24 case 24: info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno; break; #endif #ifdef FBCON_HAS_CFB32 case 32: { int i; i = (regno << 8) | regno; info->fbcon_cmap.cfb32[regno] = (i << 16) | i; } break; #endif } } return 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; }
DMPAPI(void) pci_Out8(void* handle, unsigned char offset, unsigned char val) { PCI_BASE_t* base = (PCI_BASE_t*)handle; io_DisableINT(); pci_outb(base->addr + (unsigned long)offset, val); io_RestoreINT(); }
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; }
static void write_sid(unsigned char reg, unsigned char data) { unsigned char cmd; cmd = reg & 0x1f; // Write command & address if (sid_NTSC) { cmd |= 0x40; // Make sure its correct frequency } // Write data to the SID pci_outb(data, CWbase + CW_SID_DAT); pci_outb(cmd, CWbase + CW_SID_CMD); // Waste 1ms pci_inb(CWbase + CW_SID_DAT); pci_inb(CWbase + CW_SID_DAT); }
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; }
/* * Very important functionality for the JavaEngine1 computer: * make screen border black (usign special IGA registers) */ static void iga_blank_border(struct fb_info_iga *info) { int i; #if 0 /* * PROM does this for us, so keep this code as a reminder * about required read from 0x3DA and writing of 0x20 in the end. */ (void) pci_inb(info, 0x3DA); /* required for every access */ pci_outb(info, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL); (void) pci_inb(info, IGA_ATTR_CTL+1); pci_outb(info, 0x38, IGA_ATTR_CTL); pci_outb(info, 0x20, IGA_ATTR_CTL); /* re-enable visual */ #endif /* * This does not work as it was designed because the overscan * color is looked up in the palette. Therefore, under X11 * overscan changes color. */ for (i=0; i < 3; i++) iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i); }
static unsigned char read_sid(unsigned char reg) { unsigned char cmd; cmd = (reg & 0x1f) | 0x20; // Read command & address if (sid_NTSC) { cmd |= 0x40; // Make sure its correct frequency } // Write command to the SID pci_outb(cmd, CWbase + CW_SID_CMD); // Waste 1ms pci_inb(CWbase + CW_SID_DAT); pci_inb(CWbase + CW_SID_DAT); return pci_inb(CWbase + CW_SID_DAT); }
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_outb(UBYTE value, ULONG addr, APTR dev) { pci_outb(value, addr); }
DMPAPI(void) pci_Out8(void* handle, unsigned char offset, unsigned char val) { PCI_BASE_t* base = (PCI_BASE_t*)handle; pci_outb(base->addr + (unsigned long)offset, val); }
int cw_openpci_open(void) { static int atexitinitialized = 0; unsigned int i; unsigned char bus = 0; if (!pci_lib_loaded) { return -1; } if (atexitinitialized) { cw_openpci_close(); } bus = pci_bus(); if (!bus) { log_message(LOG_DEFAULT, "No PCI bus found\n"); return -1; } dev = pci_find_device(0xe159, 0x0001, NULL); if (dev == NULL) { log_message(LOG_DEFAULT, "Unable to find a Catweasel Mk3 PCI card\n"); return -1; } #if defined(pci_obtain_card) && defined(pci_release_card) /* Lock the device, since we're a driver */ CWLock = pci_obtain_card(dev); if (!CWLock) { log_message(LOG_DEFAULT, "Unable to lock the catweasel. Another driver may have an exclusive lock\n" ); return -1; } #endif CWbase = dev->base_address[0]; // Reset the catweasel PCI interface (as per the CW programming docs) pci_outb(0xf1, CWbase + 0x00); pci_outb(0x00, CWbase + 0x01); pci_outb(0x00, CWbase + 0x02); pci_outb(0x00, CWbase + 0x04); pci_outb(0x00, CWbase + 0x05); pci_outb(0x00, CWbase + 0x29); pci_outb(0x00, CWbase + 0x2b); /* mute all sids */ memset(sidbuf, 0, sizeof(sidbuf)); for (i = 0; i < sizeof(sidbuf); i++) { write_sid(i, 0); } log_message(LOG_DEFAULT, "CatWeasel MK3 PCI SID: opened"); /* install exit handler, so device is closed on exit */ if (!atexitinitialized) { atexitinitialized = 1; atexit((voidfunc_t)cw_openpci_close); } sidfh = 1; /* ok */ return 1; }
static inline void iga_outb(struct fb_info_iga *info, unsigned char val, unsigned int reg, unsigned int idx ) { pci_outb(info, idx, reg); pci_outb(info, val, reg+1); }
static inline unsigned int iga_inb(struct fb_info_iga *info, unsigned int reg, unsigned int idx ) { pci_outb(info, idx, reg); return pci_inb(info, reg + 1); }