1 #include "pca9544_i2c_drv.h"
2 #include <aos/errno.h>
3 #include <stddef.h>
4 #include <stdint.h>
5 #include <vfsdev/i2c_dev.h>
6
7 #define I2C_PORT_MAX 4
8
9 static int g_i2c_fd[I2C_PORT_MAX] = { -1, -1, -1, -1 };
10
11 /**********************************************************
12 * @fun pca9544_i2c_init
13 * @breif pca9544 i2c initialization
14 * @param i2c:the pointer for i2c configuration
15 * @rtn 0 : on success, EIO : error
16 *********************************************************/
pca9544_i2c_init(i2c_dev_t * i2c)17 int32_t pca9544_i2c_init(i2c_dev_t *i2c)
18 {
19 int32_t ret = 0;
20 int32_t *p_fd = NULL;
21 char name[16] = { 0 };
22 io_i2c_control_u i2c_ctrl;
23
24 if (!i2c) {
25 printf("i2c is null\r\n");
26 return -EINVAL;
27 }
28
29 if (i2c->port >= I2C_PORT_MAX) {
30 return -EINVAL;
31 }
32
33 p_fd = &g_i2c_fd[i2c->port];
34 if (*p_fd >= 0) {
35 printf("i2c port[%d] isn't ready\r\n", i2c->port);
36 return -EALREADY;
37 }
38
39 memset(&i2c_ctrl, 0, sizeof(io_i2c_control_u));
40
41 snprintf(name, sizeof(name), "/dev/i2c%d", i2c->port);
42
43 *p_fd = open(name, 0);
44 if (*p_fd < 0) {
45 printf("open %s failed, fd:%d\r\n", name, *p_fd);
46 return -EIO;
47 }
48
49 i2c_ctrl.c.addr = i2c->config.dev_addr; /* sensor's address */
50 i2c_ctrl.c.addr_width = i2c->config.address_width; /* 7-bit address */
51 i2c_ctrl.c.role = 1; /* master mode */
52 ret = ioctl(*p_fd, IOC_I2C_SET_CONFIG, (unsigned long)&i2c_ctrl);
53 if (ret) {
54 printf("set i2c config on %s failed\r\n", name);
55 return -EINVAL;
56 }
57
58 i2c_ctrl.freq = i2c->config.freq;
59 ret = ioctl(*p_fd, IOC_I2C_SET_FREQ, (unsigned long)&i2c_ctrl);
60 if (ret) {
61 printf("IOC_I2C_SET_CONFIG or IOC_I2C_SET_FREQ on %s failed, ret:%d\r\n", name, ret);
62 close(*p_fd);
63 *p_fd = -1;
64 }
65
66 return ret;
67 }
68
69 /********************************************************
70 * @fun pca9544_i2c_master_send
71 *
72 * @param[in] i2c the i2c device
73 * @param[in] dev_addr device address
74 * @param[in] data i2c master send data
75 * @param[in] size i2c master send data size
76 * @param[in] timeout timeout in milisecond, set this value to
77 *HAL_WAIT_FOREVER if you want to wait forever
78 *
79 * @rtn 0 : on success, EIO : error
80 *********************************************************/
pca9544_i2c_master_send(i2c_dev_t * i2c,uint16_t dev_addr,const uint8_t * data,uint16_t size,uint32_t timeout)81 int32_t pca9544_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t* data, uint16_t size, uint32_t timeout)
82 {
83 int32_t *p_fd = NULL;
84 int32_t ret = -1;
85 io_i2c_data_t i2c_data;
86
87 if (!i2c) {
88 return -EINVAL;
89 }
90
91 if (i2c->port >= I2C_PORT_MAX) {
92 return -EINVAL;
93 }
94
95 p_fd = &g_i2c_fd[i2c->port];
96 if (!p_fd || (*p_fd < 0)) {
97 printf("i2c port[%d] has not been initialized\r\n", i2c->port);
98 return -EINVAL;
99 }
100
101 i2c_data.addr = dev_addr;
102 i2c_data.data = data;
103 i2c_data.length = size;
104 i2c_data.maddr = 0;
105 i2c_data.mlength = 0;
106 i2c_data.timeout = timeout;
107
108 ret = ioctl(*p_fd, IOC_I2C_MASTER_TX, (unsigned long)&i2c_data);
109
110 return ret;
111 }
112
113 /********************************************************
114 * @fun pca9544_i2c_master_recv
115 *
116 * @param[in] i2c the i2c device
117 * @param[in] dev_addr device address
118 * @param[in] data i2c master recv data
119 * @param[in] size i2c master recv data size
120 * @param[in] timeout timeout in milisecond, set this value to
121 *HAL_WAIT_FOREVER if you want to wait forever
122 *
123 * @rtn 0 : on success, EIO : error
124 *********************************************************/
pca9544_i2c_master_recv(i2c_dev_t * i2c,uint16_t dev_addr,uint8_t * data,uint16_t size,uint32_t timeout)125 int32_t pca9544_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, uint16_t size, uint32_t timeout)
126 {
127 int32_t *p_fd = NULL;
128 int32_t ret = -1;
129 io_i2c_data_t i2c_data;
130
131 if (!i2c) {
132 printf("i2c is null\r\n");
133 return -EINVAL;
134 }
135
136 if (i2c->port >= I2C_PORT_MAX) {
137 return -EINVAL;
138 }
139
140 p_fd = &g_i2c_fd[i2c->port];
141 if (!p_fd || (*p_fd < 0)) {
142 printf("i2c port[%d] has not been initialized\r\n", i2c->port);
143 return -EINVAL;
144 }
145
146 i2c_data.addr = dev_addr;
147 i2c_data.data = data;
148 i2c_data.length = size;
149 i2c_data.maddr = 0;
150 i2c_data.mlength = 0;
151 i2c_data.timeout = timeout;
152
153 ret = ioctl(*p_fd, IOC_I2C_MASTER_RX, (unsigned long)&i2c_data);
154
155 return 0;
156 }
157
158 /*********************************************************
159 * @fun pca9544_i2c_mem_write
160 * @param[in] i2c the i2c device
161 * @param[in] dev_addr device address
162 * @param[in] mem_addr register address
163 * @param[in] mem_addr_size register address size
164 * @param[in] data i2c master send data
165 * @param[in] size i2c master send data size
166 * @param[in] timeout timeout in milisecond, set this value to
167 *HAL_WAIT_FOREVER if you want to wait forever
168 *
169 * @rtn 0 : on success, EIO : error
170 *********************************************************/
pca9544_i2c_mem_write(i2c_dev_t * i2c,uint16_t dev_addr,uint16_t mem_addr,uint16_t mem_addr_size,const uint8_t * data,uint16_t size,uint32_t timeout)171 int32_t pca9544_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, const uint8_t* data, uint16_t size, uint32_t timeout)
172 {
173 int32_t *p_fd = NULL;
174 int32_t ret = -1;
175 io_i2c_data_t i2c_data;
176
177 if (!i2c) {
178 return -EINVAL;
179 }
180
181 if (i2c->port >= I2C_PORT_MAX) {
182 return -EINVAL;
183 }
184
185 p_fd = &g_i2c_fd[i2c->port];
186 if (!p_fd || (*p_fd < 0)) {
187 printf("i2c port[%d] has not been initialized\r\n", i2c->port);
188 return -EINVAL;
189 }
190
191 i2c_data.addr = dev_addr;
192 i2c_data.data = data;
193 i2c_data.length = size;
194 i2c_data.maddr = mem_addr;
195 i2c_data.mlength = mem_addr_size;
196 i2c_data.timeout = timeout;
197
198 ret = ioctl(*p_fd, IOC_I2C_MEM_TX, (unsigned long)&i2c_data);
199 return ret;
200 }
201
202 /*********************************************************
203 * @fun pca9544_i2c_mem_read
204 * @param[in] i2c the i2c device
205 * @param[in] dev_addr device address
206 * @param[in] mem_addr register address
207 * @param[in] mem_addr_size register address size
208 * @param[in] data i2c master send data
209 * @param[in] size i2c master send data size
210 * @param[in] timeout timeout in milisecond, set this value to
211 *HAL_WAIT_FOREVER if you want to wait forever
212 *
213 * @rtn 0 : on success, EIO : error
214 *********************************************************/
pca9544_i2c_mem_read(i2c_dev_t * i2c,uint16_t dev_addr,uint16_t mem_addr,uint16_t mem_addr_size,uint8_t * data,uint16_t size,uint32_t timeout)215 int32_t pca9544_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, uint8_t *data, uint16_t size, uint32_t timeout)
216 {
217 int32_t *p_fd = NULL;
218 int32_t ret = -1;
219 io_i2c_data_t i2c_data;
220
221 if (!i2c) {
222 return -EINVAL;
223 }
224
225 if (i2c->port >= I2C_PORT_MAX) {
226 return -EINVAL;
227 }
228
229 p_fd = &g_i2c_fd[i2c->port];
230 if (!p_fd || (*p_fd < 0)) {
231 printf("i2c port[%d] has not been initialized\r\n", i2c->port);
232 return -EINVAL;
233 }
234
235 memset(&i2c_data, 0, sizeof(io_i2c_data_t));
236
237 i2c_data.addr = dev_addr;
238 i2c_data.data = data;
239 i2c_data.length = size;
240 i2c_data.maddr = mem_addr;
241 i2c_data.mlength = mem_addr_size;
242 i2c_data.timeout = timeout;
243
244 ret = ioctl(*p_fd, IOC_I2C_MEM_RX, (unsigned long)&i2c_data);
245 return ret;
246 }
247
248 /********************************************************
249 * @fun pca9544_i2c_finalize
250 * @param[in] i2c the i2c device
251 * @rtn 0 : on success, EIO : error
252 *********************************************************/
pca9544_i2c_finalize(i2c_dev_t * i2c)253 int32_t pca9544_i2c_finalize(i2c_dev_t *i2c)
254 {
255 int32_t ret = 0;
256 int32_t *p_fd = NULL;
257
258 if (!i2c || !i2c->priv) {
259 return -EINVAL;
260 }
261
262 if (i2c->port >= I2C_PORT_MAX) {
263 return -EINVAL;
264 }
265
266 p_fd = &g_i2c_fd[i2c->port];
267 if (!p_fd || (*p_fd < 0)) {
268 printf("i2c port[%d] has not been initialized\r\n", i2c->port);
269 return -EINVAL;
270 }
271
272 close(*p_fd);
273
274 *p_fd = -1;
275
276 return 0;
277 }
278