Sfoglia il codice sorgente

update I2C driver, which now just use small memory

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2159 bbd45198-f89e-11dd-88c7-29a3b14d5316
luohui2320@gmail.com 13 anni fa
parent
commit
85169d7fe8

+ 16 - 17
components/drivers/i2c/i2c-bit-ops.c

@@ -12,8 +12,7 @@
  * 2012-04-25     weety		first version
  */
 
-#include <i2c.h>
-#include <i2c-bit-ops.h>
+#include <rtdevice.h>
 
 #ifdef RT_I2C_BIT_DEBUG
 #define bit_dbg(fmt, ...)	rt_kprintf(fmt, ##__VA_ARGS__)
@@ -126,7 +125,7 @@ rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops)
 		return -RT_ETIMEOUT;
 	}
 
-	ack = !GET_SDA(ops);    /* ack : sda pin is pulled low */
+	ack = !GET_SDA(ops);    /* ACK : SDA pin is pulled low */
 	bit_dbg("%s\n", ack ? "ACK" : "NACK");
 
 	SCL_L(ops);
@@ -135,7 +134,7 @@ rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops)
 }
 
 
-static rt_int32_t i2c_writeb(struct rt_i2c_bus *bus, rt_uint8_t data)
+static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data)
 {
 	rt_int32_t i;
 	rt_uint8_t bit;
@@ -151,7 +150,7 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus *bus, rt_uint8_t data)
 		if (SCL_H(ops) < 0) 
 		{
 			bit_dbg("i2c_writeb: 0x%02x, "
-				"wait scl pin high timeout at bit #%d\n", 
+				"wait scl pin high timeout at bit %d\n", 
 				data, i);
 			return -RT_ETIMEOUT;
 		}
@@ -164,7 +163,7 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus *bus, rt_uint8_t data)
 }
 
 
-static rt_int32_t i2c_readb(struct rt_i2c_bus *bus)
+static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus)
 {
 	rt_uint8_t i;
 	rt_uint8_t data = 0;
@@ -179,7 +178,7 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus *bus)
 		if (SCL_H(ops) < 0) 
 		{
 			bit_dbg("i2c_readb: wait scl pin high "
-				"timeout at bit #%d\n", 7 - i);
+				"timeout at bit %d\n", 7 - i);
 			return -RT_ETIMEOUT;
 		}
 		
@@ -193,7 +192,7 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus *bus)
 }
 
 
-static rt_size_t i2c_send_bytes(struct rt_i2c_bus *bus, struct rt_i2c_msg *msg)
+static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus, struct rt_i2c_msg *msg)
 {
 	rt_int32_t ret;
 	rt_size_t bytes = 0;
@@ -225,7 +224,7 @@ static rt_size_t i2c_send_bytes(struct rt_i2c_bus *bus, struct rt_i2c_msg *msg)
 	return bytes;
 }
 
-static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus *bus, int ack)
+static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack)
 {
 	struct rt_i2c_bit_ops *ops = bus->priv;
 
@@ -241,7 +240,7 @@ static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus *bus, int ack)
 	return RT_EOK;
 }
 
-static rt_size_t i2c_recv_bytes(struct rt_i2c_bus *bus, struct rt_i2c_msg *msg)
+static rt_size_t i2c_recv_bytes(struct rt_i2c_bus_device *bus, struct rt_i2c_msg *msg)
 {
 	rt_int32_t val;
 	rt_int32_t bytes = 0;	/* actual bytes */
@@ -279,7 +278,7 @@ static rt_size_t i2c_recv_bytes(struct rt_i2c_bus *bus, struct rt_i2c_msg *msg)
 	return bytes;
 }
 
-static rt_int32_t i2c_send_address(struct rt_i2c_bus *bus,
+static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
 		       rt_uint8_t addr, rt_int32_t retries)
 {
 	struct rt_i2c_bit_ops *ops = bus->priv;
@@ -301,7 +300,7 @@ static rt_int32_t i2c_send_address(struct rt_i2c_bus *bus,
 	return ret;
 }
 
-static rt_err_t i2c_bit_send_address(struct rt_i2c_bus *bus, struct rt_i2c_msg *msg)
+static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus, struct rt_i2c_msg *msg)
 {
 	rt_uint16_t flags = msg->flags;
 	rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
@@ -360,7 +359,7 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus *bus, struct rt_i2c_msg *
 }
 
 
