rk27xx: Turn off i2c clock when not in use

Change-Id: Ifc6c25a53ace1a5f4d716a33d4979ea0a37fac98
This commit is contained in:
Marcin Bukat 2012-08-27 23:18:31 +02:00
parent 16335da1cf
commit ae27c331e1

View file

@ -40,7 +40,7 @@ static struct mutex i2c_mtx;
static bool i2c_write_byte(uint8_t data, bool start)
{
long timeout = current_tick + 50;
long timeout = current_tick + HZ/50;
/* START */
I2C_CONR |= (1<<3) | (1<<2); /* master port enable, transmit bit */
@ -66,7 +66,7 @@ static bool i2c_write_byte(uint8_t data, bool start)
static bool i2c_read_byte(unsigned char *data)
{
long timeout = current_tick + HZ / 50;
long timeout = current_tick + HZ/50;
I2C_LCMR = (1<<2); /* resume op */
@ -84,7 +84,7 @@ static bool i2c_read_byte(unsigned char *data)
static bool i2c_stop(void)
{
long timeout = current_tick + HZ / 50;
long timeout = current_tick + HZ/50;
I2C_CONR &= ~(1<<4);
I2C_LCMR |= (1<<2) | (1<<1); /* resume op, stop */
@ -121,6 +121,8 @@ void i2c_init(void)
{
mutex_init(&i2c_mtx);
/* ungate i2c module clock */
SCU_CLKCFG &= ~(1<< 20);
I2C_OPR |= (1<<7); /* reset state machine */
@ -142,15 +144,23 @@ void i2c_init(void)
I2C_IER = 0x00;
I2C_OPR |= (1<<6); /* enable i2c core */
/* turn off i2c module clock until we need to comunicate */
SCU_CLKCFG |= (1<< 20);
}
int i2c_write(unsigned char slave, int address, int len,
const unsigned char *data)
{
int ret = 0;
mutex_lock(&i2c_mtx);
i2c_iomux(slave);
/* ungate i2c clock */
SCU_CLKCFG &= ~(1<<20);
/* clear all flags */
I2C_ISR = 0x00;
I2C_IER = 0x00;
@ -158,16 +168,16 @@ int i2c_write(unsigned char slave, int address, int len,
/* START */
if (! i2c_write_byte(slave & ~1, true))
{
mutex_unlock(&i2c_mtx);
return 1;
ret = 1;
goto end;
}
if (address >= 0)
{
if (! i2c_write_byte(address, false))
{
mutex_unlock(&i2c_mtx);
return 2;
ret = 2;
goto end;
}
}
@ -176,28 +186,35 @@ int i2c_write(unsigned char slave, int address, int len,
{
if (! i2c_write_byte(*data++, false))
{
mutex_unlock(&i2c_mtx);
return 4;
ret = 4;
goto end;
}
}
/* STOP */
if (! i2c_stop())
{
mutex_unlock(&i2c_mtx);
return 5;
ret = 5;
goto end;
}
end:
mutex_unlock(&i2c_mtx);
return 0;
SCU_CLKCFG |= (1<<20);
return ret;
}
int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
{
int ret = 0;
mutex_lock(&i2c_mtx);
i2c_iomux(slave);
/* ungate i2c module clock */
SCU_CLKCFG &= ~(1<<20);
/* clear all flags */
I2C_ISR = 0x00;
I2C_IER = 0x00;
@ -207,23 +224,23 @@ int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
/* START */
if (! i2c_write_byte(slave & ~1, true))
{
mutex_unlock(&i2c_mtx);
return 1;
ret = 1;
goto end;
}
/* write address */
if (! i2c_write_byte(address, false))
{
mutex_unlock(&i2c_mtx);
return 2;
ret = 2;
goto end;
}
}
/* (repeated) START */
if (! i2c_write_byte(slave | 1, true))
{
mutex_unlock(&i2c_mtx);
return 3;
ret = 3;
goto end;
}
I2C_CONR &= ~(1<<3); /* clear transmit bit (switch to receive mode) */
@ -232,8 +249,8 @@ int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
{
if (! i2c_read_byte(data++))
{
mutex_unlock(&i2c_mtx);
return 4;
ret = 4;
goto end;
}
if (len == 1)
@ -247,10 +264,12 @@ int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
/* STOP */
if (! i2c_stop())
{
mutex_unlock(&i2c_mtx);
return 5;
ret = 5;
goto end;
}
end:
mutex_unlock(&i2c_mtx);
return 0;
SCU_CLKCFG |= (1<<20);
return ret;
}