I2C overhaul part 2

This commit is contained in:
RichardG867
2020-11-20 19:23:14 -03:00
parent 886dbe09ea
commit 739fdc46cc
20 changed files with 430 additions and 641 deletions

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Implement the I2C bus and its operations.
* Implementation of the I2C bus and its operations.
*
*
*
@@ -30,17 +30,10 @@
typedef struct _i2c_ {
void (*read_quick)(void *bus, uint8_t addr, void *priv);
uint8_t (*read_byte)(void *bus, uint8_t addr, void *priv);
uint8_t (*read_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv);
uint16_t (*read_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv);
uint8_t (*read_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv);
void (*write_quick)(void *bus, uint8_t addr, void *priv);
void (*write_byte)(void *bus, uint8_t addr, uint8_t val, void *priv);
void (*write_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t val, void *priv);
void (*write_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint16_t val, void *priv);
void (*write_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv);
void (*start)(void *bus, uint8_t addr, void *priv);
uint8_t (*read)(void *bus, uint8_t addr, void *priv);
uint8_t (*write)(void *bus, uint8_t addr, uint8_t data, void *priv);
void (*stop)(void *bus, uint8_t addr, void *priv);
void *priv;
@@ -55,7 +48,7 @@ typedef struct {
void *i2c_smbus;
#define ENABLE_I2C_LOG 1
#ifdef ENABLE_I2C_LOG
int i2c_do_log = ENABLE_I2C_LOG;
@@ -100,16 +93,10 @@ i2c_removebus(void *bus_handle)
void
i2c_sethandler(void *bus_handle, uint8_t base, int size,
void (*read_quick)(void *bus, uint8_t addr, void *priv),
uint8_t (*read_byte)(void *bus, uint8_t addr, void *priv),
uint8_t (*read_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv),
uint16_t (*read_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv),
uint8_t (*read_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv),
void (*write_quick)(void *bus, uint8_t addr, void *priv),
void (*write_byte)(void *bus, uint8_t addr, uint8_t val, void *priv),
void (*write_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t val, void *priv),
void (*write_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint16_t val, void *priv),
void (*write_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv),
void (*start)(void *bus, uint8_t addr, void *priv),
uint8_t (*read)(void *bus, uint8_t addr, void *priv),
uint8_t (*write)(void *bus, uint8_t addr, uint8_t data, void *priv),
void (*stop)(void *bus, uint8_t addr, void *priv),
void *priv)
{
int c;
@@ -131,15 +118,10 @@ i2c_sethandler(void *bus_handle, uint8_t base, int size,
q->prev = NULL;
}
q->read_byte = read_byte;
q->read_byte_cmd = read_byte_cmd;
q->read_word_cmd = read_word_cmd;
q->read_block_cmd = read_block_cmd;
q->write_byte = write_byte;
q->write_byte_cmd = write_byte_cmd;
q->write_word_cmd = write_word_cmd;
q->write_block_cmd = write_block_cmd;
q->start = start;
q->read = read;
q->write = write;
q->stop = stop;
q->priv = priv;
q->next = NULL;
@@ -151,16 +133,10 @@ i2c_sethandler(void *bus_handle, uint8_t base, int size,
void
i2c_removehandler(void *bus_handle, uint8_t base, int size,
void (*read_quick)(void *bus, uint8_t addr, void *priv),
uint8_t (*read_byte)(void *bus, uint8_t addr, void *priv),
uint8_t (*read_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv),
uint16_t (*read_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv),
uint8_t (*read_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv),
void (*write_quick)(void *bus, uint8_t addr, void *priv),
void (*write_byte)(void *bus, uint8_t addr, uint8_t val, void *priv),
void (*write_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t val, void *priv),
void (*write_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint16_t val, void *priv),
void (*write_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv),
void (*start)(void *bus, uint8_t addr, void *priv),
uint8_t (*read)(void *bus, uint8_t addr, void *priv),
uint8_t (*write)(void *bus, uint8_t addr, uint8_t data, void *priv),
void (*stop)(void *bus, uint8_t addr, void *priv),
void *priv)
{
int c;
@@ -176,11 +152,7 @@ i2c_removehandler(void *bus_handle, uint8_t base, int size,
continue;
while(p) {
q = p->next;
if ((p->read_byte == read_byte) && (p->read_byte_cmd == read_byte_cmd) &&
(p->read_word_cmd == read_word_cmd) && (p->read_block_cmd == read_block_cmd) &&
(p->write_byte == write_byte) && (p->write_byte_cmd == write_byte_cmd) &&
(p->write_word_cmd == write_word_cmd) && (p->write_block_cmd == write_block_cmd) &&
(p->priv == priv)) {
if ((p->read == read) && (p->write == write) && (p->priv == priv)) {
if (p->prev)
p->prev->next = p->next;
else
@@ -201,22 +173,16 @@ i2c_removehandler(void *bus_handle, uint8_t base, int size,
void
i2c_handler(int set, void *bus_handle, uint8_t base, int size,
void (*read_quick)(void *bus, uint8_t addr, void *priv),
uint8_t (*read_byte)(void *bus, uint8_t addr, void *priv),
uint8_t (*read_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv),
uint16_t (*read_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, void *priv),
uint8_t (*read_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv),
void (*write_quick)(void *bus, uint8_t addr, void *priv),
void (*write_byte)(void *bus, uint8_t addr, uint8_t val, void *priv),
void (*write_byte_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t val, void *priv),
void (*write_word_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint16_t val, void *priv),
void (*write_block_cmd)(void *bus, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv),
void (*start)(void *bus, uint8_t addr, void *priv),
uint8_t (*read)(void *bus, uint8_t addr, void *priv),
uint8_t (*write)(void *bus, uint8_t addr, uint8_t data, void *priv),
void (*stop)(void *bus, uint8_t addr, void *priv),
void *priv)
{
if (set)
i2c_sethandler(bus_handle, base, size, read_quick, read_byte, read_byte_cmd, read_word_cmd, read_block_cmd, write_quick, write_byte, write_byte_cmd, write_word_cmd, write_block_cmd, priv);
i2c_sethandler(bus_handle, base, size, start, read, write, stop, priv);
else
i2c_removehandler(bus_handle, base, size, read_quick, read_byte, read_byte_cmd, read_word_cmd, read_block_cmd, write_quick, write_byte, write_byte_cmd, write_word_cmd, write_block_cmd, priv);
i2c_removehandler(bus_handle, base, size, start, read, write, stop, priv);
}
@@ -233,11 +199,10 @@ i2c_has_device(void *bus_handle, uint8_t addr)
void
i2c_read_quick(void *bus_handle, uint8_t addr)
i2c_start(void *bus_handle, uint8_t addr)
{
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
i2c_t *p;
int found = 0;
if (!bus)
return;
@@ -245,106 +210,23 @@ i2c_read_quick(void *bus_handle, uint8_t addr)
p = bus->devices[addr];
if (p) {
while(p) {
if (p->read_byte) {
p->read_quick(bus_handle, addr, p->priv);
found++;
if (p->start) {
p->start(bus_handle, addr, p->priv);
}
p = p->next;
}
}
i2c_log("I2C: read_quick(%s, %02X)\n", bus->name, addr);
i2c_log("I2C: start(%s, %02X)\n", bus->name, addr);
}
uint8_t
i2c_read_byte(void *bus_handle, uint8_t addr)
{
uint8_t ret = 0xff;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
i2c_t *p;
int found = 0;
if (!bus)
return(ret);
p = bus->devices[addr];
if (p) {
while(p) {
if (p->read_byte) {
ret &= p->read_byte(bus_handle, addr, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: read_byte(%s, %02X) = %02X\n", bus->name, addr, ret);
return(ret);
}
uint8_t
i2c_read_byte_cmd(void *bus_handle, uint8_t addr, uint8_t cmd)
{
uint8_t ret = 0xff;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
i2c_t *p;
int found = 0;
if (!bus)
return(ret);
p = bus->devices[addr];
if (p) {
while(p) {
if (p->read_byte_cmd) {
ret &= p->read_byte_cmd(bus_handle, addr, cmd, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: read_byte_cmd(%s, %02X, %02X) = %02X\n", bus->name, addr, cmd, ret);
return(ret);
}
uint16_t
i2c_read_word_cmd(void *bus_handle, uint8_t addr, uint8_t cmd)
{
uint16_t ret = 0xffff;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
i2c_t *p;
int found = 0;
if (!bus)
return(ret);
p = bus->devices[addr];
if (p) {
while(p) {
if (p->read_word_cmd) {
ret &= p->read_word_cmd(bus_handle, addr, cmd, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: read_word_cmd(%s, %02X, %02X) = %04X\n", bus->name, addr, cmd, ret);
return(ret);
}
uint8_t
i2c_read_block_cmd(void *bus_handle, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len)
i2c_read(void *bus_handle, uint8_t addr)
{
uint8_t ret = 0;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
i2c_t *p;
int found = 0;
if (!bus)
return(ret);
@@ -352,26 +234,51 @@ i2c_read_block_cmd(void *bus_handle, uint8_t addr, uint8_t cmd, uint8_t *data, u
p = bus->devices[addr];
if (p) {
while(p) {
if (p->read_block_cmd) {
ret = MAX(ret, p->read_block_cmd(bus_handle, addr, cmd, data, len, p->priv));
found++;
if (p->read) {
ret = p->read(bus_handle, addr, p->priv);
break;
}
p = p->next;
}
}
i2c_log("I2C: read_block_cmd(%s, %02X, %02X) = %02X\n", bus->name, addr, cmd, len);
i2c_log("I2C: read(%s, %02X) = %02X\n", bus->name, addr, ret);
return(ret);
}
uint8_t
i2c_write(void *bus_handle, uint8_t addr, uint8_t data)
{
uint8_t ret = 0;
i2c_t *p;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
if (!bus)
return(ret);
p = bus->devices[addr];
if (p) {
while(p) {
if (p->write) {
ret = p->write(bus_handle, addr, data, p->priv);
}
p = p->next;
}
}
i2c_log("I2C: write(%s, %02X, %02X) = %d\n", bus->name, addr, data, ret);
return(ret);
}
void
i2c_write_quick(void *bus_handle, uint8_t addr)
i2c_stop(void *bus_handle, uint8_t addr)
{
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
i2c_t *p;
int found = 0;
if (!bus)
return;
@@ -379,118 +286,12 @@ i2c_write_quick(void *bus_handle, uint8_t addr)
p = bus->devices[addr];
if (p) {
while(p) {
if (p->read_byte) {
p->write_quick(bus_handle, addr, p->priv);
found++;
if (p->stop) {
p->stop(bus_handle, addr, p->priv);
}
p = p->next;
}
}
i2c_log("I2C: write_quick(%s, %02X)\n", bus->name, addr);
}
void
i2c_write_byte(void *bus_handle, uint8_t addr, uint8_t val)
{
i2c_t *p;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
int found = 0;
if (!bus)
return;
if (bus->devices[addr]) {
p = bus->devices[addr];
while(p) {
if (p->write_byte) {
p->write_byte(bus_handle, addr, val, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: write_byte(%s, %02X, %02X)\n", bus->name, addr, val);
return;
}
void
i2c_write_byte_cmd(void *bus_handle, uint8_t addr, uint8_t cmd, uint8_t val)
{
i2c_t *p;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
int found = 0;
if (!bus)
return;
if (bus->devices[addr]) {
p = bus->devices[addr];
while(p) {
if (p->write_byte_cmd) {
p->write_byte_cmd(bus_handle, addr, cmd, val, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: write_byte_cmd(%s, %02X, %02X, %02X)\n", bus->name, addr, cmd, val);
return;
}
void
i2c_write_word_cmd(void *bus_handle, uint8_t addr, uint8_t cmd, uint16_t val)
{
i2c_t *p;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
int found = 0;
if (!bus)
return;
if (bus->devices[addr]) {
p = bus->devices[addr];
while(p) {
if (p->write_word_cmd) {
p->write_word_cmd(bus_handle, addr, cmd, val, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: write_word_cmd(%s, %02X, %02X, %04X)\n", bus->name, addr, cmd, val);
return;
}
void
i2c_write_block_cmd(void *bus_handle, uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len)
{
i2c_t *p;
i2c_bus_t *bus = (i2c_bus_t *) bus_handle;
int found = 0;
if (!bus)
return;
p = bus->devices[addr];
if (p) {
while(p) {
if (p->write_block_cmd) {
p->write_block_cmd(bus_handle, addr, cmd, data, len, p->priv);
found++;
}
p = p->next;
}
}
i2c_log("I2C: write_block_cmd(%s, %02X, %02X, %02X)\n", bus->name, addr, cmd, len);
return;
i2c_log("I2C: stop(%s, %02X)\n", bus->name, addr);
}