[U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c
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
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