From 1fb8242d968a3ee7091ef86db37b3e8f593eaeeb Mon Sep 17 00:00:00 2001 From: Bertrik Sikken Date: Tue, 3 Mar 2009 18:00:17 +0000 Subject: Simplify generic_i2c, removing the link between i2c address and i2c interface, adding the concept of an i2c bus index. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20193 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/generic_i2c.c | 55 ++++++++++-------------- firmware/export/generic_i2c.h | 17 ++++---- firmware/target/arm/as3525/fmradio-i2c-as3525.c | 24 ++++------- firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c | 1 - 4 files changed, 39 insertions(+), 58 deletions(-) diff --git a/firmware/drivers/generic_i2c.c b/firmware/drivers/generic_i2c.c index dcbe46f654..206ded96fb 100644 --- a/firmware/drivers/generic_i2c.c +++ b/firmware/drivers/generic_i2c.c @@ -28,9 +28,9 @@ #define MAX_I2C_INTERFACES 5 static int i2c_num_ifs = 0; -static struct i2c_interface *i2c_if[MAX_I2C_INTERFACES]; +static const struct i2c_interface *i2c_if[MAX_I2C_INTERFACES]; -static void i2c_start(struct i2c_interface *iface) +static void i2c_start(const struct i2c_interface *iface) { iface->sda_output(); @@ -41,7 +41,7 @@ static void i2c_start(struct i2c_interface *iface) iface->scl_lo(); } -static void i2c_stop(struct i2c_interface *iface) +static void i2c_stop(const struct i2c_interface *iface) { iface->sda_output(); @@ -51,7 +51,7 @@ static void i2c_stop(struct i2c_interface *iface) iface->sda_hi(); } -static void i2c_ack(struct i2c_interface *iface, bool ack) +static void i2c_ack(const struct i2c_interface *iface, bool ack) { iface->sda_output(); iface->scl_lo(); @@ -66,7 +66,7 @@ static void i2c_ack(struct i2c_interface *iface, bool ack) iface->scl_lo(); } -static int i2c_getack(struct i2c_interface *iface) +static int i2c_getack(const struct i2c_interface *iface) { int ret = 1; @@ -85,7 +85,7 @@ static int i2c_getack(struct i2c_interface *iface) return ret; } -static unsigned char i2c_inb(struct i2c_interface *iface, bool ack) +static unsigned char i2c_inb(const struct i2c_interface *iface, bool ack) { int i; unsigned char byte = 0; @@ -107,7 +107,7 @@ static unsigned char i2c_inb(struct i2c_interface *iface, bool ack) return byte; } -static int i2c_outb(struct i2c_interface *iface, unsigned char byte) +static int i2c_outb(const struct i2c_interface *iface, unsigned char byte) { int i; @@ -127,32 +127,19 @@ static int i2c_outb(struct i2c_interface *iface, unsigned char byte) } iface->sda_hi(); - - return i2c_getack(iface); -} - -static struct i2c_interface *find_if(int address) -{ - int i; - for(i = 0;i < i2c_num_ifs;i++) { - if(i2c_if[i]->address == address) - return i2c_if[i]; - } - return NULL; + return i2c_getack(iface); } -int i2c_write_data(int bus_address, int address, +int i2c_write_data(int bus_index, int bus_address, int address, const unsigned char* buf, int count) { int i; int ret = 0; - struct i2c_interface *iface = find_if(bus_address); - if(!iface) - return -1; + const struct i2c_interface *iface = i2c_if[bus_index];; i2c_start(iface); - if (!i2c_outb(iface, iface->address & 0xfe)) + if (!i2c_outb(iface, bus_address & 0xfe)) { ret = -2; goto end; @@ -181,19 +168,17 @@ end: return ret; } -int i2c_read_data(int bus_address, int address, +int i2c_read_data(int bus_index, int bus_address, int address, unsigned char* buf, int count) { int i; int ret = 0; - struct i2c_interface *iface = find_if(bus_address); - if(!iface) - return -1; + const struct i2c_interface *iface = i2c_if[bus_index];; if (address != -1) { i2c_start(iface); - if (!i2c_outb(iface, iface->address & 0xfe)) + if (!i2c_outb(iface, bus_address & 0xfe)) { ret = -2; goto end; @@ -206,7 +191,7 @@ int i2c_read_data(int bus_address, int address, } i2c_start(iface); - if (!i2c_outb(iface, iface->address | 1)) + if (!i2c_outb(iface, bus_address | 1)) { ret = -4; goto end; @@ -222,14 +207,18 @@ end: return ret; } -int i2c_add_node(struct i2c_interface *iface) +/* returns bus index which can be used as a handle, or <0 on error */ +int i2c_add_node(const struct i2c_interface *iface) { + int bus_index; + if (i2c_num_ifs == MAX_I2C_INTERFACES) return -1; - i2c_if[i2c_num_ifs++] = iface; + bus_index = i2c_num_ifs++; + i2c_if[bus_index] = iface; iface->scl_output(); - return 0; + return bus_index; } diff --git a/firmware/export/generic_i2c.h b/firmware/export/generic_i2c.h index f38728589d..6679b78415 100644 --- a/firmware/export/generic_i2c.h +++ b/firmware/export/generic_i2c.h @@ -23,9 +23,6 @@ struct i2c_interface { - unsigned char address; /* Address of the chip that this interface - describes */ - void (*scl_hi)(void); /* Drive SCL high, might sleep on clk stretch */ void (*scl_lo)(void); /* Drive SCL low */ void (*sda_hi)(void); /* Drive SDA high */ @@ -47,9 +44,11 @@ struct i2c_interface void (*delay_thigh)(void); /* SCL high period (tHIGH) 4.0us/0.6us */ }; -extern int i2c_add_node(struct i2c_interface *iface); -extern int i2c_write_data(int bus_address, int address, - const unsigned char* buf, int count); -extern int i2c_read_data(int bus_address, int address, - unsigned char* buf, int count); -#endif +int i2c_add_node(const struct i2c_interface *iface); +int i2c_write_data(int bus_index, int bus_address, int address, + const unsigned char* buf, int count); +int i2c_read_data(int bus_index, int bus_address, int address, + unsigned char* buf, int count); + +#endif /* _GEN_I2C_ */ + diff --git a/firmware/target/arm/as3525/fmradio-i2c-as3525.c b/firmware/target/arm/as3525/fmradio-i2c-as3525.c index 72775eda75..528e8c79a3 100644 --- a/firmware/target/arm/as3525/fmradio-i2c-as3525.c +++ b/firmware/target/arm/as3525/fmradio-i2c-as3525.c @@ -22,7 +22,7 @@ /* This is the fmradio_i2c interface, used by the radio driver to communicate with the radio tuner chip. - + It is implemented using the generic i2c driver, which does "bit-banged" I2C with a couple of GPIO pins. */ @@ -53,6 +53,8 @@ #error no FM I2C GPIOPIN defines #endif +static int fm_i2c_bus; + static void fm_scl_hi(void) { I2C_GPIO(I2C_SCL_PIN) = 1 << I2C_SCL_PIN; @@ -107,22 +109,14 @@ static int fm_scl(void) static void fm_delay(void) { volatile int i; - + /* this loop is uncalibrated and could use more sophistication */ for (i = 0; i < 100; i++) { } } /* interface towards the generic i2c driver */ -static struct i2c_interface fm_i2c_interface = { -#if defined(SANSA_CLIP) || defined(SANSA_FUZE) || defined(SANSA_E200V2) - .address = 0x10 << 1, -#elif defined(SANSA_M200V4) - .address = 0xC0, -#elif -#error no fm i2c address defined -#endif - +static const struct i2c_interface fm_i2c_interface = { .scl_hi = fm_scl_hi, .scl_lo = fm_scl_lo, .sda_hi = fm_sda_hi, @@ -133,7 +127,7 @@ static struct i2c_interface fm_i2c_interface = { .scl_output = fm_scl_output, .scl = fm_scl, .sda = fm_sda, - + .delay_hd_sta = fm_delay, .delay_hd_dat = fm_delay, .delay_su_dat = fm_delay, @@ -145,17 +139,17 @@ static struct i2c_interface fm_i2c_interface = { /* initialise i2c for fmradio */ void fmradio_i2c_init(void) { - i2c_add_node(&fm_i2c_interface); + fm_i2c_bus = i2c_add_node(&fm_i2c_interface); } int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) { - return i2c_write_data(address, -1, buf, count); + return i2c_write_data(fm_i2c_bus, address, -1, buf, count); } int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) { - return i2c_read_data(address, -1, buf, count); + return i2c_read_data(fm_i2c_bus, address, -1, buf, count); } diff --git a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c index 456542064c..b97448f4bb 100644 --- a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c @@ -46,7 +46,6 @@ #include "system.h" #include "jz4740.h" #include "logf.h" -#include "generic_i2c.h" /* I2C protocol */ -- cgit v1.2.3