diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index cba7f848942..52067fa7c1f 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -650,7 +650,7 @@ config SYS_I2C_GENI config SYS_I2C_S3C24X0 bool "Samsung I2C driver" - depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && DM_I2C + depends on DM_I2C help Support for Samsung I2C controller as Samsung SoCs. diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c index 189ce6d5096..fa0d1c8f64a 100644 --- a/drivers/i2c/exynos_hs_i2c.c +++ b/drivers/i2c/exynos_hs_i2c.c @@ -9,11 +9,15 @@ #include #include #include +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) #include #include #include +#endif #include +#include #include +#include #include "s3c24x0_i2c.h" DECLARE_GLOBAL_DATA_PTR; @@ -137,15 +141,26 @@ static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c) return I2C_NOK_TOUT; } -static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) +static int hsi2c_get_clk_details(struct udevice *dev) { + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; ulong clkin; unsigned int op_clk = i2c_bus->clock_frequency; unsigned int i = 0, utemp0 = 0, utemp1 = 0; unsigned int t_ftl_cycle; +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) clkin = get_i2c_clk(); +#else + struct clk clk; + int ret; + + ret = clk_get_by_name(dev, "hsi2c", &clk); + if (ret < 0) + return ret; + clkin = clk_get_rate(&clk); +#endif /* FPCLK / FI2C = * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE * uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) @@ -487,7 +502,7 @@ static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) i2c_bus->clock_frequency = speed; - if (hsi2c_get_clk_details(i2c_bus)) + if (hsi2c_get_clk_details(dev)) return -EFAULT; hsi2c_ch_init(i2c_bus); @@ -514,7 +529,9 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) static int s3c_i2c_of_to_plat(struct udevice *dev) { +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) const void *blob = gd->fdt_blob; +#endif struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); int node; @@ -522,7 +539,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev) i2c_bus->hsregs = dev_read_addr_ptr(dev); +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) i2c_bus->id = pinmux_decode_periph_id(blob, node); +#endif i2c_bus->clock_frequency = dev_read_u32_default(dev, "clock-frequency", @@ -530,7 +549,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev) i2c_bus->node = node; i2c_bus->bus_num = dev_seq(dev); +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE); +#endif i2c_bus->active = true; diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index ae3a801cad1..ade1ad6cef7 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,12 +9,15 @@ #include #include #include +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) #include #include #include +#endif #include #include #include +#include #include "s3c24x0_i2c.h" DECLARE_GLOBAL_DATA_PTR; @@ -46,10 +49,23 @@ static void read_write_byte(struct s3c24x0_i2c *i2c) clrbits_le32(&i2c->iiccon, I2CCON_IRPND); } -static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) +static int i2c_ch_init(struct udevice *dev, int speed, int slaveadd) { + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + struct s3c24x0_i2c *i2c = i2c_bus->regs; ulong freq, pres = 16, div; + +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) freq = get_i2c_clk(); +#else + struct clk clk; + int ret; + + ret = clk_get_by_name(dev, "i2c", &clk); + if (ret < 0) + return ret; + freq = clk_get_rate(&clk); +#endif /* calculate prescaler and divisor values */ if ((freq / pres / (16 + 1)) > speed) /* set prescaler to 512 */ @@ -67,6 +83,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) writel(slaveadd, &i2c->iicadd); /* program Master Transmit (and implicit STOP) */ writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); + return 0; } #define SYS_I2C_S3C24X0_SLAVE_ADDR 0 @@ -77,8 +94,9 @@ static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) i2c_bus->clock_frequency = speed; - i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, - SYS_I2C_S3C24X0_SLAVE_ADDR); + if (i2c_ch_init(dev, i2c_bus->clock_frequency, + SYS_I2C_S3C24X0_SLAVE_ADDR)) + return -EFAULT; return 0; } @@ -293,7 +311,9 @@ static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, static int s3c_i2c_of_to_plat(struct udevice *dev) { +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) const void *blob = gd->fdt_blob; +#endif struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); int node; @@ -301,7 +321,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev) i2c_bus->regs = dev_read_addr_ptr(dev); +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) i2c_bus->id = pinmux_decode_periph_id(blob, node); +#endif i2c_bus->clock_frequency = dev_read_u32_default(dev, "clock-frequency", @@ -309,7 +331,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev) i2c_bus->node = node; i2c_bus->bus_num = dev_seq(dev); +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) exynos_pinmux_config(i2c_bus->id, 0); +#endif i2c_bus->active = true; diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index ec8f1acaef5..12249d5c141 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -54,7 +54,9 @@ struct s3c24x0_i2c_bus { struct exynos5_hsi2c *hsregs; int is_highspeed; /* High speed type, rather than I2C */ unsigned clock_frequency; +#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5) int id; +#endif unsigned clk_cycle; unsigned clk_div; };