static void ak4396_write_word(struct CardData *card, unsigned int data) { int i; for (i = 0; i < 16; i++) { SetGPIOBits(card, AK4396_CCLK, 0); MicroDelay(1); SetGPIOBits(card, AK4396_CDTI, data & 0x8000); MicroDelay(1); SetGPIOBits(card, AK4396_CCLK, 1); MicroDelay(1); data <<= 1; } }
/*! * \brief Receive an Ethernet frame. * * \param tms Return with timeout after the specified * number of waiting loops. On a 14 Mhz ATmega * this value represents approximately the number * of milliseconds to wait. * * \return The number of bytes received, 0 on timeout * or -1 in case of a failure. */ int EtherInput(u_short type, u_short tms) { register u_short fsw; register u_char *buf; u_short fbc; /* Check the fifo empty bit. If it is set, then there is nothing in the receiver fifo. */ nic_bs(2); while (tms--) { if ((nic_inw(NIC_FIFO) & 0x8000) == 0) { break; } MicroDelay(1000); } if (nic_inw(NIC_FIFO) & 0x8000) { return 0; } /* Inialize pointer register. */ nic_outw(NIC_PTR, PTR_READ | PTR_RCV | PTR_AUTO_INCR); MicroDelay(1); /* Read status word and byte count. */ fsw = nic_inw(NIC_DATA); fbc = nic_inw(NIC_DATA) - 3; /* Check for frame errors. */ if ((fsw & 0xAC00) == 0) { DEBUG("\nRx("); DEBUGUSHORT(fbc); DEBUG(")"); if(fbc > sizeof(rframe)) { fbc = sizeof(rframe); } /* Perform the read. */ buf = (u_char *) & rframe; fsw = fbc; while (fsw--) { *buf++ = nic_inlb(NIC_DATA); } } else { fbc = -1; } /* Release the packet. */ nic_outlb(NIC_MMUCR, MMU_TOP); return fbc; }
/* stop callback for PHASE88, needs to deselect chip mask */ void Phase88_ak4524_unlock(struct CardData *card, int chip) { RestoreGPIOStatus(card); MicroDelay(1); Phase88_CS(card, 0x0f); }
void Phase88_akm4xxx_write(struct CardData *card, int chip, unsigned char addr, unsigned char data) { unsigned int tmp; int idx; unsigned int addrdata; if (!(chip >= 0 && chip < 4)) return; Phase88_ak4524_lock(card, chip); tmp = ReadCCI(card, CCI_GPIO_DATA); tmp |= PHASE88_RW; /* build I2C address + data byte */ addrdata = (2 << 6) | 0x20 | (addr & 0x1f); addrdata = (addrdata << 8) | data; for (idx = 15; idx >= 0; idx--) { /* drop clock */ tmp &= ~PHASE88_CLOCK; WriteCCI(card, CCI_GPIO_DATA, tmp); MicroDelay(1); /* set data */ if (addrdata & (1 << idx)) tmp |= PHASE88_DATA; else tmp &= ~PHASE88_DATA; WriteCCI(card, CCI_GPIO_DATA, tmp); MicroDelay(1); /* raise clock */ tmp |= PHASE88_CLOCK; WriteCCI(card, CCI_GPIO_DATA, tmp); MicroDelay(1); } /* assert a cs pulse to trigger */ WriteCCI(card, CCI_GPIO_DATA, tmp); MicroDelay(1); Phase88_ak4524_unlock(card, chip); }
/*! * \brief Wait until MMU is ready. * * Poll the MMU command register until \ref MMUCR_BUSY * is cleared. * * \param tmo Timeout in milliseconds. * * \return 0 on success or -1 on timeout. */ static int NicMmuWait(u_short tmo) { while (tmo--) { if ((nic_inlb(NIC_MMUCR) & MMUCR_BUSY) == 0) break; MicroDelay(1000); } return tmo ? 0 : -1; }
// Write data to the SDA line and clock to the SCL static void Phase88_Write_CLK_SDA(struct CardData *card, int clk, int data) { unsigned char tmp = 0; if (clk) tmp |= PHASE88_CLOCK; if (data) tmp |= PHASE88_DATA; WriteCCI(card, CCI_GPIO_DATA, tmp); MicroDelay(5); }
static int Revo51_GetDataBit(struct CardData *card, int ack) { int bit; if (ack) MicroDelay(5); // get data bit from the GPIO pines card->gpio_dir &= ~REVO51_I2C_DATA; SetGPIODir(card->pci_dev, card, card->gpio_dir); bit = GetGPIOData(card->pci_dev, card->iobase) & REVO51_I2C_DATA ? 1 : 0; return bit; }
// Write data to the SDA line and clock to the SCL static void Revo51_Write_CLK_SDA(struct CardData *card, int clk, int data) { unsigned int val = 0, mask = REVO51_I2C_CLOCK | REVO51_I2C_DATA;; if (clk) val |= REVO51_I2C_CLOCK; if (data) val |= REVO51_I2C_DATA; card->gpio_dir |= mask; SetGPIODir(card->pci_dev, card, card->gpio_dir); SetGPIOMask(card->pci_dev, card->iobase, ~mask); SetGPIOData(card->pci_dev, card->iobase, mask & val); MicroDelay(5); }
static void ak4396_write(struct CardData *card, unsigned int reg, unsigned int data) { unsigned int block; SaveGPIO(card->pci_dev, card); SetGPIODir(card->pci_dev, card, AK4396_CSN|AK4396_CCLK|AK4396_CDTI); SetGPIOMask(card->pci_dev, card->iobase, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI)); /* latch must be low when writing */ SetGPIOBits(card, AK4396_CSN, 0); block = ((AK4396_ADDR & 0x03) << 14) | (1 << 13) | ((reg & 0x1f) << 8) | (data & 0xff); ak4396_write_word(card, block); /* REGISTER ADDRESS */ /* release latch */ SetGPIOBits(card, AK4396_CSN, 1); MicroDelay(1); /* restore */ RestoreGPIO(card->pci_dev, card); }
/* * initialize the chip */ void ProdigyHD2_Init(struct CardData *card) { static unsigned short ak4396_inits[] = { AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */ AK4396_CTRL2, 0x02, AK4396_CTRL3, 0x00, AK4396_LCH_ATT, 0xFF, AK4396_RCH_ATT, 0xFF, }; int i; /* initialize ak4396 codec */ /* reset codec */ ak4396_write(card, AK4396_CTRL1, 0x86); MicroDelay(100); ak4396_write(card, AK4396_CTRL1, 0x87); for (i = 0; i < 10; i += 2) ak4396_write(card, ak4396_inits[i], ak4396_inits[i+1]); }
static int Phase88_GetDataBit(struct CardData *card, int ack) { int bit; //set RW to read mode WriteCCI(card, CCI_GPIO_MASK, ~PHASE88_RW); // clear rw mask first WriteCCI(card, CCI_GPIO_DATA, 0); // set to read if (ack) MicroDelay(5); // get data bit from the GPIO pines bit = ReadCCI(card, CCI_GPIO_DATA) & PHASE88_DATA ? 1 : 0; /* set RW pin to high */ WriteCCI(card, CCI_GPIO_DATA, PHASE88_RW); // set to write /* reset write mask */ WriteCCI(card, CCI_GPIO_MASK, ~PHASE88_CLOCK); return bit; }
Result HcdChannelSendWaitOne(struct UsbDevice *device, struct UsbPipeAddress *pipe, u8 channel, void* buffer, u32 bufferLength, u32 bufferOffset, struct UsbDeviceRequest *request) { Result result; u32 timeout, tries, globalTries, actualTries; for (globalTries = 0, actualTries = 0; globalTries < 3 && actualTries < 10; globalTries++, actualTries++) { SetReg(&Host->Channel[channel].Interrupt); WriteThroughReg(&Host->Channel[channel].Interrupt); ReadBackReg(&Host->Channel[channel].TransferSize); ReadBackReg(&Host->Channel[channel].SplitControl); HcdTransmitChannel(channel, (u8*)buffer + bufferOffset); timeout = 0; do { if (timeout++ == RequestTimeout) { LOGF("HCD: Request to %s has timed out.\n", UsbGetDescription(device)); device->Error = ConnectionError; return ErrorTimeout; } ReadBackReg(&Host->Channel[channel].Interrupt); if (!Host->Channel[channel].Interrupt.Halt) MicroDelay(10); else break; } while (true); ReadBackReg(&Host->Channel[channel].TransferSize); if (Host->Channel[channel].SplitControl.SplitEnable) { if (Host->Channel[channel].Interrupt.Acknowledgement) { for (tries = 0; tries < 3; tries++) { SetReg(&Host->Channel[channel].Interrupt); WriteThroughReg(&Host->Channel[channel].Interrupt); ReadBackReg(&Host->Channel[channel].SplitControl); Host->Channel[channel].SplitControl.CompleteSplit = true; WriteThroughReg(&Host->Channel[channel].SplitControl); Host->Channel[channel].Characteristic.Enable = true; Host->Channel[channel].Characteristic.Disable = false; WriteThroughReg(&Host->Channel[channel].Characteristic); timeout = 0; do { if (timeout++ == RequestTimeout) { LOGF("HCD: Request split completion to %s has timed out.\n", UsbGetDescription(device)); device->Error = ConnectionError; return ErrorTimeout; } ReadBackReg(&Host->Channel[channel].Interrupt); if (!Host->Channel[channel].Interrupt.Halt) MicroDelay(100); else break; } while (true); if (!Host->Channel[channel].Interrupt.NotYet) break; } if (tries == 3) { MicroDelay(25000); continue; } else if (Host->Channel[channel].Interrupt.NegativeAcknowledgement) { globalTries--; MicroDelay(25000); continue; } else if (Host->Channel[channel].Interrupt.TransactionError) { MicroDelay(25000); continue; } if ((result = HcdChannelInterruptToError(device, Host->Channel[channel].Interrupt, false)) != OK) { LOG_DEBUGF("HCD: Control message to %#x: %02x%02x%02x%02x %02x%02x%02x%02x.\n", *(u32*)pipe, ((u8*)request)[0], ((u8*)request)[1], ((u8*)request)[2], ((u8*)request)[3], ((u8*)request)[4], ((u8*)request)[5], ((u8*)request)[6], ((u8*)request)[7]); LOGF("HCD: Request split completion to %s failed.\n", UsbGetDescription(device)); return result; } } else if (Host->Channel[channel].Interrupt.NegativeAcknowledgement) { globalTries--; MicroDelay(25000); continue; } else if (Host->Channel[channel].Interrupt.TransactionError) { MicroDelay(25000); continue; } } else { if ((result = HcdChannelInterruptToError(device, Host->Channel[channel].Interrupt, !Host->Channel[channel].SplitControl.SplitEnable)) != OK) { LOG_DEBUGF("HCD: Control message to %#x: %02x%02x%02x%02x %02x%02x%02x%02x.\n", *(u32*)pipe, ((u8*)request)[0], ((u8*)request)[1], ((u8*)request)[2], ((u8*)request)[3], ((u8*)request)[4], ((u8*)request)[5], ((u8*)request)[6], ((u8*)request)[7]); LOGF("HCD: Request to %s failed.\n", UsbGetDescription(device)); return ErrorRetry; } } break; } if (globalTries == 3 || actualTries == 10) { LOGF("HCD: Request to %s has failed 3 times.\n", UsbGetDescription(device)); if ((result = HcdChannelInterruptToError(device, Host->Channel[channel].Interrupt, !Host->Channel[channel].SplitControl.SplitEnable)) != OK) { LOG_DEBUGF("HCD: Control message to %#x: %02x%02x%02x%02x %02x%02x%02x%02x.\n", *(u32*)pipe, ((u8*)request)[0], ((u8*)request)[1], ((u8*)request)[2], ((u8*)request)[3], ((u8*)request)[4], ((u8*)request)[5], ((u8*)request)[6], ((u8*)request)[7]); LOGF("HCD: Request to %s failed.\n", UsbGetDescription(device)); return result; } device->Error = ConnectionError; return ErrorTimeout; } return OK; }