xref: /utopia/UTPA2-700.0.x/modules/swi2c/api/swi2c/apiSWI2C.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (¡§MStar Confidential Information¡¨) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 #define _API_SWI2C_C_
95 
96 #include "MsCommon.h"
97 #include "MsVersion.h"
98 #include "apiSWI2C.h"
99 #include "drvGPIO.h"
100 #include "drvMMIO.h"
101 #include "drvCPU.h"
102 #include "drvSYS.h"
103 #include "drvSEM.h"
104 #include "ULog.h"
105 
106 //-------------------------------------------------------------------------------------------------
107 //  Local Defines
108 //-------------------------------------------------------------------------------------------------
109 #define __I2C_BUS(scl, sda, dly)    scl, sda, dly
110 #define I2C_BUS( bus )              __I2C_BUS( bus )
111 #define COUNTOF( array )            (sizeof(array) / sizeof((array)[0]))
112 #define IIC_BUS_MAX                 16
113 
114 #define PULL_HIGH                   1
115 #define PULL_LOW                    0
116 #define BIT0                    0x0001
117 #define SWI2C_READ              0
118 #define SWI2C_WRITE             1
119 #define I2C_CHECK_PIN_DUMMY     5000
120 #define I2C_ACKNOWLEDGE         PULL_LOW
121 #define I2C_NON_ACKNOWLEDGE     PULL_HIGH
122 #define I2C_ACCESS_DUMMY_TIME   7
123 
124 #define HIBYTE(value)  ((MS_U8)((value) / 0x100))
125 #define LOBYTE(value)  ((MS_U8)(value))
126 
127 static MS_S32 g_s32SWI2CMutex[IIC_BUS_MAX] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
128 const char gu8SWI2CMutexName[IIC_BUS_MAX][13] = { \
129     "SWI2CMTXBUS0","SWI2CMTXBUS1","SWI2CMTXBUS2","SWI2CMTXBUS3","SWI2CMTXBUS4","SWI2CMTXBUS5","SWI2CMTXBUS6","SWI2CMTXBUS7", \
130     "SWI2CMTXBUS8","SWI2CMTXBUS9","SWI2CMTXBUSA","SWI2CMTXBUSB","SWI2CMTXBUSC","SWI2CMTXBUSD","SWI2CMTXBUSE","SWI2CMTXBUSF" };
131 #define IIC_MUTEX_CREATE(_P_)      g_s32SWI2CMutex[_P_] = MsOS_CreateMutex(E_MSOS_FIFO, (char*)gu8SWI2CMutexName[_P_] , MSOS_PROCESS_SHARED)
132 #define IIC_MUTEX_LOCK(_P_)        OS_OBTAIN_MUTEX(g_s32SWI2CMutex[_P_],MSOS_WAIT_FOREVER)
133 #define IIC_MUTEX_UNLOCK(_P_)      OS_RELEASE_MUTEX(g_s32SWI2CMutex[_P_])
134 #define IIC_MUTEX_DELETE(_P_)      OS_DELETE_MUTEX(g_s32SWI2CMutex[_P_])
135 //For ISP Programming
136 static MS_S32 g_s32I2CMutexS = -1;
137 #define IIC_MUTEX_S_CREATE()       g_s32I2CMutexS = MsOS_CreateMutex(E_MSOS_FIFO, (char*)"OS_SWI2C_Mutex", MSOS_PROCESS_SHARED)
138 #define IIC_MUTEX_S_LOCK()         OS_OBTAIN_MUTEX(g_s32I2CMutexS,MSOS_WAIT_FOREVER)
139 #define IIC_MUTEX_S_UNLOCK()       OS_RELEASE_MUTEX(g_s32I2CMutexS)
140 #define IIC_MUTEX_S_DELETE()       OS_DELETE_MUTEX(g_s32I2CMutexS)
141 #define LOCK_HW_SEM()   {\
142                         }
143 #define UNLOCK_HW_SEM() {\
144                         }
145 //-------------------------------------------------------------------------------------------------
146 //  Local Structures
147 //-------------------------------------------------------------------------------------------------
148 
149 
150 //-------------------------------------------------------------------------------------------------
151 //  Global Variables
152 //-------------------------------------------------------------------------------------------------
153 
154 
155 //-------------------------------------------------------------------------------------------------
156 //  Local Variables
157 //-------------------------------------------------------------------------------------------------
158 static SWI2C_DbgLvl _gSWI2CDbgLevel = E_SWI2C_DBGLVL_ERROR;
159 static MSIF_Version _api_swi2c_version = {
160     .DDI = { SWI2C_API_VERSION },
161 };
162 
163 static SWI2C_BusCfg g_I2CBus[IIC_BUS_MAX];
164 static MS_U8 u8BusAllocNum = 0;
165 static MS_U8 u8BusSel = 0;
166 static SWI2C_ReadMode g_I2CReadMode[IIC_BUS_MAX];
167 
168 static MS_U32 u32DelayCount[IIC_BUS_MAX];
169 static MS_U32 u32CpuSpeedMHz;
170 static SWI2C_BusCfg g_SWI2CCBusCfg[IIC_BUS_MAX];
171 static MS_U8 g_u8CfgBusNum = 0;
172 
173 //-------------------------------------------------------------------------------------------------
174 //  Debug Functions
175 //-------------------------------------------------------------------------------------------------
176 #define SWI2C_DBG_FUNC()               do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_ALL) \
177                                         {MS_DEBUG_MSG(ULOGI("SWIIC", "\t====   %s   ====\n", __FUNCTION__));} } while(0)
178 #define SWI2C_DBG_INFO(x, args...)     do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_INFO ) \
179                                         {MS_DEBUG_MSG(ULOGI("SWIIC", "[%s]: ", __FUNCTION__); printf(x, ##args));} } while(0)
180 #define SWI2C_DBG_ERR(x, args...)      do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_ERROR) \
181                                         {MS_DEBUG_MSG(ULOGE("SWIIC", "[%s]: ", __FUNCTION__); printf(x, ##args);)} } while(0)
182 #define SWI2C_DBG_WARN(x, args...)     do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_WARNING) \
183                                         {MS_DEBUG_MSG(ULOGW("SWIIC", "[%s]: ", __FUNCTION__); printf(x, ##args);)} } while(0)
184 
185 //-------------------------------------------------------------------------------------------------
186 //  Local Functions
187 //-------------------------------------------------------------------------------------------------
iic_delay(MS_U8 u8BusNum)188 static void iic_delay(MS_U8 u8BusNum)
189 {
190     MS_U32 volatile u32Loop=u32DelayCount[u8BusNum];
191 
192     while(u32Loop--)
193     {
194         #ifdef __mips__
195         __asm__ __volatile__ ("nop");
196         #endif
197 
198         #ifdef __AEONR2__
199         __asm__ __volatile__ ("l.nop");
200         #endif
201 
202         #ifdef __arm__
203         __asm__ __volatile__ ("mov r0, r0");
204         #endif
205     }
206 }
207 
pin_scl_set_input(MS_U8 u8BusNum)208 static void pin_scl_set_input(MS_U8 u8BusNum)
209 {
210     mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSCL );
211 }
212 
pin_scl_set_high(MS_U8 u8BusNum)213 static void pin_scl_set_high(MS_U8 u8BusNum)
214 {
215      mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSCL );
216 }
217 
pin_scl_set_low(MS_U8 u8BusNum)218 static void pin_scl_set_low(MS_U8 u8BusNum)
219 {
220     mdrv_gpio_set_low( g_I2CBus[u8BusNum].padSCL );
221 }
222 
pin_scl_get_level(MS_U8 u8BusNum)223 static int pin_scl_get_level(MS_U8 u8BusNum)
224 {
225     return mdrv_gpio_get_level( g_I2CBus[u8BusNum].padSCL ) ? PULL_HIGH : PULL_LOW;
226 }
227 
pin_scl_check_high(MS_U8 u8BusNum)228 static void pin_scl_check_high(MS_U8 u8BusNum)
229 {
230     MS_U16 u16Dummy;
231 
232     pin_scl_set_high(u8BusNum);
233     u16Dummy = I2C_CHECK_PIN_DUMMY;
234     while (u16Dummy--)
235     {
236         if(pin_scl_get_level(u8BusNum) == PULL_HIGH)
237             break;
238     }
239 }
240 
pin_sda_set_input(MS_U8 u8BusNum)241 static void pin_sda_set_input(MS_U8 u8BusNum)
242 {
243     mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSDA );
244 }
245 
pin_sda_set_high(MS_U8 u8BusNum)246 static void pin_sda_set_high(MS_U8 u8BusNum)
247 {
248     mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSDA );
249 }
250 
pin_sda_set_low(MS_U8 u8BusNum)251 static void pin_sda_set_low(MS_U8 u8BusNum)
252 {
253     mdrv_gpio_set_low( g_I2CBus[u8BusNum].padSDA );
254 }
255 
pin_sda_get_level(MS_U8 u8BusNum)256 static int pin_sda_get_level(MS_U8 u8BusNum)
257 {
258     return mdrv_gpio_get_level( g_I2CBus[u8BusNum].padSDA ) ? PULL_HIGH : PULL_LOW;
259 }
260 
pin_sda_check_high(MS_U8 u8BusNum)261 static void pin_sda_check_high(MS_U8 u8BusNum)
262 {
263     MS_U16 u16Dummy;
264 
265     pin_sda_set_high(u8BusNum);
266     u16Dummy = I2C_CHECK_PIN_DUMMY;
267     while (u16Dummy--)
268     {
269         if(pin_sda_get_level(u8BusNum) == PULL_HIGH)
270             break;
271     }
272 }
273 
pin_scl_check_low(MS_U8 u8BusNum)274 static void pin_scl_check_low(MS_U8 u8BusNum)
275 {
276     MS_U16 u16Dummy = I2C_CHECK_PIN_DUMMY;
277 
278     pin_scl_set_low(u8BusNum);
279     while (u16Dummy--)
280     {
281         if(pin_scl_get_level(u8BusNum) == PULL_LOW)
282             break;
283     }
284 }
285 
286 /******************************************************************************/
287 ////////////////////////////////////////////////////////////////////////////////
288 // I2C start signal.
289 // <comment>
290 //  SCL ________
291 //              \_________
292 //  SDA _____
293 //           \____________
294 //
295 // Return value: None
296 ////////////////////////////////////////////////////////////////////////////////
297 /******************************************************************************/
IIC_Start(MS_U8 u8BusNum)298 static MS_BOOL IIC_Start(MS_U8 u8BusNum)
299 {
300     MS_BOOL bStatus = TRUE;    // success status
301 
302     pin_sda_check_high(u8BusNum);
303     iic_delay(u8BusNum);
304 
305     pin_scl_check_high(u8BusNum);
306     iic_delay(u8BusNum);
307 
308     // check pin error
309     pin_scl_set_input(u8BusNum);
310     pin_sda_set_input(u8BusNum);
311 
312     if ((pin_scl_get_level(u8BusNum) == PULL_LOW) || (pin_sda_get_level(u8BusNum) == PULL_LOW))
313     {
314         pin_scl_set_high(u8BusNum);
315         pin_sda_set_high(u8BusNum);
316         bStatus = FALSE;
317     }
318     else // success
319     {
320         pin_sda_set_low(u8BusNum);
321         iic_delay(u8BusNum);
322         pin_scl_set_low(u8BusNum);
323     }
324 
325     return bStatus;     //vain
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 // I2C stop signal.
330 // <comment>
331 //              ____________
332 //  SCL _______/
333 //                 _________
334 //  SDA __________/
335 ////////////////////////////////////////////////////////////////////////////////
IIC_Stop(MS_U8 u8BusNum)336 static void IIC_Stop(MS_U8 u8BusNum)
337 {
338     pin_scl_set_low(u8BusNum);
339     iic_delay(u8BusNum);
340     pin_sda_set_low(u8BusNum);
341 
342     iic_delay(u8BusNum);
343     pin_scl_set_input(u8BusNum);
344     iic_delay(u8BusNum);
345     pin_sda_set_input(u8BusNum);
346     iic_delay(u8BusNum);
347 }
348 
349 /******************************************************************************/
350 ///Send 1 bytes data
351 ///@param u8dat \b IN: 1 byte data to send
352 /******************************************************************************/
SendByte(MS_U8 u8BusNum,MS_U8 u8dat)353 static MS_BOOL SendByte(MS_U8 u8BusNum, MS_U8 u8dat)   // Be used int IIC_SendByte
354 {
355     MS_U8    u8Mask = 0x80;
356     int bAck; // acknowledge bit
357 
358     while ( u8Mask )
359     {
360         if (u8dat & u8Mask)
361         {
362             pin_sda_check_high(u8BusNum);
363         }
364         else
365         {
366             pin_sda_set_low(u8BusNum);
367         }
368 
369         iic_delay(u8BusNum);
370         pin_scl_check_high(u8BusNum);
371         iic_delay(u8BusNum);
372         pin_scl_set_low(u8BusNum);
373 
374         u8Mask >>= 1; // next
375     }
376 
377     // recieve acknowledge
378     pin_sda_set_input(u8BusNum);
379     iic_delay(u8BusNum);
380     pin_scl_check_high(u8BusNum);
381 
382     iic_delay(u8BusNum);
383     bAck = pin_sda_get_level(u8BusNum); // recieve acknowlege
384     pin_scl_set_low(u8BusNum);
385 
386     iic_delay(u8BusNum);
387 
388     //for I2c waveform sharp
389     if (bAck)
390         pin_sda_set_high(u8BusNum);
391     else
392         pin_sda_set_low(u8BusNum);
393 
394     pin_sda_set_input(u8BusNum);
395 
396     iic_delay(u8BusNum);
397     iic_delay(u8BusNum);
398     iic_delay(u8BusNum);
399     iic_delay(u8BusNum);
400 
401     return (bAck)? TRUE: FALSE;
402 }
403 
404 /******************************************************************************/
405 ///Send 1 bytes data, this function will retry 5 times until success.
406 ///@param u8dat \b IN: 1 byte data to send
407 ///@return MS_BOOL:
408 ///- TRUE: Success
409 ///- FALSE: Fail
410 /******************************************************************************/
IIC_SendByte(MS_U8 u8BusNum,MS_U8 u8dat)411 static MS_BOOL IIC_SendByte(MS_U8 u8BusNum, MS_U8 u8dat)
412 {
413     MS_U8 i;
414 
415     for(i=0;i<1;i++)
416     {
417         if (SendByte(u8BusNum,u8dat)==I2C_ACKNOWLEDGE)
418             return TRUE;
419     }
420 
421     SWI2C_DBG_INFO("IIC[%d] write byte 0x%x fail!!\n",u8BusNum, u8dat);
422     return FALSE;
423 }
424 
425 ////////////////////////////////////////////////////////////////////////////////
426 // I2C access start.
427 //
428 // Arguments: u8SlaveID - Slave ID (Address)
429 //            trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
430 ////////////////////////////////////////////////////////////////////////////////
IIC_AccessStart(MS_U8 u8BusNum,MS_U8 u8SlaveID,MS_U8 trans_t)431 static MS_BOOL IIC_AccessStart(MS_U8 u8BusNum, MS_U8 u8SlaveID, MS_U8 trans_t)
432 {
433     MS_U8 u8Dummy; // loop dummy
434 
435     SWI2C_DBG_FUNC();
436 
437     if (trans_t == SWI2C_READ) // check i2c read or write
438     {
439         u8SlaveID |= BIT0;
440     }
441     else
442     {
443         u8SlaveID &= ~BIT0;
444     }
445 
446     u8Dummy = I2C_ACCESS_DUMMY_TIME;
447 
448     while (u8Dummy--)
449     {
450         if ( IIC_Start(u8BusNum) == FALSE)
451         {
452             continue;
453         }
454 
455         if ( IIC_SendByte(u8BusNum,u8SlaveID) == TRUE )  // check acknowledge
456         {
457             return TRUE;
458         }
459 
460         IIC_Stop(u8BusNum);
461     }
462 
463     return FALSE;
464 }
465 /******************************************************************************/
466 ///Get 1 bytes data, this function will retry 5 times until success.
467 ///@param *u8dat \b IN: pointer to 1 byte data buffer for getting data
468 ///@return MS_BOOL:
469 ///- TRUE: Success
470 ///- FALSE: Fail
471 /******************************************************************************///
472 //static MS_BOOL IIC_GetByte(MS_U8* pu8data)    // Auto generate ACK
IIC_GetByte(MS_U8 u8BusNum,MS_U16 bAck)473 static MS_U8 IIC_GetByte (MS_U8 u8BusNum, MS_U16  bAck)
474 {
475     MS_U8 ucReceive = 0;
476     MS_U8 ucMask = 0x80;
477 
478     pin_sda_set_input(u8BusNum);
479 
480     while ( ucMask )
481     {
482         iic_delay(u8BusNum);
483         pin_scl_check_high(u8BusNum);
484         iic_delay(u8BusNum);
485 
486         if (pin_sda_get_level(u8BusNum) == PULL_HIGH)
487         {
488             ucReceive |= ucMask;
489         }
490         ucMask >>= 1; // next
491 
492         pin_scl_set_low(u8BusNum);
493         pin_scl_check_low(u8BusNum);
494     }
495     if (bAck)
496     {
497         pin_sda_set_low(u8BusNum);     // acknowledge
498     }
499     else
500     {
501         pin_sda_check_high(u8BusNum);  // non-acknowledge
502     }
503     iic_delay(u8BusNum);
504     pin_scl_check_high(u8BusNum);
505     iic_delay(u8BusNum);
506     pin_scl_set_low(u8BusNum);
507     iic_delay(u8BusNum);
508     iic_delay(u8BusNum);
509     iic_delay(u8BusNum);
510     return ucReceive;
511 }
512 
IIC_CfgSpeedParam(MS_U8 u8BusNum,MS_U32 u32Speed_K)513 static MS_BOOL IIC_CfgSpeedParam(MS_U8 u8BusNum, MS_U32 u32Speed_K)
514 {
515 #define DELAY_CNT(SpeedKHz)  ((u32FactorDelay/(SpeedKHz))-((u32Parameter1+u32AdjParam)-((SpeedKHz)/u32AdjParam))+((1<<((u32Parameter2-SpeedKHz)/40))))
516 
517     MS_U32 u32FactorDelay = 50400UL;
518     MS_U32 u32FactorAdjust = 11040UL;
519     MS_U32 u32ParamBase1 = 130UL;
520     MS_U32 u32Parameter1 = 130UL;
521     MS_U32 u32Parameter2 = 440UL;
522     MS_U32 u32AdjParam;
523 
524     //(1) assign primary parameters
525     u32FactorDelay = u32CpuSpeedMHz * 100;
526     u32FactorAdjust = (u32CpuSpeedMHz>=312)? 10000UL :13000UL;
527     if (u32CpuSpeedMHz > 0)
528     {
529         u32AdjParam = u32FactorAdjust/u32CpuSpeedMHz;
530     }
531     else
532     {
533         SWI2C_DBG_ERR("%s, Error parameter u32CpuSpeedMHz=%ld",__FUNCTION__, u32CpuSpeedMHz);
534         return FALSE;
535     }
536     u32Parameter2 = 440UL;
537     //(2) assign base for parameter 1
538     if(u32CpuSpeedMHz>=1000) u32ParamBase1 = 150UL;
539     else if(u32CpuSpeedMHz>=900) u32ParamBase1 = 140UL;
540     else if(u32CpuSpeedMHz>=780) u32ParamBase1 = 135UL;
541     else if(u32CpuSpeedMHz>=720) u32ParamBase1 = 130UL;
542     else if(u32CpuSpeedMHz>=650) u32ParamBase1 = 125UL;
543     else if(u32CpuSpeedMHz>=600) u32ParamBase1 = 110UL;
544     else if(u32CpuSpeedMHz>=560) u32ParamBase1 = 100UL;
545     else if(u32CpuSpeedMHz>=530) u32ParamBase1 = 95UL;
546     else if(u32CpuSpeedMHz>=500) u32ParamBase1 = 90UL;
547     else if(u32CpuSpeedMHz>=480) u32ParamBase1 = 85UL;
548     else if(u32CpuSpeedMHz>=430) u32ParamBase1 = 80UL;
549     else if(u32CpuSpeedMHz>=400) u32ParamBase1 = 75UL;
550     else if(u32CpuSpeedMHz>=384) u32ParamBase1 = 70UL;
551     else if(u32CpuSpeedMHz>=360) u32ParamBase1 = 65UL;
552     else if(u32CpuSpeedMHz>=336) u32ParamBase1 = 60UL;
553     else if(u32CpuSpeedMHz>=312) u32ParamBase1 = 40UL;
554     else if(u32CpuSpeedMHz>=240) u32ParamBase1 = 10UL;
555     else if(u32CpuSpeedMHz>=216) u32ParamBase1 = 0UL;
556     else u32ParamBase1 = 0UL;
557     //(3) compute parameter 1 by base
558     if(u32Speed_K>=350) u32Parameter1 = u32ParamBase1;  //400K level
559     else if(u32Speed_K>=250) u32Parameter1 = u32ParamBase1 + 10; //300K evel
560     else if(u32Speed_K>=150) u32Parameter1 = u32ParamBase1 + 60; //200K level
561     else if(u32Speed_K>=75) u32Parameter1 = u32ParamBase1 + 250; //100K level //160
562     else u32Parameter1 = u32ParamBase1 + 560; //50K level
563     //(4) compute delay counts
564     if ((u32Speed_K>0) && (u32AdjParam>0))
565     {
566         u32DelayCount[u8BusNum] = DELAY_CNT(u32Speed_K);
567     }
568     else
569     {
570         SWI2C_DBG_ERR("%s, Error parameter u32Speed_K=%ld , u32AdjParam=%ld",__FUNCTION__,  u32Speed_K, u32AdjParam);
571         return FALSE;
572     }
573 
574     return TRUE;
575 }
576 
577 /******************************************************************************/
578 ///I2C Initialize: set I2C Clock and enable I2C
579 /******************************************************************************/
IIC_ConfigBus(MS_U8 u8BusNum,SWI2C_BusCfg * pSWI2CBusCfg)580 static MS_BOOL IIC_ConfigBus(MS_U8 u8BusNum,SWI2C_BusCfg* pSWI2CBusCfg)
581 {
582     SWI2C_DBG_FUNC();
583 
584     //check resources
585     if((u8BusAllocNum>IIC_BUS_MAX)||(u8BusNum>=IIC_BUS_MAX))
586         return FALSE;
587     if(!pSWI2CBusCfg)
588         return FALSE;
589     //config IIC bus settings
590     g_I2CBus[u8BusNum].padSCL = pSWI2CBusCfg->padSCL;
591     g_I2CBus[u8BusNum].padSDA = pSWI2CBusCfg->padSDA;
592     g_I2CBus[u8BusNum].defDelay = pSWI2CBusCfg->defDelay;
593     u8BusAllocNum++;
594     SWI2C_DBG_INFO("[IIC_ConfigBus]: g_I2CBus[%d].padSCL   = %d\n",u8BusNum, g_I2CBus[u8BusNum].padSCL);
595     SWI2C_DBG_INFO("[IIC_ConfigBus]: g_I2CBus[%d].padSDA   = %d\n",u8BusNum, g_I2CBus[u8BusNum].padSDA);
596     SWI2C_DBG_INFO("[IIC_ConfigBus]: g_I2CBus[%d].defDelay = %d\n",u8BusNum, g_I2CBus[u8BusNum].defDelay);
597     SWI2C_DBG_INFO("[IIC_ConfigBus]: u8BusAllocNum = %d\n",u8BusAllocNum);
598     return TRUE;
599 }
600 
IIC_UseBus(MS_U8 u8BusNum)601 static MS_BOOL  IIC_UseBus( MS_U8 u8BusNum )
602 {
603     MS_BOOL bReturn = FALSE;
604     if ( u8BusNum < COUNTOF( g_I2CBus ) )
605     {
606         u8BusSel = u8BusNum;
607         bReturn = IIC_CfgSpeedParam(u8BusNum, g_I2CBus[u8BusNum].defDelay);
608         SWI2C_DBG_INFO("[IIC_UseBus]: u8BusSel = %d\n",u8BusSel);
609     }
610     return bReturn;
611 }
612 
IIC_UnuseBus(MS_U8 u8BusNum)613 static void IIC_UnuseBus( MS_U8 u8BusNum )
614 {
615     u8BusNum = u8BusNum;
616 }
617 
618 //-------------------------------------------------------------------------------------------------
619 //  Global Functions
620 //-------------------------------------------------------------------------------------------------
MApi_SWI2C_GetMaxBuses(void)621 MS_U8 MApi_SWI2C_GetMaxBuses(void)
622 {
623     SWI2C_DBG_FUNC();
624     return (MS_U8)IIC_BUS_MAX;
625 }
626 
MApi_SWI2C_Speed_Setting(MS_U8 u8BusNum,MS_U32 u32Speed_K)627 MS_U32 MApi_SWI2C_Speed_Setting(MS_U8 u8BusNum, MS_U32 u32Speed_K)
628 {
629     MS_U32 u32OriginalValue;
630 
631     LOCK_HW_SEM();
632     IIC_MUTEX_LOCK(u8BusNum);
633     SWI2C_DBG_FUNC();
634 
635     u32OriginalValue = g_I2CBus[u8BusNum].defDelay;
636     g_I2CBus[u8BusNum].defDelay = u32Speed_K;
637     if (IIC_UseBus(u8BusNum) == FALSE)
638     {
639         g_I2CBus[u8BusNum].defDelay = (MS_U8) u32OriginalValue;
640     }
641     SWI2C_DBG_INFO("[MApi_SWI2C_Speed_Setting]: u8BusNum = %d, u32Speed_K = %ld\n",u8BusNum,u32Speed_K);
642     IIC_MUTEX_UNLOCK(u8BusNum);
643     UNLOCK_HW_SEM();
644     return u32OriginalValue;
645 }
646 
MApi_SWI2C_SetReadMode(SWI2C_ReadMode eReadMode)647 MS_BOOL MApi_SWI2C_SetReadMode(SWI2C_ReadMode eReadMode)
648 {
649     SWI2C_DBG_FUNC();
650 
651     if(eReadMode>=E_SWI2C_READ_MODE_MAX)
652         return FALSE;
653     g_I2CReadMode[u8BusSel] = eReadMode;
654     return TRUE;
655 }
656 
MApi_SWI2C_SetBusReadMode(MS_U8 u8BusNum,SWI2C_ReadMode eReadMode)657 MS_BOOL MApi_SWI2C_SetBusReadMode(MS_U8 u8BusNum, SWI2C_ReadMode eReadMode)
658 {
659     SWI2C_DBG_FUNC();
660 
661     if(eReadMode>=E_SWI2C_READ_MODE_MAX)
662         return FALSE;
663     g_I2CReadMode[u8BusNum] = eReadMode;
664     return TRUE;
665 }
666 
MApi_SWI2C_Init(SWI2C_BusCfg SWI2CCBusCfg[],MS_U8 u8CfgBusNum)667 void MApi_SWI2C_Init(SWI2C_BusCfg SWI2CCBusCfg[],MS_U8 u8CfgBusNum)
668 {
669     MS_U8 u8Bus;
670 
671     SWI2C_DBG_FUNC();
672     // Store SWI2CCBusCfg for FastBoot Resume
673     g_u8CfgBusNum = u8CfgBusNum;
674     for(u8Bus=0;u8Bus<u8CfgBusNum;u8Bus++)
675     {
676         g_SWI2CCBusCfg[u8Bus] = SWI2CCBusCfg[u8Bus];
677     }
678 
679     u8BusAllocNum = 0;
680 
681     //Get CPU clock & delay parameters
682     MDrv_COPRO_GetBase();
683     u32CpuSpeedMHz = (MS_U32)(MDrv_CPU_QueryClock()/1000000UL);
684     SWI2C_DBG_INFO("@@@@@@ u32CpuSpeedMHz= %d MHz\n",(int)u32CpuSpeedMHz);
685     if (u32CpuSpeedMHz == 0)
686     {
687         MS_ASSERT(0);
688     }
689 
690     //config iic buses
691     for(u8Bus=0;u8Bus<u8CfgBusNum;u8Bus++)
692     {
693         IIC_MUTEX_CREATE(u8Bus);
694     }
695     // create mutex to protect access specially for ISP Programming
696     IIC_MUTEX_S_CREATE();
697 
698     for(u8Bus=0;u8Bus<u8CfgBusNum;u8Bus++)
699     {
700         IIC_ConfigBus(u8Bus,&SWI2CCBusCfg[u8Bus]);
701         MApi_SWI2C_Speed_Setting(u8Bus,SWI2CCBusCfg[u8Bus].defDelay);
702         MApi_SWI2C_SetBusReadMode(u8Bus,E_SWI2C_READ_MODE_DIRECTION_CHANGE);
703     }
704 
705     MDrv_SYS_RegisterIoProc(E_SYS_IO_SWI2C_READ, MApi_SWI2C_ReadBytes);
706     MDrv_SYS_RegisterIoProc(E_SYS_IO_SWI2C_WRITE, MApi_SWI2C_WriteBytes);
707 }
708 
709 /******************************************************************************/
710 ///Write bytes, be able to write 1 byte or several bytes to several register offsets in same slave address.
711 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
712 ///@param u8addrcount \b IN:  register NO to write, this parameter is the NO of register offsets in pu8addr buffer,
713 ///it should be 0 when *pu8addr = NULL.
714 ///@param *pu8addr \b IN: pointer to a buffer containing target register offsets to write
715 ///@param u16size \b IN: Data length (in byte) to write
716 ///@param *pu8data \b IN: pointer to the data buffer for write
717 ///@return MS_BOOL:
718 ///- TRUE: Success
719 ///- FALSE: Fail
720 /******************************************************************************/
MApi_SWI2C_WriteBytes(MS_U16 u16BusNumSlaveID,MS_U8 AddrCnt,MS_U8 * pu8addr,MS_U16 u16size,MS_U8 * pBuf)721 MS_BOOL MApi_SWI2C_WriteBytes(MS_U16 u16BusNumSlaveID, MS_U8 AddrCnt, MS_U8* pu8addr, MS_U16 u16size, MS_U8* pBuf)
722 {
723     MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; //I2C_ACCESS_DUMMY_TIME; // loop dummy
724     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
725     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
726     MS_BOOL bRet = FALSE;
727     MS_U8 AddrCnt_temp=0;
728     MS_U16 u16size_temp=0;
729     MS_U8* pu8addr_temp=(MS_U8*)NULL;
730     MS_U8* pBuf_temp=(MS_U8*)NULL;
731 
732     SWI2C_DBG_FUNC();
733 
734     if(u8BusAllocNum==0)
735         return FALSE;
736 
737     LOCK_HW_SEM();
738     IIC_MUTEX_S_LOCK();
739     IIC_MUTEX_LOCK(u8BusNum);
740     if (IIC_UseBus(u8BusNum) == FALSE)
741     {
742         IIC_MUTEX_UNLOCK(u8BusNum);
743         IIC_MUTEX_S_UNLOCK();
744         UNLOCK_HW_SEM();
745         return FALSE;
746     }
747 
748     while (u8Dummy--)
749     {
750         AddrCnt_temp = AddrCnt;
751         u16size_temp = u16size;
752         pu8addr_temp =  (MS_U8*)pu8addr;
753         pBuf_temp    =  (MS_U8*)pBuf;
754         if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
755         {
756             if( u8Dummy )
757                 continue;
758             else
759                 goto fail;
760         }
761 
762         while (AddrCnt_temp)
763         {
764             AddrCnt_temp--;
765             if (IIC_SendByte(u8BusNum,*pu8addr_temp) == FALSE)
766             {
767                 goto fail;
768             }
769             pu8addr_temp++;
770         }
771         while (u16size_temp) // loop of writting data
772         {
773             u16size_temp-- ;
774             if (IIC_SendByte(u8BusNum,*pBuf_temp) == FALSE)
775             {
776                 goto fail;
777             }
778             pBuf_temp++; // next byte pointer
779         }
780         bRet = TRUE;
781         break;
782 fail:
783         IIC_Stop(u8BusNum);
784         bRet = FALSE;
785     }
786 
787     IIC_Stop(u8BusNum);
788     IIC_UnuseBus(u8BusNum);
789     IIC_MUTEX_UNLOCK(u8BusNum);
790     IIC_MUTEX_S_UNLOCK();
791     UNLOCK_HW_SEM();
792 
793     return bRet;
794 }
795 
796  /******************************************************************************/
797  ///Write bytes with Stop control
798  ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
799  ///@param AddrCnt \b IN:  register NO to write, this parameter is the NO of register offsets in pu8addr buffer,
800  ///it should be 0 when *pu8addr = NULL.
801  ///@param *pu8addr \b IN: pointer to a buffer containing target register offsets to write
802  ///@param u16size \b IN: Data length (in byte) to write
803  ///@param *pu8data \b IN: pointer to the data buffer for write
804  ///@param bGenStop \b IN: control stop to be generated by result
805  ///@return MS_BOOL:
806  ///- TRUE: Success
807  ///- FALSE: Fail
808  /******************************************************************************/
MApi_SWI2C_WriteBytesStop(MS_U16 u16BusNumSlaveID,MS_U8 AddrCnt,MS_U8 * pu8addr,MS_U16 u16size,MS_U8 * pBuf,MS_BOOL bGenStop)809  MS_BOOL MApi_SWI2C_WriteBytesStop(MS_U16 u16BusNumSlaveID, MS_U8 AddrCnt, MS_U8* pu8addr, MS_U16 u16size, MS_U8* pBuf,MS_BOOL bGenStop)
810 {
811     MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; //I2C_ACCESS_DUMMY_TIME; // loop dummy
812     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
813     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
814     MS_BOOL bRet = FALSE;
815     MS_U8 AddrCnt_temp=0;
816     MS_U16 u16size_temp=0;
817     MS_U8* pu8addr_temp=(MS_U8*)NULL;
818     MS_U8* pBuf_temp=(MS_U8*)NULL;
819     SWI2C_DBG_FUNC();
820 
821     if(u8BusAllocNum==0)
822         return FALSE;
823 
824     LOCK_HW_SEM();
825     IIC_MUTEX_S_LOCK();
826     IIC_MUTEX_LOCK(u8BusNum);
827     if (IIC_UseBus(u8BusNum) == FALSE)
828     {
829         IIC_MUTEX_UNLOCK(u8BusNum);
830         IIC_MUTEX_S_UNLOCK();
831         UNLOCK_HW_SEM();
832         return FALSE;
833     }
834 
835     while (u8Dummy--)
836     {
837         AddrCnt_temp = AddrCnt;
838         u16size_temp = u16size;
839         pu8addr_temp = (MS_U8*)pu8addr;
840         pBuf_temp    = (MS_U8*)pBuf;
841         if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
842         {
843             if( u8Dummy )
844                 continue;
845             else
846                 goto fail;
847         }
848 
849         while (AddrCnt_temp)
850         {
851             AddrCnt_temp--;
852             if (IIC_SendByte(u8BusNum,*pu8addr_temp) == FALSE)
853             {
854                 goto fail;
855             }
856             pu8addr_temp++;
857         }
858         while (u16size_temp) // loop of writting data
859         {
860             u16size_temp-- ;
861             if (IIC_SendByte(u8BusNum,*pBuf_temp) == FALSE)
862             {
863                 goto fail;
864             }
865             pBuf_temp++; // next byte pointer
866         }
867 
868         break;
869 fail:
870         IIC_Stop(u8BusNum);
871     }
872     bRet = TRUE;
873 
874 
875     if (bRet==TRUE)
876     {
877         if (bGenStop == TRUE)
878         {
879             IIC_Stop(u8BusNum);
880         }
881     }
882     else
883     {
884         IIC_Stop(u8BusNum);
885     }
886     IIC_UnuseBus(u8BusNum);
887     IIC_MUTEX_UNLOCK(u8BusNum);
888     IIC_MUTEX_S_UNLOCK();
889     UNLOCK_HW_SEM();
890 
891     return bRet;
892 }
893 
894 
895  /******************************************************************************/
896 ///Read bytes, be able to read 1 byte or several bytes in thru mode, like ISDB demod TC90527
897 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
898 ///@param u8AddrNum \b IN:  register NO to read, this parameter is the NO of register offsets in pu8addr buffer,
899 ///it should be 0 when *paddr = NULL.
900 ///@param *paddr \b IN: pointer to a buffer containing target register offsets to read
901 ///@param u16size \b IN: Data length (in byte) to read
902 ///@param *pu8data \b IN: pointer to retun data buffer.
903 ///@return MS_BOOL:
904 ///- TRUE: Success
905 ///- FALSE: Fail
906 /******************************************************************************/
MApi_SWI2C_ReadBytes_ThruMode(MS_U16 u16BusNumSlaveID,MS_U8 ucSubAdr,MS_U8 * paddr,MS_U16 ucBufLen,MS_U8 * pBuf)907 MS_BOOL MApi_SWI2C_ReadBytes_ThruMode(MS_U16 u16BusNumSlaveID, MS_U8 ucSubAdr, MS_U8* paddr, MS_U16 ucBufLen, MS_U8* pBuf)
908 {
909     MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; // loop dummy
910     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
911     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
912     MS_BOOL bRet = FALSE;
913     MS_U8 *pAddr_bk = paddr;
914 
915     SWI2C_DBG_FUNC();
916 
917     if(u8BusAllocNum==0)
918         return FALSE;
919 
920     LOCK_HW_SEM();
921     IIC_MUTEX_S_LOCK();
922     IIC_MUTEX_LOCK(u8BusNum);
923     if (IIC_UseBus(u8BusNum) == FALSE)
924     {
925         IIC_MUTEX_UNLOCK(u8BusNum);
926         IIC_MUTEX_S_UNLOCK();
927         UNLOCK_HW_SEM();
928         return FALSE;
929     }
930 
931     while (u8Dummy--)
932     {
933         // step1
934         if((g_I2CReadMode[u8BusNum]!=E_SWI2C_READ_MODE_DIRECT) && (ucSubAdr>0) && (paddr))
935         {
936             if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
937             {
938                 if( u8Dummy )
939                     continue;
940                 else
941                     goto fail;
942             }
943 
944             while (ucSubAdr)
945             {
946                 ucSubAdr--;
947                 if (IIC_SendByte(u8BusNum,*paddr) == FALSE)
948                 {
949                     goto fail;
950                 }
951                 paddr++;
952             }
953 
954             if(g_I2CReadMode[u8BusNum]==E_SWI2C_READ_MODE_DIRECTION_CHANGE_STOP_START)
955             {
956                 IIC_Stop(u8BusNum);
957             }
958         }
959 
960         //step 2
961         if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
962         {
963             if( u8Dummy )
964                 continue;
965             else
966                 goto fail;
967         }
968         if (IIC_SendByte(u8BusNum,pAddr_bk[0]) == FALSE)
969         {
970             goto fail;
971         }
972         if (IIC_SendByte(u8BusNum,pAddr_bk[1]+1) == FALSE)
973         {
974             goto fail;
975         }
976 
977         //step3
978         if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_READ) == FALSE)
979         {
980             if( u8Dummy )
981                 continue;
982             else
983                 goto fail;
984         }
985         while (ucBufLen--) // loop to burst read
986         {
987             *pBuf = IIC_GetByte(u8BusNum,ucBufLen); // receive byte
988             pBuf++; // next byte pointer
989         }
990         break;
991 fail:
992         IIC_Stop(u8BusNum);
993     }
994     bRet = TRUE;
995 
996     IIC_Stop(u8BusNum);
997     IIC_UnuseBus(u8BusNum);
998     IIC_MUTEX_UNLOCK(u8BusNum);
999     IIC_MUTEX_S_UNLOCK();
1000     UNLOCK_HW_SEM();
1001 
1002     return bRet;
1003 }
1004  /******************************************************************************/
1005 ///Read bytes, be able to read 1 byte or several bytes from several register offsets in same slave address.
1006 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
1007 ///@param u8AddrNum \b IN:  register NO to read, this parameter is the NO of register offsets in pu8addr buffer,
1008 ///it should be 0 when *paddr = NULL.
1009 ///@param *paddr \b IN: pointer to a buffer containing target register offsets to read
1010 ///@param u16size \b IN: Data length (in byte) to read
1011 ///@param *pu8data \b IN: pointer to retun data buffer.
1012 ///@return MS_BOOL:
1013 ///- TRUE: Success
1014 ///- FALSE: Fail
1015 /******************************************************************************/
MApi_SWI2C_ReadBytes(MS_U16 u16BusNumSlaveID,MS_U8 ucSubAdr,MS_U8 * paddr,MS_U16 ucBufLen,MS_U8 * pBuf)1016 MS_BOOL MApi_SWI2C_ReadBytes(MS_U16 u16BusNumSlaveID, MS_U8 ucSubAdr, MS_U8* paddr, MS_U16 ucBufLen, MS_U8* pBuf)
1017 {
1018     MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; // loop dummy
1019     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1020     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1021     MS_BOOL bRet = FALSE;
1022     MS_U8* pu8addr_temp=(MS_U8*)NULL;
1023     MS_U8* paddr_temp=(MS_U8*)NULL;
1024     MS_U16 ucBufLen_temp=0;
1025     MS_U8 ucSubAdr_temp=0;
1026 
1027 
1028     SWI2C_DBG_FUNC();
1029 
1030     if(u8BusAllocNum==0)
1031         return FALSE;
1032 
1033     LOCK_HW_SEM();
1034     IIC_MUTEX_S_LOCK();
1035     IIC_MUTEX_LOCK(u8BusNum);
1036     if (IIC_UseBus(u8BusNum) == FALSE)
1037     {
1038         IIC_MUTEX_UNLOCK(u8BusNum);
1039         IIC_MUTEX_S_UNLOCK();
1040         UNLOCK_HW_SEM();
1041         return FALSE;
1042     }
1043 
1044     while (u8Dummy--)
1045     {
1046         ucBufLen_temp = ucBufLen;
1047         ucSubAdr_temp = ucSubAdr;
1048         pu8addr_temp  = (MS_U8*)pBuf;
1049         paddr_temp    = (MS_U8*)paddr;
1050         if((g_I2CReadMode[u8BusNum]!=E_SWI2C_READ_MODE_DIRECT) && (ucSubAdr_temp>0) && (paddr_temp))
1051         {
1052             if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
1053             {
1054                 if( u8Dummy )
1055                     continue;
1056                 else
1057                     goto fail;
1058             }
1059 
1060             while (ucSubAdr_temp)
1061             {
1062                 ucSubAdr_temp--;
1063                 if (IIC_SendByte(u8BusNum,*paddr_temp) == FALSE)
1064                 {
1065                     goto fail;
1066                 }
1067                 paddr_temp++;
1068             }
1069 
1070             if(g_I2CReadMode[u8BusNum]==E_SWI2C_READ_MODE_DIRECTION_CHANGE_STOP_START)
1071             {
1072                 IIC_Stop(u8BusNum);
1073             }
1074         }
1075 
1076         if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_READ) == FALSE)
1077         {
1078             if( u8Dummy )
1079                 continue;
1080             else
1081                 goto fail;
1082         }
1083 
1084         while (ucBufLen_temp--) // loop to burst read
1085         {
1086             *pu8addr_temp = IIC_GetByte(u8BusNum,ucBufLen_temp); // receive byte
1087             pu8addr_temp++; // next byte pointer
1088         }
1089         bRet = TRUE;
1090         break;
1091 fail:
1092 
1093         IIC_Stop(u8BusNum);
1094         bRet = FALSE;
1095     }
1096 
1097     IIC_Stop(u8BusNum);
1098     IIC_UnuseBus(u8BusNum);
1099     IIC_MUTEX_UNLOCK(u8BusNum);
1100     IIC_MUTEX_S_UNLOCK();
1101     UNLOCK_HW_SEM();
1102 
1103     return bRet;
1104 }
1105 
1106 /******************************************************************************/
1107 ///Read 1 byte through IIC
1108 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
1109 ///@param u8RegAddr \b IN: Target register offset to read
1110 ///@param *pu8Data \b IN: pointer to 1 byte return data.
1111 ///@return MS_BOOL:
1112 ///- TRUE: Success
1113 ///- FALSE: Fail
1114 /******************************************************************************/
MApi_SWI2C_ReadByte(MS_U16 u16BusNumSlaveID,MS_U8 u8RegAddr,MS_U8 * pu8Data)1115 MS_BOOL MApi_SWI2C_ReadByte(MS_U16 u16BusNumSlaveID, MS_U8 u8RegAddr, MS_U8 *pu8Data)
1116 {
1117     MS_BOOL Result;
1118 
1119     SWI2C_DBG_FUNC();
1120 
1121     Result=MApi_SWI2C_ReadBytes(u16BusNumSlaveID, 1, &u8RegAddr,1, pu8Data);
1122     return Result;
1123 }
1124 
1125 /******************************************************************************/
1126 ///Write 1 byte through IIC
1127 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
1128 ///@param u8RegAddr \b IN: Target register offset to write
1129 ///@param u8Data \b IN: 1 byte data to write
1130 ///@return MS_BOOL:
1131 ///- TRUE: Success
1132 ///- FALSE: Fail
1133 /******************************************************************************/
MApi_SWI2C_WriteByte(MS_U16 u16BusNumSlaveID,MS_U8 u8RegAddr,MS_U8 u8Data)1134 MS_BOOL MApi_SWI2C_WriteByte(MS_U16 u16BusNumSlaveID, MS_U8 u8RegAddr, MS_U8 u8Data)
1135 {
1136     SWI2C_DBG_FUNC();
1137 
1138     return( MApi_SWI2C_WriteBytes(u16BusNumSlaveID, 1, &u8RegAddr, 1, &u8Data) );
1139 }
1140 //------------------------------------------------------------------------
MApi_SWI2C_Write2Bytes(MS_U16 u16BusNumSlaveID,MS_U8 u8addr,MS_U16 u16data)1141 MS_BOOL MApi_SWI2C_Write2Bytes(MS_U16 u16BusNumSlaveID, MS_U8 u8addr, MS_U16 u16data)
1142 {
1143     MS_U8 u8Data[2];
1144 
1145     SWI2C_DBG_FUNC();
1146 
1147     u8Data[0] = (u16data>>8) & 0xFF;
1148     u8Data[1] = (u16data) & 0xFF;
1149     return (MApi_SWI2C_WriteBytes(u16BusNumSlaveID, 1, &u8addr, 2, u8Data));
1150 }
1151 
MApi_SWI2C_Read2Bytes(MS_U16 u16BusNumSlaveID,MS_U8 u8addr)1152 MS_U16 MApi_SWI2C_Read2Bytes(MS_U16 u16BusNumSlaveID, MS_U8 u8addr)
1153 {
1154     SWI2C_DBG_FUNC();
1155 
1156     MS_U8 u8Data[2]={0,0};
1157     MApi_SWI2C_ReadBytes(u16BusNumSlaveID, 1, &u8addr, 2, u8Data);
1158     return ( (((MS_U16)u8Data[0])<<8)|u8Data[1] );
1159 }
1160 
MApi_SWI2C_WriteByteDirectly(MS_U16 u16BusNumSlaveID,MS_U8 u8Data)1161 MS_BOOL MApi_SWI2C_WriteByteDirectly(MS_U16 u16BusNumSlaveID, MS_U8 u8Data)
1162 {
1163     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1164     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1165     MS_BOOL bRet = FALSE;
1166 
1167     SWI2C_DBG_FUNC();
1168 
1169     if(u8BusAllocNum==0)
1170         return FALSE;
1171 
1172     LOCK_HW_SEM();
1173     IIC_MUTEX_S_LOCK();
1174     IIC_MUTEX_LOCK(u8BusNum);
1175     if (IIC_UseBus(u8BusNum) == FALSE)
1176     {
1177         IIC_MUTEX_UNLOCK(u8BusNum);
1178         IIC_MUTEX_S_UNLOCK();
1179         UNLOCK_HW_SEM();
1180         return FALSE;
1181     }
1182 
1183     IIC_Start(u8BusNum);
1184     if (IIC_SendByte(u8BusNum,(u8SlaveID&~BIT0)) == FALSE)
1185         goto fail;
1186     if (IIC_SendByte(u8BusNum,u8Data)==FALSE)
1187         goto fail;
1188     bRet = TRUE;
1189 
1190 fail:
1191 
1192     IIC_Stop(u8BusNum);
1193     IIC_UnuseBus(u8BusNum);
1194     IIC_MUTEX_UNLOCK(u8BusNum);
1195     IIC_MUTEX_S_UNLOCK();
1196     UNLOCK_HW_SEM();
1197 
1198     return bRet;
1199 }
1200 
1201 
MApi_SWI2C_Write4Bytes(MS_U16 u16BusNumSlaveID,MS_U32 u32Data,MS_U8 u8EndData)1202 MS_BOOL MApi_SWI2C_Write4Bytes(MS_U16 u16BusNumSlaveID, MS_U32 u32Data, MS_U8 u8EndData)
1203 {
1204     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1205     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1206     MS_BOOL bRet = FALSE;
1207 
1208     SWI2C_DBG_FUNC();
1209 
1210     if (u8BusAllocNum==0)
1211         return FALSE;
1212 
1213     LOCK_HW_SEM();
1214     IIC_MUTEX_S_LOCK();
1215     IIC_MUTEX_LOCK(u8BusNum);
1216     if (IIC_UseBus(u8BusNum) == FALSE)
1217     {
1218         IIC_MUTEX_UNLOCK(u8BusNum);
1219         IIC_MUTEX_S_UNLOCK();
1220         UNLOCK_HW_SEM();
1221         return FALSE;
1222     }
1223 
1224     IIC_Start(u8BusNum);
1225     if(IIC_SendByte(u8BusNum,(u8SlaveID&~BIT0))==FALSE)
1226         goto fail;
1227     if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>24) ) == FALSE )
1228         goto fail;
1229     if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>16) ) == FALSE )
1230         goto fail;
1231     if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>8) ) == FALSE )
1232         goto fail;
1233     if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>0) ) == FALSE )
1234         goto fail;
1235     if(IIC_SendByte(u8BusNum,u8EndData)==FALSE)
1236         goto fail;
1237     bRet = TRUE;
1238 
1239 fail:
1240 
1241     IIC_Stop(u8BusNum);
1242     IIC_UnuseBus(u8BusNum);
1243     IIC_MUTEX_UNLOCK(u8BusNum);
1244     IIC_MUTEX_S_UNLOCK();
1245     UNLOCK_HW_SEM();
1246 
1247     return bRet;
1248 }
1249 
MApi_SWI2C_WriteGroupBytes(MS_U16 u16BusNumSlaveID,MS_U8 u8SubGroup,MS_U16 u16Addr,MS_U16 u16Data)1250 MS_BOOL MApi_SWI2C_WriteGroupBytes(MS_U16 u16BusNumSlaveID, MS_U8 u8SubGroup, MS_U16 u16Addr, MS_U16 u16Data)
1251 {
1252     MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1253     MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1254     MS_BOOL bRet = FALSE;
1255 
1256     SWI2C_DBG_FUNC();
1257 
1258     if(u8BusAllocNum==0)
1259         return FALSE;
1260 
1261     LOCK_HW_SEM();
1262     IIC_MUTEX_LOCK(u8BusNum);
1263     if (IIC_UseBus(u8BusNum) == FALSE)
1264     {
1265         IIC_MUTEX_UNLOCK(u8BusNum);
1266         UNLOCK_HW_SEM();
1267         return FALSE;
1268     }
1269 
1270     IIC_Start(u8BusNum);
1271     if(IIC_SendByte(u8BusNum,(u8SlaveID&~BIT0))==FALSE)
1272         goto fail;
1273     if(IIC_SendByte(u8BusNum,u8SubGroup)==FALSE)
1274         goto fail;
1275     if(IIC_SendByte(u8BusNum,(u16Addr>>8)&0xFF)==FALSE)
1276         goto fail;
1277     if(IIC_SendByte(u8BusNum,u16Addr&0xFF)==FALSE)
1278         goto fail;
1279     if(IIC_SendByte(u8BusNum,(u16Data>>8)&0xFF)==FALSE)
1280         goto fail;
1281     if(IIC_SendByte(u8BusNum,u16Data&0xFF)==FALSE)
1282         goto fail;
1283     bRet = TRUE;
1284 
1285 fail:
1286 
1287     IIC_Stop(u8BusNum);
1288     IIC_UnuseBus(u8BusNum);
1289     IIC_MUTEX_UNLOCK(u8BusNum);
1290     UNLOCK_HW_SEM();
1291 
1292     return bRet;
1293 }
1294 
MApi_SWI2C_ReadGroupBytes(MS_U16 u16BusNumSlaveID,MS_U8 u8SubGroup,MS_U16 u16Addr)1295 MS_U16 MApi_SWI2C_ReadGroupBytes(MS_U16 u16BusNumSlaveID, MS_U8 u8SubGroup, MS_U16 u16Addr)
1296 {
1297     MS_U16 u16Data = 0; // Modified it by coverity_507
1298     MS_U8 u8Address[3];
1299 
1300     SWI2C_DBG_FUNC();
1301 
1302     u8Address[0] = u8SubGroup;
1303     u8Address[1] = (u16Addr>>8)&0xFF;
1304     u8Address[2] = u16Addr&0xFF;
1305 
1306     MApi_SWI2C_ReadBytes(u16BusNumSlaveID, 3, u8Address, 2, (MS_U8 *)&u16Data);
1307 
1308     return u16Data;
1309 }
1310 
MApi_SWI2C_GetLibVer(const MSIF_Version ** ppVersion)1311 MS_BOOL MApi_SWI2C_GetLibVer(const MSIF_Version **ppVersion)
1312 {
1313     SWI2C_DBG_FUNC();
1314 
1315     if (!ppVersion)
1316     {
1317         return FALSE;
1318     }
1319 
1320     *ppVersion = &_api_swi2c_version;
1321     return TRUE;
1322 }
1323 
1324 //-------------------------------------------------------------------------------------------------
1325 /// Set SWI2C debug function level.
1326 /// @param eLevel \b IN: E_SWI2C_DBGLVL_NONE/E_SWI2C_DBGLVL_WARNING/E_SWI2C_DBGLVL_ERROR/E_SWI2C_DBGLVL_INFO/E_SWI2C_DBGLVL_ALL
1327 /// @return E_SWI2C_OK: Success
1328 /// @return E_SWI2C_FAIL or other values: Failure
1329 //-------------------------------------------------------------------------------------------------
MApi_SWI2C_SetDbgLevel(SWI2C_DbgLvl eLevel)1330 SWI2C_Result MApi_SWI2C_SetDbgLevel(SWI2C_DbgLvl eLevel)
1331 {
1332     SWI2C_DBG_INFO("Debug level: %u\n", eLevel);
1333 
1334     _gSWI2CDbgLevel = eLevel;
1335     return E_SWI2C_OK;
1336 }
1337 
1338 /******************************************************************************/
1339 ///
1340 /// The following API functions are packed for special usage in ISP programming
1341 ///
1342 /******************************************************************************/
1343 
1344 ////////////////////////////////////////////////////////////////////////////////
1345 /// Packed I2C MUTEX Lock.
1346 ///
1347 /// Arguments:
1348 /// @ None
1349 /// return:
1350 /// @ None:
1351 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_MutexLock(void)1352 void MApi_SWI2C_MutexLock(void)
1353 {
1354     IIC_MUTEX_S_LOCK();
1355 }
1356 
1357 ////////////////////////////////////////////////////////////////////////////////
1358 /// Packed I2C MUTEX Unlock.
1359 ///
1360 /// Arguments:
1361 /// @ None
1362 /// return:
1363 /// @ None:
1364 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_MutexUnlock(void)1365 void MApi_SWI2C_MutexUnlock(void)
1366 {
1367     IIC_MUTEX_S_UNLOCK();
1368 }
1369 
1370 ////////////////////////////////////////////////////////////////////////////////
1371 /// Packed I2C Bus Use.
1372 ///
1373 /// Arguments:
1374 /// @ None
1375 /// return:
1376 /// @ None:
1377 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_UseBus(MS_U8 u8BusChn)1378 void MApi_SWI2C_UseBus( MS_U8 u8BusChn )
1379 {
1380     LOCK_HW_SEM();
1381     IIC_MUTEX_LOCK(u8BusChn);
1382     IIC_UseBus(u8BusChn);
1383     IIC_MUTEX_UNLOCK(u8BusChn);
1384     UNLOCK_HW_SEM();
1385 }
1386 
1387 ////////////////////////////////////////////////////////////////////////////////
1388 /// Packed I2C Bus Unuse.
1389 ///
1390 /// Arguments:
1391 /// @ None
1392 /// return:
1393 /// @ None:
1394 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_UnuseBus(void)1395 void MApi_SWI2C_UnuseBus(void)
1396 {
1397      IIC_UnuseBus(u8BusSel);
1398 }
1399 
1400 ////////////////////////////////////////////////////////////////////////////////
1401 /// Packed I2C access start.
1402 ///
1403 /// Arguments:
1404 /// @u8SlaveID - Slave ID (Address)
1405 /// @trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
1406 /// @return MS_BOOL:
1407 /// - TRUE: Success
1408 /// - FALSE: Fail
1409 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_AccessStart(MS_U8 u8SlaveID,MS_U8 trans_t)1410 MS_BOOL MApi_SWI2C_AccessStart(MS_U8 u8SlaveID, MS_U8 trans_t)
1411 {
1412     MS_BOOL bRet;
1413     bRet = IIC_AccessStart(u8BusSel, u8SlaveID, trans_t);
1414     return bRet;
1415 }
1416 
1417 ////////////////////////////////////////////////////////////////////////////////
1418 /// Packed I2C access stop.
1419 ///
1420 /// Arguments:
1421 /// @ None
1422 /// return:
1423 /// @ None
1424 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_Stop(void)1425 void MApi_SWI2C_Stop(void)
1426 {
1427     IIC_Stop(u8BusSel);
1428 }
1429 
1430 ////////////////////////////////////////////////////////////////////////////////
1431 /// Packed I2C access start.
1432 ///
1433 /// Arguments:
1434 /// @ None
1435 /// return:
1436 /// @ MS_BOOL:
1437 /// - TRUE: Success
1438 /// - FALSE: Fail
1439 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_Start(void)1440 MS_BOOL MApi_SWI2C_Start(void)
1441 {
1442     return IIC_Start(u8BusSel);
1443 }
1444 
1445 ////////////////////////////////////////////////////////////////////////////////
1446 /// Packed I2C send byte.
1447 ///
1448 /// Arguments:
1449 /// @ u8Data : one-byte data for sending
1450 /// @return MS_BOOL:
1451 /// - TRUE: Success
1452 /// - FALSE: Fail
1453 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_SendByte(MS_U8 u8Data)1454 MS_BOOL MApi_SWI2C_SendByte(MS_U8 u8Data)
1455 {
1456     MS_BOOL bRet;
1457 
1458     bRet = IIC_SendByte(u8BusSel, u8Data);
1459     return bRet;
1460 }
1461 
1462 ////////////////////////////////////////////////////////////////////////////////
1463 /// Packed I2C send byte.
1464 ///
1465 /// Arguments:
1466 /// @ u16Ack :
1467 ///     None 0 : get next byte and request next byte from slave device,
1468 ///             0 : get next byte and inform of slave device not to send data anymore.
1469 /// @return MS_U8:
1470 ///     return one-byte data from slave device
1471 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_GetByte(MS_U16 u16Ack)1472 MS_U8 MApi_SWI2C_GetByte(MS_U16 u16Ack)
1473 {
1474     MS_U8 u8Ret;
1475 
1476     u8Ret = IIC_GetByte(u8BusSel, u16Ack);
1477     return u8Ret;
1478 }
1479 
MApi_SWI2C_SetPowerState(EN_POWER_MODE u16PowerState)1480 MS_U16 MApi_SWI2C_SetPowerState(EN_POWER_MODE u16PowerState)
1481 {
1482     static EN_POWER_MODE _prev_u16PowerState = E_POWER_MECHANICAL;
1483     MS_U16 u16Return = FALSE;
1484 
1485     if (u16PowerState == E_POWER_SUSPEND)
1486     {
1487         _prev_u16PowerState = u16PowerState;
1488         u16Return = 2;//SUSPEND_OK;
1489     }
1490     else if (u16PowerState == E_POWER_RESUME)
1491     {
1492         if (_prev_u16PowerState == E_POWER_SUSPEND)
1493         {
1494             MApi_SWI2C_Init(g_SWI2CCBusCfg,g_u8CfgBusNum);
1495             _prev_u16PowerState = u16PowerState;
1496             u16Return = 1;//RESUME_OK;
1497         }
1498         else
1499         {
1500             SWI2C_DBG_INFO("[%s,%5d]It is not suspended yet. We shouldn't resume\n",__FUNCTION__,__LINE__);
1501             u16Return = 3;//SUSPEND_FAILED;
1502         }
1503     }
1504     else
1505     {
1506         SWI2C_DBG_INFO("[%s,%5d]Do Nothing: %d\n",__FUNCTION__,__LINE__,u16PowerState);
1507         u16Return = FALSE;
1508     }
1509     return u16Return;// for success
1510 }
1511 
1512 #undef _API_SWI2C_C_
1513 
1514