From mboxrd@z Thu Jan 1 00:00:00 1970 From: Piotr Wilczek Date: Mon, 22 Oct 2012 09:21:19 +0200 Subject: [U-Boot] [PATCH v2 5/9] drivers:i2c: Add support for multi I2C In-Reply-To: <1350890483-26579-1-git-send-email-p.wilczek@samsung.com> References: <1350890483-26579-1-git-send-email-p.wilczek@samsung.com> Message-ID: <1350890483-26579-6-git-send-email-p.wilczek@samsung.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de This patch enables use of SOFT I2C and HARD I2C simultaneously. Signed-off-by: Gwuieon Jin Signed-off-by: Piotr Wilczek Signed-off-by: Kyungmin Park CC: Minkyu Kang --- Changes in v2: - new patch drivers/i2c/Makefile | 1 + drivers/i2c/multi_i2c.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++ include/multi_i2c.h | 62 +++++++++++++++++++++++ 3 files changed, 187 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/multi_i2c.c create mode 100644 include/multi_i2c.h diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 5dbdbe3..5c82130 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -46,6 +46,7 @@ COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o COBJS-$(CONFIG_SH_I2C) += sh_i2c.o COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o +COBJS-$(CONFIG_MULTI_I2C) += multi_i2c.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/i2c/multi_i2c.c b/drivers/i2c/multi_i2c.c new file mode 100644 index 0000000..7751c7b --- /dev/null +++ b/drivers/i2c/multi_i2c.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * Gwuieon Jin + * + * 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 + */ + +#include +#include +#include + + +static struct multi_i2c_dev multi_i2c_devs[MULTI_I2C_MAX]; +static struct multi_i2c_dev *active_dev; +static int count_devices; + +static struct multi_i2c_dev *multi_i2c_get_by_bus(const unsigned int bus) +{ + /* HARD I2C MAX NUM */ + if (bus > CONFIG_MAX_I2C_NUM) + return &multi_i2c_devs[MULTI_I2C_SOFT]; + + return &multi_i2c_devs[MULTI_I2C_HARD]; +} + +static void multi_i2c_register(struct i2c_ops *ops, u32 flags) +{ + int index; + + if (flags & SOFT_I2C_DEV) + index = MULTI_I2C_SOFT; + else + index = MULTI_I2C_HARD; + + multi_i2c_devs[index].ops = ops; + active_dev = &multi_i2c_devs[index]; + count_devices++; +} + +void i2c_init(int speed, int slaveadd) +{ + int i; + + count_devices = 0; + +#ifdef CONFIG_SOFT_I2C + multi_i2c_register(&soft_i2c_ops, SOFT_I2C_DEV); +#endif +#ifdef CONFIG_DRIVER_S3C24X0_I2C + multi_i2c_register(&s3c24x0_i2c_ops, HARD_I2C_DEV); +#endif + for (i = 0; i < count_devices; i++) { + if (multi_i2c_devs[i].ops->init) + multi_i2c_devs[i].ops->init(speed, slaveadd); + } +} + +int i2c_probe(uchar chip) +{ + return active_dev->ops->probe(chip); +} + +int i2c_read(uchar chip, uint addr, int alen, + uchar *buffer, int len) +{ + return active_dev->ops->read(chip, addr, alen, + buffer, len); +} + +int i2c_write(uchar chip, uint addr, int alen, + uchar *buffer, int len) +{ + return active_dev->ops->write(chip, addr, alen, + buffer, len); +} + +unsigned int i2c_get_bus_num(void) +{ + return active_dev->ops->get_bus_num(); +} + +int i2c_set_bus_num(unsigned int bus) +{ + struct multi_i2c_dev *dev; + + if (bus < 0 || bus > CONFIG_SYS_MAX_I2C_BUS) + return -1; + + dev = multi_i2c_get_by_bus(bus); + if (dev) { + active_dev = dev; + return dev->ops->set_bus_num(bus); + } + + printf("%s: Can not find I2C dev for %d bus\n", + __func__, bus); + return -EINVAL; +} + +void i2c_reset(void) +{ + int i; + + for (i = 0; i < count_devices; i++) { + if (multi_i2c_devs[i].ops->reset) + multi_i2c_devs[i].ops->reset(); + } +} diff --git a/include/multi_i2c.h b/include/multi_i2c.h new file mode 100644 index 0000000..795fbf0 --- /dev/null +++ b/include/multi_i2c.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * Gwuieon Jin + * + * 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 _MULTI_I2C_H +#define _MULTI_I2C_H + +#define SOFT_I2C_DEV (1 << 1) +#define HARD_I2C_DEV (1 << 2) + +enum { + MULTI_I2C_SOFT, + MULTI_I2C_HARD, + MULTI_I2C_MAX, +}; + +struct i2c_ops { + void (*init) (int speed, int slaveadd); + int (*probe) (uchar chip); + int (*read) (uchar chip, uint addr, int alen, + uchar *buffer, int len); + int (*read_r) (uchar chip, uint addr, int alen, + uchar *buffer, int len); + int (*write) (uchar chip, uint addr, int alen, + uchar *buffer, int len); + unsigned int (*get_bus_num) (void); + int (*set_bus_num) (unsigned int bus); + void (*reset) (void); +}; + +/* Device information */ +struct multi_i2c_dev { + struct i2c_ops *ops; +}; + +#ifdef CONFIG_SOFT_I2C +extern struct i2c_ops soft_i2c_ops; +#endif +#ifdef CONFIG_DRIVER_S3C24X0_I2C +extern struct i2c_ops s3c24x0_i2c_ops; +#endif + +#endif /* _MULTI_I2C_H */ -- 1.7.5.4