-static rt_size_t i2c_bit_xfer(struct rt_i2c_bus *bus,
+static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
 		    struct rt_i2c_msg msgs[], rt_uint32_t num)
 {
 	struct rt_i2c_msg *msg;
@@ -383,7 +382,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus *bus,
 			ret = i2c_bit_send_address(bus, msg);
 			if ((ret != RT_EOK) && !ignore_nack)
 			{
-				bit_dbg("receive NACK from device addr 0x%02x msg #%d\n",
+				bit_dbg("receive NACK from device addr 0x%02x msg %d\n",
 					msgs[i].addr, i);
 				goto out;
 			}
@@ -425,14 +424,14 @@ out:
 }
 
 
-static const struct rt_i2c_bus_ops i2c_bit_bus_ops = {
+static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops = {
 	i2c_bit_xfer,
 	RT_NULL,
 	RT_NULL
 };
 
 
-rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus *bus)
+rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus, const char *bus_name)
 {
 	rt_err_t err;
 
@@ -441,5 +440,5 @@ rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus *bus)
 
 	bus->ops = &i2c_bit_bus_ops;
 
-	return rt_i2c_bus_register(bus);
+	return rt_i2c_bus_device_register(bus, bus_name);
 }

+ 0 - 117
components/drivers/i2c/i2c.h

@@ -1,117 +0,0 @@
-/*
- * File      : i2c.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author		Notes
- * 2012-04-25     weety		first version
- */
-
-#ifndef __I2C_H__
-#define __I2C_H__
-
-#include <rtthread.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef RT_I2C_NAME_SIZE
-#define RT_I2C_NAME_SIZE 32
-#endif
-
-#define RT_I2C_WR                0x0000
-#define RT_I2C_RD               (1u << 0)
-#define RT_I2C_ADDR_10BIT       (1u << 2)  /* this is a ten bit chip address */
-#define RT_I2C_NO_START         (1u << 4)
-#define RT_I2C_IGNORE_NACK      (1u << 5)
-#define RT_I2C_NO_READ_ACK      (1u << 6)  /* when I2C reading, we do not ACK */
-
-struct rt_i2c_msg {
-	rt_uint16_t addr;
-	rt_uint16_t flags;
-	rt_uint16_t len;
-	rt_uint8_t  *buf;
-};
-
-struct rt_i2c_hardware_info {
-	char name[RT_I2C_NAME_SIZE];
-	rt_uint16_t flags;
-	rt_uint16_t addr;
-	rt_uint32_t bus_id;
-	rt_list_t  list;
-};
-
-#define RT_I2C_HARDWARE_INFO(name, flags, addr, bus_id) \
-	name,flags,addr,bus_id,{RT_NULL,RT_NULL}
-
-struct rt_i2c_bus;
-
-struct rt_i2c_bus_ops {
-	rt_size_t (*master_xfer) (struct rt_i2c_bus *bus, struct rt_i2c_msg *msgs, rt_uint32_t num);
-	rt_size_t (*slave_xfer) (struct rt_i2c_bus *bus, struct rt_i2c_msg *msgs, rt_uint32_t num);
-	rt_err_t (*i2c_bus_control) (struct rt_i2c_bus *bus, rt_uint32_t, rt_uint32_t);
-};
-
-/*for i2c bus driver*/
-struct rt_i2c_bus {
-	struct rt_device *parent;
-	char name[RT_I2C_NAME_SIZE];
-	rt_uint32_t id;
-	const struct rt_i2c_bus_ops *ops;
-	struct rt_mutex lock;
-	rt_list_t devices;
-	rt_list_t list;
-	rt_uint32_t  timeout;
-	rt_uint32_t  retries;
-	void *priv;
-};
-
-struct rt_i2c_device;
-struct rt_i2c_driver {
-	char name[RT_I2C_NAME_SIZE];
-	rt_err_t (*probe)(struct rt_i2c_device *device);
-	rt_err_t (*remove)(struct rt_i2c_device *device);
-	rt_list_t devices;
-};
-
-/*for i2c device driver*/
-struct rt_i2c_device {
-	rt_uint32_t  flags;
-	rt_uint16_t  addr;
-	struct rt_i2c_bus *bus;
-	struct rt_i2c_driver *driver;
-	struct rt_device dev;
-	rt_list_t  drv_list;
-	rt_list_t  bus_list;
-};
-
-#ifdef RT_I2C_DEBUG
-#define i2c_dbg(fmt, ...)	rt_kprintf(fmt, ##__VA_ARGS__)
-#else
-#define i2c_dbg(fmt, ...)
-#endif
-
-rt_err_t rt_i2c_bus_register(struct rt_i2c_bus *bus);
-rt_err_t rt_i2c_bus_unregister(struct rt_i2c_bus *bus);
-void rt_i2c_hw_info_register(struct rt_i2c_hardware_info *info, rt_uint32_t size);
-rt_err_t rt_i2c_bus_attach_driver(struct rt_i2c_driver *driver);
-rt_err_t rt_i2c_bus_detach_driver(struct rt_i2c_driver *driver);
-rt_size_t rt_i2c_transfer(struct rt_i2c_bus *bus, 
-			  struct rt_i2c_msg *msgs, rt_uint32_t size);
-rt_size_t rt_i2c_master_send(struct rt_i2c_device *device, 
-			     const rt_uint8_t *buf, rt_uint32_t size);
-rt_size_t rt_i2c_master_recv(struct rt_i2c_device *device, 
-			     rt_uint8_t *buf ,rt_uint32_t size);
-rt_err_t rt_i2c_core_init();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 39 - 283
components/drivers/i2c/i2c_core.c

