diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2009-03-03 18:00:17 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2009-03-03 18:00:17 +0000 |
commit | 1fb8242d968a3ee7091ef86db37b3e8f593eaeeb (patch) | |
tree | 886690cbfe9ec3294989c9d1da9b29a1da0a93d9 | |
parent | 527b2dd270edebc7fcff1fe10e784a14e5046d7b (diff) | |
download | rockbox-1fb8242d968a3ee7091ef86db37b3e8f593eaeeb.tar.gz rockbox-1fb8242d968a3ee7091ef86db37b3e8f593eaeeb.zip |
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
-rw-r--r-- | firmware/drivers/generic_i2c.c | 55 | ||||
-rw-r--r-- | firmware/export/generic_i2c.h | 17 | ||||
-rw-r--r-- | firmware/target/arm/as3525/fmradio-i2c-as3525.c | 24 | ||||
-rw-r--r-- | 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 @@ | |||
28 | #define MAX_I2C_INTERFACES 5 | 28 | #define MAX_I2C_INTERFACES 5 |
29 | 29 | ||
30 | static int i2c_num_ifs = 0; | 30 | static int i2c_num_ifs = 0; |
31 | static struct i2c_interface *i2c_if[MAX_I2C_INTERFACES]; | 31 | static const struct i2c_interface *i2c_if[MAX_I2C_INTERFACES]; |
32 | 32 | ||
33 | static void i2c_start(struct i2c_interface *iface) | 33 | static void i2c_start(const struct i2c_interface *iface) |
34 | { | 34 | { |
35 | iface->sda_output(); | 35 | iface->sda_output(); |
36 | 36 | ||
@@ -41,7 +41,7 @@ static void i2c_start(struct i2c_interface *iface) | |||
41 | iface->scl_lo(); | 41 | iface->scl_lo(); |
42 | } | 42 | } |
43 | 43 | ||
44 | static void i2c_stop(struct i2c_interface *iface) | 44 | static void i2c_stop(const struct i2c_interface *iface) |
45 | { | 45 | { |
46 | iface->sda_output(); | 46 | iface->sda_output(); |
47 | 47 | ||
@@ -51,7 +51,7 @@ static void i2c_stop(struct i2c_interface *iface) | |||
51 | iface->sda_hi(); | 51 | iface->sda_hi(); |
52 | } | 52 | } |
53 | 53 | ||
54 | static void i2c_ack(struct i2c_interface *iface, bool ack) | 54 | static void i2c_ack(const struct i2c_interface *iface, bool ack) |
55 | { | 55 | { |
56 | iface->sda_output(); | 56 | iface->sda_output(); |
57 | iface->scl_lo(); | 57 | iface->scl_lo(); |
@@ -66,7 +66,7 @@ static void i2c_ack(struct i2c_interface *iface, bool ack) | |||
66 | iface->scl_lo(); | 66 | iface->scl_lo(); |
67 | } | 67 | } |
68 | 68 | ||
69 | static int i2c_getack(struct i2c_interface *iface) | 69 | static int i2c_getack(const struct i2c_interface *iface) |
70 | { | 70 | { |
71 | int ret = 1; | 71 | int ret = 1; |
72 | 72 | ||
@@ -85,7 +85,7 @@ static int i2c_getack(struct i2c_interface *iface) | |||
85 | return ret; | 85 | return ret; |
86 | } | 86 | } |
87 | 87 | ||
88 | static unsigned char i2c_inb(struct i2c_interface *iface, bool ack) | 88 | static unsigned char i2c_inb(const struct i2c_interface *iface, bool ack) |
89 | { | 89 | { |
90 | int i; | 90 | int i; |
91 | unsigned char byte = 0; | 91 | unsigned char byte = 0; |
@@ -107,7 +107,7 @@ static unsigned char i2c_inb(struct i2c_interface *iface, bool ack) | |||
107 | return byte; | 107 | return byte; |
108 | } | 108 | } |
109 | 109 | ||
110 | static int i2c_outb(struct i2c_interface *iface, unsigned char byte) | 110 | static int i2c_outb(const struct i2c_interface *iface, unsigned char byte) |
111 | { | 111 | { |
112 | int i; | 112 | int i; |
113 | 113 | ||
@@ -127,32 +127,19 @@ static int i2c_outb(struct i2c_interface *iface, unsigned char byte) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | iface->sda_hi(); | 129 | iface->sda_hi(); |
130 | |||
131 | return i2c_getack(iface); | ||
132 | } | ||
133 | |||
134 | static struct i2c_interface *find_if(int address) | ||
135 | { | ||
136 | int i; | ||
137 | 130 | ||
138 | for(i = 0;i < i2c_num_ifs;i++) { | 131 | return i2c_getack(iface); |
139 | if(i2c_if[i]->address == address) | ||
140 | return i2c_if[i]; | ||
141 | } | ||
142 | return NULL; | ||
143 | } | 132 | } |
144 | 133 | ||
145 | int i2c_write_data(int bus_address, int address, | 134 | int i2c_write_data(int bus_index, int bus_address, int address, |
146 | const unsigned char* buf, int count) | 135 | const unsigned char* buf, int count) |
147 | { | 136 | { |
148 | int i; | 137 | int i; |
149 | int ret = 0; | 138 | int ret = 0; |
150 | struct i2c_interface *iface = find_if(bus_address); | 139 | const struct i2c_interface *iface = i2c_if[bus_index];; |
151 | if(!iface) | ||
152 | return -1; | ||
153 | 140 | ||
154 | i2c_start(iface); | 141 | i2c_start(iface); |
155 | if (!i2c_outb(iface, iface->address & 0xfe)) | 142 | if (!i2c_outb(iface, bus_address & 0xfe)) |
156 | { | 143 | { |
157 | ret = -2; | 144 | ret = -2; |
158 | goto end; | 145 | goto end; |
@@ -181,19 +168,17 @@ end: | |||
181 | return ret; | 168 | return ret; |
182 | } | 169 | } |
183 | 170 | ||
184 | int i2c_read_data(int bus_address, int address, | 171 | int i2c_read_data(int bus_index, int bus_address, int address, |
185 | unsigned char* buf, int count) | 172 | unsigned char* buf, int count) |
186 | { | 173 | { |
187 | int i; | 174 | int i; |
188 | int ret = 0; | 175 | int ret = 0; |
189 | struct i2c_interface *iface = find_if(bus_address); | 176 | const struct i2c_interface *iface = i2c_if[bus_index];; |
190 | if(!iface) | ||
191 | return -1; | ||
192 | 177 | ||
193 | if (address != -1) | 178 | if (address != -1) |
194 | { | 179 | { |
195 | i2c_start(iface); | 180 | i2c_start(iface); |
196 | if (!i2c_outb(iface, iface->address & 0xfe)) | 181 | if (!i2c_outb(iface, bus_address & 0xfe)) |
197 | { | 182 | { |
198 | ret = -2; | 183 | ret = -2; |
199 | goto end; | 184 | goto end; |
@@ -206,7 +191,7 @@ int i2c_read_data(int bus_address, int address, | |||
206 | } | 191 | } |
207 | 192 | ||
208 | i2c_start(iface); | 193 | i2c_start(iface); |
209 | if (!i2c_outb(iface, iface->address | 1)) | 194 | if (!i2c_outb(iface, bus_address | 1)) |
210 | { | 195 | { |
211 | ret = -4; | 196 | ret = -4; |
212 | goto end; | 197 | goto end; |
@@ -222,14 +207,18 @@ end: | |||
222 | return ret; | 207 | return ret; |
223 | } | 208 | } |
224 | 209 | ||
225 | int i2c_add_node(struct i2c_interface *iface) | 210 | /* returns bus index which can be used as a handle, or <0 on error */ |
211 | int i2c_add_node(const struct i2c_interface *iface) | ||
226 | { | 212 | { |
213 | int bus_index; | ||
214 | |||
227 | if (i2c_num_ifs == MAX_I2C_INTERFACES) | 215 | if (i2c_num_ifs == MAX_I2C_INTERFACES) |
228 | return -1; | 216 | return -1; |
229 | 217 | ||
230 | i2c_if[i2c_num_ifs++] = iface; | 218 | bus_index = i2c_num_ifs++; |
219 | i2c_if[bus_index] = iface; | ||
231 | 220 | ||
232 | iface->scl_output(); | 221 | iface->scl_output(); |
233 | 222 | ||
234 | return 0; | 223 | return bus_index; |
235 | } | 224 | } |
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 @@ | |||
23 | 23 | ||
24 | struct i2c_interface | 24 | struct i2c_interface |
25 | { | 25 | { |
26 | unsigned char address; /* Address of the chip that this interface | ||
27 | describes */ | ||
28 | |||
29 | void (*scl_hi)(void); /* Drive SCL high, might sleep on clk stretch */ | 26 | void (*scl_hi)(void); /* Drive SCL high, might sleep on clk stretch */ |
30 | void (*scl_lo)(void); /* Drive SCL low */ | 27 | void (*scl_lo)(void); /* Drive SCL low */ |
31 | void (*sda_hi)(void); /* Drive SDA high */ | 28 | void (*sda_hi)(void); /* Drive SDA high */ |
@@ -47,9 +44,11 @@ struct i2c_interface | |||
47 | void (*delay_thigh)(void); /* SCL high period (tHIGH) 4.0us/0.6us */ | 44 | void (*delay_thigh)(void); /* SCL high period (tHIGH) 4.0us/0.6us */ |
48 | }; | 45 | }; |
49 | 46 | ||
50 | extern int i2c_add_node(struct i2c_interface *iface); | 47 | int i2c_add_node(const struct i2c_interface *iface); |
51 | extern int i2c_write_data(int bus_address, int address, | 48 | int i2c_write_data(int bus_index, int bus_address, int address, |
52 | const unsigned char* buf, int count); | 49 | const unsigned char* buf, int count); |
53 | extern int i2c_read_data(int bus_address, int address, | 50 | int i2c_read_data(int bus_index, int bus_address, int address, |
54 | unsigned char* buf, int count); | 51 | unsigned char* buf, int count); |
55 | #endif | 52 | |
53 | #endif /* _GEN_I2C_ */ | ||
54 | |||
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 @@ | |||
22 | /* | 22 | /* |
23 | This is the fmradio_i2c interface, used by the radio driver | 23 | This is the fmradio_i2c interface, used by the radio driver |
24 | to communicate with the radio tuner chip. | 24 | to communicate with the radio tuner chip. |
25 | 25 | ||
26 | It is implemented using the generic i2c driver, which does "bit-banged" | 26 | It is implemented using the generic i2c driver, which does "bit-banged" |
27 | I2C with a couple of GPIO pins. | 27 | I2C with a couple of GPIO pins. |
28 | */ | 28 | */ |
@@ -53,6 +53,8 @@ | |||
53 | #error no FM I2C GPIOPIN defines | 53 | #error no FM I2C GPIOPIN defines |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | static int fm_i2c_bus; | ||
57 | |||
56 | static void fm_scl_hi(void) | 58 | static void fm_scl_hi(void) |
57 | { | 59 | { |
58 | I2C_GPIO(I2C_SCL_PIN) = 1 << I2C_SCL_PIN; | 60 | I2C_GPIO(I2C_SCL_PIN) = 1 << I2C_SCL_PIN; |
@@ -107,22 +109,14 @@ static int fm_scl(void) | |||
107 | static void fm_delay(void) | 109 | static void fm_delay(void) |
108 | { | 110 | { |
109 | volatile int i; | 111 | volatile int i; |
110 | 112 | ||
111 | /* this loop is uncalibrated and could use more sophistication */ | 113 | /* this loop is uncalibrated and could use more sophistication */ |
112 | for (i = 0; i < 100; i++) { | 114 | for (i = 0; i < 100; i++) { |
113 | } | 115 | } |
114 | } | 116 | } |
115 | 117 | ||
116 | /* interface towards the generic i2c driver */ | 118 | /* interface towards the generic i2c driver */ |
117 | static struct i2c_interface fm_i2c_interface = { | 119 | static const struct i2c_interface fm_i2c_interface = { |
118 | #if defined(SANSA_CLIP) || defined(SANSA_FUZE) || defined(SANSA_E200V2) | ||
119 | .address = 0x10 << 1, | ||
120 | #elif defined(SANSA_M200V4) | ||
121 | .address = 0xC0, | ||
122 | #elif | ||
123 | #error no fm i2c address defined | ||
124 | #endif | ||
125 | |||
126 | .scl_hi = fm_scl_hi, | 120 | .scl_hi = fm_scl_hi, |
127 | .scl_lo = fm_scl_lo, | 121 | .scl_lo = fm_scl_lo, |
128 | .sda_hi = fm_sda_hi, | 122 | .sda_hi = fm_sda_hi, |
@@ -133,7 +127,7 @@ static struct i2c_interface fm_i2c_interface = { | |||
133 | .scl_output = fm_scl_output, | 127 | .scl_output = fm_scl_output, |
134 | .scl = fm_scl, | 128 | .scl = fm_scl, |
135 | .sda = fm_sda, | 129 | .sda = fm_sda, |
136 | 130 | ||
137 | .delay_hd_sta = fm_delay, | 131 | .delay_hd_sta = fm_delay, |
138 | .delay_hd_dat = fm_delay, | 132 | .delay_hd_dat = fm_delay, |
139 | .delay_su_dat = fm_delay, | 133 | .delay_su_dat = fm_delay, |
@@ -145,17 +139,17 @@ static struct i2c_interface fm_i2c_interface = { | |||
145 | /* initialise i2c for fmradio */ | 139 | /* initialise i2c for fmradio */ |
146 | void fmradio_i2c_init(void) | 140 | void fmradio_i2c_init(void) |
147 | { | 141 | { |
148 | i2c_add_node(&fm_i2c_interface); | 142 | fm_i2c_bus = i2c_add_node(&fm_i2c_interface); |
149 | } | 143 | } |
150 | 144 | ||
151 | int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) | 145 | int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) |
152 | { | 146 | { |
153 | return i2c_write_data(address, -1, buf, count); | 147 | return i2c_write_data(fm_i2c_bus, address, -1, buf, count); |
154 | } | 148 | } |
155 | 149 | ||
156 | int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | 150 | int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) |
157 | { | 151 | { |
158 | return i2c_read_data(address, -1, buf, count); | 152 | return i2c_read_data(fm_i2c_bus, address, -1, buf, count); |
159 | } | 153 | } |
160 | 154 | ||
161 | 155 | ||
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 @@ | |||
46 | #include "system.h" | 46 | #include "system.h" |
47 | #include "jz4740.h" | 47 | #include "jz4740.h" |
48 | #include "logf.h" | 48 | #include "logf.h" |
49 | #include "generic_i2c.h" | ||
50 | 49 | ||
51 | 50 | ||
52 | /* I2C protocol */ | 51 | /* I2C protocol */ |