]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
c609719b | 2 | /* |
ea818dbb HS |
3 | * (C) Copyright 2009 |
4 | * Heiko Schocher, DENX Software Engineering, [email protected]. | |
5 | * Changes for multibus/multiadapter I2C support. | |
6 | * | |
c609719b WD |
7 | * (C) Copyright 2001, 2002 |
8 | * Wolfgang Denk, DENX Software Engineering, [email protected]. | |
9 | * | |
c609719b WD |
10 | * This has been changed substantially by Gerald Van Baren, Custom IDEAS, |
11 | * [email protected]. It was heavily influenced by LiMon, written by | |
12 | * Neil Russell. | |
28527096 SG |
13 | * |
14 | * NOTE: This driver should be converted to driver model before June 2017. | |
2799a69e | 15 | * Please see doc/driver-model/i2c-howto.rst for instructions. |
c609719b WD |
16 | */ |
17 | ||
18 | #include <common.h> | |
f3100ff7 | 19 | #if defined(CONFIG_AT91FAMILY) |
9d5028c2 WD |
20 | #include <asm/io.h> |
21 | #include <asm/arch/hardware.h> | |
0cf0b931 | 22 | #include <asm/arch/at91_pio.h> |
cb96a0a4 | 23 | #ifdef CONFIG_ATMEL_LEGACY |
4e574c4e | 24 | #include <asm/arch/gpio.h> |
0cf0b931 | 25 | #endif |
4e574c4e | 26 | #endif |
c609719b | 27 | #include <i2c.h> |
401d1c4f | 28 | #include <asm/global_data.h> |
c05ed00a | 29 | #include <linux/delay.h> |
c609719b | 30 | |
793b5726 MF |
31 | #if defined(CONFIG_SOFT_I2C_GPIO_SCL) |
32 | # include <asm/gpio.h> | |
33 | ||
34 | # ifndef I2C_GPIO_SYNC | |
35 | # define I2C_GPIO_SYNC | |
36 | # endif | |
37 | ||
38 | # ifndef I2C_INIT | |
39 | # define I2C_INIT \ | |
40 | do { \ | |
41 | gpio_request(CONFIG_SOFT_I2C_GPIO_SCL, "soft_i2c"); \ | |
42 | gpio_request(CONFIG_SOFT_I2C_GPIO_SDA, "soft_i2c"); \ | |
43 | } while (0) | |
44 | # endif | |
45 | ||
46 | # ifndef I2C_ACTIVE | |
47 | # define I2C_ACTIVE do { } while (0) | |
48 | # endif | |
49 | ||
50 | # ifndef I2C_TRISTATE | |
51 | # define I2C_TRISTATE do { } while (0) | |
52 | # endif | |
53 | ||
54 | # ifndef I2C_READ | |
55 | # define I2C_READ gpio_get_value(CONFIG_SOFT_I2C_GPIO_SDA) | |
56 | # endif | |
57 | ||
58 | # ifndef I2C_SDA | |
59 | # define I2C_SDA(bit) \ | |
60 | do { \ | |
61 | if (bit) \ | |
62 | gpio_direction_input(CONFIG_SOFT_I2C_GPIO_SDA); \ | |
63 | else \ | |
64 | gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SDA, 0); \ | |
65 | I2C_GPIO_SYNC; \ | |
66 | } while (0) | |
67 | # endif | |
68 | ||
69 | # ifndef I2C_SCL | |
70 | # define I2C_SCL(bit) \ | |
71 | do { \ | |
72 | gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SCL, bit); \ | |
73 | I2C_GPIO_SYNC; \ | |
74 | } while (0) | |
75 | # endif | |
76 | ||
77 | # ifndef I2C_DELAY | |
78 | # define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ | |
79 | # endif | |
80 | ||
81 | #endif | |
82 | ||
c609719b WD |
83 | /* #define DEBUG_I2C */ |
84 | ||
d87080b7 | 85 | DECLARE_GLOBAL_DATA_PTR; |
ea818dbb HS |
86 | |
87 | #ifndef I2C_SOFT_DECLARATIONS | |
ea818dbb | 88 | # define I2C_SOFT_DECLARATIONS |
ea818dbb HS |
89 | #endif |
90 | ||
90f002a9 MV |
91 | #if !defined(CONFIG_SYS_I2C_SOFT_SPEED) |
92 | #define CONFIG_SYS_I2C_SOFT_SPEED CONFIG_SYS_I2C_SPEED | |
ea818dbb | 93 | #endif |
90f002a9 MV |
94 | #if !defined(CONFIG_SYS_I2C_SOFT_SLAVE) |
95 | #define CONFIG_SYS_I2C_SOFT_SLAVE CONFIG_SYS_I2C_SLAVE | |
d87080b7 WD |
96 | #endif |
97 | ||
c609719b WD |
98 | /*----------------------------------------------------------------------- |
99 | * Definitions | |
100 | */ | |
c609719b WD |
101 | #define RETRIES 0 |
102 | ||
c609719b WD |
103 | #define I2C_ACK 0 /* PD_SDA level to ack a byte */ |
104 | #define I2C_NOACK 1 /* PD_SDA level to noack a byte */ | |
105 | ||
106 | ||
107 | #ifdef DEBUG_I2C | |
108 | #define PRINTD(fmt,args...) do { \ | |
c609719b WD |
109 | printf (fmt ,##args); \ |
110 | } while (0) | |
111 | #else | |
112 | #define PRINTD(fmt,args...) | |
113 | #endif | |
114 | ||
115 | /*----------------------------------------------------------------------- | |
116 | * Local functions | |
117 | */ | |
6d0f6bcf | 118 | #if !defined(CONFIG_SYS_I2C_INIT_BOARD) |
c609719b | 119 | static void send_reset (void); |
4ca107ef | 120 | #endif |
c609719b WD |
121 | static void send_start (void); |
122 | static void send_stop (void); | |
123 | static void send_ack (int); | |
124 | static int write_byte (uchar byte); | |
125 | static uchar read_byte (int); | |
126 | ||
6d0f6bcf | 127 | #if !defined(CONFIG_SYS_I2C_INIT_BOARD) |
c609719b WD |
128 | /*----------------------------------------------------------------------- |
129 | * Send a reset sequence consisting of 9 clocks with the data signal high | |
130 | * to clock any confused device back into an idle state. Also send a | |
131 | * <stop> at the end of the sequence for belts & suspenders. | |
132 | */ | |
133 | static void send_reset(void) | |
134 | { | |
98aed379 | 135 | I2C_SOFT_DECLARATIONS /* intentional without ';' */ |
c609719b WD |
136 | int j; |
137 | ||
60fbe254 | 138 | I2C_SCL(1); |
c609719b | 139 | I2C_SDA(1); |
60fbe254 WD |
140 | #ifdef I2C_INIT |
141 | I2C_INIT; | |
142 | #endif | |
143 | I2C_TRISTATE; | |
c609719b WD |
144 | for(j = 0; j < 9; j++) { |
145 | I2C_SCL(0); | |
146 | I2C_DELAY; | |
147 | I2C_DELAY; | |
148 | I2C_SCL(1); | |
149 | I2C_DELAY; | |
150 | I2C_DELAY; | |
151 | } | |
152 | send_stop(); | |
153 | I2C_TRISTATE; | |
154 | } | |
4ca107ef | 155 | #endif |
c609719b WD |
156 | |
157 | /*----------------------------------------------------------------------- | |
158 | * START: High -> Low on SDA while SCL is High | |
159 | */ | |
160 | static void send_start(void) | |
161 | { | |
98aed379 | 162 | I2C_SOFT_DECLARATIONS /* intentional without ';' */ |
c609719b WD |
163 | |
164 | I2C_DELAY; | |
165 | I2C_SDA(1); | |
166 | I2C_ACTIVE; | |
167 | I2C_DELAY; | |
168 | I2C_SCL(1); | |
169 | I2C_DELAY; | |
170 | I2C_SDA(0); | |
171 | I2C_DELAY; | |
172 | } | |
173 | ||
174 | /*----------------------------------------------------------------------- | |
175 | * STOP: Low -> High on SDA while SCL is High | |
176 | */ | |
177 | static void send_stop(void) | |
178 | { | |
98aed379 | 179 | I2C_SOFT_DECLARATIONS /* intentional without ';' */ |
c609719b WD |
180 | |
181 | I2C_SCL(0); | |
182 | I2C_DELAY; | |
183 | I2C_SDA(0); | |
184 | I2C_ACTIVE; | |
185 | I2C_DELAY; | |
186 | I2C_SCL(1); | |
187 | I2C_DELAY; | |
188 | I2C_SDA(1); | |
189 | I2C_DELAY; | |
190 | I2C_TRISTATE; | |
191 | } | |
192 | ||
c609719b WD |
193 | /*----------------------------------------------------------------------- |
194 | * ack should be I2C_ACK or I2C_NOACK | |
195 | */ | |
196 | static void send_ack(int ack) | |
197 | { | |
98aed379 | 198 | I2C_SOFT_DECLARATIONS /* intentional without ';' */ |
c609719b | 199 | |
c609719b WD |
200 | I2C_SCL(0); |
201 | I2C_DELAY; | |
c609719b | 202 | I2C_ACTIVE; |
c15f80ea | 203 | I2C_SDA(ack); |
c609719b WD |
204 | I2C_DELAY; |
205 | I2C_SCL(1); | |
206 | I2C_DELAY; | |
207 | I2C_DELAY; | |
208 | I2C_SCL(0); | |
209 | I2C_DELAY; | |
210 | } | |
211 | ||
c609719b WD |
212 | /*----------------------------------------------------------------------- |
213 | * Send 8 bits and look for an acknowledgement. | |
214 | */ | |
215 | static int write_byte(uchar data) | |
216 | { | |
98aed379 | 217 | I2C_SOFT_DECLARATIONS /* intentional without ';' */ |
c609719b WD |
218 | int j; |
219 | int nack; | |
220 | ||
221 | I2C_ACTIVE; | |
222 | for(j = 0; j < 8; j++) { | |
223 | I2C_SCL(0); | |
224 | I2C_DELAY; | |
225 | I2C_SDA(data & 0x80); | |
226 | I2C_DELAY; | |
227 | I2C_SCL(1); | |
228 | I2C_DELAY; | |
229 | I2C_DELAY; | |
230 | ||
231 | data <<= 1; | |
232 | } | |
233 | ||
234 | /* | |
235 | * Look for an <ACK>(negative logic) and return it. | |
236 | */ | |
237 | I2C_SCL(0); | |
238 | I2C_DELAY; | |
239 | I2C_SDA(1); | |
240 | I2C_TRISTATE; | |
241 | I2C_DELAY; | |
242 | I2C_SCL(1); | |
243 | I2C_DELAY; | |
244 | I2C_DELAY; | |
245 | nack = I2C_READ; | |
246 | I2C_SCL(0); | |
247 | I2C_DELAY; | |
248 | I2C_ACTIVE; | |
249 | ||
250 | return(nack); /* not a nack is an ack */ | |
251 | } | |
252 | ||
c609719b WD |
253 | /*----------------------------------------------------------------------- |
254 | * if ack == I2C_ACK, ACK the byte so can continue reading, else | |
255 | * send I2C_NOACK to end the read. | |
256 | */ | |
257 | static uchar read_byte(int ack) | |
258 | { | |
98aed379 | 259 | I2C_SOFT_DECLARATIONS /* intentional without ';' */ |
c609719b WD |
260 | int data; |
261 | int j; | |
262 | ||
263 | /* | |
264 | * Read 8 bits, MSB first. | |
265 | */ | |
266 | I2C_TRISTATE; | |
110e006f | 267 | I2C_SDA(1); |
c609719b WD |
268 | data = 0; |
269 | for(j = 0; j < 8; j++) { | |
270 | I2C_SCL(0); | |
271 | I2C_DELAY; | |
272 | I2C_SCL(1); | |
273 | I2C_DELAY; | |
274 | data <<= 1; | |
275 | data |= I2C_READ; | |
276 | I2C_DELAY; | |
277 | } | |
278 | send_ack(ack); | |
279 | ||
280 | return(data); | |
281 | } | |
282 | ||
c609719b WD |
283 | /*----------------------------------------------------------------------- |
284 | * Initialization | |
285 | */ | |
ea818dbb | 286 | static void soft_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) |
c609719b | 287 | { |
6d0f6bcf | 288 | #if defined(CONFIG_SYS_I2C_INIT_BOARD) |
4ca107ef HS |
289 | /* call board specific i2c bus reset routine before accessing the */ |
290 | /* environment, which might be in a chip on that bus. For details */ | |
291 | /* about this problem see doc/I2C_Edge_Conditions. */ | |
292 | i2c_init_board(); | |
293 | #else | |
c609719b | 294 | /* |
8bde7f77 WD |
295 | * WARNING: Do NOT save speed in a static variable: if the |
296 | * I2C routines are called before RAM is initialized (to read | |
297 | * the DIMM SPD, for instance), RAM won't be usable and your | |
298 | * system will crash. | |
c609719b WD |
299 | */ |
300 | send_reset (); | |
4ca107ef | 301 | #endif |
c609719b WD |
302 | } |
303 | ||
304 | /*----------------------------------------------------------------------- | |
305 | * Probe to see if a chip is present. Also good for checking for the | |
306 | * completion of EEPROM writes since the chip stops responding until | |
307 | * the write completes (typically 10mSec). | |
308 | */ | |
ea818dbb | 309 | static int soft_i2c_probe(struct i2c_adapter *adap, uint8_t addr) |
c609719b WD |
310 | { |
311 | int rc; | |
312 | ||
82d716fd | 313 | /* |
8e7b703a | 314 | * perform 1 byte write transaction with just address byte |
82d716fd WD |
315 | * (fake write) |
316 | */ | |
c609719b | 317 | send_start(); |
6aff3115 | 318 | rc = write_byte ((addr << 1) | 0); |
c609719b WD |
319 | send_stop(); |
320 | ||
321 | return (rc ? 1 : 0); | |
322 | } | |
323 | ||
324 | /*----------------------------------------------------------------------- | |
325 | * Read bytes | |
326 | */ | |
ea818dbb HS |
327 | static int soft_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, |
328 | int alen, uchar *buffer, int len) | |
c609719b WD |
329 | { |
330 | int shift; | |
331 | PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n", | |
332 | chip, addr, alen, buffer, len); | |
333 | ||
6d0f6bcf | 334 | #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW |
c609719b WD |
335 | /* |
336 | * EEPROM chips that implement "address overflow" are ones | |
337 | * like Catalyst 24WC04/08/16 which has 9/10/11 bits of | |
338 | * address and the extra bits end up in the "chip address" | |
339 | * bit slots. This makes a 24WC08 (1Kbyte) chip look like | |
340 | * four 256 byte chips. | |
341 | * | |
342 | * Note that we consider the length of the address field to | |
343 | * still be one byte because the extra address bits are | |
344 | * hidden in the chip address. | |
345 | */ | |
6d0f6bcf | 346 | chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); |
c609719b WD |
347 | |
348 | PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n", | |
349 | chip, addr); | |
350 | #endif | |
351 | ||
352 | /* | |
353 | * Do the addressing portion of a write cycle to set the | |
354 | * chip's address pointer. If the address length is zero, | |
355 | * don't do the normal write cycle to set the address pointer, | |
356 | * there is no address pointer in this chip. | |
357 | */ | |
358 | send_start(); | |
359 | if(alen > 0) { | |
360 | if(write_byte(chip << 1)) { /* write cycle */ | |
361 | send_stop(); | |
362 | PRINTD("i2c_read, no chip responded %02X\n", chip); | |
363 | return(1); | |
364 | } | |
365 | shift = (alen-1) * 8; | |
366 | while(alen-- > 0) { | |
367 | if(write_byte(addr >> shift)) { | |
368 | PRINTD("i2c_read, address not <ACK>ed\n"); | |
369 | return(1); | |
370 | } | |
371 | shift -= 8; | |
372 | } | |
2ac6985a AD |
373 | |
374 | /* Some I2C chips need a stop/start sequence here, | |
375 | * other chips don't work with a full stop and need | |
376 | * only a start. Default behaviour is to send the | |
377 | * stop/start sequence. | |
378 | */ | |
379 | #ifdef CONFIG_SOFT_I2C_READ_REPEATED_START | |
380 | send_start(); | |
381 | #else | |
382 | send_stop(); | |
c609719b | 383 | send_start(); |
2ac6985a | 384 | #endif |
c609719b WD |
385 | } |
386 | /* | |
387 | * Send the chip address again, this time for a read cycle. | |
388 | * Then read the data. On the last byte, we do a NACK instead | |
389 | * of an ACK(len == 0) to terminate the read. | |
390 | */ | |
391 | write_byte((chip << 1) | 1); /* read cycle */ | |
392 | while(len-- > 0) { | |
393 | *buffer++ = read_byte(len == 0); | |
394 | } | |
395 | send_stop(); | |
396 | return(0); | |
397 | } | |
398 | ||
399 | /*----------------------------------------------------------------------- | |
400 | * Write bytes | |
401 | */ | |
ea818dbb HS |
402 | static int soft_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, |
403 | int alen, uchar *buffer, int len) | |
c609719b WD |
404 | { |
405 | int shift, failures = 0; | |
406 | ||
407 | PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n", | |
408 | chip, addr, alen, buffer, len); | |
409 | ||
410 | send_start(); | |
411 | if(write_byte(chip << 1)) { /* write cycle */ | |
412 | send_stop(); | |
413 | PRINTD("i2c_write, no chip responded %02X\n", chip); | |
414 | return(1); | |
415 | } | |
416 | shift = (alen-1) * 8; | |
417 | while(alen-- > 0) { | |
418 | if(write_byte(addr >> shift)) { | |
419 | PRINTD("i2c_write, address not <ACK>ed\n"); | |
420 | return(1); | |
421 | } | |
422 | shift -= 8; | |
423 | } | |
424 | ||
425 | while(len-- > 0) { | |
426 | if(write_byte(*buffer++)) { | |
427 | failures++; | |
428 | } | |
429 | } | |
430 | send_stop(); | |
431 | return(failures); | |
432 | } | |
ea818dbb HS |
433 | |
434 | /* | |
435 | * Register soft i2c adapters | |
436 | */ | |
37b33254 | 437 | U_BOOT_I2C_ADAP_COMPLETE(soft00, soft_i2c_init, soft_i2c_probe, |
ea818dbb HS |
438 | soft_i2c_read, soft_i2c_write, NULL, |
439 | CONFIG_SYS_I2C_SOFT_SPEED, CONFIG_SYS_I2C_SOFT_SLAVE, | |
440 | 0) | |
441 | #if defined(I2C_SOFT_DECLARATIONS2) | |
37b33254 | 442 | U_BOOT_I2C_ADAP_COMPLETE(soft01, soft_i2c_init, soft_i2c_probe, |
ea818dbb HS |
443 | soft_i2c_read, soft_i2c_write, NULL, |
444 | CONFIG_SYS_I2C_SOFT_SPEED_2, | |
445 | CONFIG_SYS_I2C_SOFT_SLAVE_2, | |
446 | 1) | |
447 | #endif | |
448 | #if defined(I2C_SOFT_DECLARATIONS3) | |
37b33254 | 449 | U_BOOT_I2C_ADAP_COMPLETE(soft02, soft_i2c_init, soft_i2c_probe, |
ea818dbb HS |
450 | soft_i2c_read, soft_i2c_write, NULL, |
451 | CONFIG_SYS_I2C_SOFT_SPEED_3, | |
452 | CONFIG_SYS_I2C_SOFT_SLAVE_3, | |
453 | 2) | |
454 | #endif | |
455 | #if defined(I2C_SOFT_DECLARATIONS4) | |
37b33254 | 456 | U_BOOT_I2C_ADAP_COMPLETE(soft03, soft_i2c_init, soft_i2c_probe, |
ea818dbb HS |
457 | soft_i2c_read, soft_i2c_write, NULL, |
458 | CONFIG_SYS_I2C_SOFT_SPEED_4, | |
459 | CONFIG_SYS_I2C_SOFT_SLAVE_4, | |
460 | 3) | |
461 | #endif | |
7ed45d3d | 462 | #if defined(I2C_SOFT_DECLARATIONS5) |
37b33254 | 463 | U_BOOT_I2C_ADAP_COMPLETE(soft04, soft_i2c_init, soft_i2c_probe, |
7ed45d3d DE |
464 | soft_i2c_read, soft_i2c_write, NULL, |
465 | CONFIG_SYS_I2C_SOFT_SPEED_5, | |
466 | CONFIG_SYS_I2C_SOFT_SLAVE_5, | |
467 | 4) | |
468 | #endif | |
469 | #if defined(I2C_SOFT_DECLARATIONS6) | |
37b33254 | 470 | U_BOOT_I2C_ADAP_COMPLETE(soft05, soft_i2c_init, soft_i2c_probe, |
7ed45d3d DE |
471 | soft_i2c_read, soft_i2c_write, NULL, |
472 | CONFIG_SYS_I2C_SOFT_SPEED_6, | |
473 | CONFIG_SYS_I2C_SOFT_SLAVE_6, | |
474 | 5) | |
475 | #endif | |
476 | #if defined(I2C_SOFT_DECLARATIONS7) | |
37b33254 | 477 | U_BOOT_I2C_ADAP_COMPLETE(soft06, soft_i2c_init, soft_i2c_probe, |
7ed45d3d DE |
478 | soft_i2c_read, soft_i2c_write, NULL, |
479 | CONFIG_SYS_I2C_SOFT_SPEED_7, | |
480 | CONFIG_SYS_I2C_SOFT_SLAVE_7, | |
481 | 6) | |
482 | #endif | |
483 | #if defined(I2C_SOFT_DECLARATIONS8) | |
37b33254 | 484 | U_BOOT_I2C_ADAP_COMPLETE(soft07, soft_i2c_init, soft_i2c_probe, |
7ed45d3d DE |
485 | soft_i2c_read, soft_i2c_write, NULL, |
486 | CONFIG_SYS_I2C_SOFT_SPEED_8, | |
487 | CONFIG_SYS_I2C_SOFT_SLAVE_8, | |
488 | 7) | |
489 | #endif | |
5c3b6dc1 | 490 | #if defined(I2C_SOFT_DECLARATIONS9) |
37b33254 | 491 | U_BOOT_I2C_ADAP_COMPLETE(soft08, soft_i2c_init, soft_i2c_probe, |
5c3b6dc1 DE |
492 | soft_i2c_read, soft_i2c_write, NULL, |
493 | CONFIG_SYS_I2C_SOFT_SPEED_9, | |
494 | CONFIG_SYS_I2C_SOFT_SLAVE_9, | |
495 | 8) | |
496 | #endif | |
497 | #if defined(I2C_SOFT_DECLARATIONS10) | |
37b33254 | 498 | U_BOOT_I2C_ADAP_COMPLETE(soft09, soft_i2c_init, soft_i2c_probe, |
5c3b6dc1 DE |
499 | soft_i2c_read, soft_i2c_write, NULL, |
500 | CONFIG_SYS_I2C_SOFT_SPEED_10, | |
501 | CONFIG_SYS_I2C_SOFT_SLAVE_10, | |
502 | 9) | |
503 | #endif | |
504 | #if defined(I2C_SOFT_DECLARATIONS11) | |
505 | U_BOOT_I2C_ADAP_COMPLETE(soft10, soft_i2c_init, soft_i2c_probe, | |
506 | soft_i2c_read, soft_i2c_write, NULL, | |
507 | CONFIG_SYS_I2C_SOFT_SPEED_11, | |
508 | CONFIG_SYS_I2C_SOFT_SLAVE_11, | |
509 | 10) | |
510 | #endif | |
511 | #if defined(I2C_SOFT_DECLARATIONS12) | |
512 | U_BOOT_I2C_ADAP_COMPLETE(soft11, soft_i2c_init, soft_i2c_probe, | |
513 | soft_i2c_read, soft_i2c_write, NULL, | |
514 | CONFIG_SYS_I2C_SOFT_SPEED_12, | |
515 | CONFIG_SYS_I2C_SOFT_SLAVE_12, | |
516 | 11) | |
517 | #endif |