@@ -12,362 +12,118 @@
  * 2012-04-25     weety		first version
  */
 
-#include <i2c.h>
-#include <i2c_dev.h>
+#include <rtdevice.h>
 
 static struct rt_mutex i2c_core_lock;
-static struct rt_mutex i2c_hardware_lock;
-static rt_list_t i2c_hw_info_list = RT_LIST_OBJECT_INIT(i2c_hw_info_list);
-static rt_list_t i2c_bus_list = RT_LIST_OBJECT_INIT(i2c_bus_list);
 
-static struct rt_i2c_bus *find_i2c_bus(rt_uint32_t id)
+rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, const char *bus_name)
 {
-	rt_list_t *list;
-	struct rt_i2c_bus *bus = RT_NULL;
-
-	for (list = (&i2c_bus_list)->next; list != &i2c_bus_list; list = list->next)
-	{
-		bus = (struct rt_i2c_bus *)rt_list_entry(list, struct rt_i2c_bus, list);
-		if (bus->id == id)
-		{
-			return bus;
-		}
-	}
-
-	return RT_NULL;
-}
+	rt_err_t res = RT_EOK;
 
-
-rt_err_t rt_i2c_bus_register(struct rt_i2c_bus *bus)
-{
-	rt_err_t ret = RT_EOK;
-	struct rt_i2c_bus *tbus;
-
-	rt_mutex_init (&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_FIFO);
+	rt_mutex_init(&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_FIFO);
 
 	rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER);
 
-	tbus = find_i2c_bus(bus->id);
-	if (tbus != RT_NULL)
-	{
-		rt_kprintf("I2C bus ID [%d] already registered\n", bus->id);
-		ret = -RT_ERROR;
-		goto out;
-	}
-
 	if (bus->timeout == 0)
 		bus->timeout = RT_TICK_PER_SECOND;
