1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2012-04-25 weety first version 9 * 2014-08-03 bernard fix some compiling warning 10 */ 11 12 #include <rtdevice.h> 13 14 static rt_size_t i2c_bus_device_read(rt_device_t dev, 15 rt_off_t pos, 16 void *buffer, 17 rt_size_t count) 18 { 19 rt_uint16_t addr; 20 rt_uint16_t flags; 21 struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; 22 23 RT_ASSERT(bus != RT_NULL); 24 RT_ASSERT(buffer != RT_NULL); 25 26 i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count); 27 28 addr = pos & 0xffff; 29 flags = (pos >> 16) & 0xffff; 30 31 return rt_i2c_master_recv(bus, addr, flags, buffer, count); 32 } 33 34 static rt_size_t i2c_bus_device_write(rt_device_t dev, 35 rt_off_t pos, 36 const void *buffer, 37 rt_size_t count) 38 { 39 rt_uint16_t addr; 40 rt_uint16_t flags; 41 struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; 42 43 RT_ASSERT(bus != RT_NULL); 44 RT_ASSERT(buffer != RT_NULL); 45 46 i2c_dbg("I2C bus dev [%s] writing %u bytes.\n", dev->parent.name, count); 47 48 addr = pos & 0xffff; 49 flags = (pos >> 16) & 0xffff; 50 51 return rt_i2c_master_send(bus, addr, flags, buffer, count); 52 } 53 54 static rt_err_t i2c_bus_device_control(rt_device_t dev, 55 int cmd, 56 void *args) 57 { 58 rt_err_t ret; 59 struct rt_i2c_priv_data *priv_data; 60 struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; 61 62 RT_ASSERT(bus != RT_NULL); 63 64 switch (cmd) 65 { 66 /* set 10-bit addr mode */ 67 case RT_I2C_DEV_CTRL_10BIT: 68 bus->flags |= RT_I2C_ADDR_10BIT; 69 break; 70 case RT_I2C_DEV_CTRL_ADDR: 71 bus->addr = *(rt_uint16_t *)args; 72 break; 73 case RT_I2C_DEV_CTRL_TIMEOUT: 74 bus->timeout = *(rt_uint32_t *)args; 75 break; 76 case RT_I2C_DEV_CTRL_RW: 77 priv_data = (struct rt_i2c_priv_data *)args; 78 ret = rt_i2c_transfer(bus, priv_data->msgs, priv_data->number); 79 if (ret < 0) 80 { 81 return -RT_EIO; 82 } 83 break; 84 default: 85 break; 86 } 87 88 return RT_EOK; 89 } 90 91 #ifdef RT_USING_DEVICE_OPS 92 const static struct rt_device_ops i2c_ops = 93 { 94 RT_NULL, 95 RT_NULL, 96 RT_NULL, 97 i2c_bus_device_read, 98 i2c_bus_device_write, 99 i2c_bus_device_control 100 }; 101 #endif 102 103 rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus, 104 const char *name) 105 { 106 struct rt_device *device; 107 RT_ASSERT(bus != RT_NULL); 108 109 device = &bus->parent; 110 111 device->user_data = bus; 112 113 /* set device type */ 114 device->type = RT_Device_Class_I2CBUS; 115 /* initialize device interface */ 116 #ifdef RT_USING_DEVICE_OPS 117 device->ops = &i2c_ops; 118 #else 119 device->init = RT_NULL; 120 device->open = RT_NULL; 121 device->close = RT_NULL; 122 device->read = i2c_bus_device_read; 123 device->write = i2c_bus_device_write; 124 device->control = i2c_bus_device_control; 125 #endif 126 127 /* register to device manager */ 128 rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); 129 130 return RT_EOK; 131 } 132