summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/generic_i2c.c55
1 files changed, 22 insertions, 33 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
30static int i2c_num_ifs = 0; 30static int i2c_num_ifs = 0;
31static struct i2c_interface *i2c_if[MAX_I2C_INTERFACES]; 31static const struct i2c_interface *i2c_if[MAX_I2C_INTERFACES];
32 32
33static void i2c_start(struct i2c_interface *iface) 33static 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
44static void i2c_stop(struct i2c_interface *iface) 44static 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
54static void i2c_ack(struct i2c_interface *iface, bool ack) 54static 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
69static int i2c_getack(struct i2c_interface *iface) 69static 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
88static unsigned char i2c_inb(struct i2c_interface *iface, bool ack) 88static 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
110static int i2c_outb(struct i2c_interface *iface, unsigned char byte) 110static 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
134static 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
145int i2c_write_data(int bus_address, int address, 134int 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
184int i2c_read_data(int bus_address, int address, 171int 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
225int i2c_add_node(struct i2c_interface *iface) 210/* returns bus index which can be used as a handle, or <0 on error */
211int 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}