Commit a9d2ae7014d9e66dde6dd4a344308449508e4a22
Committed by
Minkyu Kang
1 parent
d055911887
Exists in
master
and in
54 other branches
I2C: Driver changes for FDT support
Functions added to get the I2C bus number and reset I2C bus using FDT node. Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> Acked-by: Simon Glass <sjg@chromium.org> Acked-by: Heiko Schocher <hs@denx.de> Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
Showing 3 changed files with 116 additions and 1 deletions Side-by-side Diff
drivers/i2c/s3c24x0_i2c.c
... | ... | @@ -27,9 +27,11 @@ |
27 | 27 | */ |
28 | 28 | |
29 | 29 | #include <common.h> |
30 | +#include <fdtdec.h> | |
30 | 31 | #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) |
31 | 32 | #include <asm/arch/clk.h> |
32 | 33 | #include <asm/arch/cpu.h> |
34 | +#include <asm/arch/pinmux.h> | |
33 | 35 | #else |
34 | 36 | #include <asm/arch/s3c24x0_cpu.h> |
35 | 37 | #endif |
... | ... | @@ -60,7 +62,14 @@ |
60 | 62 | #define I2C_TIMEOUT 1 /* 1 second */ |
61 | 63 | |
62 | 64 | |
63 | -static unsigned int g_current_bus; /* Stores Current I2C Bus */ | |
65 | +/* | |
66 | + * For SPL boot some boards need i2c before SDRAM is initialised so force | |
67 | + * variables to live in SRAM | |
68 | + */ | |
69 | +static unsigned int g_current_bus __attribute__((section(".data"))); | |
70 | +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] | |
71 | + __attribute__((section(".data"))); | |
72 | +static int i2c_busses __attribute__((section(".data"))); | |
64 | 73 | |
65 | 74 | #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) |
66 | 75 | static int GetI2CSDA(void) |
... | ... | @@ -512,5 +521,77 @@ |
512 | 521 | (i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, |
513 | 522 | len) != 0); |
514 | 523 | } |
524 | + | |
525 | +#ifdef CONFIG_OF_CONTROL | |
526 | +void board_i2c_init(const void *blob) | |
527 | +{ | |
528 | + int node_list[CONFIG_MAX_I2C_NUM]; | |
529 | + int count, i; | |
530 | + | |
531 | + count = fdtdec_find_aliases_for_id(blob, "i2c", | |
532 | + COMPAT_SAMSUNG_S3C2440_I2C, node_list, | |
533 | + CONFIG_MAX_I2C_NUM); | |
534 | + | |
535 | + for (i = 0; i < count; i++) { | |
536 | + struct s3c24x0_i2c_bus *bus; | |
537 | + int node = node_list[i]; | |
538 | + | |
539 | + if (node <= 0) | |
540 | + continue; | |
541 | + bus = &i2c_bus[i]; | |
542 | + bus->regs = (struct s3c24x0_i2c *) | |
543 | + fdtdec_get_addr(blob, node, "reg"); | |
544 | + bus->id = pinmux_decode_periph_id(blob, node); | |
545 | + bus->node = node; | |
546 | + bus->bus_num = i2c_busses++; | |
547 | + exynos_pinmux_config(bus->id, 0); | |
548 | + } | |
549 | +} | |
550 | + | |
551 | +static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) | |
552 | +{ | |
553 | + if (bus_idx < i2c_busses) | |
554 | + return &i2c_bus[bus_idx]; | |
555 | + | |
556 | + debug("Undefined bus: %d\n", bus_idx); | |
557 | + return NULL; | |
558 | +} | |
559 | + | |
560 | +int i2c_get_bus_num_fdt(int node) | |
561 | +{ | |
562 | + int i; | |
563 | + | |
564 | + for (i = 0; i < i2c_busses; i++) { | |
565 | + if (node == i2c_bus[i].node) | |
566 | + return i; | |
567 | + } | |
568 | + | |
569 | + debug("%s: Can't find any matched I2C bus\n", __func__); | |
570 | + return -1; | |
571 | +} | |
572 | + | |
573 | +int i2c_reset_port_fdt(const void *blob, int node) | |
574 | +{ | |
575 | + struct s3c24x0_i2c_bus *i2c; | |
576 | + int bus; | |
577 | + | |
578 | + bus = i2c_get_bus_num_fdt(node); | |
579 | + if (bus < 0) { | |
580 | + debug("could not get bus for node %d\n", node); | |
581 | + return -1; | |
582 | + } | |
583 | + | |
584 | + i2c = get_bus(bus); | |
585 | + if (!i2c) { | |
586 | + debug("get_bus() failed for node node %d\n", node); | |
587 | + return -1; | |
588 | + } | |
589 | + | |
590 | + i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | |
591 | + | |
592 | + return 0; | |
593 | +} | |
594 | +#endif | |
595 | + | |
515 | 596 | #endif /* CONFIG_HARD_I2C */ |
drivers/i2c/s3c24x0_i2c.h
include/i2c.h
... | ... | @@ -262,5 +262,31 @@ |
262 | 262 | extern int get_multi_sda_pin(void); |
263 | 263 | extern int multi_i2c_init(void); |
264 | 264 | #endif |
265 | + | |
266 | +/** | |
267 | + * Get FDT values for i2c bus. | |
268 | + * | |
269 | + * @param blob Device tree blbo | |
270 | + * @return the number of I2C bus | |
271 | + */ | |
272 | +void board_i2c_init(const void *blob); | |
273 | + | |
274 | +/** | |
275 | + * Find the I2C bus number by given a FDT I2C node. | |
276 | + * | |
277 | + * @param blob Device tree blbo | |
278 | + * @param node FDT I2C node to find | |
279 | + * @return the number of I2C bus (zero based), or -1 on error | |
280 | + */ | |
281 | +int i2c_get_bus_num_fdt(int node); | |
282 | + | |
283 | +/** | |
284 | + * Reset the I2C bus represented by the given a FDT I2C node. | |
285 | + * | |
286 | + * @param blob Device tree blbo | |
287 | + * @param node FDT I2C node to find | |
288 | + * @return 0 if port was reset, -1 if not found | |
289 | + */ | |
290 | +int i2c_reset_port_fdt(const void *blob, int node); | |
265 | 291 | #endif /* _I2C_H_ */ |