[U-Boot] [PATCH 1/2] i2c: soft_i2c: add simple GPIO implementation

Since the vast majority of GPIO I2C implementations behave the same way, support the common GPIO framework with default settings.
This adds two new defines CONFIG_SOFT_I2C_GPIO_{SCL,SDA} so that boards which want GPIO I2C support need only define these.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- README | 10 ++++++++++ drivers/i2c/soft_i2c.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/README b/README index a9c98f2..c9fb284 100644 --- a/README +++ b/README @@ -1495,6 +1495,16 @@ The following options need to be configured:
#define I2C_DELAY udelay(2)
+ CONFIG_SOFT_I2C_GPIO_SCL / CONFIG_SOFT_I2C_GPIO_SDA + + If your arch supports the generic GPIO framework (asm/gpio.h), + then you may alternatively define the two GPIOs that are to be + used as SCL / SDA. Any of the previous I2C_xxx macros will + have GPIO-based defaults assigned to them as appropriate. + + You should define these to the GPIO value as given directly to + the generic GPIO functions. + CONFIG_SYS_I2C_INIT_BOARD
When a board is reset during an i2c bus transfer diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index e0cf1e1..847db76 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -51,6 +51,48 @@ #endif #include <i2c.h>
+#if defined(CONFIG_SOFT_I2C_GPIO_SCL) +# include <asm/gpio.h> + +# ifndef I2C_GPIO_SYNC +# define I2C_GPIO_SYNC +# endif + +# ifndef I2C_INIT +# define I2C_INIT \ + do { \ + gpio_request(CONFIG_SOFT_I2C_GPIO_SCL, "soft_i2c"); \ + gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SCL, 0); \ + gpio_request(CONFIG_SOFT_I2C_GPIO_SDA, "soft_i2c"); \ + } while (0) +# endif + +# ifndef I2C_ACTIVE +# define I2C_ACTIVE gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SDA, 0) +# endif + +# ifndef I2C_TRISTATE +# define I2C_TRISTATE gpio_direction_input(CONFIG_SOFT_I2C_GPIO_SDA) +# endif + +# ifndef I2C_READ +# define I2C_READ (gpio_get_value(CONFIG_SOFT_I2C_GPIO_SDA) != 0) +# endif + +# ifndef I2C_SDA +# define I2C_SDA(bit) gpio_set_value(CONFIG_SOFT_I2C_GPIO_SDA, bit) +# endif + +# ifndef I2C_SCL +# define I2C_SCL(bit) gpio_set_value(CONFIG_SOFT_I2C_GPIO_SCL, bit) +# endif + +# ifndef I2C_DELAY +# define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ +# endif + +#endif + /* #define DEBUG_I2C */
#ifdef DEBUG_I2C

