Commit a9d2ae7014d9e66dde6dd4a344308449508e4a22

Authored by Rajeshwari Shinde
Committed by Minkyu Kang
1 parent d055911887

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
... ... @@ -30,5 +30,13 @@
30 30 u32 iicds;
31 31 u32 iiclc;
32 32 };
  33 +
  34 +struct s3c24x0_i2c_bus {
  35 + int node; /* device tree node */
  36 + int bus_num; /* i2c bus number */
  37 + struct s3c24x0_i2c *regs;
  38 + enum periph_id id;
  39 +};
  40 +
33 41 #endif /* _S3C24X0_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_ */