1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <internal/i2c_driver.h>
9 #include <internal/i2c_reg.h>
10 #include <internal/i2c_reg_access.h>
11 
12 #include <fmw_cmsis.h>
13 
14 #include <stdbool.h>
15 #include <stdint.h>
16 #include <stdio.h>
17 
18 #define FILE_GRP_ID DBG_DRV_I2C
19 
20 #define DEBUG_PrintError(...)
21 
22 struct I2C_REG_FUNC_TABLE tables[2] = {
23     { f_i2c_write_BSR,       f_i2c_write_UNDEFINED, f_i2c_write_BCR,
24       f_i2c_write_BC2R,      f_i2c_write_ADR,       f_i2c_write_DAR,
25       f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED,
26       f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED,
27       f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED,
28       f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED,
29       f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED,
30       f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED, f_i2c_write_UNDEFINED,
31       f_i2c_write_CCR,       f_i2c_write_CSR,       f_i2c_write_FSR,
32 
33       f_i2c_read_BSR,        f_i2c_read_UNDEFINED,  f_i2c_read_BCR,
34       f_i2c_read_BC2R,       f_i2c_read_ADR,        f_i2c_read_DAR,
35       f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,
36       f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,
37       f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,
38       f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,
39       f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,
40       f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,  f_i2c_read_UNDEFINED,
41       f_i2c_read_CCR,        f_i2c_read_CSR,        f_i2c_read_FSR },
42 
43     { f_i2c_sp1_write_BSR,       f_i2c_sp1_write_BS2R,
44       f_i2c_sp1_write_BCR,       f_i2c_sp1_write_BC2R,
45       f_i2c_sp1_write_ADR,       f_i2c_sp1_write_DAR,
46       f_i2c_sp1_write_NFR,       f_i2c_sp1_write_TLWR,
47       f_i2c_sp1_write_TLW2R,     f_i2c_sp1_write_THWR,
48       f_i2c_sp1_write_THW2R,     f_i2c_sp1_write_TBFR,
49       f_i2c_sp1_write_TBF2R,     f_i2c_sp1_write_TRSR,
50       f_i2c_sp1_write_TRS2R,     f_i2c_sp1_write_TSHR,
51       f_i2c_sp1_write_TSH2R,     f_i2c_sp1_write_TPSR,
52       f_i2c_sp1_write_TPS2R,     f_i2c_sp1_write_TLWRH,
53       f_i2c_sp1_write_THWRH,     f_i2c_sp1_write_TRSRH,
54       f_i2c_sp1_write_TSHRH,     f_i2c_sp1_write_TPSRH,
55       f_i2c_sp1_write_UNDEFINED, f_i2c_sp1_write_UNDEFINED,
56       f_i2c_sp1_write_UNDEFINED,
57 
58       f_i2c_sp1_read_BSR,        f_i2c_sp1_read_BS2R,
59       f_i2c_sp1_read_BCR,        f_i2c_sp1_read_BC2R,
60       f_i2c_sp1_read_ADR,        f_i2c_sp1_read_DAR,
61       f_i2c_sp1_read_NFR,        f_i2c_sp1_read_TLWR,
62       f_i2c_sp1_read_TLW2R,      f_i2c_sp1_read_THWR,
63       f_i2c_sp1_read_THW2R,      f_i2c_sp1_read_TBFR,
64       f_i2c_sp1_read_TBF2R,      f_i2c_sp1_read_TRSR,
65       f_i2c_sp1_read_TRS2R,      f_i2c_sp1_read_TSHR,
66       f_i2c_sp1_read_TSH2R,      f_i2c_sp1_read_TPSR,
67       f_i2c_sp1_read_TPS2R,      f_i2c_sp1_read_TLWRH,
68       f_i2c_sp1_read_THWRH,      f_i2c_sp1_read_TRSRH,
69       f_i2c_sp1_read_TSHRH,      f_i2c_sp1_read_TPSRH,
70       f_i2c_sp1_read_UNDEFINED,  f_i2c_sp1_read_UNDEFINED,
71       f_i2c_sp1_read_UNDEFINED }
72 };
73 
74 #define SET_BSR(VAL) i2c_reg->set_BSR(packet_info, (VAL))
75 #define SET_BS2R(VAL) i2c_reg->set_BS2R(packet_info, (VAL))
76 #define SET_BCR(VAL) i2c_reg->set_BCR(packet_info, (VAL))
77 #define SET_BC2R(VAL) i2c_reg->set_BC2R(packet_info, (VAL))
78 #define SET_ADR(VAL) i2c_reg->set_ADR(packet_info, (VAL))
79 #define SET_DAR(VAL) i2c_reg->set_DAR(packet_info, (VAL))
80 #define SET_NFR(VAL) i2c_reg->set_NFR(packet_info, (VAL))
81 #define SET_TLWR(VAL) i2c_reg->set_TLWR(packet_info, (VAL))
82 #define SET_TLW2R(VAL) i2c_reg->set_TLW2R(packet_info, (VAL))
83 #define SET_THWR(VAL) i2c_reg->set_THWR(packet_info, (VAL))
84 #define SET_THW2R(VAL) i2c_reg->set_THW2R(packet_info, (VAL))
85 #define SET_TBFR(VAL) i2c_reg->set_TBFR(packet_info, (VAL))
86 #define SET_TBF2R(VAL) i2c_reg->set_TBF2R(packet_info, (VAL))
87 #define SET_TRSR(VAL) i2c_reg->set_TRSR(packet_info, (VAL))
88 #define SET_TRS2R(VAL) i2c_reg->set_TRS2R(packet_info, (VAL))
89 #define SET_TSHR(VAL) i2c_reg->set_TSHR(packet_info, (VAL))
90 #define SET_TSH2R(VAL) i2c_reg->set_TSH2R(packet_info, (VAL))
91 #define SET_TPSR(VAL) i2c_reg->set_TPSR(packet_info, (VAL))
92 #define SET_TPS2R(VAL) i2c_reg->set_TPS2R(packet_info, (VAL))
93 #define SET_TLWRH(VAL) i2c_reg->set_TLWRH(packet_info, (VAL))
94 #define SET_THWRH(VAL) i2c_reg->set_THWRH(packet_info, (VAL))
95 #define SET_TRSRH(VAL) i2c_reg->set_TRSRH(packet_info, (VAL))
96 #define SET_TSHRH(VAL) i2c_reg->set_TSHRH(packet_info, (VAL))
97 #define SET_TPSRH(VAL) i2c_reg->set_TPSRH(packet_info, (VAL))
98 #define SET_CCR(VAL) i2c_reg->set_CCR(packet_info, (VAL))
99 #define SET_CSR(VAL) i2c_reg->set_CSR(packet_info, (VAL))
100 #define SET_FSR(VAL) i2c_reg->set_FSR(packet_info, (VAL))
101 
102 #define GET_BSR() i2c_reg->get_BSR(packet_info)
103 #define GET_BS2R() i2c_reg->get_BSR(packet_info)
104 #define GET_BCR() i2c_reg->get_BCR(packet_info)
105 #define GET_BC2R() i2c_reg->get_BC2R(packet_info)
106 #define GET_ADR() i2c_reg->get_ADR(packet_info)
107 #define GET_DAR() i2c_reg->get_DAR(packet_info)
108 #define GET_NFR() i2c_reg->get_NFR(packet_info)
109 #define GET_TLWR() i2c_reg->get_TLWR(packet_info)
110 #define GET_TLW2R() i2c_reg->get_TLW2R(packet_info)
111 #define GET_THWR() i2c_reg->get_THWR(packet_info)
112 #define GET_THW2R() i2c_reg->get_THW2R(packet_info)
113 #define GET_TBFR() i2c_reg->get_TBFR(packet_info)
114 #define GET_TBF2R() i2c_reg->get_TBF2R(packet_info)
115 #define GET_TRSR() i2c_reg->get_TRSR(packet_info)
116 #define GET_TRS2R() i2c_reg->get_TRS2R(packet_info)
117 #define GET_TSHR() i2c_reg->get_TSHR(packet_info)
118 #define GET_TSH2R() i2c_reg->get_TSH2R(packet_info)
119 #define GET_TPSR() i2c_reg->get_TPSR(packet_info)
120 #define GET_TPS2R() i2c_reg->get_TPS2R(packet_info)
121 #define GET_TLWRH() i2c_reg->get_TLWRH(packet_info)
122 #define GET_THWRH() i2c_reg->get_THWRH(packet_info)
123 #define GET_TRSRH() i2c_reg->get_TRSRH(packet_info)
124 #define GET_TSHRH() i2c_reg->get_TSHRH(packet_info)
125 #define GET_TPSRH() i2c_reg->get_TPSRH(packet_info)
126 #define GET_CCR() i2c_reg->get_CCR(packet_info)
127 #define GET_CSR() i2c_reg->get_CSR(packet_info)
128 #define GET_FSR() i2c_reg->get_FSR(packet_info)
129 
i2c_fifo_isfull(I2C_ST_FIFO_t * instance)130 static inline bool i2c_fifo_isfull(I2C_ST_FIFO_t *instance)
131 {
132     return (instance->LIMIT == instance->SIZE);
133 }
134 
i2c_fifo_islimit(I2C_ST_FIFO_t * instance)135 static inline bool i2c_fifo_islimit(I2C_ST_FIFO_t *instance)
136 {
137     return (instance->INDEX == instance->LIMIT);
138 }
139 
i2c_fifo_isnextlimit(I2C_ST_FIFO_t * instance)140 static inline bool i2c_fifo_isnextlimit(I2C_ST_FIFO_t *instance)
141 {
142     return ((instance->INDEX + 1) >= instance->LIMIT);
143 }
144 
i2c_fifo_initialize(I2C_ST_FIFO_t * instance)145 static inline void i2c_fifo_initialize(I2C_ST_FIFO_t *instance)
146 {
147     instance->LIMIT = instance->INDEX = 0;
148 }
149 
i2c_fifo_registry(I2C_ST_FIFO_t * instance,char * buf,bool * attribute,int size)150 static I2C_ST_FIFO_t *i2c_fifo_registry(
151     I2C_ST_FIFO_t *instance,
152     char *buf,
153     bool *attribute,
154     int size)
155 {
156     instance->BUFF = buf;
157     instance->ATTR = attribute;
158     instance->SIZE = size;
159     i2c_fifo_initialize(instance);
160 
161     return instance;
162 }
163 
i2c_fifo_push_data(I2C_ST_FIFO_t * instance,char data,bool attr)164 static bool i2c_fifo_push_data(I2C_ST_FIFO_t *instance, char data, bool attr)
165 {
166     bool bFull = i2c_fifo_isfull(instance);
167 
168     if (!bFull) {
169         if (instance->BUFF)
170             instance->BUFF[instance->LIMIT] = data;
171         if (instance->ATTR)
172             instance->ATTR[instance->LIMIT] = attr;
173         ++instance->LIMIT;
174     }
175 
176     return !bFull;
177 }
178 
i2c_fifo_get_send_data(I2C_ST_FIFO_t * instance,char * data,bool * attr)179 static bool i2c_fifo_get_send_data(
180     I2C_ST_FIFO_t *instance,
181     char *data,
182     bool *attr)
183 {
184     bool limit = i2c_fifo_islimit(instance);
185 
186     if (!limit) {
187         *data = (instance->BUFF) ? instance->BUFF[instance->INDEX] : 0x00;
188         *attr = (instance->ATTR) ? instance->ATTR[instance->INDEX] : false;
189         ++instance->INDEX;
190     }
191 
192     return !limit;
193 }
194 
i2c_fifo_put_recv_data(I2C_ST_FIFO_t * instance,char data,bool attr)195 static bool i2c_fifo_put_recv_data(
196     I2C_ST_FIFO_t *instance,
197     char data, bool attr)
198 {
199     bool limit = i2c_fifo_islimit(instance);
200 
201     if (!limit) {
202         if (instance->BUFF)
203             instance->BUFF[instance->INDEX] = data;
204         if (instance->ATTR)
205             instance->ATTR[instance->INDEX] = attr;
206         ++instance->INDEX;
207     }
208 
209     return !limit;
210 }
211 
i2c_packet_initialize(I2C_ST_PACKET_t * packet)212 I2C_ST_PACKET_t *i2c_packet_initialize(I2C_ST_PACKET_t *packet)
213 {
214     i2c_fifo_initialize(&packet->CTRL);
215     i2c_fifo_initialize(&packet->DATA);
216 
217     return packet;
218 }
219 
i2c_packet_set_payload(I2C_ST_PACKET_t * packet,char * buf,int size)220 I2C_ST_PACKET_t *i2c_packet_set_payload(
221     I2C_ST_PACKET_t *packet,
222     char *buf,
223     int size)
224 {
225     i2c_fifo_registry(&packet->DATA, buf, NULL, size);
226     packet->DATA.LIMIT = size;
227 
228     return packet;
229 }
230 
i2c_packet_set_control(I2C_ST_PACKET_t * packet,uint32_t address,bool read)231 I2C_ST_PACKET_t *i2c_packet_set_control(
232     I2C_ST_PACKET_t *packet,
233     uint32_t address,
234     bool read)
235 {
236     I2C_UN_SLVADDR_t addr = { 0 };
237 
238     addr.DATA = 0;
239 
240     addr.bit.BITFIELD_READ = read;
241     addr.bit.BITFIELD_ADDR = (uint8_t)address;
242     i2c_fifo_push_data(&packet->CTRL, (char)addr.DATA, true);
243 
244     return packet;
245 }
246 
i2c_packet_set_address(I2C_ST_PACKET_t * packet,int address,int size)247 I2C_ST_PACKET_t *i2c_packet_set_address(
248     I2C_ST_PACKET_t *packet,
249     int address,
250     int size)
251 {
252     switch (size) {
253     case 4:
254         i2c_fifo_push_data(&packet->CTRL, (char)(address >> 24), false);
255         /* fallthrough */
256     case 3:
257         i2c_fifo_push_data(&packet->CTRL, (char)(address >> 16), false);
258         /* fallthrough */
259     case 2:
260         i2c_fifo_push_data(&packet->CTRL, (char)(address >> 8), false);
261         /* fallthrough */
262     case 1:
263         i2c_fifo_push_data(&packet->CTRL, (char)(address >> 0), false);
264         break;
265     default:
266         packet = NULL;
267         break;
268     }
269 
270     return packet;
271 }
272 
i2c_packet_get_send_data(I2C_ST_PACKET_t * packet,char * data,bool * attr)273 static bool i2c_packet_get_send_data(
274     I2C_ST_PACKET_t *packet,
275     char *data,
276     bool *attr)
277 {
278     bool result;
279 
280     if (i2c_fifo_islimit(&packet->CTRL))
281         result = i2c_fifo_get_send_data(&packet->DATA, data, attr);
282     else
283         result = i2c_fifo_get_send_data(&packet->CTRL, data, attr);
284 
285     return result;
286 }
287 
i2c_packet_put_recv_data(I2C_ST_PACKET_t * packet,char data)288 static bool i2c_packet_put_recv_data(I2C_ST_PACKET_t *packet, char data)
289 {
290     bool result = i2c_fifo_put_recv_data(&packet->DATA, data, false);
291 
292     return result;
293 }
294 
i2c_handler_buserror(I2C_ST_PACKET_INFO_t * packet_info,const I2C_UN_BSR_t * bsr_reg,I2C_UN_BCR_t * bcr_reg)295 static bool i2c_handler_buserror(
296     I2C_ST_PACKET_INFO_t *packet_info,
297     const I2C_UN_BSR_t *bsr_reg,
298     I2C_UN_BCR_t *bcr_reg)
299 {
300     bool result = false;
301 
302     if (packet_info->CONTROLLER_CODE_FLAG) {
303         packet_info->CONTROLLER_CODE_FLAG = false;
304         if (!(bsr_reg->bit_COMMON.LRB))
305             result = true;
306     }
307 
308     return result;
309 }
310 
i2c_handler_normal(I2C_ST_PACKET_INFO_t * packet_info,const I2C_UN_BSR_t * bsr_reg,I2C_UN_BCR_t * bcr_reg,bool * timeout,bool * nak_detect)311 static bool i2c_handler_normal(
312     I2C_ST_PACKET_INFO_t *packet_info,
313     const I2C_UN_BSR_t *bsr_reg,
314     I2C_UN_BCR_t *bcr_reg,
315     bool *timeout,
316     bool *nak_detect)
317 {
318     bool result = false;
319     char data;
320     bool attr;
321     uint32_t count = 0;
322 
323     *timeout = false;
324     *nak_detect = false;
325 
326     struct I2C_REG_FUNC_TABLE *i2c_reg = &tables[packet_info->TYPE];
327 
328     if (bcr_reg->bit_COMMON.MSS) {
329         if (packet_info->CONTROLLER_CODE_FLAG) {
330             I2C_UN_BS2R_t unBS2R = { 0 };
331             packet_info->CONTROLLER_CODE_FLAG = 0;
332             unBS2R.DATA = GET_BS2R();
333             if (!(unBS2R.bit_F_I2C_SP1.MAS)) {
334                 bcr_reg->bit_COMMON.MSS = 0;
335             } else if (
336                 i2c_packet_get_send_data(&packet_info->PACKET, &data, &attr) ==
337                 false) {
338                 bcr_reg->bit_COMMON.MSS = 0;
339             } else {
340                 do {
341                     unBS2R.DATA = GET_BS2R();
342                     __DSB();
343                     count++;
344                     if (count > I2C_POLLING_LIMIT) {
345                         DEBUG_PrintError(
346                             "Error in %s. polling timeout "
347                             "occurred. BS2R=0x%02x",
348                             __func__,
349                             unBS2R.DATA);
350                         *timeout = true;
351                         return false;
352                     }
353                 } while (!(unBS2R.bit_F_I2C_SP1.HS));
354 
355                 bcr_reg->bit_COMMON.SCC = attr ? 1 : 0;
356                 SET_DAR(data);
357                 __DSB();
358             }
359         } else if (bsr_reg->bit_COMMON.TRX) {
360             if (bsr_reg->bit_COMMON.LRB) {
361                 bcr_reg->bit_COMMON.MSS = 0;
362                 *nak_detect = true;
363             } else if (
364                 i2c_packet_get_send_data(&packet_info->PACKET, &data, &attr) ==
365                 false) {
366                 bcr_reg->bit_COMMON.MSS = 0;
367             } else {
368                 bcr_reg->bit_COMMON.SCC = attr ? 1 : 0;
369                 SET_DAR(data);
370                 __DSB();
371             }
372         } else {
373             if (bsr_reg->bit_COMMON.FBT) {
374                 bcr_reg->bit_COMMON.ACK =
375                     i2c_fifo_isnextlimit(&packet_info->PACKET.DATA) ?
376                     0 /*NAK*/ :
377                     1 /*ACK*/;
378             } else if (
379                 i2c_packet_put_recv_data(
380                     &packet_info->PACKET, (char)GET_DAR()) == false) {
381                 /* Buffer Full */
382                 bcr_reg->bit_COMMON.MSS = 0; /* issue STOP CONDITION */
383             } else {
384                 bcr_reg->bit_COMMON.MSS =
385                     i2c_fifo_islimit(&packet_info->PACKET.DATA) ? 0 /*SC*/ :
386                                                                   1 /*---*/;
387                 bcr_reg->bit_COMMON.ACK =
388                     i2c_fifo_isnextlimit(&packet_info->PACKET.DATA) ?
389                     0 /*NAK*/ :
390                     1 /*ACK*/;
391             }
392         }
393 
394         if (bcr_reg->bit_COMMON.MSS == 0)
395             result = true;
396 
397     } else {
398         /* %MN0 TARGET MODE is not supported */
399     }
400 
401     return result;
402 }
403 
i2c_enable(I2C_ST_PACKET_INFO_t * packet_info)404 void i2c_enable(I2C_ST_PACKET_INFO_t *packet_info)
405 {
406     struct I2C_REG_FUNC_TABLE *i2c_reg = &tables[packet_info->TYPE];
407 
408     I2C_UN_BCR_t bcr_reg = { 0 };
409     bcr_reg.DATA = GET_BCR();
410 
411     bcr_reg.bit_COMMON.BER = 0; /* Clear bus error status */
412     SET_BCR(bcr_reg.DATA);
413     __DSB();
414 
415     if (packet_info->TYPE == I2C_TYPE_F_I2C_SP1) {
416         I2C_UN_BC2R_t unBC2R = { 0 };
417         unBC2R.DATA = GET_BC2R();
418         unBC2R.bit_F_I2C_SP1.EN = 1;
419         SET_BC2R(unBC2R.DATA);
420     } else {
421         I2C_UN_CCR_t unCCR = { 0 };
422         unCCR.DATA = GET_CCR();
423         unCCR.bit_F_I2C.EN = 1;
424         SET_CCR(unCCR.DATA);
425     }
426     __DSB();
427 
428     return;
429 }
430 
i2c_handler_common(I2C_ST_PACKET_INFO_t * packet_info,const I2C_UN_BSR_t * bsr_reg,I2C_UN_BCR_t * bcr_reg)431 static uint32_t i2c_handler_common(
432     I2C_ST_PACKET_INFO_t *packet_info,
433     const I2C_UN_BSR_t *bsr_reg,
434     I2C_UN_BCR_t *bcr_reg)
435 {
436     uint32_t result = 0;
437     volatile uint8_t tmp;
438     bool tmp_BER = false;
439     bool timeout = false;
440     bool nak_detect = false;
441 
442     struct I2C_REG_FUNC_TABLE *i2c_reg = &tables[packet_info->TYPE];
443 
444     if (bcr_reg->bit_COMMON.BER) { /* Bus Error */
445         tmp_BER = true;
446 
447         if (i2c_handler_buserror(packet_info, bsr_reg, bcr_reg))
448             result = I2C_EN_EVF_MC_BUSERROR;
449         else
450             result = I2C_EN_EVF_BUSERROR;
451 
452     } else if (bcr_reg->bit_COMMON.INT) { /* Normal Interrupt */
453         if (i2c_handler_normal(
454                 packet_info, bsr_reg, bcr_reg, &timeout, &nak_detect)) {
455             result = I2C_EN_EVF_FINISH;
456         }
457 
458         if (timeout)
459             result = I2C_EN_EVF_TIMEOUT;
460         if (nak_detect)
461             result = I2C_EN_EVF_NAK;
462     }
463 
464     /* clear interrupt cause */
465     bcr_reg->bit_COMMON.BER = 0;
466     bcr_reg->bit_COMMON.INT = 0;
467     SET_BCR(bcr_reg->DATA);
468     __DSB();
469 
470     if (tmp_BER)
471         i2c_enable(packet_info);
472 
473     /*===== [Important] T_PLINTR : INTR delays 3PCLK CYCLE =====*/
474     tmp = GET_BSR(); /* read interrupt status */
475     tmp = GET_BSR(); /* read interrupt status */
476     tmp = GET_BSR(); /* read interrupt status */
477     (void)tmp;
478 
479     return result;
480 }
481 
i2c_handler_polling(I2C_ST_PACKET_INFO_t * packet_info)482 I2C_ERR_t i2c_handler_polling(I2C_ST_PACKET_INFO_t *packet_info)
483 {
484     I2C_UN_BSR_t bsr_reg = { 0 }; /* +00H BSR BUS STATUS REGISTER */
485     I2C_UN_BCR_t bcr_reg = { 0 }; /* +04H BCR BUS CONTROL REGISTER */
486     uint32_t result;
487     I2C_ERR_t ercd = I2C_ERR_OK;
488     uint32_t count = 0;
489 
490     struct I2C_REG_FUNC_TABLE *i2c_reg = &tables[packet_info->TYPE];
491 
492     for (result = 0; result == 0; /*nop*/) {
493         do {
494             bcr_reg.DATA = GET_BCR();
495             __DSB();
496             count++;
497             if (count > I2C_POLLING_LIMIT) {
498                 DEBUG_PrintError(
499                     "Error in %s. polling timeout occurred. "
500                     "BCR=0x%02x",
501                     __func__,
502                     bcr_reg.DATA);
503                 return I2C_ERR_POLLING;
504             }
505         } while (!(bcr_reg.bit_COMMON.BER || bcr_reg.bit_COMMON.INT));
506         bsr_reg.DATA = GET_BSR();
507         result = i2c_handler_common(packet_info, &bsr_reg, &bcr_reg);
508     }
509 
510     switch (result) {
511     case I2C_EN_EVF_BUSERROR:
512         ercd = I2C_ERR_BER;
513         break;
514     case I2C_EN_EVF_MC_BUSERROR:
515         ercd = I2C_ERR_BER_MC;
516         break;
517     case I2C_EN_EVF_TIMEOUT:
518         ercd = I2C_ERR_POLLING;
519         break;
520     case I2C_EN_EVF_NAK:
521         ercd = I2C_ERR_UNAVAILABLE;
522         break;
523     default:
524         break;
525     }
526 
527     return ercd;
528 }
529 
i2c_initialize(I2C_ST_PACKET_INFO_t * packet_info,uint32_t reg_base,I2C_TYPE enType,const I2C_PARAM_t * param)530 I2C_ERR_t i2c_initialize(
531     I2C_ST_PACKET_INFO_t *packet_info,
532     uint32_t reg_base,
533     I2C_TYPE enType,
534     const I2C_PARAM_t *param)
535 {
536     I2C_UN_BCR_t bcr_reg = { 0 }; /* +04H BCR BUS CONTROL REGISTER */
537     struct I2C_REG_FUNC_TABLE *i2c_reg;
538 
539     if (packet_info == NULL)
540         return I2C_ERR_PARAM;
541 
542     if (reg_base == 0)
543         return I2C_ERR_PARAM;
544 
545     if ((enType != I2C_TYPE_F_I2C) && (enType != I2C_TYPE_F_I2C_SP1))
546         return I2C_ERR_PARAM;
547 
548     if (param == NULL)
549         return I2C_ERR_PARAM;
550 
551     packet_info->I2C_BASE_ADDR = reg_base;
552     packet_info->TYPE = enType;
553     i2c_reg = &tables[enType];
554 
555     i2c_fifo_registry(
556         &packet_info->PACKET.CTRL,
557         packet_info->CTRL_BUFF,
558         packet_info->CTRL_ATTR,
559         sizeof(packet_info->CTRL_BUFF));
560 
561     if (enType == I2C_TYPE_F_I2C) {
562         I2C_UN_FSR_t unFSR = { 0 };
563         I2C_UN_CSR_t unCSR = { 0 };
564         I2C_UN_CCR_t unCCR = { 0 };
565 
566         unFSR.DATA = GET_FSR();
567         unFSR.bit_F_I2C.FS = param->I2C_PARAM_F_I2C.FSR_FS;
568         SET_FSR(unFSR.DATA);
569 
570         unCSR.DATA = GET_CSR();
571         unCSR.bit_F_I2C.CS = param->I2C_PARAM_F_I2C.CSR_CS;
572         SET_CSR(unCSR.DATA);
573 
574         unCCR.DATA = GET_CCR();
575         unCCR.bit_F_I2C.CS = param->I2C_PARAM_F_I2C.CCR_CS;
576         unCCR.bit_F_I2C.FM = param->I2C_PARAM_F_I2C.CCR_FM;
577         SET_CCR(unCCR.DATA);
578     } else {
579         I2C_UN_NFR_t unNFR = { 0 };
580         uint8_t tmp = 0;
581 
582         unNFR.bit_F_I2C_SP1.NF = param->I2C_PARAM_F_I2C_SP1.NFR_NF;
583         unNFR.bit_F_I2C_SP1.NFH = param->I2C_PARAM_F_I2C_SP1.NFR_NFH;
584         SET_NFR(unNFR.DATA);
585 
586         tmp = param->I2C_PARAM_F_I2C_SP1.TLWR_TLW;
587         SET_TLWR(tmp);
588 
589         tmp = param->I2C_PARAM_F_I2C_SP1.TLW2R_TLW;
590         SET_TLW2R(tmp);
591 
592         tmp = param->I2C_PARAM_F_I2C_SP1.THWR_THW;
593         SET_THWR(tmp);
594 
595         tmp = param->I2C_PARAM_F_I2C_SP1.THW2R_THW;
596         SET_THW2R(tmp);
597 
598         tmp = param->I2C_PARAM_F_I2C_SP1.TBFR_TBF;
599         SET_TBFR(tmp);
600 
601         tmp = param->I2C_PARAM_F_I2C_SP1.TBF2R_TBF;
602         SET_TBF2R(tmp);
603 
604         tmp = param->I2C_PARAM_F_I2C_SP1.TRSR_TRS;
605         SET_TRSR(tmp);
606 
607         tmp = param->I2C_PARAM_F_I2C_SP1.TRS2R_TRS;
608         SET_TRS2R(tmp);
609 
610         tmp = param->I2C_PARAM_F_I2C_SP1.TSHR_TSH;
611         SET_TSHR(tmp);
612 
613         tmp = param->I2C_PARAM_F_I2C_SP1.TSH2R_TSH;
614         SET_TSH2R(tmp);
615 
616         tmp = param->I2C_PARAM_F_I2C_SP1.TPSR_TPS;
617         SET_TPSR(tmp);
618 
619         tmp = param->I2C_PARAM_F_I2C_SP1.TPS2R_TPS;
620         SET_TPS2R(tmp);
621 
622         tmp = param->I2C_PARAM_F_I2C_SP1.TLWRH_TLWH;
623         SET_TLWRH(tmp);
624 
625         tmp = param->I2C_PARAM_F_I2C_SP1.THWRH_THWH;
626         SET_THWRH(tmp);
627 
628         tmp = param->I2C_PARAM_F_I2C_SP1.TRSRH_TRSH;
629         SET_TRSRH(tmp);
630 
631         tmp = param->I2C_PARAM_F_I2C_SP1.TSHRH_TSHH;
632         SET_TSHRH(tmp);
633 
634         tmp = param->I2C_PARAM_F_I2C_SP1.TPSRH_TPSH;
635         SET_TPSRH(tmp);
636     }
637     __DSB();
638 
639     /*
640      * i2c_enable() is moved to each i2c access function
641      */
642 
643     bcr_reg.DATA = GET_BCR();
644     bcr_reg.bit_COMMON.INTE = 0;
645     bcr_reg.bit_COMMON.BEIE = 0;
646     SET_BCR(bcr_reg.DATA);
647     __DSB();
648 
649     return I2C_ERR_OK;
650 }
651 
i2c_exec_transfer(I2C_ST_PACKET_INFO_t * packet_info)652 I2C_ERR_t i2c_exec_transfer(I2C_ST_PACKET_INFO_t *packet_info)
653 {
654     I2C_UN_BCR_t bcr_reg = { 0 }; /* +04H BCR BUS CONTROL REGISTER */
655     char data;
656     bool attr;
657     uint32_t count = 0;
658 
659     struct I2C_REG_FUNC_TABLE *i2c_reg = &tables[packet_info->TYPE];
660 
661     if (i2c_packet_get_send_data(&packet_info->PACKET, &data, &attr)) {
662         I2C_UN_BSR_t bsr_reg = { 0 }; /* +00H BSR BUS STATUS REGISTER */
663         do {
664             bsr_reg.DATA = GET_BSR();
665             __DSB();
666             count++;
667             if (count > I2C_POLLING_LIMIT) {
668                 DEBUG_PrintError(
669                     "Error in %s. polling timeout occurred. "
670                     "BSR=0x%02x",
671                     __func__,
672                     bsr_reg.DATA);
673                 return I2C_ERR_POLLING;
674             }
675         } while (bsr_reg.bit_COMMON.BB);
676         SET_DAR(data);
677         __DSB();
678         bcr_reg.DATA = GET_BCR();
679         bcr_reg.bit_COMMON.MSS = 1; /* I2C=CONTROLLER MODE */
680         SET_BCR(bcr_reg.DATA);
681         __DSB();
682     }
683 
684     return I2C_ERR_OK;
685 }
686 
i2c_disable(I2C_ST_PACKET_INFO_t * packet_info)687 void i2c_disable(I2C_ST_PACKET_INFO_t *packet_info)
688 {
689     struct I2C_REG_FUNC_TABLE *i2c_reg = &tables[packet_info->TYPE];
690 
691     if (packet_info->TYPE == I2C_TYPE_F_I2C_SP1) {
692         I2C_UN_BC2R_t unBC2R = { 0 };
693         unBC2R.DATA = GET_BC2R();
694         unBC2R.bit_F_I2C_SP1.EN = 0;
695         SET_BC2R(unBC2R.DATA);
696     } else {
697         I2C_UN_CCR_t unCCR = { 0 };
698         unCCR.DATA = GET_BC2R();
699         unCCR.bit_F_I2C.EN = 0;
700         SET_CCR(unCCR.DATA);
701     }
702     __DSB();
703 
704     return;
705 }
706