[U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c

2011-03-22 Thread John Rigby
From: Michael Brandt 

Signed-off-by: John Rigby 
---
 drivers/i2c/Makefile|1 +
 drivers/i2c/u8500_i2c.c |  603 +++
 drivers/i2c/u8500_i2c.h |  220 +
 3 files changed, 824 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..ac9c00f 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_DRIVER_U8500_I2C) += u8500_i2c.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
new file mode 100644
index 000..8965100
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Basic U-Boot I2C interface for STn8500/DB8500
+ * Author: Michael Brandt  for ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Only 7-bit I2C device addresses are supported.
+ */
+
+#include 
+#include 
+
+#include "u8500_i2c.h"
+#include 
+#include 
+#include 
+
+#define I2C_ENDAD_COUNTER  (CONFIG_SYS_HZ/100) /* I2C bus timeout */
+#define I2C_FIFO_FLUSH_COUNTER 50  /* flush "timeout" */
+#define I2C_SCL_FREQ   10  /* I2C bus clock frequency.*/
+#define I2C_INPUT_FREQ 4800/* Input clock frequency.*/
+#define TX_FIFO_THRESHOLD  0x4
+#define RX_FIFO_THRESHOLD  0x4
+#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk 
*/
+
+#define WRITE_FIELD(var, mask, shift, value) \
+   (var = ((var & ~(mask)) | ((value) << (shift
+
+static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
+static unsigned int i2c_bus_num;
+static unsigned int i2c_bus_speed[] = {
+   CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
+   CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
+};
+static struct u8500_i2c_regs *i2c_dev[] = {
+   (struct u8500_i2c_regs *)CONFIG_SYS_I2C0_BASE,
+   (struct u8500_i2c_regs *)CONFIG_SYS_I2C1_BASE,
+   (struct u8500_i2c_regs *)CONFIG_SYS_I2C2_BASE,
+   (struct u8500_i2c_regs *)CONFIG_SYS_I2C3_BASE,
+};
+
+static struct {
+   int periph;
+   int pcken;
+   int kcken;
+} i2c_clock_bits[] = {
+   {3, 3, 3}, /* I2C0 */
+   {1, 2, 2}, /* I2C1 */
+   {1, 6, 6}, /* I2C2 */
+   {2, 0, 0}, /* I2C3 */
+};
+
+static void i2c_set_bit(void *reg, u32 mask)
+{
+   writel(readl(reg) | mask, reg);
+}
+
+static void i2c_clr_bit(void *reg, u32 mask)
+{
+   writel(readl(reg) & ~mask, reg);
+}
+
+static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
+{
+   writel((readl(reg) & ~mask) | (value << shift), reg);
+}
+
+static int __i2c_set_bus_speed(unsigned int speed)
+{
+   u32 value;
+   struct u8500_i2c_regs *i2c_regs;
+
+   i2c_regs = i2c_dev[i2c_bus_num];
+
+   /* Select standard (100 kbps) speed mode */
+   i2c_write_field(&i2c_regs->cr, I2C_CR_SM, I2C_CR_SHIFT_SM, 0x0);
+
+   /*
+* Set the Baud Rate Counter 2 value
+* Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
+* Foncycle = 0 (no digital filtering)
+*/
+   value = (u32) (I2C_INPUT_FREQ / (speed * 2));
+   i2c_write_field(&i2c_regs->brcr, I2C_BRCR_BRCNT2,
+   I2C_BRCR_SHIFT_BRCNT2, value);
+
+   /* ensure that BRCNT value is zero */
+   i2c_write_field(&i2c_regs->brcr, I2C_BRCR_BRCNT1,
+   I2C_BRCR_SHIFT_BRCNT1, 0);
+
+   return I2C_INPUT_FREQ/(value * 2);
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ *
+ * speed: bus speed (in HZ)
+ * slaveaddr: address of device in slave mode
+ *
+ * Slave mode is not implemented.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+   struct u8500_i2c_regs *i2c_regs;
+
+   debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
+
+   u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
+  i2c_clock_bits[i2c_bus_num].pcken,
+  i2c_clock_bits[i2c_bus_num].kcken);
+
+   i2c_r

Re: [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c

2011-03-23 Thread Heiko Schocher
Hello John,

John Rigby wrote:
> From: Michael Brandt 
> 
> Signed-off-by: John Rigby 
> ---
>  drivers/i2c/Makefile|1 +
>  drivers/i2c/u8500_i2c.c |  603 
> +++
>  drivers/i2c/u8500_i2c.h |  220 +
>  3 files changed, 824 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/i2c/u8500_i2c.c
>  create mode 100644 drivers/i2c/u8500_i2c.h
> 
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 052fe36..ac9c00f 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
>  COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
>  COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
>  COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
> +COBJS-$(CONFIG_DRIVER_U8500_I2C) += u8500_i2c.o

please without "_DRIVER". (you also need to sort lists
alphabetically)

>  COBJS:= $(COBJS-y)
>  SRCS := $(COBJS:.o=.c)
> diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
> new file mode 100644
> index 000..8965100
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.c
> @@ -0,0 +1,603 @@
> +/*
> + * Copyright (C) ST-Ericsson SA 2010
> + *
> + * Basic U-Boot I2C interface for STn8500/DB8500
> + * Author: Michael Brandt  for ST-Ericsson
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +/*
> + * Only 7-bit I2C device addresses are supported.
> + */
> +
> +#include 
> +#include 
> +
> +#include "u8500_i2c.h"
> +#include 
> +#include 
> +#include 
> +
> +#define I2C_ENDAD_COUNTER(CONFIG_SYS_HZ/100) /* I2C bus timeout */
> +#define I2C_FIFO_FLUSH_COUNTER   50  /* flush "timeout" */
> +#define I2C_SCL_FREQ 10  /* I2C bus clock frequency.*/
> +#define I2C_INPUT_FREQ   4800/* Input clock 
> frequency.*/
> +#define TX_FIFO_THRESHOLD0x4
> +#define RX_FIFO_THRESHOLD0x4
> +#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz 
> i2c_clk */
> +
> +#define WRITE_FIELD(var, mask, shift, value) \
> + (var = ((var & ~(mask)) | ((value) << (shift
> +
> +static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
> +static unsigned int i2c_bus_num;
> +static unsigned int i2c_bus_speed[] = {
> + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
> + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
> +};

All busses with the same speed? Also please use something
like "CONFIG_SYS_I2C_U8500_SPEED"

> +static struct u8500_i2c_regs *i2c_dev[] = {
> + (struct u8500_i2c_regs *)CONFIG_SYS_I2C0_BASE,
> + (struct u8500_i2c_regs *)CONFIG_SYS_I2C1_BASE,
> + (struct u8500_i2c_regs *)CONFIG_SYS_I2C2_BASE,
> + (struct u8500_i2c_regs *)CONFIG_SYS_I2C3_BASE,

Could we use for example "CONFIG_SYS_I2C_U8500_BASEx"?

> +};
> +
> +static struct {
> + int periph;
> + int pcken;
> + int kcken;
> +} i2c_clock_bits[] = {
> + {3, 3, 3}, /* I2C0 */
> + {1, 2, 2}, /* I2C1 */
> + {1, 6, 6}, /* I2C2 */
> + {2, 0, 0}, /* I2C3 */
> +};
[...]
> diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
> new file mode 100644
> index 000..8ef6667
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.h
> @@ -0,0 +1,220 @@
> +/*
> + * Copyright (C) ST-Ericsson SA 2009
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _U8500_I2C_H_
> +#define _U8500_I2C_H_
> +
> +#include 
> +#include 
> +#include 
> +
> +//#include "common.h"

No C99 comments please. If it is dead code, please remove.

> +#include