• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "i2c.h"
17 #include <hi_sem.h>
18 #include <hi_i2c.h>
19 #include <hi_time.h>
20 #include <hi3861_platform_base.h>
21 
22 #define I2C0_BASE HI_I2C0_REG_BASE
23 #define I2C1_BASE HI_I2C1_REG_BASE
24 #define CLKEN_I2C0 14
25 #define CLKEN_I2C1 15
26 
27 hi_u32 g_i2c_drv_sem[2] = {0xffffffff, 0xffffffff}; // for 2 i2c
28 
29 hi_u32 g_i2c_rcv_time_out_us = 4096;
30 
31 typedef struct {
32     hi_u32 baudrate;
33     i2c_reset_func reset_bus_func;
34     i2c_prepare_func prepare_func;
35     i2c_restore_func restore_func;
36     hi_u16 timeout_us;
37     hi_u8 scl_h : 3;
38     hi_u8 scl_l : 3;
39     hi_bool init : 1;
40     hi_bool pad : 1;
41     hi_u8 err_times;
42 } hi_i2c_ctrl;
43 
44 /* timeout_us unused */
45 hi_i2c_ctrl g_i2c_ctrl[I2C_NUM] = {
46     { 0, HI_NULL, HI_NULL, HI_NULL, 3000, 1, 1, HI_FALSE, 0, 0 },
47     { 0, HI_NULL, HI_NULL, HI_NULL, 3000, 1, 1, HI_FALSE, 0, 0 }
48 };
49 
50 hi_void i2c_read(hi_i2c_idx id);
51 hi_void i2c_write(hi_i2c_idx id);
52 
i2c_reset(hi_i2c_idx id)53 hi_u32 i2c_reset(hi_i2c_idx id)
54 {
55     hi_u32 value;
56     hi_u32 ret;
57 
58     hi_reg_read32(CRG_REG_SC_PERI_SRST_REG, value);
59     value |= (1 << CRG_REG_I2C_SRST_REQ_OFFSET);
60     hi_reg_write32(CRG_REG_SC_PERI_SRST_REG, value);
61     value &= ~(1 << CRG_REG_I2C_SRST_REQ_OFFSET);
62     hi_reg_write32(CRG_REG_SC_PERI_SRST_REG, value);
63 
64     ret = hi_i2c_deinit(id);
65     if (ret != HI_ERR_SUCCESS) {
66         return ret;
67     }
68 
69     if (!g_i2c_ctrl[id].baudrate) {
70         hi_i2c_init(id, g_i2c_ctrl[id].baudrate);
71     } else {
72         hi_i2c_init(id, I2C_RATE_DEFAULT);
73     }
74     return HI_ERR_SUCCESS;
75 }
76 
i2c_base(hi_i2c_idx id)77 static hi_u32 i2c_base(hi_i2c_idx id)
78 {
79     if (id == HI_I2C_IDX_0) {
80         return I2C0_BASE;
81     }
82     return I2C1_BASE;
83 }
84 
i2c_wait(hi_i2c_idx id)85 static hi_u32 i2c_wait(hi_i2c_idx id)
86 {
87     hi_u32 reg_val = 0;
88     hi_u32 time_out = 0;
89 
90     hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
91     while ((!(reg_val & I2C_INT_DONE)) && (time_out < g_i2c_ctrl[id].timeout_us)) {
92         time_out++;
93         hi_udelay(1);
94         hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
95     }
96 
97     if (time_out >= g_i2c_ctrl[id].timeout_us) {
98         i2c_error("wait-timeout >= TIMEOUT error ! \n");
99         return HI_ERR_I2C_TIMEOUT_WAIT;
100     }
101 
102     /* ack error occur */
103     if (I2C_ACK_INTR & reg_val) {
104         return HI_ERR_I2C_WAIT_ACK_ERR;
105     }
106 
107     hi_reg_read32((i2c_base(id) + I2C_ICR), reg_val);
108     hi_reg_write32((i2c_base(id) + I2C_ICR), (reg_val | I2C_CLEAR_OVER));
109 
110     return HI_ERR_SUCCESS;
111 }
112 
i2c_cfg_clk(hi_i2c_idx id,hi_u32 i2c_rate)113 static hi_void i2c_cfg_clk(hi_i2c_idx id, hi_u32 i2c_rate)
114 {
115     hi_u32 reg_val = 0;
116     hi_u32 reg_clk_val;
117 
118     /* save i2c system control */
119     hi_reg_read32((i2c_base(id) + I2C_CTRL), reg_val);
120 
121     /* mask all i2c interrupt */
122     hi_reg_write32((i2c_base(id) + I2C_CTRL), (reg_val & (~I2C_UNMASK_ALL)));
123     reg_clk_val = (I2C_CLK / (i2c_rate * 2)) *  /* 2 */
124         g_i2c_ctrl[id].scl_h / (g_i2c_ctrl[id].scl_l + g_i2c_ctrl[id].scl_h) - 1;
125     hi_reg_write32((i2c_base(id) + I2C_SCL_H), reg_clk_val);
126     reg_clk_val = (I2C_CLK / (i2c_rate * 2)) *  /* 2 */
127         g_i2c_ctrl[id].scl_l / (g_i2c_ctrl[id].scl_l + g_i2c_ctrl[id].scl_h) - 1;
128     hi_reg_write32((i2c_base(id) + I2C_SCL_L), reg_clk_val);
129 
130     /* resume i2c interrupt */
131     hi_reg_write32((i2c_base(id) + I2C_CTRL), reg_val);
132 }
133 
i2c_start(hi_i2c_idx id)134 static hi_u32 i2c_start(hi_i2c_idx id)
135 {
136     hi_u32 reg_val = 0;
137     hi_u32 time_out = 0;
138 
139     /* clear interrupt */
140     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
141 
142     /* start operation */
143     hi_reg_write32((i2c_base(id) + I2C_COM), (I2C_START | I2C_WRITE));
144 
145     hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
146 
147     while (((reg_val & I2C_INT_DONE) != I2C_INT_DONE) && (time_out < g_i2c_ctrl[id].timeout_us)) {
148         time_out++;
149         hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
150         hi_udelay(1);
151     }
152 
153     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_START_END);
154 
155     /* timeout handle */
156     if (time_out >= g_i2c_ctrl[id].timeout_us) {
157         i2c_error("timeout >= TIMEOUT error ! \n");
158         return HI_ERR_I2C_TIMEOUT_START;
159     }
160 
161     if (I2C_ACK_INTR & reg_val) { /* ack error occur */
162         return HI_ERR_I2C_START_ACK_ERR;
163     }
164 
165     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_OVER);
166 
167     return HI_ERR_SUCCESS;
168 }
169 
i2c_stop(hi_i2c_idx id)170 static hi_u32 i2c_stop(hi_i2c_idx id)
171 {
172     hi_u32 reg_val = 0;
173     hi_u32 time_out = 0;
174 
175     /* start stop operation */
176     hi_reg_write32((i2c_base(id) + I2C_COM), I2C_STOP);
177     hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
178 
179     while (((reg_val & I2C_INT_DONE) != I2C_INT_DONE) && (time_out < g_i2c_ctrl[id].timeout_us)) {
180         hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
181         hi_udelay(1);
182         time_out++;
183     }
184 
185     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
186 
187     if (time_out >= g_i2c_ctrl[id].timeout_us) {
188         i2c_error("timeout >= TIMEOUT in i2c_stop error ! \n");
189         return HI_ERR_I2C_TIMEOUT_STOP;
190     }
191 
192     return HI_ERR_SUCCESS;
193 }
194 
i2c_read(hi_i2c_idx id)195 hi_void i2c_read(hi_i2c_idx id)
196 {
197     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
198     hi_reg_write32((i2c_base(id) + I2C_COM), I2C_READ);
199 }
200 
i2c_write(hi_i2c_idx id)201 hi_void i2c_write(hi_i2c_idx id)
202 {
203     /* clear interrupt */
204     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
205 
206     /* write operation */
207     hi_reg_write32((i2c_base(id) + I2C_COM), I2C_WRITE);
208 }
209 
210 /*
211  * sends a character over I2C bus routine.
212  *
213  * @param sendvalue: character to send
214  * @return value:0--success; -1--error.
215  *
216  */
i2c_send_byte(hi_i2c_idx id,hi_u8 send_val)217 static hi_u32 i2c_send_byte(hi_i2c_idx id, hi_u8 send_val)
218 {
219     hi_reg_write32((i2c_base(id) + I2C_TXR), send_val);
220     i2c_write(id);
221 
222     return i2c_wait(id);
223 }
224 
225 /*
226  * receives a character from I2C bus routine.
227  *
228  * @return value:character received
229  *
230  */
i2c_receive_byte(hi_i2c_idx id,hi_u8 * p_data)231 static hi_u32 i2c_receive_byte(hi_i2c_idx id, hi_u8 *p_data)
232 {
233     hi_u32 ret;
234     hi_u32 reg_val = 0;
235     hi_u32 time_out = 0;
236 
237     if (p_data == HI_NULL) {
238         i2c_error("null point.\n");
239         return HI_ERR_I2C_INVALID_PARAMETER;
240     }
241 
242     i2c_read(id);
243 
244     hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
245     while ((!(reg_val & I2C_INT_DONE)) && (time_out < g_i2c_ctrl[id].timeout_us)) {
246         time_out++;
247         hi_udelay(1);
248         hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
249     }
250 
251     if (time_out >= g_i2c_ctrl[id].timeout_us) {
252         i2c_error("receive data error\n");
253         return HI_ERR_I2C_TIMEOUT_RCV_BYTE;
254     }
255 
256     hi_reg_read32((i2c_base(id) + I2C_RXR), reg_val);
257     *p_data = (hi_u8)(reg_val);
258     ret = i2c_wait(id);
259     if (ret != HI_ERR_SUCCESS) {
260         i2c_error("read wait timeout.\n");
261     }
262 
263     hi_reg_write32((i2c_base(id) + I2C_ICR), (I2C_RECEIVE_INTR | I2C_INT_DONE));
264 
265     return ret;
266 }
267 
268 /*
269  * writes address of device to I2C bus routine.
270  *
271  * @param address: address of device
272  *
273  */
i2c_set_addr(hi_i2c_idx id,hi_u16 addr)274 static hi_void i2c_set_addr(hi_i2c_idx id, hi_u16 addr)
275 {
276     hi_reg_write32((i2c_base(id) + I2C_TXR), addr);
277 }
278 
i2c_is_10bit_addr(hi_u16 uc_addr)279 static hi_bool i2c_is_10bit_addr(hi_u16 uc_addr)
280 {
281     if ((uc_addr & 0xF000) == 0xF000) {
282         return HI_TRUE;
283     }
284     return HI_FALSE;
285 }
286 
i2c_10bit_send_addressing(hi_i2c_idx id,hi_u16 device_addr)287 static hi_u32 i2c_10bit_send_addressing(hi_i2c_idx id, hi_u16 device_addr)
288 {
289     hi_u32 ret;
290     /* 10bit: */
291     /* Send 5 bits signaling 10 bit addressing(1111 0)
292       followed by the first two bits of the I2C address
293       and then the standard read/write bit. */
294     hi_u8 addr = device_addr >> 8;  /* 8 */
295 
296     i2c_set_addr(id, addr & WRITE_OPERATION);  /* R/W -> W(0) */
297     ret = i2c_start(id);
298     if (ret != HI_ERR_SUCCESS) {
299         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
300         /* for testing */
301         i2c_error("10bit SEND first addressing failed!");
302         return ret;
303     }
304 
305     addr = (hi_u8)device_addr;
306     i2c_set_addr(id, addr);  /* second addressing */
307     ret = i2c_start(id);
308     if (ret != HI_ERR_SUCCESS) {
309         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
310         /* for testing */
311         i2c_error("10bit SEND second addressing failed!");
312         return ret;
313     }
314     return HI_ERR_SUCCESS;
315 }
316 
i2c_10bit_receive_addressing(hi_i2c_idx id,hi_u16 device_addr)317 static hi_u32 i2c_10bit_receive_addressing(hi_i2c_idx id, hi_u16 device_addr)
318 {
319     hi_u32 ret;
320     /* 10bit: */
321     /* send the complete 10-bit address (two bytes) as for writing at first */
322     /* first addressing R/W->W(0) */
323     hi_u8 addr = device_addr >> 8;  /* 8 */
324 
325     i2c_set_addr(id, addr & WRITE_OPERATION);   /* R/W -> W(0) */
326     ret = i2c_start(id);
327     if (ret != HI_ERR_SUCCESS) {
328         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
329         /* for testing */
330         i2c_error("10bit RECEIVE first addressing failed");
331         return ret;
332     }
333 
334     /* second addressing */
335     addr = (hi_u8)device_addr;
336 
337     i2c_set_addr(id, addr);
338     ret = i2c_start(id);
339     if (ret != HI_ERR_SUCCESS) {
340         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
341         /* for testing */
342         i2c_error("10bit RECEIVE second addressing failed");
343         return ret;
344     }
345 
346     /* a repeated start is sent followed by the first address byte
347        with read/write bit set to high to signal reading */
348     /* third addressing R/W->R(1) */
349     addr = device_addr >> 8;    /* 8 */
350 
351     i2c_set_addr(id, addr | READ_OPERATION);
352     ret = i2c_start(id);
353     if (ret != HI_ERR_SUCCESS) {
354         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
355         /* for testing */
356         i2c_error("10bit RECEIVE after SR addressing failed");
357         return ret;
358     }
359     return HI_ERR_SUCCESS;
360 }
361 
i2c_receive_last_byte(hi_i2c_idx id,hi_u8 * p_data)362 static hi_u32 i2c_receive_last_byte(hi_i2c_idx id, hi_u8 *p_data)
363 {
364     hi_u32 reg_val = 0;
365     hi_u32 ret;
366     hi_u32 time_out = 0;
367 
368     hi_reg_write32((i2c_base(id) + I2C_COM), (I2C_READ | (~I2C_SEND_ACK)));
369     hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
370     while ((!(reg_val & I2C_INT_DONE)) && (time_out < g_i2c_rcv_time_out_us)) {
371         time_out++;
372         hi_udelay(1);
373         hi_reg_read32((i2c_base(id) + I2C_SR), reg_val);
374     }
375 
376     if (time_out >= g_i2c_rcv_time_out_us) {
377         i2c_error("receive data error\n");
378         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
379         return HI_ERR_I2C_TIMEOUT_RCV_BYTE_PROC;
380     }
381 
382     hi_reg_read32((i2c_base(id) + I2C_RXR), reg_val);
383     if (p_data != HI_NULL) {
384         *p_data = (hi_u8)reg_val;
385     }
386     ret = i2c_wait(id);
387     if (ret != HI_ERR_SUCCESS) {
388         i2c_error("Receive data with no ack error!..\n");
389         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
390         return ret;
391     }
392 
393     return HI_ERR_SUCCESS;
394 }
395 
i2c_receive_byte_proc(hi_i2c_idx id,const hi_i2c_data * i2c_data)396 static hi_u32 i2c_receive_byte_proc(hi_i2c_idx id, const hi_i2c_data *i2c_data)
397 {
398     hi_u32 ret;
399     hi_u32 i;
400 
401     for (i = 0; i < (i2c_data->receive_len); i++) {
402         if (i == (i2c_data->receive_len - 1)) {
403             ret = i2c_receive_last_byte(id, i2c_data->receive_buf + i);
404             if (ret != HI_ERR_SUCCESS) {
405                 return ret;
406             }
407         } else {
408             ret = i2c_receive_byte(id, i2c_data->receive_buf + i);
409             if (ret != HI_ERR_SUCCESS) {
410                 i2c_error("i2c_receive_byte error ! \n");
411                 hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
412                 return ret;
413             }
414         }
415     }
416 
417     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_OVER);
418 
419     ret = i2c_stop(id);
420     if (ret != HI_ERR_SUCCESS) {
421         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
422         return ret;
423     }
424 
425     return HI_ERR_SUCCESS;
426 }
427 
i2c_restart_receive_data(hi_i2c_idx id,hi_u8 device_addr,const hi_i2c_data * i2c_data)428 static hi_u32 i2c_restart_receive_data(hi_i2c_idx id, hi_u8 device_addr, const hi_i2c_data *i2c_data)
429 {
430     hi_u32 i;
431     hi_u32 ret;
432 
433     hi_reg_write32((i2c_base(id) + I2C_CTRL),
434                    (I2C_IP_ENABLE | I2C_UNMASK_ALL | I2C_UNMASK_ACK | I2C_UNMASK_ARBITRATE | I2C_UNMASK_OVER));
435 
436     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
437 
438     /* write device addr */
439     if (i2c_is_10bit_addr(device_addr) == HI_TRUE) {
440         ret = i2c_10bit_send_addressing(id, device_addr);
441         if (ret != HI_ERR_SUCCESS) {
442             return ret;
443         }
444     } else {
445         /* 7bit addressing */
446         i2c_set_addr(id, device_addr & WRITE_OPERATION);
447         ret = i2c_start(id);
448         if (ret != HI_ERR_SUCCESS) {
449             i2c_error("start error when write address.\n");
450             hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
451             return ret;
452         }
453     }
454 
455     /* write register addr */
456     for (i = 0; i < (i2c_data->send_len); i++) {
457         ret = i2c_send_byte(id, *(i2c_data->send_buf + i));
458         if (ret != HI_ERR_SUCCESS) {
459             i2c_error("no ack.\n");
460             hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
461             return ret;
462         }
463     }
464 
465     /* read device addr */
466     if (i2c_is_10bit_addr(device_addr) == HI_TRUE) {
467         ret = i2c_10bit_receive_addressing(id, device_addr);
468         if (ret != HI_ERR_SUCCESS) {
469             return ret;
470         }
471     } else {
472         /* 7bit addressing */
473         i2c_set_addr(id, device_addr | READ_OPERATION);
474         ret = i2c_start(id);
475         if (ret != HI_ERR_SUCCESS) {
476             i2c_error("start error when write address.\n");
477             hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
478             return ret;
479         }
480     }
481 
482     /* read data */
483     ret = i2c_receive_byte_proc(id, i2c_data);
484     if (ret != HI_ERR_SUCCESS) {
485         return ret;
486     }
487 
488     return HI_ERR_SUCCESS;
489 }
490 
i2c_send_data(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)491 static hi_u32 i2c_send_data(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
492 {
493     hi_u32 i;
494     hi_u32 ret;
495 
496     hi_reg_write32((i2c_base(id) + I2C_CTRL),
497                    (I2C_IP_ENABLE | I2C_UNMASK_ALL | I2C_UNMASK_ACK | I2C_UNMASK_ARBITRATE | I2C_UNMASK_OVER));
498 
499     /* clear all i2c interrupt */
500     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
501 
502     i2c_set_addr(id, device_addr & WRITE_OPERATION);
503 
504     if (i2c_is_10bit_addr(device_addr) == HI_TRUE) {
505         ret = i2c_10bit_send_addressing(id, device_addr);
506         if (ret != HI_ERR_SUCCESS) {
507             return ret;
508         }
509     } else {
510         /* 7bit addressing */
511         i2c_set_addr(id, device_addr & WRITE_OPERATION);
512         ret = i2c_start(id);
513         if (ret != HI_ERR_SUCCESS) {
514             hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
515             return ret;
516         }
517     }
518 
519     for (i = 0; i < (i2c_data->send_len); i++) {
520         ret = i2c_send_byte(id, *(i2c_data->send_buf + i));
521         if (ret != HI_ERR_SUCCESS) {
522             i2c_error("i2csendbyte() error ! \n");
523             hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
524             return ret;
525         }
526     }
527 
528     ret = i2c_stop(id);
529     if (ret != HI_ERR_SUCCESS) {
530         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
531         return ret;
532     }
533 
534     return HI_ERR_SUCCESS;
535 }
536 
i2c_receive_data(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)537 static hi_u32 i2c_receive_data(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
538 {
539     hi_u32 ret;
540 
541     hi_reg_write32((i2c_base(id) + I2C_CTRL),
542                    (I2C_IP_ENABLE | I2C_UNMASK_ALL | I2C_UNMASK_ACK | I2C_UNMASK_ARBITRATE | I2C_UNMASK_OVER));
543 
544     /* clear all i2c interrupt */
545     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
546 
547     if (i2c_is_10bit_addr(device_addr) == HI_TRUE) {
548         ret = i2c_10bit_receive_addressing(id, device_addr);
549         if (ret != HI_ERR_SUCCESS) {
550             return ret;
551         }
552     } else {
553         /* 7bit addressing */
554         i2c_set_addr(id, device_addr | READ_OPERATION);
555         ret = i2c_start(id);
556         if (ret != HI_ERR_SUCCESS) {
557             i2c_error("start error when write address.\n");
558             hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
559             return ret;
560         }
561         ret = i2c_receive_byte_proc(id, i2c_data);
562         if (ret != HI_ERR_SUCCESS) {
563             return ret;
564         }
565     }
566 
567     return HI_ERR_SUCCESS;
568 }
569 
i2c_read_param_check(hi_i2c_idx id,const hi_i2c_data * i2c_data)570 static hi_u32 i2c_read_param_check(hi_i2c_idx id, const hi_i2c_data *i2c_data)
571 {
572     if (id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0) {
573         return HI_ERR_I2C_INVALID_PARAMETER;
574     }
575 
576     if (id >= I2C_NUM) {
577         return HI_ERR_I2C_INVALID_PARAMETER;
578     }
579 
580     if (i2c_data == HI_NULL) {
581         return HI_ERR_I2C_INVALID_PARAMETER;
582     }
583 
584     if (i2c_data->receive_buf == HI_NULL) {
585         i2c_error("null point.\n");
586         return HI_ERR_I2C_INVALID_PARAMETER;
587     }
588 
589     if (i2c_data->receive_len == 0) {
590         i2c_error("invalid receive_len. \n");
591         return HI_ERR_I2C_INVALID_PARAMETER;
592     }
593 
594     return HI_ERR_SUCCESS;
595 }
596 
i2c_writeread_param_check(hi_i2c_idx id,const hi_i2c_data * i2c_data)597 static hi_u32 i2c_writeread_param_check(hi_i2c_idx id, const hi_i2c_data *i2c_data)
598 {
599     if (id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0) {
600         return HI_ERR_I2C_INVALID_PARAMETER;
601     }
602 
603     if (id >= I2C_NUM) {
604         return HI_ERR_I2C_INVALID_PARAMETER;
605     }
606 
607     if (i2c_data == HI_NULL) {
608         return HI_ERR_I2C_INVALID_PARAMETER;
609     }
610 
611     if ((i2c_data->send_buf == HI_NULL) || (i2c_data->receive_buf == HI_NULL)) {
612         i2c_error("null point.\n");
613         return HI_ERR_I2C_INVALID_PARAMETER;
614     }
615 
616     if (i2c_data->receive_len == 0 || i2c_data->send_len == 0) {
617         i2c_error("invalid receive_len or send_len. \n");
618         return HI_ERR_I2C_INVALID_PARAMETER;
619     }
620 
621     return HI_ERR_SUCCESS;
622 }
623 
i2c_read_data(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)624 static hi_u32 i2c_read_data(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
625 {
626     hi_u32 ret;
627 
628     if (g_i2c_ctrl[id].prepare_func) {
629         g_i2c_ctrl[id].prepare_func();
630     }
631 
632     ret = i2c_receive_data(id, device_addr, i2c_data);
633     if (ret) {
634         if (g_i2c_ctrl[id].reset_bus_func) {
635             g_i2c_ctrl[id].reset_bus_func();
636         }
637     }
638 
639     if (g_i2c_ctrl[id].restore_func) {
640         g_i2c_ctrl[id].restore_func();
641     }
642 
643     return ret;
644 }
645 
i2c_writeread_data(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)646 static hi_void i2c_writeread_data(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
647 {
648     hi_u32 ret;
649 
650     if (g_i2c_ctrl[id].prepare_func) {
651         g_i2c_ctrl[id].prepare_func();
652     }
653 
654     ret = i2c_restart_receive_data(id, device_addr, i2c_data);
655     if (ret) {
656         if (g_i2c_ctrl[id].reset_bus_func) {
657             g_i2c_ctrl[id].reset_bus_func();
658         }
659     }
660     if (g_i2c_ctrl[id].restore_func) {
661         g_i2c_ctrl[id].restore_func();
662     }
663 }
664 
hi_i2c_writeread(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)665 hi_u32 hi_i2c_writeread(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
666 {
667     hi_u32 ret;
668 
669     ret = i2c_writeread_param_check(id, i2c_data);
670     if (ret != HI_ERR_SUCCESS) {
671         return HI_ERR_I2C_INVALID_PARAMETER;
672     }
673 
674     if (g_i2c_ctrl[id].init == HI_FALSE) {
675         return HI_ERR_I2C_NOT_INIT;
676     }
677 
678     i2c_writeread_data(id, device_addr, i2c_data);
679 
680     ret = hi_sem_wait(g_i2c_drv_sem[id], HI_SYS_WAIT_FOREVER);
681     if (ret != HI_ERR_SUCCESS) {
682         return HI_ERR_I2C_WAIT_SEM_FAIL;
683     }
684 
685     hi_sem_signal(g_i2c_drv_sem[id]);
686     return ret;
687 }
688 
hi_i2c_write(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)689 hi_u32 hi_i2c_write(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
690 {
691     hi_u32 ret;
692 
693     if (id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0) {
694         return HI_ERR_I2C_INVALID_PARAMETER;
695     }
696 
697     if (id >= I2C_NUM) {
698         return HI_ERR_I2C_INVALID_PARAMETER;
699     }
700 
701     if (g_i2c_ctrl[id].init == HI_FALSE) {
702         return HI_ERR_I2C_NOT_INIT;
703     }
704 
705     if (i2c_data == HI_NULL) {
706         return HI_ERR_I2C_INVALID_PARAMETER;
707     }
708 
709     if (i2c_data->send_buf == HI_NULL) {
710         i2c_error("null point.\n");
711         return HI_ERR_I2C_INVALID_PARAMETER;
712     }
713 
714     if (i2c_data->send_len == 0) {
715         i2c_error("invalid send_len. \n");
716         return HI_ERR_I2C_INVALID_PARAMETER;
717     }
718 
719     ret = hi_sem_wait(g_i2c_drv_sem[id], HI_SYS_WAIT_FOREVER);
720     if (ret != HI_ERR_SUCCESS) {
721         return HI_ERR_I2C_WAIT_SEM_FAIL;
722     }
723 
724     if (g_i2c_ctrl[id].prepare_func) {
725         g_i2c_ctrl[id].prepare_func();
726     }
727 
728     ret = i2c_send_data(id, device_addr, i2c_data);
729     if (ret) {
730         if (g_i2c_ctrl[id].reset_bus_func) {
731             g_i2c_ctrl[id].reset_bus_func();
732         }
733     }
734 
735     if (g_i2c_ctrl[id].restore_func) {
736         g_i2c_ctrl[id].restore_func();
737     }
738 
739     hi_sem_signal(g_i2c_drv_sem[id]);
740 
741     return ret;
742 }
743 
hi_i2c_read(hi_i2c_idx id,hi_u16 device_addr,const hi_i2c_data * i2c_data)744 hi_u32 hi_i2c_read(hi_i2c_idx id, hi_u16 device_addr, const hi_i2c_data *i2c_data)
745 {
746     hi_u32 ret, sem_ret;
747 
748     ret = i2c_read_param_check(id, i2c_data);
749     if (ret != HI_ERR_SUCCESS) {
750         return ret;
751     }
752 
753     if (g_i2c_ctrl[id].init == HI_FALSE) {
754         return HI_ERR_I2C_NOT_INIT;
755     }
756 
757     ret = hi_sem_wait(g_i2c_drv_sem[id], HI_SYS_WAIT_FOREVER);
758     if (ret != HI_ERR_SUCCESS) {
759         return HI_ERR_I2C_WAIT_SEM_FAIL;
760     }
761 
762     ret = i2c_read_data(id, device_addr, i2c_data);
763 
764     sem_ret = hi_sem_signal(g_i2c_drv_sem[id]);
765     if (sem_ret != HI_ERR_SUCCESS) {
766         return sem_ret;
767     }
768 
769     return ret;
770 }
771 
hi_i2c_init(hi_i2c_idx id,hi_u32 baudrate)772 hi_u32 hi_i2c_init(hi_i2c_idx id, hi_u32 baudrate)
773 {
774     hi_u32 ret;
775 
776     if (baudrate == 0 || id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0) {
777         return HI_ERR_I2C_INVALID_PARAMETER;
778     }
779 
780     if (id >= I2C_NUM) {
781         return HI_ERR_I2C_INVALID_PARAMETER;
782     }
783 
784     if (g_i2c_ctrl[id].init == HI_FALSE) {
785         hi_u16 reg_val;
786         hi_reg_read16(CLDO_CTL_CLKEN_REG, reg_val);
787         reg_val |= (id == HI_I2C_IDX_0) ? (1 << CLKEN_I2C0) : (1 << CLKEN_I2C1);
788         hi_reg_write16(CLDO_CTL_CLKEN_REG, reg_val); /* enable i2cx clk bus */
789         hi_reg_write32((i2c_base(id) + I2C_CTRL), (~(I2C_IP_ENABLE)));
790 
791         g_i2c_ctrl[id].baudrate = baudrate;
792 
793         i2c_cfg_clk(id, baudrate);
794 
795         hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
796 
797         ret = hi_sem_bcreate(&g_i2c_drv_sem[id], HI_TRUE);
798         if (ret) {
799             return ret;
800         }
801         g_i2c_ctrl[id].init = HI_TRUE;
802     }
803 
804     return HI_ERR_SUCCESS;
805 }
806 
hi_i2c_deinit(hi_i2c_idx id)807 hi_u32 hi_i2c_deinit(hi_i2c_idx id)
808 {
809     hi_u32 ret;
810 
811     if (id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0) {
812         return HI_ERR_I2C_INVALID_PARAMETER;
813     }
814 
815     if (id >= I2C_NUM) {
816         return HI_ERR_I2C_INVALID_PARAMETER;
817     }
818 
819     if (g_i2c_ctrl[id].init == HI_TRUE) {
820         ret = hi_sem_delete(g_i2c_drv_sem[id]);
821         if (ret != HI_ERR_SUCCESS) {
822             return ret;
823         }
824         g_i2c_ctrl[id].init = HI_FALSE;
825         hi_u16 reg_val;
826         hi_reg_read16(CLDO_CTL_CLKEN_REG, reg_val);
827         reg_val &= (id == HI_I2C_IDX_0) ? ~(1 << CLKEN_I2C0) : ~(1 << CLKEN_I2C1);
828         hi_reg_write16(CLDO_CTL_CLKEN_REG, reg_val); /* disable i2cx clk bus */
829     }
830 
831     return HI_ERR_SUCCESS;
832 }
833 
hi_i2c_set_baudrate(hi_i2c_idx id,hi_u32 baudrate)834 hi_u32 hi_i2c_set_baudrate(hi_i2c_idx id, hi_u32 baudrate)
835 {
836     /* baudrate range */
837     if (id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0 || baudrate == 0) {
838         return HI_ERR_I2C_INVALID_PARAMETER;
839     }
840 
841     if (g_i2c_ctrl[id].init == HI_FALSE) {
842         return HI_ERR_I2C_NOT_INIT;
843     }
844 
845     hi_reg_write32((i2c_base(id) + I2C_CTRL), (~(I2C_IP_ENABLE)));
846 
847     g_i2c_ctrl[id].baudrate = baudrate;
848 
849     i2c_cfg_clk(id, baudrate);
850 
851     hi_reg_write32((i2c_base(id) + I2C_ICR), I2C_CLEAR_ALL);
852 
853     return HI_ERR_SUCCESS;
854 }
855 
hi_i2c_register_reset_bus_func(hi_i2c_idx id,hi_i2c_func pfn)856 hi_void hi_i2c_register_reset_bus_func(hi_i2c_idx id, hi_i2c_func pfn)
857 {
858     if (id > HI_I2C_IDX_1 || id < HI_I2C_IDX_0) {
859         return;
860     }
861     g_i2c_ctrl[id].reset_bus_func = pfn.reset_func;
862     g_i2c_ctrl[id].prepare_func = pfn.prepare_func;
863     g_i2c_ctrl[id].restore_func = pfn.restore_func;
864 }
865 
866