-	
-	rt_list_init(&bus->devices);
-	
-	ret = rt_i2c_bus_device_init(bus, bus->name);
-	if (ret != RT_EOK)
-	{
-		rt_mutex_release(&i2c_core_lock);
-		rt_kprintf("I2C bus [%s] register failed\n", bus->name);
-		goto out;
-	}
-
-	rt_list_insert_after(&i2c_bus_list, &bus->list);
-
-	rt_mutex_release(&i2c_core_lock);
-
-	rt_kprintf("I2C bus [%s] registered\n", bus->name);
-out:
-	return ret;
-}
-
-
-rt_err_t rt_i2c_bus_unregister(struct rt_i2c_bus *bus)
-{
-	rt_err_t ret = RT_EOK;
-	struct rt_i2c_bus *bus_l;
-	rt_list_t *list;
-	struct rt_i2c_device *device;
-
-	rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER);
-	
-	rt_i2c_bus_device_exit(bus);
-	
-	for (list = (&bus->devices)->next; list != &bus->devices; list = list->next)
-	{
-		device = (struct rt_i2c_device *)rt_list_entry(list, struct rt_i2c_device, bus_list);
-		if (device)
-		{
-			ret = device->driver->remove(device);
-			if (ret != RT_EOK)
-			{
-				i2c_dbg("I2C driver [%s] unregister failed\n", device->driver->name);
-				goto out;
-			}
-			rt_list_remove(&device->drv_list);
-			rt_list_remove(&device->bus_list);
-		}
-	}
-	
-	rt_list_init(&bus->devices);
-	rt_list_remove(&bus->list);
+		
+	res = rt_i2c_bus_device_device_init(bus, bus_name);
 
-	rt_mutex_detach (&bus->lock);
+	i2c_dbg("I2C bus [%s] registered\n", bus_name);
 
-	rt_kprintf("I2C bus [%s] unregister\n", bus->name);
-out:
 	rt_mutex_release(&i2c_core_lock);
-	return ret;
+	return res;
 }
 
 
-rt_inline struct rt_i2c_hardware_info *
-i2c_check_hw_info(struct rt_i2c_hardware_info *hwinfo)
+struct rt_i2c_bus_device* rt_i2c_bus_device_find(const char *bus_name)
 {
-	rt_list_t *list;
-	struct rt_i2c_hardware_info *info;
-
-	for (list = (&i2c_hw_info_list)->next; list != &i2c_hw_info_list; list = list->next)
+	struct rt_i2c_bus_device *bus;
+	rt_device_t dev = rt_device_find(bus_name);
+	if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS)
 	{
-		info = (struct rt_i2c_hardware_info *)rt_list_entry(list, 
-				struct rt_i2c_hardware_info, list);
-		if ((info->bus_id == hwinfo->bus_id) && (info->addr == hwinfo->addr))
-		{
-			return info;
-		}
+		i2c_dbg("I2C bus %s not exist\n", bus_name);
+		return RT_NULL;
 	}
-
-	return RT_NULL;
-}
-
-void rt_i2c_hw_info_register(struct rt_i2c_hardware_info *info, rt_uint32_t size)
-{
-	rt_mutex_take(&i2c_hardware_lock, RT_WAITING_FOREVER);
-	for( ; size > 0; size--, info++)
-	{
-		if (i2c_check_hw_info(info) == RT_NULL)
-		{
-			rt_list_insert_after(&i2c_hw_info_list, &info->list);
-		}
-		else
-		{
-			rt_kprintf("I2C hw info [%s:%d:%d] already registered\n", 
-				   info->name, info->bus_id, info->addr);
-		}
-	}
-	rt_mutex_release(&i2c_hardware_lock);
-}
-
-rt_err_t rt_i2c_check_addr(struct rt_i2c_bus *bus, rt_uint16_t addr)
-{
-	rt_list_t *list;
-	struct rt_i2c_device *device;
 	
-	for (list = (&bus->devices)->next; list != &bus->devices; list = list->next)
-	{
-		device = (struct rt_i2c_device *)rt_list_entry(list, struct rt_i2c_device, bus_list);
-		if (device->addr == addr)
-		{
-			rt_kprintf("ERR: device at addr[0x%02x] "
-				   "already registered\n", addr);
-			return -RT_ERROR;
-		}
-	}
+	bus = (struct rt_i2c_bus_device *)dev->user_data;
 	
-	return RT_EOK;
+	return bus;
 }
 