Use the new common gpio framework to simplify and unify the soft i2c configuration settings.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- note: i can run this through the Blackfin tree if you want
include/configs/bf533-ezkit.h | 43 +--------------------------------------- include/configs/bf533-stamp.h | 43 +--------------------------------------- include/configs/bf561-ezkit.h | 42 +-------------------------------------- include/configs/blackstamp.h | 28 +------------------------ include/configs/ibf-dsp561.h | 29 +------------------------- 5 files changed, 10 insertions(+), 175 deletions(-)
diff --git a/include/configs/bf533-ezkit.h b/include/configs/bf533-ezkit.h index 37a7059..95d3afa 100644 --- a/include/configs/bf533-ezkit.h +++ b/include/configs/bf533-ezkit.h @@ -94,49 +94,10 @@
/* * I2C Settings - * By default PF1 is used as SDA and PF0 as SCL on the Stamp board */ #define CONFIG_SOFT_I2C -#ifdef CONFIG_SOFT_I2C -#define PF_SCL PF0 -#define PF_SDA PF1 -#define I2C_INIT \ - do { \ - *pFIO_DIR |= PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_ACTIVE \ - do { \ - *pFIO_DIR |= PF_SDA; \ - *pFIO_INEN &= ~PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_TRISTATE \ - do { \ - *pFIO_DIR &= ~PF_SDA; \ - *pFIO_INEN |= PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_READ ((*pFIO_FLAG_D & PF_SDA) != 0) -#define I2C_SDA(bit) \ - do { \ - if (bit) \ - *pFIO_FLAG_S = PF_SDA; \ - else \ - *pFIO_FLAG_C = PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_SCL(bit) \ - do { \ - if (bit) \ - *pFIO_FLAG_S = PF_SCL; \ - else \ - *pFIO_FLAG_C = PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ - -#endif +#define CONFIG_SOFT_I2C_GPIO_SCL GPIO_PF0 +#define CONFIG_SOFT_I2C_GPIO_SDA GPIO_PF1
/* diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h index 02c8bc3..f39bfee 100644 --- a/include/configs/bf533-stamp.h +++ b/include/configs/bf533-stamp.h @@ -138,49 +138,10 @@
/* * I2C Settings - * By default PF2 is used as SDA and PF3 as SCL on the Stamp board */ #define CONFIG_SOFT_I2C -#ifdef CONFIG_SOFT_I2C -#define PF_SCL PF3 -#define PF_SDA PF2 -#define I2C_INIT \ - do { \ - *pFIO_DIR |= PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_ACTIVE \ - do { \ - *pFIO_DIR |= PF_SDA; \ - *pFIO_INEN &= ~PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_TRISTATE \ - do { \ - *pFIO_DIR &= ~PF_SDA; \ - *pFIO_INEN |= PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_READ ((*pFIO_FLAG_D & PF_SDA) != 0) -#define I2C_SDA(bit) \ - do { \ - if (bit) \ - *pFIO_FLAG_S = PF_SDA; \ - else \ - *pFIO_FLAG_C = PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_SCL(bit) \ - do { \ - if (bit) \ - *pFIO_FLAG_S = PF_SCL; \ - else \ - *pFIO_FLAG_C = PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ - -#endif +#define CONFIG_SOFT_I2C_GPIO_SCL GPIO_PF3 +#define CONFIG_SOFT_I2C_GPIO_SDA GPIO_PF2
/* diff --git a/include/configs/bf561-ezkit.h b/include/configs/bf561-ezkit.h index 036bfe4..4e293b5 100644 --- a/include/configs/bf561-ezkit.h +++ b/include/configs/bf561-ezkit.h @@ -112,46 +112,8 @@ * I2C Settings */ #define CONFIG_SOFT_I2C -#ifdef CONFIG_SOFT_I2C -#define PF_SCL PF0 -#define PF_SDA PF1 -#define I2C_INIT \ - do { \ - *pFIO0_DIR |= PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_ACTIVE \ - do { \ - *pFIO0_DIR |= PF_SDA; \ - *pFIO0_INEN &= ~PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_TRISTATE \ - do { \ - *pFIO0_DIR &= ~PF_SDA; \ - *pFIO0_INEN |= PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_READ ((*pFIO0_FLAG_D & PF_SDA) != 0) -#define I2C_SDA(bit) \ - do { \ - if (bit) \ - *pFIO0_FLAG_S = PF_SDA; \ - else \ - *pFIO0_FLAG_C = PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_SCL(bit) \ - do { \ - if (bit) \ - *pFIO0_FLAG_S = PF_SCL; \ - else \ - *pFIO0_FLAG_C = PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ - -#endif +#define CONFIG_SOFT_I2C_GPIO_SCL GPIO_PF0 +#define CONFIG_SOFT_I2C_GPIO_SDA GPIO_PF1
/* diff --git a/include/configs/blackstamp.h b/include/configs/blackstamp.h index aa33933..85f08ea 100644 --- a/include/configs/blackstamp.h +++ b/include/configs/blackstamp.h @@ -206,32 +206,8 @@ * them yet. You can (and probably should) change these values! */ #ifdef CONFIG_SOFT_I2C - -#define PF_SCL PF9 -#define PF_SDA PF8 - -#define I2C_INIT do { *pFIO_DIR |= PF_SCL; SSYNC(); } while (0) -#define I2C_ACTIVE do { *pFIO_DIR |= PF_SDA; *pFIO_INEN &= ~PF_SDA; SSYNC(); } while (0) -#define I2C_TRISTATE do { *pFIO_DIR &= ~PF_SDA; *pFIO_INEN |= PF_SDA; SSYNC(); } while (0) -#define I2C_READ ((*pFIO_FLAG_D & PF_SDA) != 0) -#define I2C_SDA(bit) \ - do { \ - if (bit) \ - *pFIO_FLAG_S = PF_SDA; \ - else \ - *pFIO_FLAG_C = PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_SCL(bit) \ - do { \ - if (bit) \ - *pFIO_FLAG_S = PF_SCL; \ - else \ - *pFIO_FLAG_C = PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ - +#define CONFIG_SOFT_I2C_GPIO_SCL GPIO_PF9 +#define CONFIG_SOFT_I2C_GPIO_SDA GPIO_PF8 #define CONFIG_SYS_I2C_SPEED 50000 #define CONFIG_SYS_I2C_SLAVE 0xFE #endif diff --git a/include/configs/ibf-dsp561.h b/include/configs/ibf-dsp561.h index 2c0a263..53b5197 100644 --- a/include/configs/ibf-dsp561.h +++ b/include/configs/ibf-dsp561.h @@ -112,33 +112,8 @@ * I2C Settings */ #define CONFIG_SOFT_I2C 1 -#define PF_SCL 0x1/*PF0*/ -#define PF_SDA 0x2/*PF1*/ - -#ifdef CONFIG_SOFT_I2C -#define I2C_INIT do { *pFIO0_DIR |= PF_SCL; SSYNC(); } while (0) -#define I2C_ACTIVE do { *pFIO0_DIR |= PF_SDA; *pFIO0_INEN &= ~PF_SDA; SSYNC(); } while (0) -#define I2C_TRISTATE do { *pFIO0_DIR &= ~PF_SDA; *pFIO0_INEN |= PF_SDA; SSYNC(); } while (0) -#define I2C_READ ((*pFIO0_FLAG_D & PF_SDA) != 0) -#define I2C_SDA(bit) \ - do { \ - if (bit) \ - *pFIO0_FLAG_S = PF_SDA; \ - else \ - *pFIO0_FLAG_C = PF_SDA; \ - SSYNC(); \ - } while (0) -#define I2C_SCL(bit) \ - do { \ - if (bit) \ - *pFIO0_FLAG_S = PF_SCL; \ - else \ - *pFIO0_FLAG_C = PF_SCL; \ - SSYNC(); \ - } while (0) -#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ - -#endif +#define CONFIG_SOFT_I2C_GPIO_SCL GPIO_PF0 +#define CONFIG_SOFT_I2C_GPIO_SDA GPIO_PF1
/*

Hello Mike,
Mike Frysinger wrote:
Use the new common gpio framework to simplify and unify the soft i2c configuration settings.
Signed-off-by: Mike Frysinger vapier@gentoo.org
note: i can run this through the Blackfin tree if you want
I actually tried your 2 patches, but this patch doesn;t apply :-(
[hs@pollux u-boot-i2c]$ git am -i --whitespace=strip [U-Boot]\ [PATCH\ 2_2]\ Blackfin:\ bf533_bf561\ boards:\ convert\ to\ new\ soft\ gpio\ i2c\ code.eml Commit Body is: -------------------------- Blackfin: bf533/bf561 boards: convert to new soft gpio i2c code
Use the new common gpio framework to simplify and unify the soft i2c configuration settings.
Signed-off-by: Mike Frysinger vapier@gentoo.org -------------------------- Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all y Applying: Blackfin: bf533/bf561 boards: convert to new soft gpio i2c code error: patch failed: include/configs/bf533-ezkit.h:94 error: include/configs/bf533-ezkit.h: patch does not apply error: patch failed: include/configs/bf533-stamp.h:138 error: include/configs/bf533-stamp.h: patch does not apply error: patch failed: include/configs/bf561-ezkit.h:112 error: include/configs/bf561-ezkit.h: patch does not apply error: patch failed: include/configs/ibf-dsp561.h:112 error: include/configs/ibf-dsp561.h: patch does not apply Patch failed at 0001 Blackfin: bf533/bf561 boards: convert to new soft gpio i2c code When you have resolved this problem run "git am -i --resolved". If you would prefer to skip this patch, instead run "git am -i --skip". To restore the original branch and stop patching run "git am -i --abort". [hs@pollux u-boot-i2c]$
Beside of this issue, your 2 patches are looking good!
So, if you want to pick up this patches in your blackfin tree, you can add my
Acked-by: Heiko Schocher hs@denx.de
bye Heiko

On Monday, July 05, 2010 07:14:16 Heiko Schocher wrote:
Mike Frysinger wrote:
Use the new common gpio framework to simplify and unify the soft i2c configuration settings.
Signed-off-by: Mike Frysinger vapier@gentoo.org
note: i can run this through the Blackfin tree if you want
I actually tried your 2 patches, but this patch doesn;t apply :-(
it might depend on patches that are pending in my tree ...
So, if you want to pick up this patches in your blackfin tree, you can add my
Acked-by: Heiko Schocher hs@denx.de
will do then, thanks -mike

On 07/05/2010 04:50 PM, Mike Frysinger wrote:
Since the vast majority of GPIO I2C implementations behave the same way, support the common GPIO framework with default settings.
This adds two new defines CONFIG_SOFT_I2C_GPIO_{SCL,SDA} so that boards which want GPIO I2C support need only define these.
Signed-off-by: Mike Frysingervapier@gentoo.org
Tested on my nios2 boards after additional patch "i2c: fix SDA contention in read_byte()".
Tested-by: Thomas Chou thomas@wytron.com.tw
Cheers, Thomas

On Monday, July 05, 2010 04:50:08 Mike Frysinger wrote:
Since the vast majority of GPIO I2C implementations behave the same way, support the common GPIO framework with default settings.
This adds two new defines CONFIG_SOFT_I2C_GPIO_{SCL,SDA} so that boards which want GPIO I2C support need only define these.
i guess postpone this until we can get the tristate/sda issues sorted out -mike

Since the vast majority of GPIO I2C implementations behave the same way, support the common GPIO framework with default settings.
This adds two new defines CONFIG_SOFT_I2C_GPIO_{SCL,SDA} so that boards which want GPIO I2C support need only define these.
Signed-off-by: Mike Frysinger vapier@gentoo.org Tested-by: Thomas Chou thomas@wytron.com.tw --- v2 - stub out tristate/active by default and let the gpios handle things in the sda/scl macros
README | 10 +++++++++ drivers/i2c/soft_i2c.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/README b/README index a9c98f2..c9fb284 100644 --- a/README +++ b/README @@ -1495,6 +1495,16 @@ The following options need to be configured:
#define I2C_DELAY udelay(2)
+ CONFIG_SOFT_I2C_GPIO_SCL / CONFIG_SOFT_I2C_GPIO_SDA + + If your arch supports the generic GPIO framework (asm/gpio.h), + then you may alternatively define the two GPIOs that are to be + used as SCL / SDA. Any of the previous I2C_xxx macros will + have GPIO-based defaults assigned to them as appropriate. + + You should define these to the GPIO value as given directly to + the generic GPIO functions. + CONFIG_SYS_I2C_INIT_BOARD
When a board is reset during an i2c bus transfer diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index e0cf1e1..1a1809a 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -51,6 +51,58 @@ #endif #include <i2c.h>
+#if defined(CONFIG_SOFT_I2C_GPIO_SCL) +# include <asm/gpio.h> + +# ifndef I2C_GPIO_SYNC +# define I2C_GPIO_SYNC +# endif + +# ifndef I2C_INIT +# define I2C_INIT \ + do { \ + gpio_request(CONFIG_SOFT_I2C_GPIO_SCL, "soft_i2c"); \ + gpio_request(CONFIG_SOFT_I2C_GPIO_SDA, "soft_i2c"); \ + } while (0) +# endif + +# ifndef I2C_ACTIVE +# define I2C_ACTIVE do { } while (0) +# endif + +# ifndef I2C_TRISTATE +# define I2C_TRISTATE do { } while (0) +# endif + +# ifndef I2C_READ +# define I2C_READ gpio_get_value(CONFIG_SOFT_I2C_GPIO_SDA) +# endif + +# ifndef I2C_SDA +# define I2C_SDA(bit) \ + do { \ + if (bit) \ + gpio_direction_input(CONFIG_SOFT_I2C_GPIO_SDA); \ + else \ + gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SDA, 0); \ + I2C_GPIO_SYNC; \ + } while (0) +# endif + +# ifndef I2C_SCL +# define I2C_SCL(bit) \ + do { \ + gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SCL, bit); \ + I2C_GPIO_SYNC; \ + } while (0) +# endif + +# ifndef I2C_DELAY +# define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ +# endif + +#endif + /* #define DEBUG_I2C */
#ifdef DEBUG_I2C

