s5p: gpio: change gpio coding method for s5p gpio.

Old s5p gpio coding method was not clean and was not working properly
for all parts and banks. New method is clean and easy to extend.

Gpio coding mask:
0x000000ff - pin number
0x00ffff00 - bank offset
0xff000000 - part number

Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
This commit is contained in:
Przemyslaw Marczak 2014-01-22 11:24:10 +01:00 committed by Minkyu Kang
parent 047eada42a
commit 8475c869c3
7 changed files with 120 additions and 191 deletions

View File

@ -247,180 +247,81 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode);
/* GPIO pins per bank */
#define GPIO_PER_BANK 8
#define S5P_GPIO_PART_SHIFT (24)
#define S5P_GPIO_PART_MASK (0xff)
#define S5P_GPIO_BANK_SHIFT (8)
#define S5P_GPIO_BANK_MASK (0xffff)
#define S5P_GPIO_PIN_MASK (0xff)
#define exynos4_gpio_part1_get_nr(bank, pin) \
((((((unsigned int) &(((struct exynos4_gpio_part1 *) \
EXYNOS4_GPIO_PART1_BASE)->bank)) \
- EXYNOS4_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin)
#define S5P_GPIO_SET_PART(x) \
(((x) & S5P_GPIO_PART_MASK) << S5P_GPIO_PART_SHIFT)
#define EXYNOS4_GPIO_PART1_MAX ((sizeof(struct exynos4_gpio_part1) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define S5P_GPIO_GET_PART(x) \
(((x) >> S5P_GPIO_PART_SHIFT) & S5P_GPIO_PART_MASK)
#define exynos4_gpio_part2_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos4_gpio_part2 *) \
EXYNOS4_GPIO_PART2_BASE)->bank)) \
- EXYNOS4_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS4_GPIO_PART1_MAX)
#define S5P_GPIO_SET_PIN(x) \
((x) & S5P_GPIO_PIN_MASK)
#define exynos4x12_gpio_part1_get_nr(bank, pin) \
((((((unsigned int) &(((struct exynos4x12_gpio_part1 *) \
EXYNOS4X12_GPIO_PART1_BASE)->bank)) \
- EXYNOS4X12_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin)
#define EXYNOS4_GPIO_SET_BANK(part, bank) \
((((unsigned)&(((struct exynos4_gpio_part##part *) \
EXYNOS4_GPIO_PART##part##_BASE)->bank) \
- EXYNOS4_GPIO_PART##part##_BASE) \
& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
#define EXYNOS4X12_GPIO_PART1_MAX ((sizeof(struct exynos4x12_gpio_part1) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define EXYNOS4X12_GPIO_SET_BANK(part, bank) \
((((unsigned)&(((struct exynos4x12_gpio_part##part *) \
EXYNOS4X12_GPIO_PART##part##_BASE)->bank) \
- EXYNOS4X12_GPIO_PART##part##_BASE) \
& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
#define exynos4x12_gpio_part2_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos4x12_gpio_part2 *) \
EXYNOS4X12_GPIO_PART2_BASE)->bank)) \
- EXYNOS4X12_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS4X12_GPIO_PART1_MAX)
#define EXYNOS5_GPIO_SET_BANK(part, bank) \
((((unsigned)&(((struct exynos5420_gpio_part##part *) \
EXYNOS5420_GPIO_PART##part##_BASE)->bank) \
- EXYNOS5_GPIO_PART##part##_BASE) \
& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
#define EXYNOS4X12_GPIO_PART2_MAX ((sizeof(struct exynos4x12_gpio_part2) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define EXYNOS5420_GPIO_SET_BANK(part, bank) \
((((unsigned)&(((struct exynos5420_gpio_part##part *) \
EXYNOS5420_GPIO_PART##part##_BASE)->bank) \
- EXYNOS5420_GPIO_PART##part##_BASE) \
& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
#define exynos4x12_gpio_part3_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos4x12_gpio_part3 *) \
EXYNOS4X12_GPIO_PART3_BASE)->bank)) \
- EXYNOS4X12_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS4X12_GPIO_PART2_MAX)
#define exynos4_gpio_get(part, bank, pin) \
(S5P_GPIO_SET_PART(part) | \
EXYNOS4_GPIO_SET_BANK(part, bank) | \
S5P_GPIO_SET_PIN(pin))
#define exynos5_gpio_part1_get_nr(bank, pin) \
((((((unsigned int) &(((struct exynos5_gpio_part1 *) \
EXYNOS5_GPIO_PART1_BASE)->bank)) \
- EXYNOS5_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin)
#define exynos4x12_gpio_get(part, bank, pin) \
(S5P_GPIO_SET_PART(part) | \
EXYNOS4X12_GPIO_SET_BANK(part, bank) | \
S5P_GPIO_SET_PIN(pin))
#define EXYNOS5_GPIO_PART1_MAX ((sizeof(struct exynos5_gpio_part1) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define exynos5420_gpio_get(part, bank, pin) \
(S5P_GPIO_SET_PART(part) | \
EXYNOS5420_GPIO_SET_BANK(part, bank) | \
S5P_GPIO_SET_PIN(pin))
#define exynos5_gpio_part2_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos5_gpio_part2 *) \
EXYNOS5_GPIO_PART2_BASE)->bank)) \
- EXYNOS5_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART1_MAX)
#define exynos5_gpio_get(part, bank, pin) \
(S5P_GPIO_SET_PART(part) | \
EXYNOS5_GPIO_SET_BANK(part, bank) | \
S5P_GPIO_SET_PIN(pin))
#define EXYNOS5_GPIO_PART2_MAX ((sizeof(struct exynos5_gpio_part2) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define exynos5_gpio_part3_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos5_gpio_part3 *) \
EXYNOS5_GPIO_PART3_BASE)->bank)) \
- EXYNOS5_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART2_MAX)
/* EXYNOS5420 */
#define exynos5420_gpio_part1_get_nr(bank, pin) \
((((((unsigned int) &(((struct exynos5420_gpio_part1 *)\
EXYNOS5420_GPIO_PART1_BASE)->bank)) \
- EXYNOS5420_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin)
#define EXYNOS5420_GPIO_PART1_MAX ((sizeof(struct exynos5420_gpio_part1) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define exynos5420_gpio_part2_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos5420_gpio_part2 *)\
EXYNOS5420_GPIO_PART2_BASE)->bank)) \
- EXYNOS5420_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS5420_GPIO_PART1_MAX)
#define EXYNOS5420_GPIO_PART2_MAX ((sizeof(struct exynos5420_gpio_part2) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define exynos5420_gpio_part3_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos5420_gpio_part3 *)\
EXYNOS5420_GPIO_PART3_BASE)->bank)) \
- EXYNOS5420_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS5420_GPIO_PART2_MAX)
#define EXYNOS5420_GPIO_PART3_MAX ((sizeof(struct exynos5420_gpio_part3) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define exynos5420_gpio_part4_get_nr(bank, pin) \
(((((((unsigned int) &(((struct exynos5420_gpio_part4 *)\
EXYNOS5420_GPIO_PART4_BASE)->bank)) \
- EXYNOS5420_GPIO_PART4_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin) + EXYNOS5420_GPIO_PART3_MAX)
#define EXYNOS5420_GPIO_PART4_MAX ((sizeof(struct exynos5420_gpio_part4) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
#define EXYNOS5420_GPIO_PART5_MAX ((sizeof(struct exynos5420_gpio_part5) \
/ sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK)
static inline unsigned int s5p_gpio_base(int nr)
static inline unsigned int s5p_gpio_base(int gpio)
{
if (cpu_is_exynos5()) {
if (proid_is_exynos5420()) {
if (nr < EXYNOS5420_GPIO_PART1_MAX)
return EXYNOS5420_GPIO_PART1_BASE;
else if (nr < EXYNOS5420_GPIO_PART2_MAX)
return EXYNOS5420_GPIO_PART2_BASE;
else if (nr < EXYNOS5420_GPIO_PART3_MAX)
return EXYNOS5420_GPIO_PART3_BASE;
else
return EXYNOS5420_GPIO_PART4_BASE;
} else {
if (nr < EXYNOS5_GPIO_PART1_MAX)
return EXYNOS5_GPIO_PART1_BASE;
else if (nr < EXYNOS5_GPIO_PART2_MAX)
return EXYNOS5_GPIO_PART2_BASE;
else
return EXYNOS5_GPIO_PART3_BASE;
}
} else if (cpu_is_exynos4()) {
if (nr < EXYNOS4_GPIO_PART1_MAX)
return EXYNOS4_GPIO_PART1_BASE;
else
return EXYNOS4_GPIO_PART2_BASE;
unsigned gpio_part = S5P_GPIO_GET_PART(gpio);
switch (gpio_part) {
case 1:
return samsung_get_base_gpio_part1();
case 2:
return samsung_get_base_gpio_part2();
case 3:
return samsung_get_base_gpio_part3();
case 4:
return samsung_get_base_gpio_part4();
default:
return 0;
}
return 0;
}
static inline unsigned int s5p_gpio_part_max(int nr)
{
if (cpu_is_exynos5()) {
if (proid_is_exynos5420()) {
if (nr < EXYNOS5420_GPIO_PART1_MAX)
return 0;
else if (nr < EXYNOS5420_GPIO_PART2_MAX)
return EXYNOS5420_GPIO_PART1_MAX;
else if (nr < EXYNOS5420_GPIO_PART3_MAX)
return EXYNOS5420_GPIO_PART2_MAX;
else if (nr < EXYNOS5420_GPIO_PART4_MAX)
return EXYNOS5420_GPIO_PART3_MAX;
else
return EXYNOS5420_GPIO_PART4_MAX;
} else {
if (nr < EXYNOS5_GPIO_PART1_MAX)
return 0;
else if (nr < EXYNOS5_GPIO_PART2_MAX)
return EXYNOS5_GPIO_PART1_MAX;
else
return EXYNOS5_GPIO_PART2_MAX;
}
} else if (cpu_is_exynos4()) {
if (proid_is_exynos4412()) {
if (nr < EXYNOS4X12_GPIO_PART1_MAX)
return 0;
else if (nr < EXYNOS4X12_GPIO_PART2_MAX)
return EXYNOS4X12_GPIO_PART1_MAX;
else
return EXYNOS4X12_GPIO_PART2_MAX;
} else {
if (nr < EXYNOS4_GPIO_PART1_MAX)
return 0;
else
return EXYNOS4_GPIO_PART1_MAX;
}
}
return 0;
}
#endif

View File

@ -125,20 +125,45 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode);
/* GPIO pins per bank */
#define GPIO_PER_BANK 8
#define S5P_GPIO_PART_SHIFT (24)
#define S5P_GPIO_PART_MASK (0xff)
#define S5P_GPIO_BANK_SHIFT (8)
#define S5P_GPIO_BANK_MASK (0xffff)
#define S5P_GPIO_PIN_MASK (0xff)
#define S5P_GPIO_SET_PART(x) \
(((x) & S5P_GPIO_PART_MASK) << S5P_GPIO_PART_SHIFT)
#define S5P_GPIO_GET_PART(x) \
(((x) >> S5P_GPIO_PART_SHIFT) & S5P_GPIO_PART_MASK)
#define S5P_GPIO_SET_PIN(x) \
((x) & S5P_GPIO_PIN_MASK)
#define S5PC100_SET_BANK(bank) \
(((unsigned)&(((struct s5pc100_gpio *) \
S5PC100_GPIO_BASE)->bank) - S5PC100_GPIO_BASE) \
& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
#define S5PC110_SET_BANK(bank) \
((((unsigned)&(((struct s5pc110_gpio *) \
S5PC110_GPIO_BASE)->bank) - S5PC110_GPIO_BASE) \
& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
#define s5pc100_gpio_get(bank, pin) \
(S5P_GPIO_SET_PART(0) | \
S5PC100_SET_BANK(bank) | \
S5P_GPIO_SET_PIN(pin))
#define s5pc110_gpio_get(bank, pin) \
(S5P_GPIO_SET_PART(0) | \
S5PC110_SET_BANK(bank) | \
S5P_GPIO_SET_PIN(pin))
static inline unsigned int s5p_gpio_base(int nr)
{
return S5PC110_GPIO_BASE;
return samsung_get_base_gpio();
}
static inline unsigned int s5p_gpio_part_max(int nr)
{
return 0;
}
#define s5pc110_gpio_get_nr(bank, pin) \
((((((unsigned int)&(((struct s5pc110_gpio *)S5PC110_GPIO_BASE)->bank))\
- S5PC110_GPIO_BASE) / sizeof(struct s5p_gpio_bank)) \
* GPIO_PER_BANK) + pin)
#endif
/* Pin configurations */

View File

@ -144,17 +144,17 @@ static void board_init_i2c(void)
int get_soft_i2c_scl_pin(void)
{
if (I2C_ADAP_HWNR)
return exynos4x12_gpio_part2_get_nr(m2, 1); /* I2C9 */
return exynos4x12_gpio_get(2, m2, 1); /* I2C9 */
else
return exynos4x12_gpio_part1_get_nr(f1, 4); /* I2C8 */
return exynos4x12_gpio_get(1, f1, 4); /* I2C8 */
}
int get_soft_i2c_sda_pin(void)
{
if (I2C_ADAP_HWNR)
return exynos4x12_gpio_part2_get_nr(m2, 0); /* I2C9 */
return exynos4x12_gpio_get(2, m2, 0); /* I2C9 */
else
return exynos4x12_gpio_part1_get_nr(f1, 5); /* I2C8 */
return exynos4x12_gpio_get(1, f1, 5); /* I2C8 */
}
#endif

View File

@ -9,6 +9,11 @@
#include <asm/io.h>
#include <asm/gpio.h>
#define S5P_GPIO_GET_BANK(x) ((x >> S5P_GPIO_BANK_SHIFT) \
& S5P_GPIO_BANK_MASK)
#define S5P_GPIO_GET_PIN(x) (x & S5P_GPIO_PIN_MASK)
#define CON_MASK(x) (0xf << ((x) << 2))
#define CON_SFR(x, v) ((v) << ((x) << 2))
@ -124,17 +129,15 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
{
int bank;
unsigned g = gpio - s5p_gpio_part_max(gpio);
unsigned bank = S5P_GPIO_GET_BANK(gpio);
unsigned base = s5p_gpio_base(gpio);
bank = g / GPIO_PER_BANK;
bank *= sizeof(struct s5p_gpio_bank);
return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
return (struct s5p_gpio_bank *)(base + bank);
}
int s5p_gpio_get_pin(unsigned gpio)
{
return gpio % GPIO_PER_BANK;
return S5P_GPIO_GET_PIN(gpio);
}
/* Common GPIO API */

View File

@ -208,8 +208,8 @@
/*
* I2C Settings
*/
#define CONFIG_SOFT_I2C_GPIO_SCL s5pc110_gpio_get_nr(j4, 3)
#define CONFIG_SOFT_I2C_GPIO_SDA s5pc110_gpio_get_nr(j4, 0)
#define CONFIG_SOFT_I2C_GPIO_SCL s5pc110_gpio_get(j4, 3)
#define CONFIG_SOFT_I2C_GPIO_SDA s5pc110_gpio_get(j4, 0)
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */

View File

@ -229,8 +229,8 @@
/*
* I2C Settings
*/
#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part1_get_nr(b, 7)
#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part1_get_nr(b, 6)
#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_get(1, b, 7)
#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_get(1, b, 6)
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */
@ -253,10 +253,10 @@
*/
#define CONFIG_SOFT_SPI
#define CONFIG_SOFT_SPI_MODE SPI_MODE_3
#define CONFIG_SOFT_SPI_GPIO_SCLK exynos4_gpio_part2_get_nr(y3, 1)
#define CONFIG_SOFT_SPI_GPIO_MOSI exynos4_gpio_part2_get_nr(y3, 3)
#define CONFIG_SOFT_SPI_GPIO_MISO exynos4_gpio_part2_get_nr(y3, 0)
#define CONFIG_SOFT_SPI_GPIO_CS exynos4_gpio_part2_get_nr(y4, 3)
#define CONFIG_SOFT_SPI_GPIO_SCLK exynos4_gpio_get(2, y3, 1)
#define CONFIG_SOFT_SPI_GPIO_MOSI exynos4_gpio_get(2, y3, 3)
#define CONFIG_SOFT_SPI_GPIO_MISO exynos4_gpio_get(2, y3, 0)
#define CONFIG_SOFT_SPI_GPIO_CS exynos4_gpio_get(2, y4, 3)
#define SPI_DELAY udelay(1)
#undef SPI_INIT

View File

@ -287,8 +287,8 @@
#include <asm/arch/gpio.h>
/* I2C FG */
#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part2_get_nr(y4, 1)
#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part2_get_nr(y4, 0)
#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_get(2, y4, 1)
#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_get(2, y4, 0)
#define CONFIG_POWER
#define CONFIG_POWER_I2C