-static rt_err_t i2c_driver_probe(struct rt_i2c_bus *bus, 
-	struct rt_i2c_driver *driver, struct rt_i2c_hardware_info *info)
-{
-	rt_err_t ret = RT_EOK;
-	struct rt_i2c_device *device;
-
-	device = rt_malloc(sizeof(struct rt_i2c_device));
-	if (device == RT_NULL)
-	{
-		i2c_dbg("I2C malloc memory failed\n");
-		return -RT_ENOMEM;
-	}
-	rt_memset(device, 0, sizeof(struct rt_i2c_device));
-
-	device->flags = info->flags;
-	device->addr = info->addr;
-	device->bus = bus;
-	device->driver = driver;
-	
-	rt_list_insert_after(&bus->devices, &device->bus_list);
-	rt_list_insert_after(&driver->devices, &device->drv_list);
-	ret = driver->probe(device);
-
-	return ret;
-}
 
-static rt_err_t i2c_bus_match_hw(struct rt_i2c_driver *driver)
-{
-	rt_err_t ret = RT_EOK;
-	rt_list_t *list;
-	struct rt_i2c_hardware_info *info;
-	struct rt_i2c_bus *bus = RT_NULL;
-
-	for (list = (&i2c_hw_info_list)->next; list != &i2c_hw_info_list; list = list->next)
-	{
-		info = (struct rt_i2c_hardware_info *)rt_list_entry(list, 
-				struct rt_i2c_hardware_info, list);
-		if (rt_strncmp(info->name, driver->name, RT_I2C_NAME_SIZE) == 0)
-		{
-			bus = find_i2c_bus(info->bus_id);
-			if (bus)
-			{
-				if (rt_i2c_check_addr(bus, info->addr) != RT_EOK)
-				{
-					continue;
-				}
-				if (i2c_driver_probe(bus, driver, info) != RT_EOK)
-				{
-					ret = -RT_ERROR;
-				}
-			}
-		}
-	}
-
-	return ret;
-}
-
-rt_err_t rt_i2c_bus_attach_driver(struct rt_i2c_driver *driver)
-{
-	rt_err_t ret = RT_EOK;
-
-	rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER);
-	ret = i2c_bus_match_hw(driver);
-	rt_mutex_release(&i2c_core_lock);
-
-	if (ret != RT_EOK)
-	{
-		goto out;
-	}
-	
-	rt_kprintf("I2C driver [%s] registered\n", driver->name);
-	
-	return RT_EOK;
-
-out:
-	rt_kprintf("I2C driver [%s] register failed\n", driver->name);
-	return ret;
-}
-
-
-rt_err_t rt_i2c_bus_detach_driver(struct rt_i2c_driver *driver)
-{
-	rt_err_t ret = RT_EOK;
-	rt_list_t *list;
-	struct rt_i2c_device *device;
-
-	rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER);
-	for (list = (&driver->devices)->next; list != &driver->devices; list = list->next)
-	{
-		device = (struct rt_i2c_device *)rt_list_entry(list, struct rt_i2c_device, drv_list);
-		if (device)
-		{
-			ret = driver->remove(device);
-			if (ret != RT_EOK)
-			{
-				rt_mutex_release(&i2c_core_lock);
-				goto out;
-			}
-			rt_list_remove(&device->drv_list);
-			rt_list_remove(&device->bus_list);
-		}
-	}
-	
-	rt_mutex_release(&i2c_core_lock);
-	
-	rt_kprintf("I2C driver [%s] unregister\n", driver->name);
-	
-out:	
-	return ret;
-}
-
-
-rt_size_t rt_i2c_transfer(struct rt_i2c_bus *bus, 
-			  struct rt_i2c_msg *msgs, rt_uint32_t size)
+rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
 {
 	rt_size_t ret;
 
 	if (bus->ops->master_xfer)
 	{
-#ifdef RT_I2C_DEBUG
-		for (ret = 0; ret < size; ret++)
+	#ifdef RT_I2C_DEBUG
+		for (ret = 0; ret < num; ret++)
 		{
 			i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d%s\n", ret, 
 				(msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W', 
 				msgs[ret].addr, msgs[ret].len);
 		}
-#endif
+	#endif
 
 		rt_mutex_take(&bus->lock, RT_WAITING_FOREVER);
-
-		ret = bus->ops->master_xfer(bus, msgs, size);
+		ret = bus->ops->master_xfer(bus, msgs, num);
 		rt_mutex_release(&bus->lock);
 
 		return ret;
 	}
 	else
 	{
-		rt_kprintf("I2C bus transfers not supported\n");
+		rt_kprintf("I2C bus operation not supported\n");
 		return -RT_ERROR;
 	}
 }
 
 
