First part of this patch introduces i2c-core. The codebase is sourced from 2.6.25 rc5 kernel contains ONLY i2c support. SMBUS is to be added on a need basis
Signed-off-by: Nishanth Menon <[EMAIL PROTECTED]> --- drivers/Kconfig | 1 drivers/Makefile | 1 drivers/i2c/Kconfig | 39 ++++ drivers/i2c/Makefile | 10 + drivers/i2c/busses/Kconfig | 7 drivers/i2c/busses/Makefile | 9 + drivers/i2c/i2c-core.c | 387 ++++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/i2c-core.h | 37 ++++ include/driver.h | 4 include/linux/i2c.h | 299 +++++++++++++++++++++++++++++++++ 10 files changed, 793 insertions(+), 1 deletion(-) Index: u-boot-v2.git/drivers/i2c/i2c-core.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/drivers/i2c/i2c-core.c 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,387 @@ +/** + * @file + * @brief a device driver for the iic-bus interface + * + * FileName: drivers/i2c/i2c-core.c + * + */ +/* Originally from Linux kernel. Ported to U-boot-v2. + * (C) Copyright 2006-2008 + * Texas Instruments, <www.ti.com> + * Nishanth Menon <[EMAIL PROTECTED]> + */ +/* ------------------------------------------------------------------------- */ +/* Copyright (C) 1995-99 Simon G. Vogl + + 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. */ +/* ------------------------------------------------------------------------- */ + +/* With some changes from Kyösti MÃ$lkki <[EMAIL PROTECTED]>. + All SMBus-related things are written by Frodo Looijaard <[EMAIL PROTECTED]> + SMBus 2.0 support by Mark Studebaker <[EMAIL PROTECTED]> and + Jean Delvare <[EMAIL PROTECTED]> */ + +#include <common.h> +#include <errno.h> +#include <list.h> +#include <init.h> +#include <driver.h> +#include <malloc.h> +#include <string.h> +#include <linux/i2c.h> +#include <linux/idr.h> + +#include "i2c-core.h" + +#ifdef CONFIG_I2C_DEBUG_CORE +#define DBG_MODULE_NAME "i2c-core" +#define dev_dbg(ARGS...) fprintf(stdout, ARGS); +#define dev_warn(ARGS...) fprintf(stderr, ARGS); +#define dbg_entry(FORMAT, ARGS...) fprintf(stdout,\ + DBG_MODULE_NAME"%s:%d:Entry:"FORMAT"\n",\ + __func__, __LINE__, ARGS) +#define dbg_exit(FORMAT, ARGS...) fprintf(stdout,\ + DBG_MODULE_NAME"%s:%d:Exit:"FORMAT"\n",\ + __func__, __LINE__, ARGS) +#else +#define dev_dbg(ARGS...) +#define dev_warn(ARGS...) +#define dbg_entry(FORMAT, ARGS...) +#define dbg_exit(FORMAT, ARGS...) +#endif +#define dev_err(ARGS...) fprintf(stderr, ARGS); + +static DEFINE_IDR(i2c_adapter_idr); + + +/* ------------------------------------------------------------------------- */ + +/** + * @brief When traversing the driver model tree, perhaps using driver model + * iterators like @device_for_each_child(), you can't assume very much + * about the nodes you find. Use this function to avoid oopses caused + * by wrongly treating some non-I2C device as an i2c_client. + * + * @param dev device, probably from some driver model iterator + * + * @return return parameter as i2c_client, or NULL + */ +struct i2c_client *i2c_verify_client(struct device_d *dev) +{ + dbg_entry("dev=%x", (u32) dev); + return (dev->type == DEVICE_TYPE_I2C) ? to_i2c_client(dev) : NULL; +} +EXPORT_SYMBOL(i2c_verify_client); + +static int i2c_register_adapter(struct i2c_adapter *adap) +{ + int res = 0; + dbg_entry("adap=%x", (u32) adap); + + INIT_LIST_HEAD(&adap->clients); + + /* Add the adapter to the driver core. + * If the parent pointer is not set up, + * we add this adapter to the host bus. + */ + res = register_device(&adap->dev); + if (res) + goto out_list; + + dev_dbg("adapter [%s] registered\n", adap->name); + +out_unlock: + return res; + +out_list: + idr_remove(&i2c_adapter_idr, adap->nr); + goto out_unlock; +} + +/** + * @brief declare i2c adapter, use dynamic bus number + * + * This routine is used to declare an I2C adapter when its bus number + * doesn't matter. Examples: for I2C adapters dynamically added by + * USB links or PCI plugin cards. + * + * @param adapter the adapter to add + * + * @return When this returns zero, a new bus number was allocated and stored + * in adap->nr, and the specified adapter became available for clients. + * Otherwise, a negative errno value is returned. + */ +int i2c_add_adapter(struct i2c_adapter *adapter) +{ + int id, res = 0; + dbg_entry("adapter=%x", (u32) adapter); + +retry: + if (idr_pre_get(&i2c_adapter_idr) == 0) + return -ENOMEM; + + /* "above" here means "above or equal to", sigh */ + res = idr_get_new_above(&i2c_adapter_idr, adapter, + __i2c_first_dynamic_bus_num, &id); + + if (res < 0) { + if (res == -EAGAIN) + goto retry; + return res; + } + + adapter->nr = id; + return i2c_register_adapter(adapter); +} +EXPORT_SYMBOL(i2c_add_adapter); + +/** + * @brief declare i2c adapter, use static bus number + * + * This routine is used to declare an I2C adapter when its bus number + * matters. For example, use it for I2C adapters from system-on-chip CPUs, + * or otherwise built in to the system's mainboard, and where i2c_board_info + * is used to properly configure I2C devices. + * + * If no devices have pre-been declared for this bus, then be sure to + * register the adapter before any dynamically allocated ones. Otherwise + * the required bus ID may not be available. + * + * @param adap adapter to register (with adap->nr initialized) + * + * @return When this returns zero, the specified adapter became available for + * clients using the bus number provided in adap->nr. Also, the table + * of I2C devices pre-declared using i2c_register_board_info() is scanned, + * and the appropriate driver model device nodes are created. Otherwise, a + * negative errno value is returned. + */ +int i2c_add_numbered_adapter(struct i2c_adapter *adap) +{ + int id; + int status; + + dbg_entry("adap=%x", (u32) adap); + if (adap->nr & ~MAX_ID_MASK) + return -EINVAL; + +retry: + if (idr_pre_get(&i2c_adapter_idr) == 0) + return -ENOMEM; + + /* "above" here means "above or equal to", sigh; + * we need the "equal to" result to force the result + */ + status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id); + if (status == 0 && id != adap->nr) { + status = -EBUSY; + idr_remove(&i2c_adapter_idr, id); + } + if (status == -EAGAIN) + goto retry; + + if (status == 0) + status = i2c_register_adapter(adap); + return status; +} +EXPORT_SYMBOL(i2c_add_numbered_adapter); + +/** + * @brief unregister I2C adapter + * + * This unregisters an I2C adapter which was previously registered + * by @i2c_add_adapter or @i2c_add_numbered_adapter. + * + * @param adap the adapter being unregistered + * + * @return success or failure in removal + */ +int i2c_del_adapter(struct i2c_adapter *adap) +{ + struct list_head *item, *_n; + struct i2c_client *client; + int res = 0; + + dbg_entry("adap=%x", (u32) adap); + /* First make sure that this adapter was ever added */ + if (idr_find(&i2c_adapter_idr, adap->nr) != adap) { + dev_err("i2c-core: attempting to delete unregistered " + "adapter [%s]\n", adap->name); + res = -EINVAL; + goto out_unlock; + } + + /* detach any active clients. This must be done first, because + * it can fail; in which case we give up. */ + list_for_each_safe(item, _n, &adap->clients) { + struct i2c_driver *driver; + + client = list_entry(item, struct i2c_client, list); + driver = client->driver; + + /* new style, follow standard driver model + * Place holder + if (!driver) { + i2c_unregister_device(client); + continue; + } + */ + + } + + /* clean up the sysfs representation */ + unregister_device(&adap->dev); + + /* free bus id */ + idr_remove(&i2c_adapter_idr, adap->nr); + + dev_dbg("adapter [%s] unregistered\n", adap->name); + +out_unlock: + return res; +} +EXPORT_SYMBOL(i2c_del_adapter); +/** + * @brief find the adapter for an id + * Also increase the adapter refcount + * + * @param id id to search + * + * @return adapter else NULL + */ +struct i2c_adapter *i2c_get_adapter(int id) +{ + struct i2c_adapter *adapter; + dbg_entry("id=%x", id); + + adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); + + return adapter; +} +EXPORT_SYMBOL(i2c_get_adapter); + +/** + * @brief return the usage of get_adapter -> reduce refcount + * + * @param adap adapter to return + * + * @return none + */ +void i2c_put_adapter(struct i2c_adapter *adap) +{ + dbg_entry("adap=%x", (u32) adap); + /* Empty function for the timebeing.. */ +} +EXPORT_SYMBOL(i2c_put_adapter); + +/* ------------------------------------------------------------------------- */ + +/* ---------------------------------------------------- + * the functional interface to the i2c busses. + * ---------------------------------------------------- + */ + +/** + * @brief do i2c_transfer to an adapter + * + * @param adap adapter + * @param msgs the messages + * @param num number of messages + * + * @return result of transfer + */ +int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + int ret; + + dbg_entry("adap=%x msg=%x num=%x", (u32) adap, (u32) msgs, num); + if (adap->algo->master_xfer) { +#ifdef DEBUG + for (ret = 0; ret < num; ret++) { + dev_dbg("master_xfer[%d] %c, addr=0x%02x, " + "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD) + ? 'R' : 'W', msgs[ret].addr, msgs[ret].len, + (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : ""); + } +#endif + + ret = adap->algo->master_xfer(adap, msgs, num); + return ret; + } else { + dev_dbg("I2C level transfers not supported\n"); + return -ENOSYS; + } +} +EXPORT_SYMBOL(i2c_transfer); + +/** + * @brief send few bytes to a client + * + * @param client client to send data to + * @param buf buffer data + * @param count num bytes + * + * @return result of operation + */ +int i2c_master_send(struct i2c_client *client, const char *buf, int count) +{ + int ret; + struct i2c_adapter *adap = client->adapter; + struct i2c_msg msg; + + dbg_entry("client=%x buf=%x count=%x", (u32) client, (u32) buf, + (u32) count); + msg.addr = client->addr; + msg.flags = client->flags & I2C_M_TEN; + msg.len = count; + msg.buf = (char *)buf; + + ret = i2c_transfer(adap, &msg, 1); + + /* If everything went ok (i.e. 1 msg transmitted), return #bytes + transmitted, else error code. */ + return (ret == 1) ? count : ret; +} +EXPORT_SYMBOL(i2c_master_send); + +/** + * @brief read a few bytes from client + * + * @param client client + * @param buf buffer + * @param count num bytes to read + * + * @return result of operation + */ +int i2c_master_recv(struct i2c_client *client, char *buf, int count) +{ + struct i2c_adapter *adap = client->adapter; + struct i2c_msg msg; + int ret; + + dbg_entry("client=%x buf=%x count=%x", (u32) client, (u32) buf, + (u32) count); + msg.addr = client->addr; + msg.flags = client->flags & I2C_M_TEN; + msg.flags |= I2C_M_RD; + msg.len = count; + msg.buf = buf; + + ret = i2c_transfer(adap, &msg, 1); + + /* If everything went ok (i.e. 1 msg transmitted), return #bytes + transmitted, else error code. */ + return (ret == 1) ? count : ret; +} +EXPORT_SYMBOL(i2c_master_recv); Index: u-boot-v2.git/drivers/i2c/Kconfig =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/drivers/i2c/Kconfig 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,39 @@ +# +# I2C subsystem configuration +# + +menuconfig I2C + tristate "I2C support" + ---help--- + I2C (pronounce: I-square-C) is a slow serial bus protocol used in + many micro controller applications and developed by Philips. SMBus, + or System Management Bus is a subset of the I2C protocol. More + information is contained in the directory <file:Documentation/i2c/>, + especially in the file called "summary" there. + + If you want I2C support, you should say Y here and also to the + specific driver for your bus adapter(s) below. + + This I2C support can also be built as a module. If so, the module + will be called i2c-core. + +if I2C + +source drivers/i2c/busses/Kconfig + +config I2C_DEBUG_CORE + bool "I2C Core debugging messages" + help + Say Y here if you want the I2C core to produce a bunch of debug + messages to the system log. Select this if you are having a + problem with I2C support and want to see more of what is going on. + +config I2C_DEBUG_BUS + bool "I2C Bus debugging messages" + help + Say Y here if you want the I2C bus drivers to produce a bunch of + debug messages to the system log. Select this if you are having + a problem with I2C support and want to see more of what is going + on. + +endif # I2C Index: u-boot-v2.git/drivers/i2c/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/drivers/i2c/Makefile 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,10 @@ +# +# Makefile for the i2c core. +# + +obj-$(CONFIG_I2C) += i2c-core.o +obj-y += busses/ + +ifeq ($(CONFIG_I2C_DEBUG_CORE),y) +EXTRA_CFLAGS += -DDEBUG +endif Index: u-boot-v2.git/drivers/i2c/busses/Kconfig =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/drivers/i2c/busses/Kconfig 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,7 @@ +# +# Sensor device configuration +# + +menu "I2C Hardware Bus support" + +endmenu Index: u-boot-v2.git/drivers/i2c/busses/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/drivers/i2c/busses/Makefile 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,9 @@ +# +# Makefile for the i2c bus drivers. +# + +obj-$(CONFIG_I2C_OMAP) += i2c-omap.o + +ifeq ($(CONFIG_I2C_DEBUG_BUS),y) +EXTRA_CFLAGS += -DDEBUG +endif Index: u-boot-v2.git/drivers/i2c/i2c-core.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/drivers/i2c/i2c-core.h 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,37 @@ +/** + * @file + * @brief - interfaces internal to the I2C framework + * + * FileName: drivers/i2c/i2c-core.h + * + */ +/* Originally from Linux kernel. Ported to U-boot-v2. + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * Nishanth Menon <[EMAIL PROTECTED]> + */ +/* + * 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. + */ +#ifndef __i2C_CORE_H +#define __i2C_CORE_H + +/* board_lock protects board_list and first_dynamic_bus_num. + * only i2c core components are allowed to use these symbols. + */ +extern struct list_head __i2c_board_list; +extern int __i2c_first_dynamic_bus_num; + +#endif /* __i2C_CORE_H */ Index: u-boot-v2.git/include/linux/i2c.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-v2.git/include/linux/i2c.h 2008-06-19 08:42:46.000000000 -0500 @@ -0,0 +1,299 @@ +/** + * @file + * @brief definitions for the i2c-bus interface + * + * FileName: include/linux/i2c.h + * + */ +/* Originally from Linux kernel. Ported to U-boot-v2. + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * Nishanth Menon <[EMAIL PROTECTED]> + */ +/* Copyright (C) 1995-2000 Simon G. Vogl + + 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. */ +/* ------------------------------------------------------------------------- */ + +/* With some changes from Kyösti MÃ$lkki <[EMAIL PROTECTED]> and + Frodo Looijaard <[EMAIL PROTECTED]> */ + +#ifndef _LINUX_I2C_H +#define _LINUX_I2C_H + +#include <linux/types.h> +#ifdef __U_BOOT__ +#include <module.h> +#include <linux/mod_devicetable.h> +#include <driver.h> + +/* --- General options ------------------------------------------------ */ + +struct i2c_msg; +struct i2c_algorithm; +struct i2c_adapter; +struct i2c_client; +struct i2c_driver; + +/** + * The master routines are the ones normally used to transmit data to devices + * on a bus (or read from them). Apart from two basic transfer functions to + * transmit one message at a time, a more complex version can be used to + * transmit an arbitrary number of messages without interruption. + */ +extern int i2c_master_send(struct i2c_client *, const char *, int); +extern int i2c_master_recv(struct i2c_client *, char *, int); + +/** Transfer num messages. + */ +extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,\ + int num); + +/** + * A driver is capable of handling one or more physical devices present on + * I2C adapters. This information is used to inform the driver of adapter + * events. + * + * The driver.owner field should be set to the module owner of this driver. + * The driver.name field should be set to the name of this driver. + * + * @warning: U-Boot V2 does not support legacy drivers as defined in Linux + * kernel + */ +struct i2c_driver { + int id; + + /** Standard driver model interfaces, for "new style" i2c drivers. + * With the driver model, device enumeration is NEVER done by drivers; + * it's done by infrastructure. (NEW STYLE DRIVERS ONLY) + */ + int (*probe)(struct i2c_client *, const struct i2c_device_id *); + int (*remove)(struct i2c_client *); + + /** a ioctl like command that can be used to perform specific functions + * with the device. + */ + int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); + + struct driver_d driver; + const struct i2c_device_id *id_table; +}; +#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) + +/** + * struct i2c_client - represent an I2C slave device + * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address; + * I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking + * @addr: Address used on the I2C bus connected to the parent adapter. + * @name: Indicates the type of the device, usually a chip name that's + * generic enough to hide second-sourcing and compatible revisions. + * @adapter: manages the bus segment hosting this I2C device + * @driver: device's driver, hence pointer to access routines + * @dev: Driver model device node for the slave. + * @irq: indicates the IRQ generated by this device (if any) + * @list: list of active/busy clients (DEPRECATED) + * @released: used to synchronize client releases & detaches and references + * + * An i2c_client identifies a single device (i.e. chip) connected to an + * i2c bus. The behaviour exposed to Linux is defined by the driver + * managing the device. + */ +struct i2c_client { + unsigned short flags; /* div., see below */ + unsigned short addr; /* chip address - NOTE: 7bit */ + /* addresses are stored in the */ + /* _LOWER_ 7 bits */ + char name[I2C_NAME_SIZE]; + struct i2c_adapter *adapter; /* the adapter we sit on */ + struct i2c_driver *driver; /* and our access routines */ + struct device_d dev; /* the device structure */ + int irq; /* irq issued by device (or -1) */ + struct list_head list; /* DEPRECATED */ +}; +#define to_i2c_client(d) container_of(d, struct i2c_client, dev) + +extern struct i2c_client *i2c_verify_client(struct device_d *dev); + +static inline void *i2c_get_clientdata(struct i2c_client *dev) +{ + return (&dev->dev)->platform_data; +} + +static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) +{ + (&dev->dev)->platform_data = data; +} + + +/** + * The following structs are for those who like to implement new bus drivers: + * i2c_algorithm is the interface to a class of hardware solutions which can + * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 + * to name two of the most common. + */ +struct i2c_algorithm { + /** If an adapter algorithm can't do I2C-level access, set master_xfer + to NULL. If an adapter algorithm can do SMBus access, set + smbus_xfer. If set to NULL, the SMBus protocol is simulated + using common I2C messages */ + /** master_xfer should return the number of messages successfully + processed, or a negative value on error */ + int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); + /* To determine what the adapter supports */ + u32 (*functionality) (struct i2c_adapter *); +}; + +/** + * i2c_adapter is the structure used to identify a physical i2c bus along + * with the access algorithms necessary to access it. + */ +struct i2c_adapter { + struct module *owner; + unsigned int id; + const struct i2c_algorithm *algo; /* the algorithm to access the bus */ + void *algo_data; + + /* --- administration stuff. */ + int (*client_register)(struct i2c_client *); + int (*client_unregister)(struct i2c_client *); + + int timeout; + int retries; + struct device_d dev; /* the adapter device */ + + int nr; + struct list_head clients; /* DEPRECATED */ + char name[48]; +}; +#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) + +static inline void *i2c_get_adapdata(struct i2c_adapter *dev) +{ + return (&dev->dev)->platform_data; +} + +static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) +{ + (&dev->dev)->platform_data = data; +} + +/*flags for the client struct: */ +#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ +#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ + /* Must equal I2C_M_TEN below */ + +/* ----- functions exported by i2c.o */ + +/* administration... + */ +extern int i2c_add_adapter(struct i2c_adapter *); +extern int i2c_del_adapter(struct i2c_adapter *); +extern int i2c_add_numbered_adapter(struct i2c_adapter *); + +extern struct i2c_adapter *i2c_get_adapter(int id); +extern void i2c_put_adapter(struct i2c_adapter *adap); + + +/** Return the functionality mask */ +static inline u32 i2c_get_functionality(struct i2c_adapter *adap) +{ + return adap->algo->functionality(adap); +} + +/** Return 1 if adapter supports everything we need, 0 if not. */ +static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func) +{ + return (func & i2c_get_functionality(adap)) == func; +} + +/** Return id number for a specific adapter */ +static inline int i2c_adapter_id(struct i2c_adapter *adap) +{ + return adap->nr; +} +#endif /* __U_BOOT__ */ + +/** + * struct i2c_msg - an I2C transaction segment beginning with START + * @addr: Slave address, either seven or ten bits. When this is a ten + * bit address, I2C_M_TEN must be set in @flags and the adapter + * must support I2C_FUNC_10BIT_ADDR. + * @flags: I2C_M_RD is handled by all adapters. No other flags may be + * provided unless the adapter exported the relevant I2C_FUNC_* + * flags through i2c_check_functionality(). + * @len: Number of data bytes in @buf being read from or written to the + * I2C slave address. For read transactions where I2C_M_RECV_LEN + * is set, the caller guarantees that this buffer can hold up to + * 32 bytes in addition to the initial length byte sent by the + * slave (plus, if used, the SMBus PEC); and this value will be + * incremented by the number of block data bytes received. + * @buf: The buffer into which data is read, or from which it's written. + * + * An i2c_msg is the low level representation of one segment of an I2C + * transaction. It is visible to drivers in the @i2c_transfer() procedure, + * to userspace from i2c-dev, and to I2C adapter drivers through the + * @[EMAIL PROTECTED]() method. + * + * Except when I2C "protocol mangling" is used, all I2C adapters implement + * the standard rules for I2C transactions. Each transaction begins with a + * START. That is followed by the slave address, and a bit encoding read + * versus write. Then follow all the data bytes, possibly including a byte + * with SMBus PEC. The transfer terminates with a NAK, or when all those + * bytes have been transferred and ACKed. If this is the last message in a + * group, it is followed by a STOP. Otherwise it is followed by the next + * @i2c_msg transaction segment, beginning with a (repeated) START. + * + * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then + * passing certain @flags may have changed those standard protocol behaviors. + * Those flags are only for use with broken/nonconforming slaves, and with + * adapters which are known to support the specific mangling options they + * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR). + */ +struct i2c_msg { + __u16 addr; /* slave address */ + __u16 flags; +#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ +#define I2C_M_RD 0x0001 /* read data, from slave to master */ +#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ + __u16 len; /* msg length */ + __u8 *buf; /* pointer to msg data */ +}; + +/** To determine what functionality is present */ + +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +/** I2C_M_{REV_DIR_ADDR,NOSTART,..} */ +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 + + +/** SMBus transaction types (size parameter in the above functions) + Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 8 + +#endif /* _LINUX_I2C_H */ Index: u-boot-v2.git/drivers/Kconfig =================================================================== --- u-boot-v2.git.orig/drivers/Kconfig 2008-06-19 08:40:01.000000000 -0500 +++ u-boot-v2.git/drivers/Kconfig 2008-06-19 08:42:46.000000000 -0500 @@ -3,6 +3,7 @@ source "drivers/serial/Kconfig" source "drivers/net/Kconfig" source "drivers/spi/Kconfig" +source "drivers/i2c/Kconfig" menu "flash drivers " Index: u-boot-v2.git/drivers/Makefile =================================================================== --- u-boot-v2.git.orig/drivers/Makefile 2008-06-19 08:40:01.000000000 -0500 +++ u-boot-v2.git/drivers/Makefile 2008-06-19 08:42:46.000000000 -0500 @@ -2,6 +2,7 @@ obj-y += serial/ obj-y += nand/ obj-$(CONFIG_SPI) += spi/ +obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_DRIVER_CFI_OLD) += cfi_flash.o obj-$(CONFIG_DRIVER_CFI_NEW) += cfi_flash_new.o obj-$(CONFIG_DRIVER_CFI_INTEL) += cfi_flash_intel.o Index: u-boot-v2.git/include/driver.h =================================================================== --- u-boot-v2.git.orig/include/driver.h 2008-06-19 08:40:00.000000000 -0500 +++ u-boot-v2.git/include/driver.h 2008-06-19 08:42:46.000000000 -0500 @@ -34,7 +34,9 @@ #define DEVICE_TYPE_BLOCK 4 #define DEVICE_TYPE_FS 5 #define DEVICE_TYPE_MIIPHY 6 -#define MAX_DEVICE_TYPE 6 +#define DEVICE_TYPE_I2C 7 +#define DEVICE_TYPE_I2CDEV 8 +#define MAX_DEVICE_TYPE 8 #include <param.h> ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users