[U-Boot] [PATCH 0/2] EXYNOS5: Add GPIO numbering feature

This patchset adds GPIO numbering feature where pinmux setting can be done just by seding the pin munber and we do not have to remember which bank it belongs to.
Rajeshwari Shinde (2): S5P: GPIO: Add generic pin mumbering API's EXYNOS5: Add gpio pin numbering feature
arch/arm/cpu/armv7/exynos/pinmux.c | 148 +++++-------- arch/arm/include/asm/arch-exynos/gpio.h | 366 ++++++++++++++++++++++++++++++- drivers/gpio/s5p_gpio.c | 18 ++ 3 files changed, 437 insertions(+), 95 deletions(-)

This patch adds API's to set config,drive and pull factor in gpio pin mumbering feature.
Signed-off-by: Rajeshawari Shinde rajeshwari.s@samsung.com --- drivers/gpio/s5p_gpio.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c index 656bf4a..a53bdca 100644 --- a/drivers/gpio/s5p_gpio.c +++ b/drivers/gpio/s5p_gpio.c @@ -196,3 +196,21 @@ int gpio_set_value(unsigned gpio, int value)
return 0; } + +void gpio_set_pull(int gpio, int mode) +{ + s5p_gpio_set_pull(s5p_gpio_get_bank(gpio), + s5p_gpio_get_pin(gpio), mode); +} + +void gpio_set_drv(int gpio, int mode) +{ + s5p_gpio_set_drv(s5p_gpio_get_bank(gpio), + s5p_gpio_get_pin(gpio), mode); +} + +void gpio_cfg_pin(int gpio, int cfg) +{ + s5p_gpio_cfg_pin(s5p_gpio_get_bank(gpio), + s5p_gpio_get_pin(gpio), cfg); +}

