blob: 6937eb5edf6a13e836bc918ade96ecfec43db321 [file] [log] [blame]
/*******************************************************************************
Copyright (C) Marvell International Ltd. and its affiliates
********************************************************************************
Marvell GPL License Option
If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File in accordance with the terms and conditions of the General
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
available along with the File in the license.txt file or by writing to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
DISCLAIMED. The GPL License provides additional details about this warranty
disclaimer.
*******************************************************************************/
#include <common.h>
#if defined(CONFIG_CMD_I2C)
//#include <mpc8xx.h>
#include <malloc.h>
#include <config.h>
#include "twsi/mvTwsi.h"
#include "mvCtrlEnvSpec.h"
//#define MAX_I2C_RETRYS 10
#define I2C_DELAY 300 /* Should be at least the # of MHz of Tclk */
#undef DEBUG_I2C
#ifdef DEBUG_I2C
#define DP(x) x
#else
#define DP(x)
#endif
MV_U8 i2c_current_bus = 0;
MV_U32 i2c_current_speed = CONFIG_SYS_I2C_SPEED;
/*
* Initialization, must be called once on start up, may be called
* repeatedly to change the speed and slave addresses.
*/
void i2c_init(int speed, int slaveaddr)
{
MV_TWSI_ADDR slave;
slave.type = ADDR7_BIT;
slave.address = slaveaddr;
mvTwsiInit(i2c_current_bus, speed, CONFIG_SYS_TCLK, &slave, 0);
}
/*
* Read/Write interface:
* chip: I2C chip address, range 0..127
* addr: Memory (register) address within the chip
* alen: Number of bytes to use for addr (typically 1, 2 for larger
* memories, 0 for register type devices with only one
* register)
* buffer: Where to read/write the data
* len: How many bytes to read/write
*
* Returns: 0 on success, not 0 on failure
*/
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
MV_TWSI_SLAVE twsiSlave;
DP(puts("i2c_read\n"));
twsiSlave.slaveAddr.type = ADDR7_BIT;
twsiSlave.slaveAddr.address = chip;
if(alen != 0){
twsiSlave.validOffset = MV_TRUE;
twsiSlave.offset = addr;
if(alen == 2)
{
twsiSlave.moreThen256 = MV_TRUE;
}
else
{
twsiSlave.moreThen256 = MV_FALSE;
}
}
i2c_init(i2c_current_speed,0); /* set the i2c frequency */
return mvTwsiRead (i2c_current_bus, &twsiSlave, buffer, len);
}
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
MV_TWSI_SLAVE twsiSlave;
DP(puts("i2c_write\n"));
twsiSlave.slaveAddr.type = ADDR7_BIT;
twsiSlave.slaveAddr.address = chip;
if(alen != 0){
twsiSlave.validOffset = MV_TRUE;
twsiSlave.offset = addr;
if(alen == 2)
{
twsiSlave.moreThen256 = MV_TRUE;
}
else
{
twsiSlave.moreThen256 = MV_FALSE;
}
}
i2c_init(i2c_current_speed,0); /* set the i2c frequency */
return mvTwsiWrite (i2c_current_bus, &twsiSlave, buffer, len);
}
/*
* 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(i2c_current_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 */
}
/*
* i2c_set_bus_num:
*
* Change the active I2C bus. Subsequent read/write calls will
* go to this one.
*
* bus - bus index, zero based
*
* Returns: 0 on success, not 0 on failure
*
*/
int i2c_set_bus_num(unsigned int bus)
{
if (bus >= CONFIG_SYS_MAX_I2C_BUS)
return -1;
i2c_current_bus = bus;
return 0;
}
/*
* i2c_get_bus_num:
*
* Returns index of currently active I2C bus. Zero-based.
*/
unsigned int i2c_get_bus_num(void)
{
return i2c_current_bus;
}
/*
* i2c_set_bus_speed:
*
* Change the speed of the active I2C bus
*
* speed - bus speed in Hz
*
* Returns: 0 on success, not 0 on failure
*
*/
int i2c_set_bus_speed(unsigned int speed)
{
if (speed <= 0 || speed > CONFIG_SYS_I2C_SPEED) {
printf("Error: TWSI frequency speed must be under %d Khz\n", CONFIG_SYS_I2C_SPEED);
return -1;
}
i2c_current_speed = speed;
return 0;
}
/*
* i2c_get_bus_speed:
*
* Returns speed of currently active I2C bus in Hz
*/
unsigned int i2c_get_bus_speed(void)
{
return i2c_current_speed;
}
#endif