-rt_size_t rt_i2c_master_send(struct rt_i2c_device *device, 
-			     const rt_uint8_t *buf, rt_uint32_t size)
+rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, rt_uint16_t addr, 
+                               rt_uint16_t flags, const rt_uint8_t *buf, 
+                               rt_uint32_t count)
 {
 	rt_size_t ret;
 	struct rt_i2c_msg msg;
-	struct rt_i2c_bus *bus = device->bus;
 
-	msg.addr = device->addr;
-	msg.flags = device->flags & RT_I2C_ADDR_10BIT;
-	msg.len = size;
+	msg.addr = addr;
+	msg.flags = flags & RT_I2C_ADDR_10BIT;
+	msg.len = count;
 	msg.buf = (rt_uint8_t *)buf;
 
 	ret = rt_i2c_transfer(bus, &msg, 1);
 
-	if (ret > 0)
-	{
-		return size;
-	}
-
-	return ret;
+	return (ret > 0) ? count : ret;
 }
 
 
 
-rt_size_t rt_i2c_master_recv(struct rt_i2c_device *device, 
-			     rt_uint8_t *buf, rt_uint32_t size)
+rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, rt_uint16_t addr, 
+                               rt_uint16_t flags, rt_uint8_t *buf, 
+                               rt_uint32_t count)
 {
 	rt_size_t ret;
 	struct rt_i2c_msg msg;
-	struct rt_i2c_bus *bus = device->bus;
 	RT_ASSERT(bus != RT_NULL);
 
-	msg.addr = device->addr;
-	msg.flags = device->flags & RT_I2C_ADDR_10BIT;
+	msg.addr = addr;
+	msg.flags = flags & RT_I2C_ADDR_10BIT;
 	msg.flags |= RT_I2C_RD;
-	msg.len = size;
+	msg.len = count;
 	msg.buf = buf;
 
 	ret = rt_i2c_transfer(bus, &msg, 1);
 
-	if (ret > 0)
-	{
-		return size;
-	}
-
-	return ret;
+	return (ret > 0) ? count : ret;
 }
 
 
-rt_err_t rt_i2c_core_init()
+rt_err_t rt_i2c_core_init(void)
 {
+
 	rt_mutex_init (&i2c_core_lock, "i2c_core_lock", RT_IPC_FLAG_FIFO);
-	rt_mutex_init (&i2c_hardware_lock, "i2c_hw_lock", RT_IPC_FLAG_FIFO);
+
 }
 

+ 26 - 58
components/drivers/i2c/i2c_dev.c

@@ -1,12 +1,8 @@
-#include <i2c.h>
-#include <i2c_dev.h>
+#include <rtdevice.h>
 
 static rt_err_t i2c_bus_device_init(rt_device_t dev)
 {
-	struct rt_i2c_bus* bus;
-	struct rt_i2c_device *i2c_device = dev->user_data;
-
-	bus = i2c_device->bus;
+	struct rt_i2c_bus_device* bus = (struct rt_i2c_bus_device *)dev->user_data;
 	RT_ASSERT(bus != RT_NULL);
 
 	return RT_EOK;
@@ -14,53 +10,54 @@ static rt_err_t i2c_bus_device_init(rt_device_t dev)
 
 static rt_size_t i2c_bus_device_read (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t count)
 {
-	struct rt_i2c_bus* bus;
-	struct rt_i2c_device *i2c_device = dev->user_data;
+	rt_uint16_t addr;
+	rt_uint16_t flags;
+	struct rt_i2c_bus_device* bus = (struct rt_i2c_bus_device *)dev->user_data;
 	
-	bus = i2c_device->bus;
 	RT_ASSERT(bus != RT_NULL);
-	RT_ASSERT(i2c_device != RT_NULL);
 	RT_ASSERT(buffer != RT_NULL);
 
-	i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", bus->name, count);
+	i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count);
+
+	addr = pos & 0xffff;
+	flags = (pos >> 16) & 0xffff;
 
-	return rt_i2c_master_recv(i2c_device, buffer, count);
+	return rt_i2c_master_recv(bus, addr, flags, buffer, count);
 }
 
 