This patch adds support for gpio pin numbering support on EXYNOS5 pinmux.
Signed-off-by: Leela Krishna Amudala l.krishna@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 148 +++++-------- arch/arm/include/asm/arch-exynos/gpio.h | 360 ++++++++++++++++++++++++++++++- 2 files changed, 413 insertions(+), 95 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index f02f441..9b4355a 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -28,89 +28,77 @@
static void exynos5_uart_config(int peripheral) { - struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); - struct s5p_gpio_bank *bank; int i, start, count;
switch (peripheral) { case PERIPH_ID_UART0: - bank = &gpio1->a0; - start = 0; + start = GPIO_A00; count = 4; break; case PERIPH_ID_UART1: - bank = &gpio1->d0; - start = 0; + start = GPIO_D00; count = 4; break; case PERIPH_ID_UART2: - bank = &gpio1->a1; - start = 0; + start = GPIO_A10; count = 4; break; case PERIPH_ID_UART3: - bank = &gpio1->a1; - start = 4; + start = GPIO_A14; count = 2; break; } for (i = start; i < start + count; i++) { - s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); - s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + gpio_set_pull(i, GPIO_PULL_NONE); + gpio_cfg_pin(i, GPIO_FUNC(0x2)); } }
static int exynos5_mmc_config(int peripheral, int flags) { - struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); - struct s5p_gpio_bank *bank, *bank_ext; - int i, start = 0, gpio_func = 0; + int i, start, start_ext, gpio_func = 0;
switch (peripheral) { case PERIPH_ID_SDMMC0: - bank = &gpio1->c0; - bank_ext = &gpio1->c1; - start = 0; + start = GPIO_C00; + start_ext = GPIO_C10; gpio_func = GPIO_FUNC(0x2); break; case PERIPH_ID_SDMMC1: - bank = &gpio1->c2; - bank_ext = NULL; + start = GPIO_C20; + start_ext = 0; break; case PERIPH_ID_SDMMC2: - bank = &gpio1->c3; - bank_ext = &gpio1->c4; - start = 3; + start = GPIO_C30; + start_ext = GPIO_C43; gpio_func = GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC3: - bank = &gpio1->c4; - bank_ext = NULL; + start = GPIO_C40; + start_ext = 0; break; } - if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { + if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) { debug("SDMMC device %d does not support 8bit mode", peripheral); return -1; } if (flags & PINMUX_FLAG_8BIT_MODE) { - for (i = start; i <= (start + 3); i++) { - s5p_gpio_cfg_pin(bank_ext, i, gpio_func); - s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); - s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); + for (i = start_ext; i <= (start_ext + 3); i++) { + gpio_cfg_pin(i, gpio_func); + gpio_set_pull(i, GPIO_PULL_UP); + gpio_set_drv(i, GPIO_DRV_4X); } } for (i = 0; i < 2; i++) { - s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); - s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); - s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + gpio_cfg_pin(start + i, GPIO_FUNC(0x2)); + gpio_set_pull(start + i, GPIO_PULL_NONE); + gpio_set_drv(start + i, GPIO_DRV_4X); } for (i = 3; i <= 6; i++) { - s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); - s5p_gpio_set_pull(bank, i, GPIO_PULL_UP); - s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + gpio_cfg_pin(start + i, GPIO_FUNC(0x2)); + gpio_set_pull(start + i, GPIO_PULL_UP); + gpio_set_drv(start + i, GPIO_DRV_4X); }
return 0; @@ -118,8 +106,6 @@ static int exynos5_mmc_config(int peripheral, int flags)
static void exynos5_sromc_config(int flags) { - struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); int i;
/* @@ -137,13 +123,13 @@ static void exynos5_sromc_config(int flags) * GPY1[2] SROM_WAIT(2) * GPY1[3] EBI_DATA_RDn(2) */ - s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK), + gpio_cfg_pin(GPIO_Y00 + (flags & PINMUX_FLAG_BANK), GPIO_FUNC(2)); - s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2)); - s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2)); + gpio_cfg_pin(GPIO_Y04, GPIO_FUNC(2)); + gpio_cfg_pin(GPIO_Y05, GPIO_FUNC(2));
for (i = 0; i < 4; i++) - s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2)); + gpio_cfg_pin(GPIO_Y10 + i, GPIO_FUNC(2));
/* * EBI: 8 Addrss Lines @@ -178,55 +164,52 @@ static void exynos5_sromc_config(int flags) * GPY6[7] EBI_DATA[15](2) */ for (i = 0; i < 8; i++) { - s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2)); - s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP); + gpio_cfg_pin(GPIO_Y30 + i, GPIO_FUNC(2)); + gpio_set_pull(GPIO_Y30 + i, GPIO_PULL_UP);
- s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2)); - s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP); + gpio_cfg_pin(GPIO_Y50 + i, GPIO_FUNC(2)); + gpio_set_pull(GPIO_Y50 + i, GPIO_PULL_UP);
- s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2)); - s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP); + gpio_cfg_pin(GPIO_Y60 + i, GPIO_FUNC(2)); + gpio_set_pull(GPIO_Y60 + i, GPIO_PULL_UP); } }
static void exynos5_i2c_config(int peripheral, int flags) {
- struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); - switch (peripheral) { case PERIPH_ID_I2C0: - s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2)); - s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2)); + gpio_cfg_pin(GPIO_B30, GPIO_FUNC(0x2)); + gpio_cfg_pin(GPIO_B31, GPIO_FUNC(0x2)); break; case PERIPH_ID_I2C1: - s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2)); - s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2)); + gpio_cfg_pin(GPIO_B32, GPIO_FUNC(0x2)); + gpio_cfg_pin(GPIO_B33, GPIO_FUNC(0x2)); break; case PERIPH_ID_I2C2: - s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3)); - s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A06, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A07, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C3: - s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3)); - s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A12, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A13, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C4: - s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3)); - s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A20, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A21, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C5: - s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3)); - s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A22, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_A23, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C6: - s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4)); - s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4)); + gpio_cfg_pin(GPIO_B13, GPIO_FUNC(0x4)); + gpio_cfg_pin(GPIO_B14, GPIO_FUNC(0x4)); break; case PERIPH_ID_I2C7: - s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3)); - s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_B22, GPIO_FUNC(0x3)); + gpio_cfg_pin(GPIO_B23, GPIO_FUNC(0x3)); break; } } @@ -234,53 +217,42 @@ static void exynos5_i2c_config(int peripheral, int flags) static void exynos5_i2s_config(int peripheral) { int i; - struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
for (i = 0; i < 5; i++) - s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02)); + gpio_cfg_pin(GPIO_B00+i, GPIO_FUNC(0x02)); }
void exynos5_spi_config(int peripheral) { int cfg = 0, pin = 0, i; - struct s5p_gpio_bank *bank = NULL; - struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); - struct exynos5_gpio_part2 *gpio2 = - (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
switch (peripheral) { case PERIPH_ID_SPI0: - bank = &gpio1->a2; cfg = GPIO_FUNC(0x2); - pin = 0; + pin = GPIO_A20; break; case PERIPH_ID_SPI1: - bank = &gpio1->a2; cfg = GPIO_FUNC(0x2); - pin = 4; + pin = GPIO_A24; break; case PERIPH_ID_SPI2: - bank = &gpio1->b1; cfg = GPIO_FUNC(0x5); - pin = 1; + pin = GPIO_B11; break; case PERIPH_ID_SPI3: - bank = &gpio2->f1; cfg = GPIO_FUNC(0x2); - pin = 0; + pin = GPIO_F10; break; case PERIPH_ID_SPI4: for (i = 0; i < 2; i++) { - s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4)); - s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4)); + gpio_cfg_pin(GPIO_F02 + i, GPIO_FUNC(0x4)); + gpio_cfg_pin(GPIO_E04 + i, GPIO_FUNC(0x4)); } break; } if (peripheral != PERIPH_ID_SPI4) { for (i = pin; i < pin + 4; i++) - s5p_gpio_cfg_pin(bank, i, cfg); + gpio_cfg_pin(i, cfg); } }
diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h index 4db8fd6..cf69895 100644 --- a/arch/arm/include/asm/arch-exynos/gpio.h +++ b/arch/arm/include/asm/arch-exynos/gpio.h @@ -187,15 +187,355 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode); - EXYNOS5_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \ * GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART2_MAX)
+/* A list of valid GPIO numbers for the asm-generic/gpio.h interface */ +enum exynos5_gpio_pin { + /* GPIO_PART1_STARTS */ + GPIO_A00, + GPIO_A01, + GPIO_A02, + GPIO_A03, + GPIO_A04, + GPIO_A05, + GPIO_A06, + GPIO_A07, + GPIO_A10, + GPIO_A11, + GPIO_A12, + GPIO_A13, + GPIO_A14, + GPIO_A15, + GPIO_A16, + GPIO_A17, + GPIO_A20, + GPIO_A21, + GPIO_A22, + GPIO_A23, + GPIO_A24, + GPIO_A25, + GPIO_A26, + GPIO_A27, + GPIO_B00, + GPIO_B01, + GPIO_B02, + GPIO_B03, + GPIO_B04, + GPIO_B05, + GPIO_B06, + GPIO_B07, + GPIO_B10, + GPIO_B11, + GPIO_B12, + GPIO_B13, + GPIO_B14, + GPIO_B15, + GPIO_B16, + GPIO_B17, + GPIO_B20, + GPIO_B21, + GPIO_B22, + GPIO_B23, + GPIO_B24, + GPIO_B25, + GPIO_B26, + GPIO_B27, + GPIO_B30, + GPIO_B31, + GPIO_B32, + GPIO_B33, + GPIO_B34, + GPIO_B35, + GPIO_B36, + GPIO_B37, + GPIO_C00, + GPIO_C01, + GPIO_C02, + GPIO_C03, + GPIO_C04, + GPIO_C05, + GPIO_C06, + GPIO_C07, + GPIO_C10, + GPIO_C11, + GPIO_C12, + GPIO_C13, + GPIO_C14, + GPIO_C15, + GPIO_C16, + GPIO_C17, + GPIO_C20, + GPIO_C21, + GPIO_C22, + GPIO_C23, + GPIO_C24, + GPIO_C25, + GPIO_C26, + GPIO_C27, + GPIO_C30, + GPIO_C31, + GPIO_C32, + GPIO_C33, + GPIO_C34, + GPIO_C35, + GPIO_C36, + GPIO_C37, + GPIO_D00, + GPIO_D01, + GPIO_D02, + GPIO_D03, + GPIO_D04, + GPIO_D05, + GPIO_D06, + GPIO_D07, + GPIO_D10, + GPIO_D11, + GPIO_D12, + GPIO_D13, + GPIO_D14, + GPIO_D15, + GPIO_D16, + GPIO_D17, + GPIO_Y00, + GPIO_Y01, + GPIO_Y02, + GPIO_Y03, + GPIO_Y04, + GPIO_Y05, + GPIO_Y06, + GPIO_Y07, + GPIO_Y10, + GPIO_Y11, + GPIO_Y12, + GPIO_Y13, + GPIO_Y14, + GPIO_Y15, + GPIO_Y16, + GPIO_Y17, + GPIO_Y20, + GPIO_Y21, + GPIO_Y22, + GPIO_Y23, + GPIO_Y24, + GPIO_Y25, + GPIO_Y26, + GPIO_Y27, + GPIO_Y30, + GPIO_Y31, + GPIO_Y32, + GPIO_Y33, + GPIO_Y34, + GPIO_Y35, + GPIO_Y36, + GPIO_Y37, + GPIO_Y40, + GPIO_Y41, + GPIO_Y42, + GPIO_Y43, + GPIO_Y44, + GPIO_Y45, + GPIO_Y46, + GPIO_Y47, + GPIO_Y50, + GPIO_Y51, + GPIO_Y52, + GPIO_Y53, + GPIO_Y54, + GPIO_Y55, + GPIO_Y56, + GPIO_Y57, + GPIO_Y60, + GPIO_Y61, + GPIO_Y62, + GPIO_Y63, + GPIO_Y64, + GPIO_Y65, + GPIO_Y66, + GPIO_Y67, + RES = GPIO_Y67 + (0x3 * GPIO_PER_BANK), + GPIO_C40, + GPIO_C41, + GPIO_C42, + GPIO_C43, + GPIO_C44, + GPIO_C45, + GPIO_C46, + GPIO_C47, + RES1 = GPIO_C47 + (0x48 * GPIO_PER_BANK), + GPIO_X00, + GPIO_X01, + GPIO_X02, + GPIO_X03, + GPIO_X04, + GPIO_X05, + GPIO_X06, + GPIO_X07, + GPIO_X10, + GPIO_X11, + GPIO_X12, + GPIO_X13, + GPIO_X14, + GPIO_X15, + GPIO_X16, + GPIO_X17, + GPIO_X20, + GPIO_X21, + GPIO_X22, + GPIO_X23, + GPIO_X24, + GPIO_X25, + GPIO_X26, + GPIO_X27, + GPIO_X30, + GPIO_X31, + GPIO_X32, + GPIO_X33, + GPIO_X34, + GPIO_X35, + GPIO_X36, + GPIO_X37, + + /* GPIO_PART2_STARTS */ + GPIO_PART1_MAX, + GPIO_E00 = GPIO_PART1_MAX, + GPIO_E01, + GPIO_E02, + GPIO_E03, + GPIO_E04, + GPIO_E05, + GPIO_E06, + GPIO_E07, + GPIO_E10, + GPIO_E11, + GPIO_E12, + GPIO_E13, + GPIO_E14, + GPIO_E15, + GPIO_E16, + GPIO_E17, + GPIO_F00, + GPIO_F01, + GPIO_F02, + GPIO_F03, + GPIO_F04, + GPIO_F05, + GPIO_F06, + GPIO_F07, + GPIO_F10, + GPIO_F11, + GPIO_F12, + GPIO_F13, + GPIO_F14, + GPIO_F15, + GPIO_F16, + GPIO_F17, + GPIO_G00, + GPIO_G01, + GPIO_G02, + GPIO_G03, + GPIO_G04, + GPIO_G05, + GPIO_G06, + GPIO_G07, + GPIO_G10, + GPIO_G11, + GPIO_G12, + GPIO_G13, + GPIO_G14, + GPIO_G15, + GPIO_G16, + GPIO_G17, + GPIO_G20, + GPIO_G21, + GPIO_G22, + GPIO_G23, + GPIO_G24, + GPIO_G25, + GPIO_G26, + GPIO_G27, + GPIO_H00, + GPIO_H01, + GPIO_H02, + GPIO_H03, + GPIO_H04, + GPIO_H05, + GPIO_H06, + GPIO_H07, + GPIO_H10, + GPIO_H11, + GPIO_H12, + GPIO_H13, + GPIO_H14, + GPIO_H15, + GPIO_H16, + GPIO_H17, + + /* GPIO_PART3_STARTS */ + GPIO_PART2_MAX, + GPIO_V00 = GPIO_PART2_MAX, + GPIO_V01, + GPIO_V02, + GPIO_V03, + GPIO_V04, + GPIO_V05, + GPIO_V06, + GPIO_V07, + GPIO_V10, + GPIO_V11, + GPIO_V12, + GPIO_V13, + GPIO_V14, + GPIO_V15, + GPIO_V16, + GPIO_V17, + RES3 = GPIO_V17 + GPIO_PER_BANK, + GPIO_V20, + GPIO_V21, + GPIO_V22, + GPIO_V23, + GPIO_V24, + GPIO_V25, + GPIO_V26, + GPIO_V27, + GPIO_V30, + GPIO_V31, + GPIO_V32, + GPIO_V33, + GPIO_V34, + GPIO_V35, + GPIO_V36, + GPIO_V37, + RES4 = GPIO_V37 + GPIO_PER_BANK, + GPIO_V40, + GPIO_V41, + GPIO_V42, + GPIO_V43, + GPIO_V44, + GPIO_V45, + GPIO_V46, + GPIO_V47, + + /* GPIO_PART4_STARTS */ + GPIO_PART3_MAX, + GPIO_Z0 = GPIO_PART3_MAX, + GPIO_Z1, + GPIO_Z2, + GPIO_Z3, + GPIO_Z4, + GPIO_Z5, + GPIO_Z6, + GPIO_MAX_PORT +}; + static inline unsigned int s5p_gpio_base(int nr) { if (cpu_is_exynos5()) { - if (nr < EXYNOS5_GPIO_PART1_MAX) + if (nr < GPIO_PART1_MAX) return EXYNOS5_GPIO_PART1_BASE; - else if (nr < EXYNOS5_GPIO_PART2_MAX) + else if (nr < GPIO_PART2_MAX) return EXYNOS5_GPIO_PART2_BASE; - else + else if (nr < GPIO_PART3_MAX) return EXYNOS5_GPIO_PART3_BASE; + else + return EXYNOS5_GPIO_PART4_BASE;
} else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX) @@ -210,12 +550,14 @@ static inline unsigned int s5p_gpio_base(int nr) static inline unsigned int s5p_gpio_part_max(int nr) { if (cpu_is_exynos5()) { - if (nr < EXYNOS5_GPIO_PART1_MAX) + if (nr < GPIO_PART1_MAX) return 0; - else if (nr < EXYNOS5_GPIO_PART2_MAX) - return EXYNOS5_GPIO_PART1_MAX; + else if (nr < GPIO_PART2_MAX) + return GPIO_PART1_MAX; + else if (nr < GPIO_PART3_MAX) + return GPIO_PART2_MAX; else - return EXYNOS5_GPIO_PART2_MAX; + return GPIO_PART3_MAX;
} else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX) @@ -226,6 +568,10 @@ static inline unsigned int s5p_gpio_part_max(int nr)
return 0; } + +void gpio_cfg_pin(int gpio, int cfg); +void gpio_set_pull(int gpio, int mode); +void gpio_set_drv(int gpio, int mode); #endif
/* Pin configurations */

Hi,
On Wed, Dec 12, 2012 at 8:33 PM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds support for gpio pin numbering support on EXYNOS5 pinmux.
We already know that each exynos5 SoCs has different GPIO name and offsets. So it's good time to use proper soc prefix. e.g., EXYNOS5250_*. Since only exynos5250 is mainlined at this time.
Thank you, Kyungmin Park
Signed-off-by: Leela Krishna Amudala l.krishna@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
arch/arm/cpu/armv7/exynos/pinmux.c | 148 +++++-------- arch/arm/include/asm/arch-exynos/gpio.h | 360 ++++++++++++++++++++++++++++++- 2 files changed, 413 insertions(+), 95 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index f02f441..9b4355a 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -28,89 +28,77 @@
static void exynos5_uart_config(int peripheral) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
struct s5p_gpio_bank *bank; int i, start, count; switch (peripheral) { case PERIPH_ID_UART0:
bank = &gpio1->a0;
start = 0;
start = GPIO_A00; count = 4; break; case PERIPH_ID_UART1:
bank = &gpio1->d0;
start = 0;
start = GPIO_D00; count = 4; break; case PERIPH_ID_UART2:
bank = &gpio1->a1;
start = 0;
start = GPIO_A10; count = 4; break; case PERIPH_ID_UART3:
bank = &gpio1->a1;
start = 4;
start = GPIO_A14; count = 2; break; } for (i = start; i < start + count; i++) {
s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
gpio_set_pull(i, GPIO_PULL_NONE);
gpio_cfg_pin(i, GPIO_FUNC(0x2)); }
}
static int exynos5_mmc_config(int peripheral, int flags) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
struct s5p_gpio_bank *bank, *bank_ext;
int i, start = 0, gpio_func = 0;
int i, start, start_ext, gpio_func = 0; switch (peripheral) { case PERIPH_ID_SDMMC0:
bank = &gpio1->c0;
bank_ext = &gpio1->c1;
start = 0;
start = GPIO_C00;
start_ext = GPIO_C10; gpio_func = GPIO_FUNC(0x2); break; case PERIPH_ID_SDMMC1:
bank = &gpio1->c2;
bank_ext = NULL;
start = GPIO_C20;
start_ext = 0; break; case PERIPH_ID_SDMMC2:
bank = &gpio1->c3;
bank_ext = &gpio1->c4;
start = 3;
start = GPIO_C30;
start_ext = GPIO_C43; gpio_func = GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC3:
bank = &gpio1->c4;
bank_ext = NULL;
start = GPIO_C40;
start_ext = 0; break; }
if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) { debug("SDMMC device %d does not support 8bit mode", peripheral); return -1; } if (flags & PINMUX_FLAG_8BIT_MODE) {
for (i = start; i <= (start + 3); i++) {
s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
for (i = start_ext; i <= (start_ext + 3); i++) {
gpio_cfg_pin(i, gpio_func);
gpio_set_pull(i, GPIO_PULL_UP);
gpio_set_drv(i, GPIO_DRV_4X); } } for (i = 0; i < 2; i++) {
s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
gpio_cfg_pin(start + i, GPIO_FUNC(0x2));
gpio_set_pull(start + i, GPIO_PULL_NONE);
gpio_set_drv(start + i, GPIO_DRV_4X); } for (i = 3; i <= 6; i++) {
s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
gpio_cfg_pin(start + i, GPIO_FUNC(0x2));
gpio_set_pull(start + i, GPIO_PULL_UP);
gpio_set_drv(start + i, GPIO_DRV_4X); } return 0;
@@ -118,8 +106,6 @@ static int exynos5_mmc_config(int peripheral, int flags)
static void exynos5_sromc_config(int flags) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); int i; /*
@@ -137,13 +123,13 @@ static void exynos5_sromc_config(int flags) * GPY1[2] SROM_WAIT(2) * GPY1[3] EBI_DATA_RDn(2) */
s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
gpio_cfg_pin(GPIO_Y00 + (flags & PINMUX_FLAG_BANK), GPIO_FUNC(2));
s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
gpio_cfg_pin(GPIO_Y04, GPIO_FUNC(2));
gpio_cfg_pin(GPIO_Y05, GPIO_FUNC(2)); for (i = 0; i < 4; i++)
s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
gpio_cfg_pin(GPIO_Y10 + i, GPIO_FUNC(2)); /* * EBI: 8 Addrss Lines
@@ -178,55 +164,52 @@ static void exynos5_sromc_config(int flags) * GPY6[7] EBI_DATA[15](2) */ for (i = 0; i < 8; i++) {
s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
gpio_cfg_pin(GPIO_Y30 + i, GPIO_FUNC(2));
gpio_set_pull(GPIO_Y30 + i, GPIO_PULL_UP);
s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
gpio_cfg_pin(GPIO_Y50 + i, GPIO_FUNC(2));
gpio_set_pull(GPIO_Y50 + i, GPIO_PULL_UP);
s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
gpio_cfg_pin(GPIO_Y60 + i, GPIO_FUNC(2));
gpio_set_pull(GPIO_Y60 + i, GPIO_PULL_UP); }
}
static void exynos5_i2c_config(int peripheral, int flags) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
switch (peripheral) { case PERIPH_ID_I2C0:
s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B30, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B31, GPIO_FUNC(0x2)); break; case PERIPH_ID_I2C1:
s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B32, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B33, GPIO_FUNC(0x2)); break; case PERIPH_ID_I2C2:
s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A06, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A07, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C3:
s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A12, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A13, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C4:
s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A20, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A21, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C5:
s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A22, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A23, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C6:
s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_B13, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_B14, GPIO_FUNC(0x4)); break; case PERIPH_ID_I2C7:
s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_B22, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_B23, GPIO_FUNC(0x3)); break; }
} @@ -234,53 +217,42 @@ static void exynos5_i2c_config(int peripheral, int flags) static void exynos5_i2s_config(int peripheral) { int i;
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); for (i = 0; i < 5; i++)
s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
gpio_cfg_pin(GPIO_B00+i, GPIO_FUNC(0x02));
}
void exynos5_spi_config(int peripheral) { int cfg = 0, pin = 0, i;
struct s5p_gpio_bank *bank = NULL;
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
struct exynos5_gpio_part2 *gpio2 =
(struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2(); switch (peripheral) { case PERIPH_ID_SPI0:
bank = &gpio1->a2; cfg = GPIO_FUNC(0x2);
pin = 0;
pin = GPIO_A20; break; case PERIPH_ID_SPI1:
bank = &gpio1->a2; cfg = GPIO_FUNC(0x2);
pin = 4;
pin = GPIO_A24; break; case PERIPH_ID_SPI2:
bank = &gpio1->b1; cfg = GPIO_FUNC(0x5);
pin = 1;
pin = GPIO_B11; break; case PERIPH_ID_SPI3:
bank = &gpio2->f1; cfg = GPIO_FUNC(0x2);
pin = 0;
pin = GPIO_F10; break; case PERIPH_ID_SPI4: for (i = 0; i < 2; i++) {
s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_F02 + i, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_E04 + i, GPIO_FUNC(0x4)); } break; } if (peripheral != PERIPH_ID_SPI4) { for (i = pin; i < pin + 4; i++)
s5p_gpio_cfg_pin(bank, i, cfg);
gpio_cfg_pin(i, cfg); }
}
diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h index 4db8fd6..cf69895 100644 --- a/arch/arm/include/asm/arch-exynos/gpio.h +++ b/arch/arm/include/asm/arch-exynos/gpio.h @@ -187,15 +187,355 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode); - EXYNOS5_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \ * GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART2_MAX)
+/* A list of valid GPIO numbers for the asm-generic/gpio.h interface */ +enum exynos5_gpio_pin {
/* GPIO_PART1_STARTS */
GPIO_A00,
GPIO_A01,
GPIO_A02,
GPIO_A03,
GPIO_A04,
GPIO_A05,
GPIO_A06,
GPIO_A07,
GPIO_A10,
GPIO_A11,
GPIO_A12,
GPIO_A13,
GPIO_A14,
GPIO_A15,
GPIO_A16,
GPIO_A17,
GPIO_A20,
GPIO_A21,
GPIO_A22,
GPIO_A23,
GPIO_A24,
GPIO_A25,
GPIO_A26,
GPIO_A27,
GPIO_B00,
GPIO_B01,
GPIO_B02,
GPIO_B03,
GPIO_B04,
GPIO_B05,
GPIO_B06,
GPIO_B07,
GPIO_B10,
GPIO_B11,
GPIO_B12,
GPIO_B13,
GPIO_B14,
GPIO_B15,
GPIO_B16,
GPIO_B17,
GPIO_B20,
GPIO_B21,
GPIO_B22,
GPIO_B23,
GPIO_B24,
GPIO_B25,
GPIO_B26,
GPIO_B27,
GPIO_B30,
GPIO_B31,
GPIO_B32,
GPIO_B33,
GPIO_B34,
GPIO_B35,
GPIO_B36,
GPIO_B37,
GPIO_C00,
GPIO_C01,
GPIO_C02,
GPIO_C03,
GPIO_C04,
GPIO_C05,
GPIO_C06,
GPIO_C07,
GPIO_C10,
GPIO_C11,
GPIO_C12,
GPIO_C13,
GPIO_C14,
GPIO_C15,
GPIO_C16,
GPIO_C17,
GPIO_C20,
GPIO_C21,
GPIO_C22,
GPIO_C23,
GPIO_C24,
GPIO_C25,
GPIO_C26,
GPIO_C27,
GPIO_C30,
GPIO_C31,
GPIO_C32,
GPIO_C33,
GPIO_C34,
GPIO_C35,
GPIO_C36,
GPIO_C37,
GPIO_D00,
GPIO_D01,
GPIO_D02,
GPIO_D03,
GPIO_D04,
GPIO_D05,
GPIO_D06,
GPIO_D07,
GPIO_D10,
GPIO_D11,
GPIO_D12,
GPIO_D13,
GPIO_D14,
GPIO_D15,
GPIO_D16,
GPIO_D17,
GPIO_Y00,
GPIO_Y01,
GPIO_Y02,
GPIO_Y03,
GPIO_Y04,
GPIO_Y05,
GPIO_Y06,
GPIO_Y07,
GPIO_Y10,
GPIO_Y11,
GPIO_Y12,
GPIO_Y13,
GPIO_Y14,
GPIO_Y15,
GPIO_Y16,
GPIO_Y17,
GPIO_Y20,
GPIO_Y21,
GPIO_Y22,
GPIO_Y23,
GPIO_Y24,
GPIO_Y25,
GPIO_Y26,
GPIO_Y27,
GPIO_Y30,
GPIO_Y31,
GPIO_Y32,
GPIO_Y33,
GPIO_Y34,
GPIO_Y35,
GPIO_Y36,
GPIO_Y37,
GPIO_Y40,
GPIO_Y41,
GPIO_Y42,
GPIO_Y43,
GPIO_Y44,
GPIO_Y45,
GPIO_Y46,
GPIO_Y47,
GPIO_Y50,
GPIO_Y51,
GPIO_Y52,
GPIO_Y53,
GPIO_Y54,
GPIO_Y55,
GPIO_Y56,
GPIO_Y57,
GPIO_Y60,
GPIO_Y61,
GPIO_Y62,
GPIO_Y63,
GPIO_Y64,
GPIO_Y65,
GPIO_Y66,
GPIO_Y67,
RES = GPIO_Y67 + (0x3 * GPIO_PER_BANK),
GPIO_C40,
GPIO_C41,
GPIO_C42,
GPIO_C43,
GPIO_C44,
GPIO_C45,
GPIO_C46,
GPIO_C47,
RES1 = GPIO_C47 + (0x48 * GPIO_PER_BANK),
GPIO_X00,
GPIO_X01,
GPIO_X02,
GPIO_X03,
GPIO_X04,
GPIO_X05,
GPIO_X06,
GPIO_X07,
GPIO_X10,
GPIO_X11,
GPIO_X12,
GPIO_X13,
GPIO_X14,
GPIO_X15,
GPIO_X16,
GPIO_X17,
GPIO_X20,
GPIO_X21,
GPIO_X22,
GPIO_X23,
GPIO_X24,
GPIO_X25,
GPIO_X26,
GPIO_X27,
GPIO_X30,
GPIO_X31,
GPIO_X32,
GPIO_X33,
GPIO_X34,
GPIO_X35,
GPIO_X36,
GPIO_X37,
/* GPIO_PART2_STARTS */
GPIO_PART1_MAX,
GPIO_E00 = GPIO_PART1_MAX,
GPIO_E01,
GPIO_E02,
GPIO_E03,
GPIO_E04,
GPIO_E05,
GPIO_E06,
GPIO_E07,
GPIO_E10,
GPIO_E11,
GPIO_E12,
GPIO_E13,
GPIO_E14,
GPIO_E15,
GPIO_E16,
GPIO_E17,
GPIO_F00,
GPIO_F01,
GPIO_F02,
GPIO_F03,
GPIO_F04,
GPIO_F05,
GPIO_F06,
GPIO_F07,
GPIO_F10,
GPIO_F11,
GPIO_F12,
GPIO_F13,
GPIO_F14,
GPIO_F15,
GPIO_F16,
GPIO_F17,
GPIO_G00,
GPIO_G01,
GPIO_G02,
GPIO_G03,
GPIO_G04,
GPIO_G05,
GPIO_G06,
GPIO_G07,
GPIO_G10,
GPIO_G11,
GPIO_G12,
GPIO_G13,
GPIO_G14,
GPIO_G15,
GPIO_G16,
GPIO_G17,
GPIO_G20,
GPIO_G21,
GPIO_G22,
GPIO_G23,
GPIO_G24,
GPIO_G25,
GPIO_G26,
GPIO_G27,
GPIO_H00,
GPIO_H01,
GPIO_H02,
GPIO_H03,
GPIO_H04,
GPIO_H05,
GPIO_H06,
GPIO_H07,
GPIO_H10,
GPIO_H11,
GPIO_H12,
GPIO_H13,
GPIO_H14,
GPIO_H15,
GPIO_H16,
GPIO_H17,
/* GPIO_PART3_STARTS */
GPIO_PART2_MAX,
GPIO_V00 = GPIO_PART2_MAX,
GPIO_V01,
GPIO_V02,
GPIO_V03,
GPIO_V04,
GPIO_V05,
GPIO_V06,
GPIO_V07,
GPIO_V10,
GPIO_V11,
GPIO_V12,
GPIO_V13,
GPIO_V14,
GPIO_V15,
GPIO_V16,
GPIO_V17,
RES3 = GPIO_V17 + GPIO_PER_BANK,
GPIO_V20,
GPIO_V21,
GPIO_V22,
GPIO_V23,
GPIO_V24,
GPIO_V25,
GPIO_V26,
GPIO_V27,
GPIO_V30,
GPIO_V31,
GPIO_V32,
GPIO_V33,
GPIO_V34,
GPIO_V35,
GPIO_V36,
GPIO_V37,
RES4 = GPIO_V37 + GPIO_PER_BANK,
GPIO_V40,
GPIO_V41,
GPIO_V42,
GPIO_V43,
GPIO_V44,
GPIO_V45,
GPIO_V46,
GPIO_V47,
/* GPIO_PART4_STARTS */
GPIO_PART3_MAX,
GPIO_Z0 = GPIO_PART3_MAX,
GPIO_Z1,
GPIO_Z2,
GPIO_Z3,
GPIO_Z4,
GPIO_Z5,
GPIO_Z6,
GPIO_MAX_PORT
+};
static inline unsigned int s5p_gpio_base(int nr) { if (cpu_is_exynos5()) {
if (nr < EXYNOS5_GPIO_PART1_MAX)
if (nr < GPIO_PART1_MAX) return EXYNOS5_GPIO_PART1_BASE;
else if (nr < EXYNOS5_GPIO_PART2_MAX)
else if (nr < GPIO_PART2_MAX) return EXYNOS5_GPIO_PART2_BASE;
else
else if (nr < GPIO_PART3_MAX) return EXYNOS5_GPIO_PART3_BASE;
else
return EXYNOS5_GPIO_PART4_BASE; } else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX)
@@ -210,12 +550,14 @@ static inline unsigned int s5p_gpio_base(int nr) static inline unsigned int s5p_gpio_part_max(int nr) { if (cpu_is_exynos5()) {
if (nr < EXYNOS5_GPIO_PART1_MAX)
if (nr < GPIO_PART1_MAX) return 0;
else if (nr < EXYNOS5_GPIO_PART2_MAX)
return EXYNOS5_GPIO_PART1_MAX;
else if (nr < GPIO_PART2_MAX)
return GPIO_PART1_MAX;
else if (nr < GPIO_PART3_MAX)
return GPIO_PART2_MAX; else
return EXYNOS5_GPIO_PART2_MAX;
return GPIO_PART3_MAX; } else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX)
@@ -226,6 +568,10 @@ static inline unsigned int s5p_gpio_part_max(int nr)
return 0;
}
+void gpio_cfg_pin(int gpio, int cfg); +void gpio_set_pull(int gpio, int mode); +void gpio_set_drv(int gpio, int mode); #endif
/* Pin configurations */
1.7.4.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi,
On Wed, Dec 12, 2012 at 5:17 AM, Kyungmin Park kmpark@infradead.org wrote:
Hi,
On Wed, Dec 12, 2012 at 8:33 PM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds support for gpio pin numbering support on EXYNOS5 pinmux.
We already know that each exynos5 SoCs has different GPIO name and offsets. So it's good time to use proper soc prefix. e.g., EXYNOS5250_*. Since only exynos5250 is mainlined at this time.
Do you mean for the GPIO_ names? I am not so sure - after all only one SOC can be included at a time, so we either use one numbering or another, and this will make the names much longer.
I think this series should enable CMD_GPIO and it would be nice if that command could support named GPIOs so we can use:
gpio set gpa0
for example.
Regards, Simon
Thank you, Kyungmin Park
Signed-off-by: Leela Krishna Amudala l.krishna@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
arch/arm/cpu/armv7/exynos/pinmux.c | 148 +++++-------- arch/arm/include/asm/arch-exynos/gpio.h | 360 ++++++++++++++++++++++++++++++- 2 files changed, 413 insertions(+), 95 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index f02f441..9b4355a 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -28,89 +28,77 @@
static void exynos5_uart_config(int peripheral) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
struct s5p_gpio_bank *bank; int i, start, count; switch (peripheral) { case PERIPH_ID_UART0:
bank = &gpio1->a0;
start = 0;
start = GPIO_A00; count = 4; break; case PERIPH_ID_UART1:
bank = &gpio1->d0;
start = 0;
start = GPIO_D00; count = 4; break; case PERIPH_ID_UART2:
bank = &gpio1->a1;
start = 0;
start = GPIO_A10; count = 4; break; case PERIPH_ID_UART3:
bank = &gpio1->a1;
start = 4;
start = GPIO_A14; count = 2; break; } for (i = start; i < start + count; i++) {
s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
gpio_set_pull(i, GPIO_PULL_NONE);
gpio_cfg_pin(i, GPIO_FUNC(0x2)); }
}
static int exynos5_mmc_config(int peripheral, int flags) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
struct s5p_gpio_bank *bank, *bank_ext;
int i, start = 0, gpio_func = 0;
int i, start, start_ext, gpio_func = 0; switch (peripheral) { case PERIPH_ID_SDMMC0:
bank = &gpio1->c0;
bank_ext = &gpio1->c1;
start = 0;
start = GPIO_C00;
start_ext = GPIO_C10; gpio_func = GPIO_FUNC(0x2); break; case PERIPH_ID_SDMMC1:
bank = &gpio1->c2;
bank_ext = NULL;
start = GPIO_C20;
start_ext = 0; break; case PERIPH_ID_SDMMC2:
bank = &gpio1->c3;
bank_ext = &gpio1->c4;
start = 3;
start = GPIO_C30;
start_ext = GPIO_C43; gpio_func = GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC3:
bank = &gpio1->c4;
bank_ext = NULL;
start = GPIO_C40;
start_ext = 0; break; }
if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) { debug("SDMMC device %d does not support 8bit mode", peripheral); return -1; } if (flags & PINMUX_FLAG_8BIT_MODE) {
for (i = start; i <= (start + 3); i++) {
s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
for (i = start_ext; i <= (start_ext + 3); i++) {
gpio_cfg_pin(i, gpio_func);
gpio_set_pull(i, GPIO_PULL_UP);
gpio_set_drv(i, GPIO_DRV_4X); } } for (i = 0; i < 2; i++) {
s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
gpio_cfg_pin(start + i, GPIO_FUNC(0x2));
gpio_set_pull(start + i, GPIO_PULL_NONE);
gpio_set_drv(start + i, GPIO_DRV_4X); } for (i = 3; i <= 6; i++) {
s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
gpio_cfg_pin(start + i, GPIO_FUNC(0x2));
gpio_set_pull(start + i, GPIO_PULL_UP);
gpio_set_drv(start + i, GPIO_DRV_4X); } return 0;
@@ -118,8 +106,6 @@ static int exynos5_mmc_config(int peripheral, int flags)
static void exynos5_sromc_config(int flags) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); int i; /*
@@ -137,13 +123,13 @@ static void exynos5_sromc_config(int flags) * GPY1[2] SROM_WAIT(2) * GPY1[3] EBI_DATA_RDn(2) */
s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
gpio_cfg_pin(GPIO_Y00 + (flags & PINMUX_FLAG_BANK), GPIO_FUNC(2));
s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
gpio_cfg_pin(GPIO_Y04, GPIO_FUNC(2));
gpio_cfg_pin(GPIO_Y05, GPIO_FUNC(2)); for (i = 0; i < 4; i++)
s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
gpio_cfg_pin(GPIO_Y10 + i, GPIO_FUNC(2)); /* * EBI: 8 Addrss Lines
@@ -178,55 +164,52 @@ static void exynos5_sromc_config(int flags) * GPY6[7] EBI_DATA[15](2) */ for (i = 0; i < 8; i++) {
s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
gpio_cfg_pin(GPIO_Y30 + i, GPIO_FUNC(2));
gpio_set_pull(GPIO_Y30 + i, GPIO_PULL_UP);
s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
gpio_cfg_pin(GPIO_Y50 + i, GPIO_FUNC(2));
gpio_set_pull(GPIO_Y50 + i, GPIO_PULL_UP);
s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
gpio_cfg_pin(GPIO_Y60 + i, GPIO_FUNC(2));
gpio_set_pull(GPIO_Y60 + i, GPIO_PULL_UP); }
}
static void exynos5_i2c_config(int peripheral, int flags) {
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
switch (peripheral) { case PERIPH_ID_I2C0:
s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B30, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B31, GPIO_FUNC(0x2)); break; case PERIPH_ID_I2C1:
s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B32, GPIO_FUNC(0x2));
gpio_cfg_pin(GPIO_B33, GPIO_FUNC(0x2)); break; case PERIPH_ID_I2C2:
s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A06, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A07, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C3:
s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A12, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A13, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C4:
s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A20, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A21, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C5:
s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A22, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_A23, GPIO_FUNC(0x3)); break; case PERIPH_ID_I2C6:
s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_B13, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_B14, GPIO_FUNC(0x4)); break; case PERIPH_ID_I2C7:
s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_B22, GPIO_FUNC(0x3));
gpio_cfg_pin(GPIO_B23, GPIO_FUNC(0x3)); break; }
} @@ -234,53 +217,42 @@ static void exynos5_i2c_config(int peripheral, int flags) static void exynos5_i2s_config(int peripheral) { int i;
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); for (i = 0; i < 5; i++)
s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
gpio_cfg_pin(GPIO_B00+i, GPIO_FUNC(0x02));
}
void exynos5_spi_config(int peripheral) { int cfg = 0, pin = 0, i;
struct s5p_gpio_bank *bank = NULL;
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
struct exynos5_gpio_part2 *gpio2 =
(struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2(); switch (peripheral) { case PERIPH_ID_SPI0:
bank = &gpio1->a2; cfg = GPIO_FUNC(0x2);
pin = 0;
pin = GPIO_A20; break; case PERIPH_ID_SPI1:
bank = &gpio1->a2; cfg = GPIO_FUNC(0x2);
pin = 4;
pin = GPIO_A24; break; case PERIPH_ID_SPI2:
bank = &gpio1->b1; cfg = GPIO_FUNC(0x5);
pin = 1;
pin = GPIO_B11; break; case PERIPH_ID_SPI3:
bank = &gpio2->f1; cfg = GPIO_FUNC(0x2);
pin = 0;
pin = GPIO_F10; break; case PERIPH_ID_SPI4: for (i = 0; i < 2; i++) {
s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_F02 + i, GPIO_FUNC(0x4));
gpio_cfg_pin(GPIO_E04 + i, GPIO_FUNC(0x4)); } break; } if (peripheral != PERIPH_ID_SPI4) { for (i = pin; i < pin + 4; i++)
s5p_gpio_cfg_pin(bank, i, cfg);
gpio_cfg_pin(i, cfg); }
}
diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h index 4db8fd6..cf69895 100644 --- a/arch/arm/include/asm/arch-exynos/gpio.h +++ b/arch/arm/include/asm/arch-exynos/gpio.h @@ -187,15 +187,355 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode); - EXYNOS5_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \ * GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART2_MAX)
+/* A list of valid GPIO numbers for the asm-generic/gpio.h interface */ +enum exynos5_gpio_pin {
/* GPIO_PART1_STARTS */
GPIO_A00,
GPIO_A01,
GPIO_A02,
GPIO_A03,
GPIO_A04,
GPIO_A05,
GPIO_A06,
GPIO_A07,
GPIO_A10,
GPIO_A11,
GPIO_A12,
GPIO_A13,
GPIO_A14,
GPIO_A15,
GPIO_A16,
GPIO_A17,
GPIO_A20,
GPIO_A21,
GPIO_A22,
GPIO_A23,
GPIO_A24,
GPIO_A25,
GPIO_A26,
GPIO_A27,
GPIO_B00,
GPIO_B01,
GPIO_B02,
GPIO_B03,
GPIO_B04,
GPIO_B05,
GPIO_B06,
GPIO_B07,
GPIO_B10,
GPIO_B11,
GPIO_B12,
GPIO_B13,
GPIO_B14,
GPIO_B15,
GPIO_B16,
GPIO_B17,
GPIO_B20,
GPIO_B21,
GPIO_B22,
GPIO_B23,
GPIO_B24,
GPIO_B25,
GPIO_B26,
GPIO_B27,
GPIO_B30,
GPIO_B31,
GPIO_B32,
GPIO_B33,
GPIO_B34,
GPIO_B35,
GPIO_B36,
GPIO_B37,
GPIO_C00,
GPIO_C01,
GPIO_C02,
GPIO_C03,
GPIO_C04,
GPIO_C05,
GPIO_C06,
GPIO_C07,
GPIO_C10,
GPIO_C11,
GPIO_C12,
GPIO_C13,
GPIO_C14,
GPIO_C15,
GPIO_C16,
GPIO_C17,
GPIO_C20,
GPIO_C21,
GPIO_C22,
GPIO_C23,
GPIO_C24,
GPIO_C25,
GPIO_C26,
GPIO_C27,
GPIO_C30,
GPIO_C31,
GPIO_C32,
GPIO_C33,
GPIO_C34,
GPIO_C35,
GPIO_C36,
GPIO_C37,
GPIO_D00,
GPIO_D01,
GPIO_D02,
GPIO_D03,
GPIO_D04,
GPIO_D05,
GPIO_D06,
GPIO_D07,
GPIO_D10,
GPIO_D11,
GPIO_D12,
GPIO_D13,
GPIO_D14,
GPIO_D15,
GPIO_D16,
GPIO_D17,
GPIO_Y00,
GPIO_Y01,
GPIO_Y02,
GPIO_Y03,
GPIO_Y04,
GPIO_Y05,
GPIO_Y06,
GPIO_Y07,
GPIO_Y10,
GPIO_Y11,
GPIO_Y12,
GPIO_Y13,
GPIO_Y14,
GPIO_Y15,
GPIO_Y16,
GPIO_Y17,
GPIO_Y20,
GPIO_Y21,
GPIO_Y22,
GPIO_Y23,
GPIO_Y24,
GPIO_Y25,
GPIO_Y26,
GPIO_Y27,
GPIO_Y30,
GPIO_Y31,
GPIO_Y32,
GPIO_Y33,
GPIO_Y34,
GPIO_Y35,
GPIO_Y36,
GPIO_Y37,
GPIO_Y40,
GPIO_Y41,
GPIO_Y42,
GPIO_Y43,
GPIO_Y44,
GPIO_Y45,
GPIO_Y46,
GPIO_Y47,
GPIO_Y50,
GPIO_Y51,
GPIO_Y52,
GPIO_Y53,
GPIO_Y54,
GPIO_Y55,
GPIO_Y56,
GPIO_Y57,
GPIO_Y60,
GPIO_Y61,
GPIO_Y62,
GPIO_Y63,
GPIO_Y64,
GPIO_Y65,
GPIO_Y66,
GPIO_Y67,
RES = GPIO_Y67 + (0x3 * GPIO_PER_BANK),
GPIO_C40,
GPIO_C41,
GPIO_C42,
GPIO_C43,
GPIO_C44,
GPIO_C45,
GPIO_C46,
GPIO_C47,
RES1 = GPIO_C47 + (0x48 * GPIO_PER_BANK),
GPIO_X00,
GPIO_X01,
GPIO_X02,
GPIO_X03,
GPIO_X04,
GPIO_X05,
GPIO_X06,
GPIO_X07,
GPIO_X10,
GPIO_X11,
GPIO_X12,
GPIO_X13,
GPIO_X14,
GPIO_X15,
GPIO_X16,
GPIO_X17,
GPIO_X20,
GPIO_X21,
GPIO_X22,
GPIO_X23,
GPIO_X24,
GPIO_X25,
GPIO_X26,
GPIO_X27,
GPIO_X30,
GPIO_X31,
GPIO_X32,
GPIO_X33,
GPIO_X34,
GPIO_X35,
GPIO_X36,
GPIO_X37,
/* GPIO_PART2_STARTS */
GPIO_PART1_MAX,
GPIO_E00 = GPIO_PART1_MAX,
GPIO_E01,
GPIO_E02,
GPIO_E03,
GPIO_E04,
GPIO_E05,
GPIO_E06,
GPIO_E07,
GPIO_E10,
GPIO_E11,
GPIO_E12,
GPIO_E13,
GPIO_E14,
GPIO_E15,
GPIO_E16,
GPIO_E17,
GPIO_F00,
GPIO_F01,
GPIO_F02,
GPIO_F03,
GPIO_F04,
GPIO_F05,
GPIO_F06,
GPIO_F07,
GPIO_F10,
GPIO_F11,
GPIO_F12,
GPIO_F13,
GPIO_F14,
GPIO_F15,
GPIO_F16,
GPIO_F17,
GPIO_G00,
GPIO_G01,
GPIO_G02,
GPIO_G03,
GPIO_G04,
GPIO_G05,
GPIO_G06,
GPIO_G07,
GPIO_G10,
GPIO_G11,
GPIO_G12,
GPIO_G13,
GPIO_G14,
GPIO_G15,
GPIO_G16,
GPIO_G17,
GPIO_G20,
GPIO_G21,
GPIO_G22,
GPIO_G23,
GPIO_G24,
GPIO_G25,
GPIO_G26,
GPIO_G27,
GPIO_H00,
GPIO_H01,
GPIO_H02,
GPIO_H03,
GPIO_H04,
GPIO_H05,
GPIO_H06,
GPIO_H07,
GPIO_H10,
GPIO_H11,
GPIO_H12,
GPIO_H13,
GPIO_H14,
GPIO_H15,
GPIO_H16,
GPIO_H17,
/* GPIO_PART3_STARTS */
GPIO_PART2_MAX,
GPIO_V00 = GPIO_PART2_MAX,
GPIO_V01,
GPIO_V02,
GPIO_V03,
GPIO_V04,
GPIO_V05,
GPIO_V06,
GPIO_V07,
GPIO_V10,
GPIO_V11,
GPIO_V12,
GPIO_V13,
GPIO_V14,
GPIO_V15,
GPIO_V16,
GPIO_V17,
RES3 = GPIO_V17 + GPIO_PER_BANK,
GPIO_V20,
GPIO_V21,
GPIO_V22,
GPIO_V23,
GPIO_V24,
GPIO_V25,
GPIO_V26,
GPIO_V27,
GPIO_V30,
GPIO_V31,
GPIO_V32,
GPIO_V33,
GPIO_V34,
GPIO_V35,
GPIO_V36,
GPIO_V37,
RES4 = GPIO_V37 + GPIO_PER_BANK,
GPIO_V40,
GPIO_V41,
GPIO_V42,
GPIO_V43,
GPIO_V44,
GPIO_V45,
GPIO_V46,
GPIO_V47,
/* GPIO_PART4_STARTS */
GPIO_PART3_MAX,
GPIO_Z0 = GPIO_PART3_MAX,
GPIO_Z1,
GPIO_Z2,
GPIO_Z3,
GPIO_Z4,
GPIO_Z5,
GPIO_Z6,
GPIO_MAX_PORT
+};
static inline unsigned int s5p_gpio_base(int nr) { if (cpu_is_exynos5()) {
if (nr < EXYNOS5_GPIO_PART1_MAX)
if (nr < GPIO_PART1_MAX) return EXYNOS5_GPIO_PART1_BASE;
else if (nr < EXYNOS5_GPIO_PART2_MAX)
else if (nr < GPIO_PART2_MAX) return EXYNOS5_GPIO_PART2_BASE;
else
else if (nr < GPIO_PART3_MAX) return EXYNOS5_GPIO_PART3_BASE;
else
return EXYNOS5_GPIO_PART4_BASE; } else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX)
@@ -210,12 +550,14 @@ static inline unsigned int s5p_gpio_base(int nr) static inline unsigned int s5p_gpio_part_max(int nr) { if (cpu_is_exynos5()) {
if (nr < EXYNOS5_GPIO_PART1_MAX)
if (nr < GPIO_PART1_MAX) return 0;
else if (nr < EXYNOS5_GPIO_PART2_MAX)
return EXYNOS5_GPIO_PART1_MAX;
else if (nr < GPIO_PART2_MAX)
return GPIO_PART1_MAX;
else if (nr < GPIO_PART3_MAX)
return GPIO_PART2_MAX; else
return EXYNOS5_GPIO_PART2_MAX;
return GPIO_PART3_MAX; } else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX)
@@ -226,6 +568,10 @@ static inline unsigned int s5p_gpio_part_max(int nr)
return 0;
}
+void gpio_cfg_pin(int gpio, int cfg); +void gpio_set_pull(int gpio, int mode); +void gpio_set_drv(int gpio, int mode); #endif
/* Pin configurations */
1.7.4.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
participants (3)
-
Kyungmin Park
-
Rajeshwari Shinde
-
Simon Glass