mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
rk27xx: fix i2c driver
Change-Id: I205cc92f452c1990c64da7e91b2baf00b920c922
This commit is contained in:
parent
dcba74155e
commit
e6c0bd0350
1 changed files with 33 additions and 21 deletions
|
|
@ -24,8 +24,6 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "i2c-rk27xx.h"
|
#include "i2c-rk27xx.h"
|
||||||
|
|
||||||
/* NOT TESTED YET */
|
|
||||||
|
|
||||||
/* Driver for the rockchip rk27xx built-in I2C controller in master mode
|
/* Driver for the rockchip rk27xx built-in I2C controller in master mode
|
||||||
|
|
||||||
Both the i2c_read and i2c_write function take the following arguments:
|
Both the i2c_read and i2c_write function take the following arguments:
|
||||||
|
|
@ -38,12 +36,26 @@
|
||||||
|
|
||||||
static struct mutex i2c_mtx;
|
static struct mutex i2c_mtx;
|
||||||
|
|
||||||
static bool i2c_write_byte(uint8_t data, bool start)
|
static bool i2c_stop(void)
|
||||||
{
|
{
|
||||||
long timeout = current_tick + HZ/50;
|
long timeout = current_tick + HZ/50;
|
||||||
|
|
||||||
/* START */
|
I2C_CONR |= (1<<4); /* NACK */
|
||||||
I2C_CONR |= (1<<3) | (1<<2); /* master port enable, transmit bit */
|
I2C_LCMR |= (1<<2) | (1<<1); /* resume op, stop */
|
||||||
|
|
||||||
|
while (I2C_LCMR & (1<<1))
|
||||||
|
if (TIME_AFTER(current_tick, timeout))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool i2c_write_byte(uint8_t data, bool start)
|
||||||
|
{
|
||||||
|
long timeout = current_tick + HZ/50;
|
||||||
|
unsigned int isr_status;
|
||||||
|
|
||||||
|
I2C_CONR = (1<<3) | (1<<2); /* master port enable, MTX mode, ACK enable */
|
||||||
I2C_MTXR = data;
|
I2C_MTXR = data;
|
||||||
|
|
||||||
if (start)
|
if (start)
|
||||||
|
|
@ -51,13 +63,23 @@ static bool i2c_write_byte(uint8_t data, bool start)
|
||||||
else
|
else
|
||||||
I2C_LCMR = (1<<2); /* resume op */
|
I2C_LCMR = (1<<2); /* resume op */
|
||||||
|
|
||||||
I2C_CONR &= ~(1<<4); /* ACK enable */
|
|
||||||
|
|
||||||
/* wait for ACK from slave */
|
/* wait for ACK from slave */
|
||||||
while ( (!(I2C_ISR & (1<<0))) || (I2C_LSR & (1<<1)) )
|
do
|
||||||
|
{
|
||||||
|
isr_status = I2C_ISR;
|
||||||
|
|
||||||
|
if (isr_status & (1<<7))
|
||||||
|
{
|
||||||
|
i2c_stop();
|
||||||
|
I2C_ISR = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (TIME_AFTER(current_tick, timeout))
|
if (TIME_AFTER(current_tick, timeout))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
} while ((isr_status & (1<<0)) == 0);
|
||||||
|
|
||||||
/* clear status bit */
|
/* clear status bit */
|
||||||
I2C_ISR &= ~(1<<0);
|
I2C_ISR &= ~(1<<0);
|
||||||
|
|
||||||
|
|
@ -82,19 +104,7 @@ static bool i2c_read_byte(unsigned char *data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool i2c_stop(void)
|
|
||||||
{
|
|
||||||
long timeout = current_tick + HZ/50;
|
|
||||||
|
|
||||||
I2C_CONR &= ~(1<<4);
|
|
||||||
I2C_LCMR |= (1<<2) | (1<<1); /* resume op, stop */
|
|
||||||
|
|
||||||
while (I2C_LCMR & (1<<1))
|
|
||||||
if (TIME_AFTER(current_tick, timeout))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* route i2c bus to internal codec or external bus
|
/* route i2c bus to internal codec or external bus
|
||||||
* internal codec has 0x4e i2c slave address so
|
* internal codec has 0x4e i2c slave address so
|
||||||
|
|
@ -202,6 +212,7 @@ int i2c_write(unsigned char slave, int address, int len,
|
||||||
end:
|
end:
|
||||||
mutex_unlock(&i2c_mtx);
|
mutex_unlock(&i2c_mtx);
|
||||||
SCU_CLKCFG |= CLKCFG_I2C;
|
SCU_CLKCFG |= CLKCFG_I2C;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +255,7 @@ int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
I2C_CONR &= ~(1<<3); /* clear transmit bit (switch to receive mode) */
|
I2C_CONR = (1<<2); /* master port enable, MRX mode, ACK enable */
|
||||||
|
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
|
@ -272,5 +283,6 @@ int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
|
||||||
end:
|
end:
|
||||||
mutex_unlock(&i2c_mtx);
|
mutex_unlock(&i2c_mtx);
|
||||||
SCU_CLKCFG |= CLKCFG_I2C;
|
SCU_CLKCFG |= CLKCFG_I2C;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue