]>
Commit | Line | Data |
---|---|---|
96a78ac0 YL |
1 | /* |
2 | * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
3 | * Copyright (c) 2010-2011 NVIDIA Corporation | |
4 | * NVIDIA Corporation <www.nvidia.com> | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
96a78ac0 YL |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <fdtdec.h> | |
11 | #include <i2c.h> | |
12 | #include <asm/io.h> | |
96a78ac0 YL |
13 | #include <asm/arch/clock.h> |
14 | #include <asm/arch/funcmux.h> | |
15 | #include <asm/arch/gpio.h> | |
16 | #include <asm/arch/pinmux.h> | |
150c2493 TW |
17 | #include <asm/arch-tegra/clk_rst.h> |
18 | #include <asm/arch-tegra/tegra_i2c.h> | |
96a78ac0 YL |
19 | |
20 | DECLARE_GLOBAL_DATA_PTR; | |
21 | ||
22 | static unsigned int i2c_bus_num; | |
23 | ||
24 | /* Information about i2c controller */ | |
25 | struct i2c_bus { | |
26 | int id; | |
27 | enum periph_id periph_id; | |
28 | int speed; | |
29 | int pinmux_config; | |
30 | struct i2c_control *control; | |
31 | struct i2c_ctlr *regs; | |
32 | int is_dvc; /* DVC type, rather than I2C */ | |
e32624ef | 33 | int is_scs; /* single clock source (T114+) */ |
96a78ac0 YL |
34 | int inited; /* bus is inited */ |
35 | }; | |
36 | ||
37 | static struct i2c_bus i2c_controllers[TEGRA_I2C_NUM_CONTROLLERS]; | |
38 | ||
39 | static void set_packet_mode(struct i2c_bus *i2c_bus) | |
40 | { | |
41 | u32 config; | |
42 | ||
43 | config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK; | |
44 | ||
45 | if (i2c_bus->is_dvc) { | |
46 | struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; | |
47 | ||
48 | writel(config, &dvc->cnfg); | |
49 | } else { | |
50 | writel(config, &i2c_bus->regs->cnfg); | |
51 | /* | |
52 | * program I2C_SL_CNFG.NEWSL to ENABLE. This fixes probe | |
53 | * issues, i.e., some slaves may be wrongly detected. | |
54 | */ | |
55 | setbits_le32(&i2c_bus->regs->sl_cnfg, I2C_SL_CNFG_NEWSL_MASK); | |
56 | } | |
57 | } | |
58 | ||
59 | static void i2c_reset_controller(struct i2c_bus *i2c_bus) | |
60 | { | |
61 | /* Reset I2C controller. */ | |
62 | reset_periph(i2c_bus->periph_id, 1); | |
63 | ||
64 | /* re-program config register to packet mode */ | |
65 | set_packet_mode(i2c_bus); | |
66 | } | |
67 | ||
68 | static void i2c_init_controller(struct i2c_bus *i2c_bus) | |
69 | { | |
70 | /* | |
71 | * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8 | |
72 | * here, in section 23.3.1, but in fact we seem to need a factor of | |
73 | * 16 to get the right frequency. | |
74 | */ | |
75 | clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH, | |
e32624ef TW |
76 | i2c_bus->speed * 2 * 8); |
77 | ||
78 | if (i2c_bus->is_scs) { | |
79 | /* | |
80 | * T114 I2C went to a single clock source for standard/fast and | |
81 | * HS clock speeds. The new clock rate setting calculation is: | |
82 | * SCL = CLK_SOURCE.I2C / | |
83 | * (CLK_MULT_STD_FAST_MODE * (I2C_CLK_DIV_STD_FAST_MODE+1) * | |
84 | * I2C FREQUENCY DIVISOR) as per the T114 TRM (sec 30.3.1). | |
85 | * | |
86 | * NOTE: We do this here, after the initial clock/pll start, | |
87 | * because if we read the clk_div reg before the controller | |
88 | * is running, we hang, and we need it for the new calc. | |
89 | */ | |
90 | int clk_div_stdfst_mode = readl(&i2c_bus->regs->clk_div) >> 16; | |
91 | debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__, | |
92 | clk_div_stdfst_mode); | |
93 | ||
94 | clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH, | |
95 | CLK_MULT_STD_FAST_MODE * (clk_div_stdfst_mode + 1) * | |
96 | i2c_bus->speed * 2); | |
97 | } | |
96a78ac0 YL |
98 | |
99 | /* Reset I2C controller. */ | |
100 | i2c_reset_controller(i2c_bus); | |
101 | ||
102 | /* Configure I2C controller. */ | |
103 | if (i2c_bus->is_dvc) { /* only for DVC I2C */ | |
104 | struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; | |
105 | ||
106 | setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK); | |
107 | } | |
108 | ||
109 | funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config); | |
110 | } | |
111 | ||
112 | static void send_packet_headers( | |
113 | struct i2c_bus *i2c_bus, | |
114 | struct i2c_trans_info *trans, | |
115 | u32 packet_id) | |
116 | { | |
117 | u32 data; | |
118 | ||
119 | /* prepare header1: Header size = 0 Protocol = I2C, pktType = 0 */ | |
120 | data = PROTOCOL_TYPE_I2C << PKT_HDR1_PROTOCOL_SHIFT; | |
121 | data |= packet_id << PKT_HDR1_PKT_ID_SHIFT; | |
122 | data |= i2c_bus->id << PKT_HDR1_CTLR_ID_SHIFT; | |
123 | writel(data, &i2c_bus->control->tx_fifo); | |
124 | debug("pkt header 1 sent (0x%x)\n", data); | |
125 | ||
126 | /* prepare header2 */ | |
127 | data = (trans->num_bytes - 1) << PKT_HDR2_PAYLOAD_SIZE_SHIFT; | |
128 | writel(data, &i2c_bus->control->tx_fifo); | |
129 | debug("pkt header 2 sent (0x%x)\n", data); | |
130 | ||
131 | /* prepare IO specific header: configure the slave address */ | |
132 | data = trans->address << PKT_HDR3_SLAVE_ADDR_SHIFT; | |
133 | ||
134 | /* Enable Read if it is not a write transaction */ | |
135 | if (!(trans->flags & I2C_IS_WRITE)) | |
136 | data |= PKT_HDR3_READ_MODE_MASK; | |
137 | ||
138 | /* Write I2C specific header */ | |
139 | writel(data, &i2c_bus->control->tx_fifo); | |
140 | debug("pkt header 3 sent (0x%x)\n", data); | |
141 | } | |
142 | ||
143 | static int wait_for_tx_fifo_empty(struct i2c_control *control) | |
144 | { | |
145 | u32 count; | |
146 | int timeout_us = I2C_TIMEOUT_USEC; | |
147 | ||
148 | while (timeout_us >= 0) { | |
149 | count = (readl(&control->fifo_status) & TX_FIFO_EMPTY_CNT_MASK) | |
150 | >> TX_FIFO_EMPTY_CNT_SHIFT; | |
151 | if (count == I2C_FIFO_DEPTH) | |
152 | return 1; | |
153 | udelay(10); | |
154 | timeout_us -= 10; | |
155 | } | |
156 | ||
157 | return 0; | |
158 | } | |
159 | ||
160 | static int wait_for_rx_fifo_notempty(struct i2c_control *control) | |
161 | { | |
162 | u32 count; | |
163 | int timeout_us = I2C_TIMEOUT_USEC; | |
164 | ||
165 | while (timeout_us >= 0) { | |
166 | count = (readl(&control->fifo_status) & TX_FIFO_FULL_CNT_MASK) | |
167 | >> TX_FIFO_FULL_CNT_SHIFT; | |
168 | if (count) | |
169 | return 1; | |
170 | udelay(10); | |
171 | timeout_us -= 10; | |
172 | } | |
173 | ||
174 | return 0; | |
175 | } | |
176 | ||
177 | static int wait_for_transfer_complete(struct i2c_control *control) | |
178 | { | |
179 | int int_status; | |
180 | int timeout_us = I2C_TIMEOUT_USEC; | |
181 | ||
182 | while (timeout_us >= 0) { | |
183 | int_status = readl(&control->int_status); | |
184 | if (int_status & I2C_INT_NO_ACK_MASK) | |
185 | return -int_status; | |
186 | if (int_status & I2C_INT_ARBITRATION_LOST_MASK) | |
187 | return -int_status; | |
188 | if (int_status & I2C_INT_XFER_COMPLETE_MASK) | |
189 | return 0; | |
190 | ||
191 | udelay(10); | |
192 | timeout_us -= 10; | |
193 | } | |
194 | ||
195 | return -1; | |
196 | } | |
197 | ||
198 | static int send_recv_packets(struct i2c_bus *i2c_bus, | |
199 | struct i2c_trans_info *trans) | |
200 | { | |
201 | struct i2c_control *control = i2c_bus->control; | |
202 | u32 int_status; | |
203 | u32 words; | |
204 | u8 *dptr; | |
205 | u32 local; | |
206 | uchar last_bytes; | |
207 | int error = 0; | |
208 | int is_write = trans->flags & I2C_IS_WRITE; | |
209 | ||
210 | /* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */ | |
211 | int_status = readl(&control->int_status); | |
212 | writel(int_status, &control->int_status); | |
213 | ||
214 | send_packet_headers(i2c_bus, trans, 1); | |
215 | ||
216 | words = DIV_ROUND_UP(trans->num_bytes, 4); | |
217 | last_bytes = trans->num_bytes & 3; | |
218 | dptr = trans->buf; | |
219 | ||
220 | while (words) { | |
221 | u32 *wptr = (u32 *)dptr; | |
222 | ||
223 | if (is_write) { | |
224 | /* deal with word alignment */ | |
225 | if ((unsigned)dptr & 3) { | |
226 | memcpy(&local, dptr, sizeof(u32)); | |
227 | writel(local, &control->tx_fifo); | |
228 | debug("pkt data sent (0x%x)\n", local); | |
229 | } else { | |
230 | writel(*wptr, &control->tx_fifo); | |
231 | debug("pkt data sent (0x%x)\n", *wptr); | |
232 | } | |
233 | if (!wait_for_tx_fifo_empty(control)) { | |
234 | error = -1; | |
235 | goto exit; | |
236 | } | |
237 | } else { | |
238 | if (!wait_for_rx_fifo_notempty(control)) { | |
239 | error = -1; | |
240 | goto exit; | |
241 | } | |
242 | /* | |
243 | * for the last word, we read into our local buffer, | |
244 | * in case that caller did not provide enough buffer. | |
245 | */ | |
246 | local = readl(&control->rx_fifo); | |
247 | if ((words == 1) && last_bytes) | |
248 | memcpy(dptr, (char *)&local, last_bytes); | |
249 | else if ((unsigned)dptr & 3) | |
250 | memcpy(dptr, &local, sizeof(u32)); | |
251 | else | |
252 | *wptr = local; | |
253 | debug("pkt data received (0x%x)\n", local); | |
254 | } | |
255 | words--; | |
256 | dptr += sizeof(u32); | |
257 | } | |
258 | ||
259 | if (wait_for_transfer_complete(control)) { | |
260 | error = -1; | |
261 | goto exit; | |
262 | } | |
263 | return 0; | |
264 | exit: | |
265 | /* error, reset the controller. */ | |
266 | i2c_reset_controller(i2c_bus); | |
267 | ||
268 | return error; | |
269 | } | |
270 | ||
29f3e3f2 | 271 | static int tegra_i2c_write_data(u32 addr, u8 *data, u32 len) |
96a78ac0 YL |
272 | { |
273 | int error; | |
274 | struct i2c_trans_info trans_info; | |
275 | ||
276 | trans_info.address = addr; | |
277 | trans_info.buf = data; | |
278 | trans_info.flags = I2C_IS_WRITE; | |
279 | trans_info.num_bytes = len; | |
280 | trans_info.is_10bit_address = 0; | |
281 | ||
282 | error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info); | |
283 | if (error) | |
29f3e3f2 | 284 | debug("tegra_i2c_write_data: Error (%d) !!!\n", error); |
96a78ac0 YL |
285 | |
286 | return error; | |
287 | } | |
288 | ||
29f3e3f2 | 289 | static int tegra_i2c_read_data(u32 addr, u8 *data, u32 len) |
96a78ac0 YL |
290 | { |
291 | int error; | |
292 | struct i2c_trans_info trans_info; | |
293 | ||
294 | trans_info.address = addr | 1; | |
295 | trans_info.buf = data; | |
296 | trans_info.flags = 0; | |
297 | trans_info.num_bytes = len; | |
298 | trans_info.is_10bit_address = 0; | |
299 | ||
300 | error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info); | |
301 | if (error) | |
29f3e3f2 | 302 | debug("tegra_i2c_read_data: Error (%d) !!!\n", error); |
96a78ac0 YL |
303 | |
304 | return error; | |
305 | } | |
306 | ||
307 | #ifndef CONFIG_OF_CONTROL | |
308 | #error "Please enable device tree support to use this driver" | |
309 | #endif | |
310 | ||
311 | unsigned int i2c_get_bus_speed(void) | |
312 | { | |
313 | return i2c_controllers[i2c_bus_num].speed; | |
314 | } | |
315 | ||
316 | int i2c_set_bus_speed(unsigned int speed) | |
317 | { | |
318 | struct i2c_bus *i2c_bus; | |
319 | ||
320 | i2c_bus = &i2c_controllers[i2c_bus_num]; | |
321 | i2c_bus->speed = speed; | |
322 | i2c_init_controller(i2c_bus); | |
323 | ||
324 | return 0; | |
325 | } | |
326 | ||
327 | static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus) | |
328 | { | |
329 | i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg"); | |
330 | ||
331 | /* | |
332 | * We don't have a binding for pinmux yet. Leave it out for now. So | |
333 | * far no one needs anything other than the default. | |
334 | */ | |
335 | i2c_bus->pinmux_config = FUNCMUX_DEFAULT; | |
336 | i2c_bus->speed = fdtdec_get_int(blob, node, "clock-frequency", 0); | |
337 | i2c_bus->periph_id = clock_decode_periph_id(blob, node); | |
338 | ||
339 | /* | |
340 | * We can't specify the pinmux config in the fdt, so I2C2 will not | |
341 | * work on Seaboard. It normally has no devices on it anyway. | |
342 | * You could add in this little hack if you need to use it. | |
343 | * The correct solution is a pinmux binding in the fdt. | |
344 | * | |
345 | * if (i2c_bus->periph_id == PERIPH_ID_I2C2) | |
346 | * i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA; | |
347 | */ | |
348 | if (i2c_bus->periph_id == -1) | |
349 | return -FDT_ERR_NOTFOUND; | |
350 | ||
351 | return 0; | |
352 | } | |
353 | ||
354 | /* | |
355 | * Process a list of nodes, adding them to our list of I2C ports. | |
356 | * | |
357 | * @param blob fdt blob | |
358 | * @param node_list list of nodes to process (any <=0 are ignored) | |
359 | * @param count number of nodes to process | |
360 | * @param is_dvc 1 if these are DVC ports, 0 if standard I2C | |
e32624ef | 361 | * @param is_scs 1 if this HW uses a single clock source (T114+) |
96a78ac0 YL |
362 | * @return 0 if ok, -1 on error |
363 | */ | |
364 | static int process_nodes(const void *blob, int node_list[], int count, | |
e32624ef | 365 | int is_dvc, int is_scs) |
96a78ac0 YL |
366 | { |
367 | struct i2c_bus *i2c_bus; | |
368 | int i; | |
369 | ||
370 | /* build the i2c_controllers[] for each controller */ | |
371 | for (i = 0; i < count; i++) { | |
372 | int node = node_list[i]; | |
373 | ||
374 | if (node <= 0) | |
375 | continue; | |
376 | ||
377 | i2c_bus = &i2c_controllers[i]; | |
378 | i2c_bus->id = i; | |
379 | ||
380 | if (i2c_get_config(blob, node, i2c_bus)) { | |
381 | printf("i2c_init_board: failed to decode bus %d\n", i); | |
382 | return -1; | |
383 | } | |
384 | ||
e32624ef TW |
385 | i2c_bus->is_scs = is_scs; |
386 | ||
96a78ac0 YL |
387 | i2c_bus->is_dvc = is_dvc; |
388 | if (is_dvc) { | |
389 | i2c_bus->control = | |
390 | &((struct dvc_ctlr *)i2c_bus->regs)->control; | |
391 | } else { | |
392 | i2c_bus->control = &i2c_bus->regs->control; | |
393 | } | |
394 | debug("%s: controller bus %d at %p, periph_id %d, speed %d: ", | |
395 | is_dvc ? "dvc" : "i2c", i, i2c_bus->regs, | |
396 | i2c_bus->periph_id, i2c_bus->speed); | |
397 | i2c_init_controller(i2c_bus); | |
398 | debug("ok\n"); | |
399 | i2c_bus->inited = 1; | |
400 | ||
401 | /* Mark position as used */ | |
402 | node_list[i] = -1; | |
403 | } | |
404 | ||
405 | return 0; | |
406 | } | |
407 | ||
408 | /* Sadly there is no error return from this function */ | |
409 | void i2c_init_board(void) | |
410 | { | |
411 | int node_list[TEGRA_I2C_NUM_CONTROLLERS]; | |
412 | const void *blob = gd->fdt_blob; | |
413 | int count; | |
414 | ||
e32624ef TW |
415 | /* First check for newer (T114+) I2C ports */ |
416 | count = fdtdec_find_aliases_for_id(blob, "i2c", | |
417 | COMPAT_NVIDIA_TEGRA114_I2C, node_list, | |
418 | TEGRA_I2C_NUM_CONTROLLERS); | |
419 | if (process_nodes(blob, node_list, count, 0, 1)) | |
420 | return; | |
421 | ||
422 | /* Now get the older (T20/T30) normal I2C ports */ | |
96a78ac0 YL |
423 | count = fdtdec_find_aliases_for_id(blob, "i2c", |
424 | COMPAT_NVIDIA_TEGRA20_I2C, node_list, | |
425 | TEGRA_I2C_NUM_CONTROLLERS); | |
e32624ef | 426 | if (process_nodes(blob, node_list, count, 0, 0)) |
96a78ac0 YL |
427 | return; |
428 | ||
429 | /* Now look for dvc ports */ | |
430 | count = fdtdec_add_aliases_for_id(blob, "i2c", | |
431 | COMPAT_NVIDIA_TEGRA20_DVC, node_list, | |
432 | TEGRA_I2C_NUM_CONTROLLERS); | |
e32624ef | 433 | if (process_nodes(blob, node_list, count, 1, 0)) |
96a78ac0 YL |
434 | return; |
435 | } | |
436 | ||
437 | void i2c_init(int speed, int slaveaddr) | |
438 | { | |
439 | /* This will override the speed selected in the fdt for that port */ | |
440 | debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); | |
441 | i2c_set_bus_speed(speed); | |
442 | } | |
443 | ||
444 | /* i2c write version without the register address */ | |
445 | int i2c_write_data(uchar chip, uchar *buffer, int len) | |
446 | { | |
447 | int rc; | |
448 | ||
449 | debug("i2c_write_data: chip=0x%x, len=0x%x\n", chip, len); | |
450 | debug("write_data: "); | |
451 | /* use rc for counter */ | |
452 | for (rc = 0; rc < len; ++rc) | |
453 | debug(" 0x%02x", buffer[rc]); | |
454 | debug("\n"); | |
455 | ||
456 | /* Shift 7-bit address over for lower-level i2c functions */ | |
29f3e3f2 | 457 | rc = tegra_i2c_write_data(chip << 1, buffer, len); |
96a78ac0 YL |
458 | if (rc) |
459 | debug("i2c_write_data(): rc=%d\n", rc); | |
460 | ||
461 | return rc; | |
462 | } | |
463 | ||
464 | /* i2c read version without the register address */ | |
465 | int i2c_read_data(uchar chip, uchar *buffer, int len) | |
466 | { | |
467 | int rc; | |
468 | ||
469 | debug("inside i2c_read_data():\n"); | |
470 | /* Shift 7-bit address over for lower-level i2c functions */ | |
29f3e3f2 | 471 | rc = tegra_i2c_read_data(chip << 1, buffer, len); |
96a78ac0 YL |
472 | if (rc) { |
473 | debug("i2c_read_data(): rc=%d\n", rc); | |
474 | return rc; | |
475 | } | |
476 | ||
477 | debug("i2c_read_data: "); | |
478 | /* reuse rc for counter*/ | |
479 | for (rc = 0; rc < len; ++rc) | |
480 | debug(" 0x%02x", buffer[rc]); | |
481 | debug("\n"); | |
482 | ||
483 | return 0; | |
484 | } | |
485 | ||
486 | /* Probe to see if a chip is present. */ | |
487 | int i2c_probe(uchar chip) | |
488 | { | |
489 | int rc; | |
490 | uchar reg; | |
491 | ||
492 | debug("i2c_probe: addr=0x%x\n", chip); | |
493 | reg = 0; | |
494 | rc = i2c_write_data(chip, ®, 1); | |
495 | if (rc) { | |
496 | debug("Error probing 0x%x.\n", chip); | |
497 | return 1; | |
498 | } | |
499 | return 0; | |
500 | } | |
501 | ||
502 | static int i2c_addr_ok(const uint addr, const int alen) | |
503 | { | |
504 | /* We support 7 or 10 bit addresses, so one or two bytes each */ | |
505 | return alen == 1 || alen == 2; | |
506 | } | |
507 | ||
508 | /* Read bytes */ | |
509 | int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) | |
510 | { | |
511 | uint offset; | |
512 | int i; | |
513 | ||
514 | debug("i2c_read: chip=0x%x, addr=0x%x, len=0x%x\n", | |
515 | chip, addr, len); | |
516 | if (!i2c_addr_ok(addr, alen)) { | |
517 | debug("i2c_read: Bad address %x.%d.\n", addr, alen); | |
518 | return 1; | |
519 | } | |
520 | for (offset = 0; offset < len; offset++) { | |
521 | if (alen) { | |
522 | uchar data[alen]; | |
523 | for (i = 0; i < alen; i++) { | |
524 | data[alen - i - 1] = | |
525 | (addr + offset) >> (8 * i); | |
526 | } | |
527 | if (i2c_write_data(chip, data, alen)) { | |
528 | debug("i2c_read: error sending (0x%x)\n", | |
529 | addr); | |
530 | return 1; | |
531 | } | |
532 | } | |
533 | if (i2c_read_data(chip, buffer + offset, 1)) { | |
534 | debug("i2c_read: error reading (0x%x)\n", addr); | |
535 | return 1; | |
536 | } | |
537 | } | |
538 | ||
539 | return 0; | |
540 | } | |
541 | ||
542 | /* Write bytes */ | |
543 | int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) | |
544 | { | |
545 | uint offset; | |
546 | int i; | |
547 | ||
548 | debug("i2c_write: chip=0x%x, addr=0x%x, len=0x%x\n", | |
549 | chip, addr, len); | |
550 | if (!i2c_addr_ok(addr, alen)) { | |
551 | debug("i2c_write: Bad address %x.%d.\n", addr, alen); | |
552 | return 1; | |
553 | } | |
554 | for (offset = 0; offset < len; offset++) { | |
555 | uchar data[alen + 1]; | |
556 | for (i = 0; i < alen; i++) | |
557 | data[alen - i - 1] = (addr + offset) >> (8 * i); | |
558 | data[alen] = buffer[offset]; | |
559 | if (i2c_write_data(chip, data, alen + 1)) { | |
560 | debug("i2c_write: error sending (0x%x)\n", addr); | |
561 | return 1; | |
562 | } | |
563 | } | |
564 | ||
565 | return 0; | |
566 | } | |
567 | ||
568 | #if defined(CONFIG_I2C_MULTI_BUS) | |
569 | /* | |
570 | * Functions for multiple I2C bus handling | |
571 | */ | |
572 | unsigned int i2c_get_bus_num(void) | |
573 | { | |
574 | return i2c_bus_num; | |
575 | } | |
576 | ||
577 | int i2c_set_bus_num(unsigned int bus) | |
578 | { | |
579 | if (bus >= TEGRA_I2C_NUM_CONTROLLERS || !i2c_controllers[bus].inited) | |
580 | return -1; | |
581 | i2c_bus_num = bus; | |
582 | ||
583 | return 0; | |
584 | } | |
585 | #endif | |
e31c1e50 SG |
586 | |
587 | int tegra_i2c_get_dvc_bus_num(void) | |
588 | { | |
589 | int i; | |
590 | ||
591 | for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; i++) { | |
592 | struct i2c_bus *bus = &i2c_controllers[i]; | |
593 | ||
594 | if (bus->inited && bus->is_dvc) | |
595 | return i; | |
596 | } | |
597 | ||
598 | return -1; | |
599 | } |