-static rt_size_t i2c_bus_device_write (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+static rt_size_t i2c_bus_device_write (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t count)
 {
-	struct rt_i2c_bus* bus;
-	struct rt_i2c_device *i2c_device = dev->user_data;
-	
-	bus = i2c_device->bus;
+	rt_uint16_t addr;
+	rt_uint16_t flags;
+	struct rt_i2c_bus_device* bus = (struct rt_i2c_bus_device *)dev->user_data;
+
 	RT_ASSERT(bus != RT_NULL);
-	RT_ASSERT(i2c_device != RT_NULL);
 	RT_ASSERT(buffer != RT_NULL);
 
-	i2c_dbg("I2C bus dev writing %u bytes.\n", bus->name, size);
+	i2c_dbg("I2C bus dev writing %u bytes.\n", dev->parent.name, count);
+
+	addr = pos & 0xffff;
+	flags = (pos >> 16) & 0xffff;
 
-	return rt_i2c_master_send(i2c_device, buffer, size);
+	return rt_i2c_master_send(bus, addr, flags, buffer, count);
 }
 
 static rt_err_t i2c_bus_device_control(rt_device_t dev, rt_uint8_t cmd, void *args)
 {
 	rt_err_t ret;
-	struct rt_i2c_bus* bus;
 	struct rt_i2c_priv_data *priv_data;
-	struct rt_i2c_device *i2c_device = dev->user_data;
+	struct rt_i2c_bus_device* bus = (struct rt_i2c_bus_device *)dev->user_data;
 
-	bus = i2c_device->bus;
 	RT_ASSERT(bus != RT_NULL);
-	RT_ASSERT(i2c_device != RT_NULL);
 
 	switch (cmd)
 	{
 	case RT_I2C_DEV_CTRL_10BIT: /* set 10-bit addr mode */
-		i2c_device->flags |= RT_I2C_ADDR_10BIT;
+		bus->flags |= RT_I2C_ADDR_10BIT;
 		break;
 	case RT_I2C_DEV_CTRL_ADDR:
-		i2c_device->addr = *(rt_uint16_t *)args;
+		bus->addr = *(rt_uint16_t *)args;
 		break;
 	case RT_I2C_DEV_CTRL_TIMEOUT:
 		bus->timeout = *(rt_uint32_t *)args;
@@ -80,27 +77,14 @@ static rt_err_t i2c_bus_device_control(rt_device_t dev, rt_uint8_t cmd, void *ar
 }
 
 
-rt_err_t rt_i2c_bus_device_init(struct rt_i2c_bus* bus, const char* name)
+rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device* bus, const char* name)
 {
 	struct rt_device *device;
-	struct rt_i2c_device *i2c_device;
 	RT_ASSERT(bus != RT_NULL);
 
-	//device = &bus->parent;
-	
-	i2c_device = rt_malloc(sizeof(struct rt_i2c_device));
-	if (i2c_device == RT_NULL)
-	{
-		return -RT_ENOMEM;
-	}
-
-	rt_memset(i2c_device, 0, sizeof(struct rt_i2c_device));
-	
-	device = &i2c_device->dev;
-	i2c_device->bus = bus;
-	bus->parent = device;
+	device = &bus->parent;
 	
-	device->user_data = i2c_device;
+	device->user_data = bus;
 
 	/* set device type */
 	device->type    = RT_Device_Class_I2CBUS;
@@ -118,20 +102,4 @@ rt_err_t rt_i2c_bus_device_init(struct rt_i2c_bus* bus, const char* name)
 	return RT_EOK;
 }
 
-rt_err_t rt_i2c_bus_device_exit(struct rt_i2c_bus* bus)
-{
-	struct rt_device *device;
-	struct rt_i2c_device *i2c_device;
-	RT_ASSERT(bus != RT_NULL);
-
-	device = bus->parent;
-	
-	i2c_device = device->user_data;;
-	
-	/* register to device manager */
-	rt_device_unregister(device);
-	
-	rt_free(i2c_device);
 
-	return RT_EOK;
-}

+ 1 - 1
components/drivers/i2c/i2c-bit-ops.h → components/drivers/include/drivers/i2c-bit-ops.h

@@ -32,7 +32,7 @@ struct rt_i2c_bit_ops {
 	rt_uint32_t timeout;  /* in tick */
 };
 
-rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus *bus);
+rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus, const char *bus_name);
 
 #ifdef __cplusplus
 }

