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