]>
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> | |
b0e6ef46 SG |
10 | #include <dm.h> |
11 | #include <errno.h> | |
96a78ac0 YL |
12 | #include <fdtdec.h> |
13 | #include <i2c.h> | |
14 | #include <asm/io.h> | |
3c27fa21 BW |
15 | #include <clk.h> |
16 | #include <reset.h> | |
fc607d9a | 17 | #ifndef CONFIG_TEGRA186 |
96a78ac0 YL |
18 | #include <asm/arch/clock.h> |
19 | #include <asm/arch/funcmux.h> | |
3c27fa21 BW |
20 | #endif |
21 | #include <asm/arch/gpio.h> | |
150c2493 | 22 | #include <asm/arch-tegra/tegra_i2c.h> |
96a78ac0 YL |
23 | |
24 | DECLARE_GLOBAL_DATA_PTR; | |
25 | ||
b0e6ef46 SG |
26 | enum i2c_type { |
27 | TYPE_114, | |
28 | TYPE_STD, | |
29 | TYPE_DVC, | |
30 | }; | |
31 | ||
96a78ac0 YL |
32 | /* Information about i2c controller */ |
33 | struct i2c_bus { | |
34 | int id; | |
3c27fa21 BW |
35 | struct reset_ctl reset_ctl; |
36 | struct clk clk; | |
96a78ac0 YL |
37 | int speed; |
38 | int pinmux_config; | |
39 | struct i2c_control *control; | |
40 | struct i2c_ctlr *regs; | |
b0e6ef46 | 41 | enum i2c_type type; |
96a78ac0 YL |
42 | int inited; /* bus is inited */ |
43 | }; | |
44 | ||
96a78ac0 YL |
45 | static void set_packet_mode(struct i2c_bus *i2c_bus) |
46 | { | |
47 | u32 config; | |
48 | ||
49 | config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK; | |
50 | ||
b0e6ef46 | 51 | if (i2c_bus->type == TYPE_DVC) { |
96a78ac0 YL |
52 | struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; |
53 | ||
54 | writel(config, &dvc->cnfg); | |
55 | } else { | |
56 | writel(config, &i2c_bus->regs->cnfg); | |
57 | /* | |
58 | * program I2C_SL_CNFG.NEWSL to ENABLE. This fixes probe | |
59 | * issues, i.e., some slaves may be wrongly detected. | |
60 | */ | |
61 | setbits_le32(&i2c_bus->regs->sl_cnfg, I2C_SL_CNFG_NEWSL_MASK); | |
62 | } | |
63 | } | |
64 | ||
65 | static void i2c_reset_controller(struct i2c_bus *i2c_bus) | |
66 | { | |
67 | /* Reset I2C controller. */ | |
3c27fa21 BW |
68 | reset_assert(&i2c_bus->reset_ctl); |
69 | udelay(1); | |
70 | reset_deassert(&i2c_bus->reset_ctl); | |
71 | udelay(1); | |
96a78ac0 YL |
72 | |
73 | /* re-program config register to packet mode */ | |
74 | set_packet_mode(i2c_bus); | |
75 | } | |
76 | ||
3c27fa21 BW |
77 | static int i2c_init_clock(struct i2c_bus *i2c_bus, unsigned rate) |
78 | { | |
79 | int ret; | |
80 | ||
81 | ret = reset_assert(&i2c_bus->reset_ctl); | |
82 | if (ret) | |
83 | return ret; | |
84 | ret = clk_enable(&i2c_bus->clk); | |
85 | if (ret) | |
86 | return ret; | |
87 | ret = clk_set_rate(&i2c_bus->clk, rate); | |
88 | if (IS_ERR_VALUE(ret)) | |
89 | return ret; | |
90 | ret = reset_deassert(&i2c_bus->reset_ctl); | |
91 | if (ret) | |
92 | return ret; | |
93 | ||
94 | return 0; | |
95 | } | |
3c27fa21 | 96 | |
96a78ac0 YL |
97 | static void i2c_init_controller(struct i2c_bus *i2c_bus) |
98 | { | |
b0e6ef46 SG |
99 | if (!i2c_bus->speed) |
100 | return; | |
101 | debug("%s: speed=%d\n", __func__, i2c_bus->speed); | |
96a78ac0 YL |
102 | /* |
103 | * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8 | |
104 | * here, in section 23.3.1, but in fact we seem to need a factor of | |
105 | * 16 to get the right frequency. | |
106 | */ | |
3c27fa21 | 107 | i2c_init_clock(i2c_bus, i2c_bus->speed * 2 * 8); |
e32624ef | 108 | |
b0e6ef46 | 109 | if (i2c_bus->type == TYPE_114) { |
e32624ef TW |
110 | /* |
111 | * T114 I2C went to a single clock source for standard/fast and | |
112 | * HS clock speeds. The new clock rate setting calculation is: | |
113 | * SCL = CLK_SOURCE.I2C / | |
114 | * (CLK_MULT_STD_FAST_MODE * (I2C_CLK_DIV_STD_FAST_MODE+1) * | |
115 | * I2C FREQUENCY DIVISOR) as per the T114 TRM (sec 30.3.1). | |
116 | * | |
117 | * NOTE: We do this here, after the initial clock/pll start, | |
118 | * because if we read the clk_div reg before the controller | |
119 | * is running, we hang, and we need it for the new calc. | |
120 | */ | |
121 | int clk_div_stdfst_mode = readl(&i2c_bus->regs->clk_div) >> 16; | |
3c27fa21 BW |
122 | unsigned rate = CLK_MULT_STD_FAST_MODE * |
123 | (clk_div_stdfst_mode + 1) * i2c_bus->speed * 2; | |
e32624ef TW |
124 | debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__, |
125 | clk_div_stdfst_mode); | |
126 | ||
3c27fa21 | 127 | i2c_init_clock(i2c_bus, rate); |
e32624ef | 128 | } |
96a78ac0 YL |
129 | |
130 | /* Reset I2C controller. */ | |
131 | i2c_reset_controller(i2c_bus); | |
132 | ||
133 | /* Configure I2C controller. */ | |
b0e6ef46 | 134 | if (i2c_bus->type == TYPE_DVC) { /* only for DVC I2C */ |
96a78ac0 YL |
135 | struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; |
136 | ||
137 | setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK); | |
138 | } | |
139 | ||
3c27fa21 | 140 | #ifndef CONFIG_TEGRA186 |
fc607d9a | 141 | funcmux_select(i2c_bus->clk.id, i2c_bus->pinmux_config); |
3c27fa21 | 142 | #endif |
96a78ac0 YL |
143 | } |
144 | ||
145 | static void send_packet_headers( | |
146 | struct i2c_bus *i2c_bus, | |
147 | struct i2c_trans_info *trans, | |
68049a08 SW |
148 | u32 packet_id, |
149 | bool end_with_repeated_start) | |
96a78ac0 YL |
150 | { |
151 | u32 data; | |
152 | ||
153 | /* prepare header1: Header size = 0 Protocol = I2C, pktType = 0 */ | |
154 | data = PROTOCOL_TYPE_I2C << PKT_HDR1_PROTOCOL_SHIFT; | |
155 | data |= packet_id << PKT_HDR1_PKT_ID_SHIFT; | |
156 | data |= i2c_bus->id << PKT_HDR1_CTLR_ID_SHIFT; | |
157 | writel(data, &i2c_bus->control->tx_fifo); | |
158 | debug("pkt header 1 sent (0x%x)\n", data); | |
159 | ||
160 | /* prepare header2 */ | |
161 | data = (trans->num_bytes - 1) << PKT_HDR2_PAYLOAD_SIZE_SHIFT; | |
162 | writel(data, &i2c_bus->control->tx_fifo); | |
163 | debug("pkt header 2 sent (0x%x)\n", data); | |
164 | ||
165 | /* prepare IO specific header: configure the slave address */ | |
166 | data = trans->address << PKT_HDR3_SLAVE_ADDR_SHIFT; | |
167 | ||
168 | /* Enable Read if it is not a write transaction */ | |
169 | if (!(trans->flags & I2C_IS_WRITE)) | |
170 | data |= PKT_HDR3_READ_MODE_MASK; | |
68049a08 SW |
171 | if (end_with_repeated_start) |
172 | data |= PKT_HDR3_REPEAT_START_MASK; | |
96a78ac0 YL |
173 | |
174 | /* Write I2C specific header */ | |
175 | writel(data, &i2c_bus->control->tx_fifo); | |
176 | debug("pkt header 3 sent (0x%x)\n", data); | |
177 | } | |
178 | ||
179 | static int wait_for_tx_fifo_empty(struct i2c_control *control) | |
180 | { | |
181 | u32 count; | |
182 | int timeout_us = I2C_TIMEOUT_USEC; | |
183 | ||
184 | while (timeout_us >= 0) { | |
185 | count = (readl(&control->fifo_status) & TX_FIFO_EMPTY_CNT_MASK) | |
186 | >> TX_FIFO_EMPTY_CNT_SHIFT; | |
187 | if (count == I2C_FIFO_DEPTH) | |
188 | return 1; | |
189 | udelay(10); | |
190 | timeout_us -= 10; | |
191 | } | |
192 | ||
193 | return 0; | |
194 | } | |
195 | ||
196 | static int wait_for_rx_fifo_notempty(struct i2c_control *control) | |
197 | { | |
198 | u32 count; | |
199 | int timeout_us = I2C_TIMEOUT_USEC; | |
200 | ||
201 | while (timeout_us >= 0) { | |
202 | count = (readl(&control->fifo_status) & TX_FIFO_FULL_CNT_MASK) | |
203 | >> TX_FIFO_FULL_CNT_SHIFT; | |
204 | if (count) | |
205 | return 1; | |
206 | udelay(10); | |
207 | timeout_us -= 10; | |
208 | } | |
209 | ||
210 | return 0; | |
211 | } | |
212 | ||
213 | static int wait_for_transfer_complete(struct i2c_control *control) | |
214 | { | |
215 | int int_status; | |
216 | int timeout_us = I2C_TIMEOUT_USEC; | |
217 | ||
218 | while (timeout_us >= 0) { | |
219 | int_status = readl(&control->int_status); | |
220 | if (int_status & I2C_INT_NO_ACK_MASK) | |
221 | return -int_status; | |
222 | if (int_status & I2C_INT_ARBITRATION_LOST_MASK) | |
223 | return -int_status; | |
224 | if (int_status & I2C_INT_XFER_COMPLETE_MASK) | |
225 | return 0; | |
226 | ||
227 | udelay(10); | |
228 | timeout_us -= 10; | |
229 | } | |
230 | ||
231 | return -1; | |
232 | } | |
233 | ||
234 | static int send_recv_packets(struct i2c_bus *i2c_bus, | |
235 | struct i2c_trans_info *trans) | |
236 | { | |
237 | struct i2c_control *control = i2c_bus->control; | |
238 | u32 int_status; | |
239 | u32 words; | |
240 | u8 *dptr; | |
241 | u32 local; | |
242 | uchar last_bytes; | |
243 | int error = 0; | |
244 | int is_write = trans->flags & I2C_IS_WRITE; | |
245 | ||
246 | /* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */ | |
247 | int_status = readl(&control->int_status); | |
248 | writel(int_status, &control->int_status); | |
249 | ||
68049a08 SW |
250 | send_packet_headers(i2c_bus, trans, 1, |
251 | trans->flags & I2C_USE_REPEATED_START); | |
96a78ac0 YL |
252 | |
253 | words = DIV_ROUND_UP(trans->num_bytes, 4); | |
254 | last_bytes = trans->num_bytes & 3; | |
255 | dptr = trans->buf; | |
256 | ||
257 | while (words) { | |
258 | u32 *wptr = (u32 *)dptr; | |
259 | ||
260 | if (is_write) { | |
261 | /* deal with word alignment */ | |
981b14f0 SW |
262 | if ((words == 1) && last_bytes) { |
263 | local = 0; | |
264 | memcpy(&local, dptr, last_bytes); | |
8e67c5d0 | 265 | } else if ((unsigned long)dptr & 3) { |
96a78ac0 | 266 | memcpy(&local, dptr, sizeof(u32)); |
96a78ac0 | 267 | } else { |
981b14f0 | 268 | local = *wptr; |
96a78ac0 | 269 | } |
981b14f0 SW |
270 | writel(local, &control->tx_fifo); |
271 | debug("pkt data sent (0x%x)\n", local); | |
96a78ac0 YL |
272 | if (!wait_for_tx_fifo_empty(control)) { |
273 | error = -1; | |
274 | goto exit; | |
275 | } | |
276 | } else { | |
277 | if (!wait_for_rx_fifo_notempty(control)) { | |
278 | error = -1; | |
279 | goto exit; | |
280 | } | |
281 | /* | |
282 | * for the last word, we read into our local buffer, | |
283 | * in case that caller did not provide enough buffer. | |
284 | */ | |
285 | local = readl(&control->rx_fifo); | |
286 | if ((words == 1) && last_bytes) | |
287 | memcpy(dptr, (char *)&local, last_bytes); | |
8e67c5d0 | 288 | else if ((unsigned long)dptr & 3) |
96a78ac0 YL |
289 | memcpy(dptr, &local, sizeof(u32)); |
290 | else | |
291 | *wptr = local; | |
292 | debug("pkt data received (0x%x)\n", local); | |
293 | } | |
294 | words--; | |
295 | dptr += sizeof(u32); | |
296 | } | |
297 | ||
298 | if (wait_for_transfer_complete(control)) { | |
299 | error = -1; | |
300 | goto exit; | |
301 | } | |
302 | return 0; | |
303 | exit: | |
304 | /* error, reset the controller. */ | |
305 | i2c_reset_controller(i2c_bus); | |
306 | ||
307 | return error; | |
308 | } | |
309 | ||
b0e6ef46 | 310 | static int tegra_i2c_write_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data, |
68049a08 | 311 | u32 len, bool end_with_repeated_start) |
96a78ac0 YL |
312 | { |
313 | int error; | |
314 | struct i2c_trans_info trans_info; | |
315 | ||
316 | trans_info.address = addr; | |
317 | trans_info.buf = data; | |
318 | trans_info.flags = I2C_IS_WRITE; | |
68049a08 SW |
319 | if (end_with_repeated_start) |
320 | trans_info.flags |= I2C_USE_REPEATED_START; | |
96a78ac0 YL |
321 | trans_info.num_bytes = len; |
322 | trans_info.is_10bit_address = 0; | |
323 | ||
b0e6ef46 | 324 | error = send_recv_packets(i2c_bus, &trans_info); |
96a78ac0 | 325 | if (error) |
29f3e3f2 | 326 | debug("tegra_i2c_write_data: Error (%d) !!!\n", error); |
96a78ac0 YL |
327 | |
328 | return error; | |
329 | } | |
330 | ||
b0e6ef46 | 331 | static int tegra_i2c_read_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data, |
d84eb856 | 332 | u32 len) |
96a78ac0 YL |
333 | { |
334 | int error; | |
335 | struct i2c_trans_info trans_info; | |
336 | ||
337 | trans_info.address = addr | 1; | |
338 | trans_info.buf = data; | |
339 | trans_info.flags = 0; | |
340 | trans_info.num_bytes = len; | |
341 | trans_info.is_10bit_address = 0; | |
342 | ||
b0e6ef46 | 343 | error = send_recv_packets(i2c_bus, &trans_info); |
96a78ac0 | 344 | if (error) |
29f3e3f2 | 345 | debug("tegra_i2c_read_data: Error (%d) !!!\n", error); |
96a78ac0 YL |
346 | |
347 | return error; | |
348 | } | |
349 | ||
b0e6ef46 | 350 | static int tegra_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) |
96a78ac0 | 351 | { |
b0e6ef46 | 352 | struct i2c_bus *i2c_bus = dev_get_priv(dev); |
d84eb856 | 353 | |
b0e6ef46 SG |
354 | i2c_bus->speed = speed; |
355 | i2c_init_controller(i2c_bus); | |
96a78ac0 YL |
356 | |
357 | return 0; | |
358 | } | |
359 | ||
b0e6ef46 | 360 | static int tegra_i2c_probe(struct udevice *dev) |
96a78ac0 | 361 | { |
b0e6ef46 | 362 | struct i2c_bus *i2c_bus = dev_get_priv(dev); |
3c27fa21 | 363 | int ret; |
b0e6ef46 SG |
364 | bool is_dvc; |
365 | ||
366 | i2c_bus->id = dev->seq; | |
39de8433 | 367 | i2c_bus->type = dev_get_driver_data(dev); |
a821c4af | 368 | i2c_bus->regs = (struct i2c_ctlr *)devfdt_get_addr(dev); |
96a78ac0 | 369 | |
3c27fa21 BW |
370 | ret = reset_get_by_name(dev, "i2c", &i2c_bus->reset_ctl); |
371 | if (ret) { | |
372 | error("reset_get_by_name() failed: %d\n", ret); | |
373 | return ret; | |
374 | } | |
b4ee081e | 375 | ret = clk_get_by_name(dev, "div-clk", &i2c_bus->clk); |
3c27fa21 BW |
376 | if (ret) { |
377 | error("clk_get_by_name() failed: %d\n", ret); | |
378 | return ret; | |
379 | } | |
fc607d9a SW |
380 | |
381 | #ifndef CONFIG_TEGRA186 | |
382 | /* | |
383 | * We don't have a binding for pinmux yet. Leave it out for now. So | |
384 | * far no one needs anything other than the default. | |
385 | */ | |
96a78ac0 | 386 | i2c_bus->pinmux_config = FUNCMUX_DEFAULT; |
96a78ac0 YL |
387 | |
388 | /* | |
389 | * We can't specify the pinmux config in the fdt, so I2C2 will not | |
390 | * work on Seaboard. It normally has no devices on it anyway. | |
391 | * You could add in this little hack if you need to use it. | |
392 | * The correct solution is a pinmux binding in the fdt. | |
393 | * | |
fc607d9a | 394 | * if (i2c_bus->clk.id == PERIPH_ID_I2C2) |
96a78ac0 YL |
395 | * i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA; |
396 | */ | |
3c27fa21 | 397 | #endif |
96a78ac0 | 398 | |
39de8433 | 399 | is_dvc = dev_get_driver_data(dev) == TYPE_DVC; |
b0e6ef46 SG |
400 | if (is_dvc) { |
401 | i2c_bus->control = | |
402 | &((struct dvc_ctlr *)i2c_bus->regs)->control; | |
403 | } else { | |
404 | i2c_bus->control = &i2c_bus->regs->control; | |
96a78ac0 | 405 | } |
b0e6ef46 | 406 | i2c_init_controller(i2c_bus); |
fc607d9a SW |
407 | debug("%s: controller bus %d at %p, speed %d: ", |
408 | is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs, i2c_bus->speed); | |
96a78ac0 YL |
409 | |
410 | return 0; | |
411 | } | |
412 | ||
96a78ac0 | 413 | /* i2c write version without the register address */ |
b0e6ef46 | 414 | static int i2c_write_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer, |
19d7bf3d | 415 | int len, bool end_with_repeated_start) |
96a78ac0 YL |
416 | { |
417 | int rc; | |
418 | ||
419 | debug("i2c_write_data: chip=0x%x, len=0x%x\n", chip, len); | |
420 | debug("write_data: "); | |
421 | /* use rc for counter */ | |
422 | for (rc = 0; rc < len; ++rc) | |
423 | debug(" 0x%02x", buffer[rc]); | |
424 | debug("\n"); | |
425 | ||
426 | /* Shift 7-bit address over for lower-level i2c functions */ | |
b0e6ef46 | 427 | rc = tegra_i2c_write_data(i2c_bus, chip << 1, buffer, len, |
68049a08 | 428 | end_with_repeated_start); |
96a78ac0 YL |
429 | if (rc) |
430 | debug("i2c_write_data(): rc=%d\n", rc); | |
431 | ||
432 | return rc; | |
433 | } | |
434 | ||
435 | /* i2c read version without the register address */ | |
b0e6ef46 SG |
436 | static int i2c_read_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer, |
437 | int len) | |
96a78ac0 YL |
438 | { |
439 | int rc; | |
440 | ||
441 | debug("inside i2c_read_data():\n"); | |
442 | /* Shift 7-bit address over for lower-level i2c functions */ | |
b0e6ef46 | 443 | rc = tegra_i2c_read_data(i2c_bus, chip << 1, buffer, len); |
96a78ac0 YL |
444 | if (rc) { |
445 | debug("i2c_read_data(): rc=%d\n", rc); | |
446 | return rc; | |
447 | } | |
448 | ||
449 | debug("i2c_read_data: "); | |
450 | /* reuse rc for counter*/ | |
451 | for (rc = 0; rc < len; ++rc) | |
452 | debug(" 0x%02x", buffer[rc]); | |
453 | debug("\n"); | |
454 | ||
455 | return 0; | |
456 | } | |
457 | ||
458 | /* Probe to see if a chip is present. */ | |
b0e6ef46 SG |
459 | static int tegra_i2c_probe_chip(struct udevice *bus, uint chip_addr, |
460 | uint chip_flags) | |
96a78ac0 | 461 | { |
b0e6ef46 | 462 | struct i2c_bus *i2c_bus = dev_get_priv(bus); |
96a78ac0 | 463 | int rc; |
b0e6ef46 | 464 | u8 reg; |
96a78ac0 | 465 | |
b0e6ef46 SG |
466 | /* Shift 7-bit address over for lower-level i2c functions */ |
467 | rc = tegra_i2c_write_data(i2c_bus, chip_addr << 1, ®, sizeof(reg), | |
468 | false); | |
469 | ||
470 | return rc; | |
96a78ac0 YL |
471 | } |
472 | ||
b0e6ef46 SG |
473 | static int tegra_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, |
474 | int nmsgs) | |
96a78ac0 | 475 | { |
b0e6ef46 SG |
476 | struct i2c_bus *i2c_bus = dev_get_priv(bus); |
477 | int ret; | |
478 | ||
479 | debug("i2c_xfer: %d messages\n", nmsgs); | |
480 | for (; nmsgs > 0; nmsgs--, msg++) { | |
481 | bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); | |
482 | ||
483 | debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); | |
484 | if (msg->flags & I2C_M_RD) { | |
485 | ret = i2c_read_data(i2c_bus, msg->addr, msg->buf, | |
486 | msg->len); | |
487 | } else { | |
488 | ret = i2c_write_data(i2c_bus, msg->addr, msg->buf, | |
489 | msg->len, next_is_read); | |
96a78ac0 | 490 | } |
b0e6ef46 SG |
491 | if (ret) { |
492 | debug("i2c_write: error sending\n"); | |
493 | return -EREMOTEIO; | |
96a78ac0 YL |
494 | } |
495 | } | |
496 | ||
497 | return 0; | |
498 | } | |
499 | ||
b0e6ef46 | 500 | int tegra_i2c_get_dvc_bus(struct udevice **busp) |
96a78ac0 | 501 | { |
b0e6ef46 SG |
502 | struct udevice *bus; |
503 | ||
504 | for (uclass_first_device(UCLASS_I2C, &bus); | |
505 | bus; | |
506 | uclass_next_device(&bus)) { | |
39de8433 | 507 | if (dev_get_driver_data(bus) == TYPE_DVC) { |
b0e6ef46 SG |
508 | *busp = bus; |
509 | return 0; | |
96a78ac0 YL |
510 | } |
511 | } | |
512 | ||
b0e6ef46 | 513 | return -ENODEV; |
96a78ac0 YL |
514 | } |
515 | ||
b0e6ef46 SG |
516 | static const struct dm_i2c_ops tegra_i2c_ops = { |
517 | .xfer = tegra_i2c_xfer, | |
518 | .probe_chip = tegra_i2c_probe_chip, | |
519 | .set_bus_speed = tegra_i2c_set_bus_speed, | |
520 | }; | |
e31c1e50 | 521 | |
b0e6ef46 SG |
522 | static const struct udevice_id tegra_i2c_ids[] = { |
523 | { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, | |
524 | { .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD }, | |
525 | { .compatible = "nvidia,tegra20-i2c-dvc", .data = TYPE_DVC }, | |
526 | { } | |
527 | }; | |
528 | ||
529 | U_BOOT_DRIVER(i2c_tegra) = { | |
530 | .name = "i2c_tegra", | |
531 | .id = UCLASS_I2C, | |
532 | .of_match = tegra_i2c_ids, | |
b0e6ef46 | 533 | .probe = tegra_i2c_probe, |
b0e6ef46 SG |
534 | .priv_auto_alloc_size = sizeof(struct i2c_bus), |
535 | .ops = &tegra_i2c_ops, | |
536 | }; |