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