+ 79 - 0
components/drivers/include/drivers/i2c.h

@@ -0,0 +1,79 @@
+/*
+ * File      : i2c.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author		Notes
+ * 2012-04-25     weety		first version
+ */
+
+#ifndef __I2C_H__
+#define __I2C_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RT_I2C_WR                0x0000
+#define RT_I2C_RD               (1u << 0)
+#define RT_I2C_ADDR_10BIT       (1u << 2)  /* this is a ten bit chip address */
+#define RT_I2C_NO_START         (1u << 4)
+#define RT_I2C_IGNORE_NACK      (1u << 5)
+#define RT_I2C_NO_READ_ACK      (1u << 6)  /* when I2C reading, we do not ACK */
+
+struct rt_i2c_msg {
+	rt_uint16_t addr;
+	rt_uint16_t flags;
+	rt_uint16_t len;
+	rt_uint8_t  *buf;
+};
+
+struct rt_i2c_bus_device;
+
+struct rt_i2c_bus_device_ops {
+	rt_size_t (*master_xfer) (struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
+	rt_size_t (*slave_xfer) (struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
+	rt_err_t (*i2c_bus_control) (struct rt_i2c_bus_device *bus, rt_uint32_t, rt_uint32_t);
+};
+
+/*for i2c bus driver*/
+struct rt_i2c_bus_device {
+	struct rt_device parent;
+	const struct rt_i2c_bus_device_ops *ops;
+	rt_uint16_t  flags;
+	rt_uint16_t  addr;
+	struct rt_mutex lock;
+	rt_uint32_t  timeout;
+	rt_uint32_t  retries;
+	void *priv;
+};
+
+#ifdef RT_I2C_DEBUG
+#define i2c_dbg(fmt, ...)	rt_kprintf(fmt, ##__VA_ARGS__)
+#else
+#define i2c_dbg(fmt, ...)
+#endif
+
+rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, const char *bus_name);
+struct rt_i2c_bus_device* rt_i2c_bus_device_find(const char *bus_name);
+rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
+rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, rt_uint16_t addr, 
+                               rt_uint16_t flags, const rt_uint8_t *buf, 
+                               rt_uint32_t count);
+rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, rt_uint16_t addr, 
+                               rt_uint16_t flags, rt_uint8_t *buf, 
+                               rt_uint32_t count);
+rt_err_t rt_i2c_core_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 1 - 2
components/drivers/i2c/i2c_dev.h → components/drivers/include/drivers/i2c_dev.h

@@ -17,8 +17,7 @@ struct rt_i2c_priv_data {
 	rt_size_t  number;
 };
 
-rt_err_t rt_i2c_bus_device_init(struct rt_i2c_bus* bus, const char* name);
-rt_err_t rt_i2c_bus_device_exit(struct rt_i2c_bus* bus);
+rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device* bus, const char* name);
 
 
 #ifdef __cplusplus

+ 9 - 0
components/drivers/include/rtdevice.h

@@ -67,4 +67,13 @@ rt_size_t rt_ringbuffer_emptry_size(struct rt_ringbuffer* rb);
 #include "drivers/serial.h"
 #endif
 
+#ifdef RT_USING_I2C
+#include "drivers/i2c.h"
+#include "drivers/i2c_dev.h"
+#endif
+
+#ifdef RT_USING_I2C_BITOPS
+#include "drivers/i2c-bit-ops.h"
+#endif
+
 #endif