/******************************************************************************* * twsiInit - Initialize TWSI interface * * DESCRIPTION: * This routine: * -Reset the TWSI. * -Initialize the TWSI clock baud rate according to given frequancy * parameter based on Tclk frequancy and enables TWSI slave. * -Set the ack bit. * -Assign the TWSI slave address according to the TWSI address Type. * * * INPUT: * chanNum - TWSI channel * frequancy - TWSI frequancy in KHz. (up to 100KHZ) * * OUTPUT: * None. * * RETURN: * Actual frequancy. * *******************************************************************************/ MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable) { MV_U32 n,m,freq,margin,minMargin = 0xffffffff; MV_U32 power; MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val; if(frequancy > 100000) { mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n"); } DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy)); /* Calucalte N and M for the TWSI clock baud rate */ for(n = 0 ; n < 8 ; n++) { for(m = 0 ; m < 16 ; m++) { power = 2 << n; /* power = 2^(n+1) */ freq = Tclk/(10*(m+1)*power); margin = MV_ABS(frequancy - freq); if(margin < minMargin) { minMargin = margin; actualFreq = freq; actualN = n; actualM = m; } } } DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq)); /* Reset the TWSI logic */ twsiReset(chanNum); /* Set the baud rate */ val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS); MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val); /* Enable the TWSI and slave */ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK); /* set the TWSI slave address */ if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */ { /* writing the 2 most significant bits of the 10 bit address*/ val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS ); /* bits 7:3 must be 0x11110 */ val |= TWSI_SLAVE_ADDR_10BIT_CONST; /* set GCE bit */ if(generalCallEnable) val |= TWSI_SLAVE_ADDR_GCE_ENA; /* write slave address */ MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val); /* writing the 8 least significant bits of the 10 bit address*/ val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK; MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val); }
/******************************************************************************* * twsiInit - Initialize TWSI interface * * DESCRIPTION: * This routine: * -Reset the TWSI. * -Initialize the TWSI clock baud rate according to given frequancy * parameter based on Tclk frequancy and enables TWSI slave. * -Set the ack bit. * -Assign the TWSI slave address according to the TWSI address Type. * * INPUT: * chanNum - TWSI channel * frequancy - TWSI frequancy in KHz. (up to 100KHZ) * * OUTPUT: * None. * * RETURN: * Actual frequancy. * *******************************************************************************/ MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable) { MV_U32 n, m, freq, margin, minMargin = 0xffffffff; MV_U32 power; MV_U32 actualFreq = 0, actualN = 0, actualM = 0, val; #ifdef MV88F67XX /* set twsi MPPS */ val = (MV_REG_READ(REG_MPP_CONTROL_ADDR) | (REG_MPP_CONTROL_TWSI_VALUE << REG_MPP_CONTROL_TWSI_OFFS)); MV_REG_WRITE(REG_MPP_CONTROL_ADDR, val); #endif /* Calucalte N and M for the TWSI clock baud rate */ for (n = 0; n < 8; n++) { for (m = 0; m < 16; m++) { power = 2 << n; /* power = 2^(n+1) */ freq = Tclk / (10 * (m + 1) * power); margin = MV_ABS(frequancy - freq); if ((freq <= frequancy) && (margin < minMargin)) { minMargin = margin; actualFreq = freq; actualN = n; actualM = m; } } } /* Reset the TWSI logic */ twsiReset(chanNum); /* Set the baud rate */ val = ((actualM << TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS); MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum), val); /* Enable the TWSI and slave */ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK); /* set the TWSI slave address */ if (pTwsiAddr->type == ADDR10_BIT) { /* 10 Bit deviceAddress */ /* writing the 2 most significant bits of the 10 bit address */ val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS); /* bits 7:3 must be 0x11110 */ val |= TWSI_SLAVE_ADDR_10BIT_CONST; /* set GCE bit */ if (generalCallEnable) val |= TWSI_SLAVE_ADDR_GCE_ENA; /* write slave address */ MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val); /* writing the 8 least significant bits of the 10 bit address */ val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK; MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val); } else { /*7 bit address */
/* * Probe the given I2C chip address. Returns 0 if a chip responded, * not 0 on failure. */ int i2c_probe(uchar chip) { /* We are just looking for an <ACK> back. */ /* To see if the device/chip is there */ MV_TWSI_ADDR eepromAddress; unsigned int status = 0; //unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED; //MV_U8 i2c_current_bus; DP(puts("i2c_probe\n")); //for (i2c_current_bus = 0; i2c_current_bus < MV_TWSI_MAX_CHAN; i2c_current_bus++) { i2c_init(CONFIG_SYS_I2C_SPEED,0); /* set the i2c frequency */ status = mvTwsiStartBitSet(i2c_current_bus); if (status) { DP(printf("Transaction start failed: 0x%02x\n", status)); mvTwsiStopBitSet(i2c_current_bus); return (int)status; } eepromAddress.type = ADDR7_BIT; eepromAddress.address = chip; status = mvTwsiAddrSet(i2c_current_bus, &eepromAddress, MV_TWSI_WRITE); /* send the slave address */ if (status) { DP(printf("Failed to set slave address: 0x%02x\n", status)); mvTwsiStopBitSet(i2c_current_bus); return (int)status; } DP(printf("address %#x returned %#x\n",chip,MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(i2c_current_bus)))); /* issue a stop bit */ mvTwsiStopBitSet(i2c_current_bus); //} DP(printf("*** successful completion \n")); return 0; /* successful completion */ }