1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Bertrik Sikken 2009-03-03 18:00:17 +00:00
parent 527b2dd270
commit 1fb8242d96
4 changed files with 39 additions and 58 deletions

View file

@ -28,9 +28,9 @@
#define MAX_I2C_INTERFACES 5 #define MAX_I2C_INTERFACES 5
static int i2c_num_ifs = 0; 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(); iface->sda_output();
@ -41,7 +41,7 @@ static void i2c_start(struct i2c_interface *iface)
iface->scl_lo(); iface->scl_lo();
} }
static void i2c_stop(struct i2c_interface *iface) static void i2c_stop(const struct i2c_interface *iface)
{ {
iface->sda_output(); iface->sda_output();
@ -51,7 +51,7 @@ static void i2c_stop(struct i2c_interface *iface)
iface->sda_hi(); 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->sda_output();
iface->scl_lo(); iface->scl_lo();
@ -66,7 +66,7 @@ static void i2c_ack(struct i2c_interface *iface, bool ack)
iface->scl_lo(); iface->scl_lo();
} }
static int i2c_getack(struct i2c_interface *iface) static int i2c_getack(const struct i2c_interface *iface)
{ {
int ret = 1; int ret = 1;
@ -85,7 +85,7 @@ static int i2c_getack(struct i2c_interface *iface)
return ret; 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; int i;
unsigned char byte = 0; unsigned char byte = 0;
@ -107,7 +107,7 @@ static unsigned char i2c_inb(struct i2c_interface *iface, bool ack)
return byte; 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; int i;
@ -127,32 +127,19 @@ static int i2c_outb(struct i2c_interface *iface, unsigned char byte)
} }
iface->sda_hi(); iface->sda_hi();
return i2c_getack(iface); return i2c_getack(iface);
} }
static struct i2c_interface *find_if(int address) int i2c_write_data(int bus_index, int bus_address, int address,
{
int i;
for(i = 0;i < i2c_num_ifs;i++) {
if(i2c_if[i]->address == address)
return i2c_if[i];
}
return NULL;
}
int i2c_write_data(int bus_address, int address,
const unsigned char* buf, int count) const unsigned char* buf, int count)
{ {
int i; int i;
int ret = 0; int ret = 0;
struct i2c_interface *iface = find_if(bus_address); const struct i2c_interface *iface = i2c_if[bus_index];;
if(!iface)
return -1;
i2c_start(iface); i2c_start(iface);
if (!i2c_outb(iface, iface->address & 0xfe)) if (!i2c_outb(iface, bus_address & 0xfe))
{ {
ret = -2; ret = -2;
goto end; goto end;
@ -181,19 +168,17 @@ end:
return ret; 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) unsigned char* buf, int count)
{ {
int i; int i;
int ret = 0; int ret = 0;
struct i2c_interface *iface = find_if(bus_address); const struct i2c_interface *iface = i2c_if[bus_index];;
if(!iface)
return -1;
if (address != -1) if (address != -1)
{ {
i2c_start(iface); i2c_start(iface);
if (!i2c_outb(iface, iface->address & 0xfe)) if (!i2c_outb(iface, bus_address & 0xfe))
{ {
ret = -2; ret = -2;
goto end; goto end;
@ -206,7 +191,7 @@ int i2c_read_data(int bus_address, int address,
} }
i2c_start(iface); i2c_start(iface);
if (!i2c_outb(iface, iface->address | 1)) if (!i2c_outb(iface, bus_address | 1))
{ {
ret = -4; ret = -4;
goto end; goto end;
@ -222,14 +207,18 @@ end:
return ret; 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) if (i2c_num_ifs == MAX_I2C_INTERFACES)
return -1; return -1;
i2c_if[i2c_num_ifs++] = iface; bus_index = i2c_num_ifs++;
i2c_if[bus_index] = iface;
iface->scl_output(); iface->scl_output();
return 0; return bus_index;
} }

View file

@ -23,9 +23,6 @@
struct i2c_interface 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_hi)(void); /* Drive SCL high, might sleep on clk stretch */
void (*scl_lo)(void); /* Drive SCL low */ void (*scl_lo)(void); /* Drive SCL low */
void (*sda_hi)(void); /* Drive SDA high */ 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 */ void (*delay_thigh)(void); /* SCL high period (tHIGH) 4.0us/0.6us */
}; };
extern int i2c_add_node(struct i2c_interface *iface); int i2c_add_node(const struct i2c_interface *iface);
extern 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); const unsigned char* buf, int count);
extern 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); unsigned char* buf, int count);
#endif
#endif /* _GEN_I2C_ */

View file

@ -22,7 +22,7 @@
/* /*
This is the fmradio_i2c interface, used by the radio driver This is the fmradio_i2c interface, used by the radio driver
to communicate with the radio tuner chip. to communicate with the radio tuner chip.
It is implemented using the generic i2c driver, which does "bit-banged" It is implemented using the generic i2c driver, which does "bit-banged"
I2C with a couple of GPIO pins. I2C with a couple of GPIO pins.
*/ */
@ -53,6 +53,8 @@
#error no FM I2C GPIOPIN defines #error no FM I2C GPIOPIN defines
#endif #endif
static int fm_i2c_bus;
static void fm_scl_hi(void) static void fm_scl_hi(void)
{ {
I2C_GPIO(I2C_SCL_PIN) = 1 << I2C_SCL_PIN; I2C_GPIO(I2C_SCL_PIN) = 1 << I2C_SCL_PIN;
@ -107,22 +109,14 @@ static int fm_scl(void)
static void fm_delay(void) static void fm_delay(void)
{ {
volatile int i; volatile int i;
/* this loop is uncalibrated and could use more sophistication */ /* this loop is uncalibrated and could use more sophistication */
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {
} }
} }
/* interface towards the generic i2c driver */ /* interface towards the generic i2c driver */
static struct i2c_interface fm_i2c_interface = { static const 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
.scl_hi = fm_scl_hi, .scl_hi = fm_scl_hi,
.scl_lo = fm_scl_lo, .scl_lo = fm_scl_lo,
.sda_hi = fm_sda_hi, .sda_hi = fm_sda_hi,
@ -133,7 +127,7 @@ static struct i2c_interface fm_i2c_interface = {
.scl_output = fm_scl_output, .scl_output = fm_scl_output,
.scl = fm_scl, .scl = fm_scl,
.sda = fm_sda, .sda = fm_sda,
.delay_hd_sta = fm_delay, .delay_hd_sta = fm_delay,
.delay_hd_dat = fm_delay, .delay_hd_dat = fm_delay,
.delay_su_dat = fm_delay, .delay_su_dat = fm_delay,
@ -145,17 +139,17 @@ static struct i2c_interface fm_i2c_interface = {
/* initialise i2c for fmradio */ /* initialise i2c for fmradio */
void fmradio_i2c_init(void) 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) 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) 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);
} }

View file

@ -46,7 +46,6 @@
#include "system.h" #include "system.h"
#include "jz4740.h" #include "jz4740.h"
#include "logf.h" #include "logf.h"
#include "generic_i2c.h"
/* I2C protocol */ /* I2C protocol */