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
i2c_bus_device_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t count)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
i2c_bus_device_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t count)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
i2c_bus_device_control(rt_device_t dev,int cmd,void * args)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
rt_i2c_bus_device_device_init(struct rt_i2c_bus_device * bus,const char * name)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