Mike Frysinger wrote:
Since the vast majority of GPIO I2C implementations behave the same way, support the common GPIO framework with default settings.
This adds two new defines CONFIG_SOFT_I2C_GPIO_{SCL,SDA} so that boards which want GPIO I2C support need only define these.
Signed-off-by: Mike Frysinger vapier@gentoo.org Tested-by: Thomas Chou thomas@wytron.com.tw
v2
- stub out tristate/active by default and let the gpios handle things in the sda/scl macros
Tested v2 on nios2 boards.
Tested-by: Thomas Chou thomas@wytron.com.tw

Hello Mike,
Mike Frysinger wrote:
Since the vast majority of GPIO I2C implementations behave the same way, support the common GPIO framework with default settings.
This adds two new defines CONFIG_SOFT_I2C_GPIO_{SCL,SDA} so that boards which want GPIO I2C support need only define these.
Signed-off-by: Mike Frysinger vapier@gentoo.org Tested-by: Thomas Chou thomas@wytron.com.tw
v2
- stub out tristate/active by default and let the gpios handle things in the sda/scl macros
README | 10 +++++++++ drivers/i2c/soft_i2c.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 0 deletions(-)
Apllied to u-boot-i2c.git
Thanks.
bye Heiko
participants (3)
-
Heiko Schocher
-
Mike Frysinger
-
Thomas Chou