From 7b0c0f69a465661f7273c9343d017481dcdf2e39 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 11 Oct 2014 18:42:56 +0200 Subject: i2c: s3c: Implant support for S3C2440 This is a matter of simple additional ifdefery to cater for the different register layout of the S3C2440 chip. Signed-off-by: Marek Vasut Cc: Heiko Schocher Cc: Kyungmin Park Cc: Lukasz Majewski Cc: Minkyu Kang Cc: Vladimir Zapolskiy Signed-off-by: Minkyu Kang diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 27ff587..c053e84 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -165,7 +165,7 @@ static int GetI2CSDA(void) { struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) return (readl(&gpio->gpedat) & 0x8000) >> 15; #endif #ifdef CONFIG_S3C2400 @@ -177,7 +177,7 @@ static void SetI2CSCL(int x) { struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) writel((readl(&gpio->gpedat) & ~0x4000) | (x & 1) << 14, &gpio->gpedat); #endif @@ -443,7 +443,7 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) int i; if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) { -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) ulong old_gpecon = readl(&gpio->gpecon); #endif #ifdef CONFIG_S3C2400 @@ -452,7 +452,7 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) /* bus still busy probably by (most) previously interrupted transfer */ -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */ writel((readl(&gpio->gpecon) & ~0xF0000000) | 0x10000000, &gpio->gpecon); @@ -478,7 +478,7 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) udelay(1000); /* restore pin functions */ -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) writel(old_gpecon, &gpio->gpecon); #endif #ifdef CONFIG_S3C2400 -- cgit v0.10.2 From 13cfd101dda099db55593fd42ddb6e387f2f3065 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 11 Oct 2014 18:42:57 +0200 Subject: gpio: s3c: Fix the GPIO driver The GPIO driver didn't correctly compute the bank offset from the GPIO number and caused random writes into the GPIO block address space. Fix the driver so it actually does the writes correctly. While at it, make use of the clrsetbits_le32() mechanisms. Signed-off-by: Marek Vasut Cc: Kyungmin Park Cc: Lukasz Majewski Cc: Minkyu Kang Cc: Vladimir Zapolskiy Signed-off-by: Minkyu Kang diff --git a/drivers/gpio/s3c2440_gpio.c b/drivers/gpio/s3c2440_gpio.c index e1e2d3f..d6c7eeb 100644 --- a/drivers/gpio/s3c2440_gpio.c +++ b/drivers/gpio/s3c2440_gpio.c @@ -8,53 +8,50 @@ #include #include #include +#include #define GPIO_INPUT 0x0 #define GPIO_OUTPUT 0x1 -/* 0x4 means that we want DAT and not CON register */ -#define GPIO_PORT(x) ((((x) >> 5) & 0x3) + 0x4) -#define GPIO_BIT(x) ((x) & 0x3f) +#define S3C_GPIO_CON 0x0 +#define S3C_GPIO_DAT 0x4 -/* - * It's how we calculate the full port address - * We have to get the number of the port + 1 (Port A is at 0x56000001 ...) - * We move it at the second digit, and finally we add 0x4 because we want - * to modify GPIO DAT and not CON - */ -#define GPIO_FULLPORT(x) (S3C24X0_GPIO_BASE | ((GPIO_PORT(gpio) + 1) << 1)) +static uint32_t s3c_gpio_get_bank_addr(unsigned gpio) +{ + /* There is up to 16 pins per bank, one bank is 0x10 big. */ + uint32_t addr = gpio & ~0xf; + + if (addr >= 0x80 && addr != 0xd0) { /* Wrong GPIO bank. */ + printf("Invalid GPIO bank (bank %02x)\n", addr); + return 0xffffffff; + } + + return addr | S3C24X0_GPIO_BASE; +} int gpio_set_value(unsigned gpio, int value) { - unsigned l = readl(GPIO_FULLPORT(gpio)); - unsigned bit; - unsigned port = GPIO_FULLPORT(gpio); - - /* - * All GPIO Port have a configuration on - * 2 bits excepted the first GPIO (A) which - * have only 1 bit of configuration. - */ - if (!GPIO_PORT(gpio)) - bit = (0x1 << GPIO_BIT(gpio)); - else - bit = (0x3 << GPIO_BIT(gpio)); + uint32_t addr = s3c_gpio_get_bank_addr(gpio); + + if (addr == 0xffffffff) + return -EINVAL; if (value) - l |= bit; + setbits_le32(addr | S3C_GPIO_DAT, 1 << (gpio & 0xf)); else - l &= ~bit; + clrbits_le32(addr | S3C_GPIO_DAT, 1 << (gpio & 0xf)); - return writel(l, port); + return 0; } int gpio_get_value(unsigned gpio) { - unsigned l = readl(GPIO_FULLPORT(gpio)); + uint32_t addr = s3c_gpio_get_bank_addr(gpio); + + if (addr == 0xffffffff) + return -EINVAL; - if (GPIO_PORT(gpio) == 0) /* PORT A */ - return (l >> GPIO_BIT(gpio)) & 0x1; - return (l >> GPIO_BIT(gpio)) & 0x3; + return !!(readl(addr | S3C_GPIO_DAT) & (1 << (gpio & 0xf))); } int gpio_request(unsigned gpio, const char *label) @@ -67,13 +64,25 @@ int gpio_free(unsigned gpio) return 0; } +static int s3c_gpio_direction(unsigned gpio, uint8_t dir) +{ + uint32_t addr = s3c_gpio_get_bank_addr(gpio); + const uint32_t mask = 0x3 << ((gpio & 0xf) << 1); + const uint32_t dirm = dir << ((gpio & 0xf) << 1); + + if (addr == 0xffffffff) + return -EINVAL; + + clrsetbits_le32(addr | S3C_GPIO_CON, mask, dirm); + return 0; +} + int gpio_direction_input(unsigned gpio) { - return writel(GPIO_INPUT << GPIO_BIT(gpio), GPIO_FULLPORT(gpio)); + return s3c_gpio_direction(gpio, GPIO_INPUT); } int gpio_direction_output(unsigned gpio, int value) { - writel(GPIO_OUTPUT << GPIO_BIT(gpio), GPIO_FULLPORT(gpio)); - return gpio_set_value(gpio, value); + return s3c_gpio_direction(gpio, GPIO_OUTPUT); } -- cgit v0.10.2 From cf85202770d95474ba341b8881f9b76589244bed Mon Sep 17 00:00:00 2001 From: Minkyu Kang Date: Mon, 11 May 2015 16:27:07 +0900 Subject: exynos: clock: clean up checkpatch issues Signed-off-by: Minkyu Kang diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index df4d473..1c6baa1 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -1362,7 +1362,7 @@ int exynos5_set_i2s_clk_prescaler(unsigned int src_frq, } clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK, (div & AUDIO_0_RATIO_MASK)); - } else if(i2s_id == 1) { + } else if (i2s_id == 1) { if (div > AUDIO_1_RATIO_MASK) { debug("%s: Frequency ratio is out of range\n", __func__); @@ -1579,45 +1579,49 @@ unsigned long get_pll_clk(int pllreg) if (proid_is_exynos5420() || proid_is_exynos5800()) return exynos542x_get_pll_clk(pllreg); return exynos5_get_pll_clk(pllreg); - } else { + } else if (cpu_is_exynos4()) { if (proid_is_exynos4412()) return exynos4x12_get_pll_clk(pllreg); return exynos4_get_pll_clk(pllreg); } + + return 0; } unsigned long get_arm_clk(void) { - if (cpu_is_exynos5()) + if (cpu_is_exynos5()) { return exynos5_get_arm_clk(); - else { + } else if (cpu_is_exynos4()) { if (proid_is_exynos4412()) return exynos4x12_get_arm_clk(); return exynos4_get_arm_clk(); } + + return 0; } unsigned long get_i2c_clk(void) { - if (cpu_is_exynos5()) { + if (cpu_is_exynos5()) return clock_get_periph_rate(PERIPH_ID_I2C0); - } else if (cpu_is_exynos4()) { + else if (cpu_is_exynos4()) return exynos4_get_i2c_clk(); - } else { - debug("I2C clock is not set for this CPU\n"); - return 0; - } + + return 0; } unsigned long get_pwm_clk(void) { if (cpu_is_exynos5()) { return clock_get_periph_rate(PERIPH_ID_PWM0); - } else { + } else if (cpu_is_exynos4()) { if (proid_is_exynos4412()) return exynos4x12_get_pwm_clk(); return exynos4_get_pwm_clk(); } + + return 0; } unsigned long get_uart_clk(int dev_index) @@ -1644,11 +1648,13 @@ unsigned long get_uart_clk(int dev_index) if (cpu_is_exynos5()) { return clock_get_periph_rate(id); - } else { + } else if (cpu_is_exynos4()) { if (proid_is_exynos4412()) return exynos4x12_get_uart_clk(dev_index); return exynos4_get_uart_clk(dev_index); } + + return 0; } unsigned long get_mmc_clk(int dev_index) @@ -1673,11 +1679,12 @@ unsigned long get_mmc_clk(int dev_index) return -1; } - if (cpu_is_exynos5()) { + if (cpu_is_exynos5()) return clock_get_periph_rate(id); - } else { + else if (cpu_is_exynos4()) return exynos4_get_mmc_clk(dev_index); - } + + return 0; } void set_mmc_clk(int dev_index, unsigned int div) @@ -1691,16 +1698,16 @@ void set_mmc_clk(int dev_index, unsigned int div) exynos5420_set_mmc_clk(dev_index, div); else exynos5_set_mmc_clk(dev_index, div); - } else { + } else if (cpu_is_exynos4()) { exynos4_set_mmc_clk(dev_index, div); } } unsigned long get_lcd_clk(void) { - if (cpu_is_exynos4()) + if (cpu_is_exynos4()) { return exynos4_get_lcd_clk(); - else { + } else if (cpu_is_exynos5()) { if (proid_is_exynos5420()) return exynos5420_get_lcd_clk(); else if (proid_is_exynos5800()) @@ -1708,13 +1715,15 @@ unsigned long get_lcd_clk(void) else return exynos5_get_lcd_clk(); } + + return 0; } void set_lcd_clk(void) { - if (cpu_is_exynos4()) + if (cpu_is_exynos4()) { exynos4_set_lcd_clk(); - else { + } else if (cpu_is_exynos5()) { if (proid_is_exynos5250()) exynos5_set_lcd_clk(); else if (proid_is_exynos5420()) @@ -1736,9 +1745,9 @@ int set_spi_clk(int periph_id, unsigned int rate) if (proid_is_exynos5420() || proid_is_exynos5800()) return exynos5420_set_spi_clk(periph_id, rate); return exynos5_set_spi_clk(periph_id, rate); - } else { - return 0; } + + return 0; } int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, @@ -1746,22 +1755,22 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, { if (cpu_is_exynos5()) return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id); - else - return 0; + + return 0; } int set_i2s_clk_source(unsigned int i2s_id) { if (cpu_is_exynos5()) return exynos5_set_i2s_clk_source(i2s_id); - else - return 0; + + return 0; } int set_epll_clk(unsigned long rate) { if (cpu_is_exynos5()) return exynos5_set_epll_clk(rate); - else - return 0; + + return 0; } -- cgit v0.10.2