xref: /utopia/UTPA2-700.0.x/modules/ir/drv/ir/drvIR.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) 2008-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 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    drvIR.c
98 /// @brief  IR Driver Interface
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 //-------------------------------------------------------------------------------------------------
103 //  Include Files
104 //-------------------------------------------------------------------------------------------------
105 #include <string.h>
106 #include "MsCommon.h"
107 #include "MsVersion.h"
108 #include "utopia_dapi.h"
109 #include "utopia.h"
110 #include "MsOS.h"
111 #include "drvMBX.h"
112 #include "drvIR.h"
113 #include "ULog.h"
114 
115 //-------------------------------------------------------------------------------------------------
116 //  Driver Compiler Options
117 //-------------------------------------------------------------------------------------------------
118 
119 //-------------------------------------------------------------------------------------------------
120 //  Local Defines
121 //-------------------------------------------------------------------------------------------------
122 #define IR_MBX_QUEUESIZE        8
123 #define IR_MBX_TIMEOUT          5000
124 #define TAG_IR "IR"
125 
126 //-------------------------------------------------------------------------------------------------
127 //  Local Structurs
128 //-------------------------------------------------------------------------------------------------
129 typedef struct
130 {
131     MS_U8 u8Reserved[16]; //Dummy Write for flushing MIU FIFO
132 
133 }IR_Dummy;
134 
135 
136 //-------------------------------------------------------------------------------------------------
137 //  Global Variables
138 //-------------------------------------------------------------------------------------------------
139 
140 //-------------------------------------------------------------------------------------------------
141 //  Local Variables
142 //-------------------------------------------------------------------------------------------------
143 static IR_DbgLvl _gIRDbgLevel = E_IR_DBGLVL_ERROR;
144 
145 static MSIF_Version _drv_ir_version = {
146     .DDI = { IR_DRV_VERSION },
147 };
148 
149 static MS_BOOL gbIRInitialized = FALSE;
150 static IR_AckFlags gIRAckFlags;
151 static MS_U8 gu8IRKey;
152 static MS_U8 gu8IRRepeat;
153 static MS_U8 gu8IRStatus;
154 static IR_Callback gfIRCallback = NULL;
155 static IR_Result gIRResult;
156 static MBX_Result gMBXResult;
157 #ifdef MSOS_TYPE_LINUX
158 static IR_DrvInfo* pIRDrvInfo;
159 #else
160 static IR_DrvInfo gIRDrvInfo;
161 #endif
162 //for Fast boot
163 IR_RegCfg g_IRCfg_Fast;
164 
165 
166 //-------------------------------------------------------------------------------------------------
167 //  Debug Functions
168 //-------------------------------------------------------------------------------------------------
169 #define IR_DBG_FUNC()               if (_gIRDbgLevel >= E_IR_DBGLVL_ALL) \
170                                         {MS_DEBUG_MSG(ULOGD(TAG_IR, "\t====   %s   ====\n", __FUNCTION__));}
171 #define IR_DBG_INFO(x, args...)     if (_gIRDbgLevel >= E_IR_DBGLVL_INFO ) \
172                                         {MS_DEBUG_MSG(ULOGI(TAG_IR, "[%s]: ", __FUNCTION__); ULOGI(TAG_IR, x, ##args));}
173 #define IR_DBG_ERR(x, args...)      if (_gIRDbgLevel >= E_IR_DBGLVL_ERROR) \
174                                         {MS_DEBUG_MSG(ULOGE(TAG_IR, "[%s]: ", __FUNCTION__); ULOGE(TAG_IR, x, ##args);)}
175 #define IR_DBG_WARN(x, args...)     if (_gIRDbgLevel >= E_IR_DBGLVL_WARNING) \
176                                         {MS_DEBUG_MSG(ULOGW(TAG_IR, "[%s]: ", __FUNCTION__); ULOGW(TAG_IR, x, ##args);)}
177 
178 #define IR_MUTEX_LOCK()
179 #define IR_MUTEX_UNLOCK()
180 #define IR_MUTEX_DELETE()
181 
182 
183 //-------------------------------------------------------------------------------------------------
184 //  Local Functions
185 //-------------------------------------------------------------------------------------------------
186 //it is called by PM51 side MailBox driver(MailBox ISR)
_IR_MailBoxCallbackHandler(MBX_Msg * pMsg,MS_BOOL * pbAddToQueue)187 static void _IR_MailBoxCallbackHandler( MBX_Msg *pMsg, MS_BOOL *pbAddToQueue)
188 {
189     IR_DBG_FUNC();
190 
191     *pbAddToQueue = FALSE; //no need to add to queue
192 
193     if(!pMsg) return;
194 
195     if(pMsg->u8MsgClass != E_MBX_CLASS_IRKEY_NOWAIT)
196     {
197         IR_DBG_INFO("Invalid Message Class!\n");
198         return;
199     }
200 
201     // check control type
202     if ((pMsg->u8Ctrl != 4) && (pMsg->u8Ctrl != 5))
203     {
204         gIRResult = E_IR_FAIL;
205         IR_DBG_INFO("Control: 0x%02x\n", pMsg->u8Ctrl);
206         IR_DBG_ERR("Not Implemented!\n");
207         return;
208     }
209     IR_DBG_INFO("Get IR command: 0x%02x\n", pMsg->u8Index);
210     IR_DBG_INFO("Parameter[0]=%d\n",  pMsg->u8Parameters[0]);
211     IR_DBG_INFO("Parameter[1]=%d\n",  pMsg->u8Parameters[1]);
212     gIRResult = E_IR_FAIL;
213 
214     if (pMsg->u8Index == E_IR_51ToCPU_CMD_KEYCODE)
215     {
216         gIRResult = E_IR_OK;
217         gu8IRKey = (MS_U8)pMsg->u8Parameters[0];
218         gu8IRRepeat = (MS_U8)pMsg->u8Parameters[1];
219         IR_DBG_INFO("Notify => (key=0x%02x, repeat=0x%02x)\n", gu8IRKey,gu8IRRepeat);
220         if(gfIRCallback)
221         {
222             gfIRCallback(gu8IRKey, gu8IRRepeat);
223         }
224     }
225 
226     return;
227 }
228 
_IR_MailBoxHandler(MBX_Class eMsgClass,MBX_MSGQ_Status * pMsgQueueStatus)229 static void _IR_MailBoxHandler(MBX_Class eMsgClass, MBX_MSGQ_Status *pMsgQueueStatus)
230 {
231     MBX_Msg MB_Command;
232 
233     IR_DBG_FUNC();
234 
235     if(eMsgClass != E_MBX_CLASS_IRKEY)
236     {
237         IR_DBG_INFO("Invalid Message Class!\n");
238         return;
239     }
240 
241     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
242     gMBXResult = MDrv_MBX_RecvMsg(eMsgClass, &MB_Command, IR_MBX_TIMEOUT/*ms*/, MBX_CHECK_NORMAL_MSG);
243     if (gMBXResult == E_MBX_ERR_TIME_OUT)
244     {
245         IR_DBG_INFO("Handler Timeout!\n");
246         return;
247     }
248 
249     if (gMBXResult == E_MBX_SUCCESS)
250     {
251         if ((MB_Command.u8Ctrl != 0) && (MB_Command.u8Ctrl != 1))
252         {
253             gIRResult = E_IR_FAIL;
254             IR_DBG_ERR("Not Implemented!\n");
255             return;
256         }
257         IR_DBG_INFO("Get IR command: 0x%02x.\n", MB_Command.u8Index);
258         IR_DBG_INFO("Parameter[0]=%d\n",  MB_Command.u8Parameters[0]);
259         gIRResult = E_IR_FAIL;
260         switch (MB_Command.u8Index)
261         {
262             case E_IR_51ToCPU_CMD_ACK_INIT:
263                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
264                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_INIT);
265                 break;
266             case E_IR_51ToCPU_CMD_ACK_CONFIG:
267                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
268                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_CONFIG);
269                 break;
270             case E_IR_51ToCPU_CMD_ACK_KEYCODE:
271                 gIRResult = E_IR_OK;
272                 gu8IRKey = MB_Command.u8Parameters[0];
273                 gu8IRRepeat = MB_Command.u8Parameters[1];
274                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_KEYCODE);
275                 break;
276             case E_IR_51ToCPU_CMD_ACK_SETCLBK:
277                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
278                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_SETCLBK);
279                 break;
280             case E_IR_51ToCPU_CMD_ACK_LIBVER:
281                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
282                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_LIBVER);
283                 break;
284             case E_IR_51ToCPU_CMD_ACK_STATUS:
285                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
286                 gu8IRStatus = MB_Command.u8Parameters[1];
287                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_STATUS);
288                 break;
289             case E_IR_51ToCPU_CMD_ACK_ENABLE:
290                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
291                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_ENABLE);
292                 break;
293             case E_IR_51ToCPU_CMD_ACK_INFO:
294                 gIRResult = (IR_Result)MB_Command.u8Parameters[0];
295                 gIRAckFlags &= (IR_AckFlags)(~E_IR_ACKFLG_WAIT_INFO);
296                 break;
297             default:
298                 break;
299         }
300 
301     }
302 
303     return;
304 }
305 
306 //Software patch to flush MIU FIFO data to DRAM
_MDrv_IR_DummyMiuFifo(void)307 static void _MDrv_IR_DummyMiuFifo(void)
308 {
309     static IR_Dummy IrDummy;
310     MS_U8 u8Idx;
311     int count=0;
312 
313     for(u8Idx = 0; u8Idx<16; u8Idx++)
314     {
315         IrDummy.u8Reserved[u8Idx] = u8Idx;
316         //Coverity Fixed
317         if( IrDummy.u8Reserved[u8Idx] < 8)
318         {
319             count++;
320         }
321         else
322         {
323             count--;
324         }
325     }
326     MsOS_FlushMemory();
327 }
328 
329 //-------------------------------------------------------------------------------------------------
330 //  Global Functions
331 //-------------------------------------------------------------------------------------------------
332 
333 //-------------------------------------------------------------------------------------------------
334 /// IR Iinitialized function before using IR to receive keys.
335 /// @param pIRRegCfg \b IN: pointer to IR configuration structure
336 /// @return E_IR_OK: Success
337 /// @return E_IR_FAIL or other values: Failure
338 //-------------------------------------------------------------------------------------------------
MDrv_IR_Init(IR_RegCfg * pIRRegCfg)339 IR_Result MDrv_IR_Init(IR_RegCfg *pIRRegCfg)
340 {
341     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
342     MBX_Msg MB_Command;
343     MBX_MSGQ_Status MbxMsgQStatus;
344     MS_PHYADDR u32SrcAddr;
345     MS_U32 MBX_Resendcnt=0;
346 
347     IR_DBG_FUNC();
348     //flush MIU FIFO
349     _MDrv_IR_DummyMiuFifo();
350     //(0) register handler callback in MBX
351     gbIRInitialized = FALSE;
352     MbxResult = MDrv_MBX_RegisterMSGWithCallBack(E_MBX_CLASS_IRKEY_NOWAIT,IR_MBX_QUEUESIZE,_IR_MailBoxCallbackHandler);
353     if(MbxResult!=E_MBX_SUCCESS)
354     {
355     	if (MbxResult == E_MBX_ERR_SLOT_AREADY_OPENNED)
356     	{
357             IR_DBG_WARN("Mailbox has been registered, classNumber=%d !\n", E_MBX_CLASS_IRKEY_NOWAIT);
358     	}
359     	else
360     	{
361             IR_DBG_ERR("Mailbox registered with callback fails!\n");
362             return E_IR_FAIL;
363         }
364     }
365     MbxResult = MDrv_MBX_RegisterMSG(E_MBX_CLASS_IRKEY,IR_MBX_QUEUESIZE);
366     if(MbxResult!=E_MBX_SUCCESS)
367     {
368     	if (MbxResult == E_MBX_ERR_SLOT_AREADY_OPENNED)
369     	{
370             IR_DBG_WARN("Mailbox has been registered, classNumber=%d !\n", E_MBX_CLASS_IRKEY);
371     	}
372     	else
373     	{
374             IR_DBG_ERR("Mailbox registered fails!\n");
375             return E_IR_FAIL;
376         }
377     }
378 
379     //(1) set address to get final result
380     u32SrcAddr = (MS_PHYADDR)pIRRegCfg;
381     #ifdef MSOS_TYPE_LINUX
382     //backup physical address
383     pIRDrvInfo = (IR_DrvInfo*)pIRRegCfg;
384     #endif
385 
386     //(2) send msg to CPU to get keycode if interrupt happens
387     // set flag
388     gIRAckFlags |= E_IR_ACKFLG_WAIT_INIT;
389     // send to PM51
390     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
391     MB_Command.eRoleID = E_MBX_ROLE_PM;
392     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
393     MB_Command.u8Ctrl = 0;
394     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
395     MB_Command.u8Index = E_IR_CPUTo51_CMD_INIT;
396     MB_Command.u8ParameterCount = 4;
397     MB_Command.u8Parameters[0] = (MS_S8)(u32SrcAddr>>24);
398     MB_Command.u8Parameters[1] = (MS_S8)(u32SrcAddr>>16);
399     MB_Command.u8Parameters[2] = (MS_S8)(u32SrcAddr>>8);
400     MB_Command.u8Parameters[3] = (MS_S8)(u32SrcAddr&0x000000FFUL);
401     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
402     while(E_MBX_SUCCESS != MbxResult)
403     {
404         //Error Handling here:
405         return E_IR_FAIL;
406     }
407 
408     //(3) Waiting for IR message done
409     do
410     {
411        if(MBX_Resendcnt<10)
412        {
413         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
414         MBX_Resendcnt++;
415        }
416        else
417        {
418           MBX_Resendcnt=0;
419           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
420           while(E_MBX_SUCCESS != MbxResult)
421           {
422             //Error Handling here:
423             return E_IR_FAIL;
424           }
425        }
426 
427     }
428     while((gIRAckFlags & E_IR_ACKFLG_WAIT_INIT) && (gMBXResult != E_MBX_ERR_TIME_OUT));
429 
430     //(4) check result
431     if(gIRResult == E_IR_FAIL)
432     {
433         IR_DBG_ERR("Fail\n");
434     }
435     else
436     {
437         gbIRInitialized = TRUE;
438         IR_DBG_INFO("OK\n");
439     }
440 
441     return gIRResult;
442 }
443 
444 //-------------------------------------------------------------------------------------------------
445 /// IR parameter configuration function.
446 /// @param pIRRegCfg \b IN: pointer to the IR configuration structure.
447 /// @return E_IR_OK: Success
448 /// @return E_IR_FAIL or other values: Failure
449 //-------------------------------------------------------------------------------------------------
MDrv_IR_Config(IR_TimeBnd * pIRTimeBnd)450 IR_Result MDrv_IR_Config(IR_TimeBnd *pIRTimeBnd)
451 {
452     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
453     MBX_Msg MB_Command;
454     MBX_MSGQ_Status MbxMsgQStatus;
455     MS_PHYADDR u32SrcAddr;
456     MS_U32 MBX_Resendcnt=0;
457 
458     IR_DBG_FUNC();
459 
460     //(0) check IR driver is initialized
461     //flush MIU FIFO
462     _MDrv_IR_DummyMiuFifo();
463     //check IR is initialized
464     if(gbIRInitialized==FALSE)
465     {
466         IR_DBG_ERR("Not initialized!\n");
467         return E_IR_FAIL;
468     }
469 
470     //(1) set address to get final result
471     u32SrcAddr = (MS_PHYADDR)pIRTimeBnd;
472 
473     //(2) send msg to CPU to get keycode if interrupt happens
474     // set flag
475     gIRAckFlags |= E_IR_ACKFLG_WAIT_CONFIG;
476     // send to PM51
477     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
478     MB_Command.eRoleID = E_MBX_ROLE_PM;
479     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
480     MB_Command.u8Ctrl = 0;
481     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
482     MB_Command.u8Index = E_IR_CPUTo51_CMD_CONFIG;
483     MB_Command.u8ParameterCount = 4;
484     MB_Command.u8Parameters[0] = (MS_S8)(u32SrcAddr>>24);
485     MB_Command.u8Parameters[1] = (MS_S8)(u32SrcAddr>>16);
486     MB_Command.u8Parameters[2] = (MS_S8)(u32SrcAddr>>8);
487     MB_Command.u8Parameters[3] = (MS_S8)(u32SrcAddr&0x000000FFUL);
488     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
489     while(E_MBX_SUCCESS != MbxResult)
490     {
491         //Error Handling here:
492         return E_IR_FAIL;
493     }
494 
495     //(3) Waiting for IR message done
496     do
497     {
498         if(MBX_Resendcnt<10)
499        {
500         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
501         MBX_Resendcnt++;
502        }
503        else
504        {
505           MBX_Resendcnt=0;
506           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
507           while(E_MBX_SUCCESS != MbxResult)
508           {
509             //Error Handling here:
510             return E_IR_FAIL;
511           }
512        }
513     }
514     while((gIRAckFlags & E_IR_ACKFLG_WAIT_CONFIG) && (gMBXResult != E_MBX_ERR_TIME_OUT));
515 
516     //(4) check result
517     if(gIRResult == E_IR_FAIL)
518     {
519         IR_DBG_ERR("Fail\n");
520     }
521     else
522     {
523         IR_DBG_INFO("OK\n");
524     }
525     return gIRResult;
526 }
527 
528 //-------------------------------------------------------------------------------------------------
529 /// IR get key code function.
530 /// @param pu8Key \b OUT: Get IR key code
531 /// @param pu8Repeat \b OUT: Get IR key repeat status
532 /// @return E_IR_OK: Success
533 /// @return E_IR_FAIL or other values: Failure
534 //-------------------------------------------------------------------------------------------------
MDrv_IR_GetKeyCode(MS_U8 * pu8Key,MS_U8 * pu8Repeat)535 IR_Result MDrv_IR_GetKeyCode(MS_U8 *pu8Key, MS_U8 *pu8Repeat)
536 {
537     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
538     MBX_Msg MB_Command;
539     MBX_MSGQ_Status MbxMsgQStatus;
540     MS_U32 MBX_Resendcnt=0;
541 
542     IR_DBG_FUNC();
543 
544     //(0) check IR driver is initialized
545     *pu8Key = IR_DUMMY_KEY;
546     *pu8Repeat = FALSE;
547     //flush MIU FIFO
548     _MDrv_IR_DummyMiuFifo();
549     //check IR is initialized
550     if(gbIRInitialized==FALSE)
551     {
552         IR_DBG_ERR("Not initialized!\n");
553         return E_IR_FAIL;
554     }
555 
556     //(1) send msg to CPU to get keycode if interrupt happens
557     // set flag
558     gIRAckFlags |= E_IR_ACKFLG_WAIT_KEYCODE;
559     // send to PM51
560     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
561     MB_Command.eRoleID = E_MBX_ROLE_PM;
562     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
563     MB_Command.u8Ctrl = 0;
564     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
565     MB_Command.u8Index = E_IR_CPUTo51_CMD_KEYCODE;
566     MB_Command.u8ParameterCount = 0;
567     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
568     while(E_MBX_SUCCESS != MbxResult)
569     {
570         //Error Handling here:
571         return E_IR_FAIL;
572     }
573 
574     //(2) Waiting for IR message done
575     do
576     {
577         if(MBX_Resendcnt<10)
578        {
579         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
580         MBX_Resendcnt++;
581        }
582        else
583        {
584           MBX_Resendcnt=0;
585           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
586           while(E_MBX_SUCCESS != MbxResult)
587           {
588             //Error Handling here:
589             return E_IR_FAIL;
590           }
591        }
592     }
593     while((gIRAckFlags & E_IR_ACKFLG_WAIT_KEYCODE) && (gMBXResult != E_MBX_ERR_TIME_OUT));
594 
595     //(3) check result and get key
596     if(gIRResult == E_IR_FAIL)
597     {
598         IR_DBG_ERR("Fail\n");
599     }
600     else
601     {
602         *pu8Key = gu8IRKey;
603         *pu8Repeat = gu8IRRepeat;
604         IR_DBG_INFO("OK\n");
605     }
606     return gIRResult;
607 }
608 
609 //-------------------------------------------------------------------------------------------------
610 /// Set IR callback function when receive IR key. Support only one callback. If call it twice,
611 /// the first callback does not be called.
612 /// Note: The callback runs at interrupt mode.
613 /// @param pCallback \b IN: Set the callback function when generate IR interrupt.
614 /// @return E_IR_OK: Success
615 /// @return E_IR_FAIL or other values: Failure
616 //-------------------------------------------------------------------------------------------------
MDrv_IR_SetCallback(IR_Callback pCallback)617 IR_Result MDrv_IR_SetCallback(IR_Callback pCallback)
618 {
619     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
620     MBX_Msg MB_Command;
621     MBX_MSGQ_Status MbxMsgQStatus;
622     MS_U32 MBX_Resendcnt=0;
623 
624     IR_DBG_FUNC();
625 
626     //(0) check IR driver is initialized
627     //flush MIU FIFO
628     _MDrv_IR_DummyMiuFifo();
629     //check IR is initialized
630     if(gbIRInitialized==FALSE)
631     {
632         IR_DBG_ERR("Not initialized!\n");
633         return E_IR_FAIL;
634     }
635 
636     //(1) set local callback
637     gfIRCallback = pCallback;
638 
639     //(2) send msg to CPU to get keycode if interrupt happens
640     // set flag
641     gIRAckFlags |= E_IR_ACKFLG_WAIT_SETCLBK;
642     // send to PM51
643     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
644     MB_Command.eRoleID = E_MBX_ROLE_PM;
645     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
646     MB_Command.u8Ctrl = 0;
647     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
648     MB_Command.u8Index = E_IR_CPUTo51_CMD_SETCLBK;
649     MB_Command.u8ParameterCount = 0;
650     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
651     while(E_MBX_SUCCESS != MbxResult)
652     {
653         //Error Handling here:
654         return E_IR_FAIL;
655     }
656 
657     //(3) Waiting for IR message done
658     do
659     {
660        if(MBX_Resendcnt<10)
661        {
662         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
663         MBX_Resendcnt++;
664        }
665        else
666        {
667           MBX_Resendcnt=0;
668           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
669           while(E_MBX_SUCCESS != MbxResult)
670           {
671             //Error Handling here:
672             return E_IR_FAIL;
673           }
674        }
675     }
676     while((gIRAckFlags & E_IR_ACKFLG_WAIT_SETCLBK) && (gMBXResult != E_MBX_ERR_TIME_OUT));
677 
678     //(4) check result
679     if(gIRResult == E_IR_FAIL)
680     {
681         IR_DBG_ERR("Fail\n");
682     }
683     else
684     {
685         IR_DBG_INFO("OK\n");
686     }
687     return gIRResult;
688 }
689 
690 //-------------------------------------------------------------------------------------------------
691 /// Get IR callback function which receive IR key.
692 /// @return the callback function when generate IR interrupt
693 //-------------------------------------------------------------------------------------------------
MDrv_IR_GetCallback(void)694 IR_Callback MDrv_IR_GetCallback(void)
695 {
696     IR_DBG_FUNC();
697 
698     return gfIRCallback;
699 }
700 
701 //-------------------------------------------------------------------------------------------------
702 /// Get IR library version function.
703 /// @param ppVersion \b OUT: pointer to library structure
704 /// @return E_IR_OK: Success
705 /// @return E_IR_FAIL or other values: Failure
706 //-------------------------------------------------------------------------------------------------
MDrv_IR_GetLibVer(const MSIF_Version ** ppVersion)707 IR_Result MDrv_IR_GetLibVer(const MSIF_Version **ppVersion)
708 {
709     if (!ppVersion)
710     {
711         IR_DBG_ERR("Fail\n");
712         return E_IR_FAIL;
713     }
714     *ppVersion = &_drv_ir_version;
715     IR_DBG_INFO("OK\n");
716     return E_IR_OK;
717 }
718 
719 //-------------------------------------------------------------------------------------------------
720 /// Get IR status function.
721 /// @param pu8IRStatus \b OUT: pointer to status structure
722 /// @return E_IR_OK: Success
723 /// @return E_IR_FAIL or other values: Failure
724 //-------------------------------------------------------------------------------------------------
MDrv_IR_GetStatus(MS_U8 * pu8IRStatus)725 IR_Result MDrv_IR_GetStatus(MS_U8 *pu8IRStatus)
726 {
727     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
728     MBX_Msg MB_Command;
729     MBX_MSGQ_Status MbxMsgQStatus;
730     MS_U32 MBX_Resendcnt=0;
731 
732     IR_DBG_FUNC();
733 
734     //(0) check IR driver is initialized
735     *pu8IRStatus = IR_DUMMY_STATUS;
736     //flush MIU FIFO
737     _MDrv_IR_DummyMiuFifo();
738     //check IR is initialized
739     if(gbIRInitialized==FALSE)
740     {
741         IR_DBG_ERR("Not initialized!\n");
742         return E_IR_FAIL;
743     }
744 
745     //(1) send msg to CPU to get keycode if interrupt happens
746     // set flag
747     gIRAckFlags |= E_IR_ACKFLG_WAIT_STATUS;
748     // send to PM51
749     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
750     MB_Command.eRoleID = E_MBX_ROLE_PM;
751     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
752     MB_Command.u8Ctrl = 0;
753     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
754     MB_Command.u8Index = E_IR_CPUTo51_CMD_STATUS;
755     MB_Command.u8ParameterCount = 0;
756     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
757     while(E_MBX_SUCCESS != MbxResult)
758     {
759         //Error Handling here:
760         return E_IR_FAIL;
761     }
762 
763     //(2) Waiting for IR message done
764     do
765     {
766         if(MBX_Resendcnt<10)
767        {
768         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
769         MBX_Resendcnt++;
770        }
771        else
772        {
773           MBX_Resendcnt=0;
774           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
775           while(E_MBX_SUCCESS != MbxResult)
776           {
777             //Error Handling here:
778             return E_IR_FAIL;
779           }
780        }
781     }
782     while((gIRAckFlags & E_IR_ACKFLG_WAIT_STATUS) && (gMBXResult != E_MBX_ERR_TIME_OUT));
783 
784     if(gIRResult == E_IR_FAIL)
785     {
786         IR_DBG_ERR("Fail\n");
787     }
788     else
789     {
790         *pu8IRStatus = gu8IRStatus;
791         IR_DBG_INFO("OK\n");
792     }
793     return gIRResult;
794 }
795 
796 //-------------------------------------------------------------------------------------------------
797 /// Set IR enable function.
798 /// @param bEnable \b IN: TRUE: enable IR, FALSE: disable IR
799 /// @return E_IR_OK: Success
800 /// @return E_IR_FAIL or other values: Failure
801 //-------------------------------------------------------------------------------------------------
MDrv_IR_Enable(MS_BOOL bEnable)802 IR_Result MDrv_IR_Enable(MS_BOOL bEnable)
803 {
804     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
805     MBX_Msg MB_Command;
806     MBX_MSGQ_Status MbxMsgQStatus;
807     MS_U32 MBX_Resendcnt=0;
808 
809     IR_DBG_FUNC();
810 
811     //(0) check IR driver is initialized
812     //flush MIU FIFO
813     _MDrv_IR_DummyMiuFifo();
814     //check IR is initialized
815     if(gbIRInitialized==FALSE)
816     {
817         IR_DBG_ERR("Not initialized!\n");
818         return E_IR_FAIL;
819     }
820 
821     //(1) send msg to CPU to get keycode if interrupt happens
822     // set flag
823     gIRAckFlags |= E_IR_ACKFLG_WAIT_ENABLE;
824     // send to PM51
825     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
826     MB_Command.eRoleID = E_MBX_ROLE_PM;
827     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
828     MB_Command.u8Ctrl = 0;
829     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
830     MB_Command.u8Index = E_IR_CPUTo51_CMD_ENABLE;
831     MB_Command.u8ParameterCount = 1;
832     MB_Command.u8Parameters[0] = (MS_S8)bEnable;
833     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
834     while(E_MBX_SUCCESS != MbxResult)
835     {
836         //Error Handling here:
837         return E_IR_FAIL;
838     }
839 
840     //(2) Waiting for IR message done
841     do
842     {
843         if(MBX_Resendcnt<10)
844        {
845         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
846         MBX_Resendcnt++;
847        }
848        else
849        {
850           MBX_Resendcnt=0;
851           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
852           while(E_MBX_SUCCESS != MbxResult)
853           {
854             //Error Handling here:
855             return E_IR_FAIL;
856           }
857        }
858     }
859     while((gIRAckFlags & E_IR_ACKFLG_WAIT_ENABLE) && (gMBXResult != E_MBX_ERR_TIME_OUT));
860 
861     if(gIRResult == E_IR_FAIL)
862     {
863         IR_DBG_ERR("Fail\n");
864     }
865     else
866     {
867         IR_DBG_INFO("OK\n");
868     }
869     return gIRResult;
870 }
871 
872 //-------------------------------------------------------------------------------------------------
873 /// Get IR driver information function.
874 /// @return @ref IR_DrvInfo structure
875 //-------------------------------------------------------------------------------------------------
MDrv_IR_GetInfo(void)876 const IR_DrvInfo* MDrv_IR_GetInfo(void)
877 {
878     MBX_Result MbxResult=E_MBX_UNKNOW_ERROR;
879     MBX_Msg MB_Command;
880     MBX_MSGQ_Status MbxMsgQStatus;
881     MS_PHYADDR u32SrcAddr;
882     MS_U32 MBX_Resendcnt=0;
883 
884     IR_DBG_FUNC();
885 
886     //(0) check IR driver is initialized
887     //flush MIU FIFO
888     _MDrv_IR_DummyMiuFifo();
889     //check IR is initialized
890     if(gbIRInitialized==FALSE)
891     {
892         IR_DBG_ERR("Not initialized!\n");
893         return (IR_DrvInfo*)NULL;
894     }
895 
896     //(1) set address to get final result
897     #ifdef MSOS_TYPE_LINUX
898     u32SrcAddr = (MS_PHYADDR)pIRDrvInfo;
899     #else
900     u32SrcAddr = (MS_PHYADDR)&gIRDrvInfo;
901     #endif
902     IR_DBG_INFO("u32SrcAddr = 0x%08lX\n", u32SrcAddr);
903 
904     //(2) send msg to CPU to get keycode if interrupt happens
905     // set flag
906     gIRAckFlags |= E_IR_ACKFLG_WAIT_INFO;
907     // send to PM51
908     memset((void*)&MB_Command, 0, sizeof(MBX_Msg));
909     MB_Command.eRoleID = E_MBX_ROLE_PM;
910     MB_Command.eMsgType = E_MBX_MSG_TYPE_INSTANT;
911     MB_Command.u8Ctrl = 0;
912     MB_Command.u8MsgClass = E_MBX_CLASS_IRKEY_NOWAIT;
913     MB_Command.u8Index = E_IR_CPUTo51_CMD_INFO;
914     MB_Command.u8ParameterCount = 4;
915     MB_Command.u8Parameters[0] = (MS_S8)(u32SrcAddr>>24);
916     MB_Command.u8Parameters[1] = (MS_S8)(u32SrcAddr>>16);
917     MB_Command.u8Parameters[2] = (MS_S8)(u32SrcAddr>>8);
918     MB_Command.u8Parameters[3] = (MS_S8)(u32SrcAddr&0x000000FFUL);
919     MbxResult = MDrv_MBX_SendMsg(&MB_Command);
920     while(E_MBX_SUCCESS != MbxResult)
921     {
922         //Error Handling here:
923         return (IR_DrvInfo*)NULL;
924     }
925 
926     //(3) Waiting for IR message done
927     do
928     {
929         if(MBX_Resendcnt<10)
930        {
931         _IR_MailBoxHandler(E_MBX_CLASS_IRKEY,&MbxMsgQStatus);
932         MBX_Resendcnt++;
933        }
934        else
935        {
936           MBX_Resendcnt=0;
937           MbxResult = MDrv_MBX_SendMsg(&MB_Command);
938           while(E_MBX_SUCCESS != MbxResult)
939           {
940             //Error Handling here:
941             return (IR_DrvInfo*)NULL;
942           }
943        }
944     }
945     while((gIRAckFlags & E_IR_ACKFLG_WAIT_INFO) && (gMBXResult != E_MBX_ERR_TIME_OUT));
946 
947     //(4) check result
948     if(gIRResult == E_IR_FAIL)
949     {
950         IR_DBG_ERR("Fail\n");
951     }
952     else
953     {
954         IR_DBG_INFO("OK\n");
955     }
956     #ifdef MSOS_TYPE_LINUX
957     return pIRDrvInfo;
958     #else
959     return &gIRDrvInfo;
960     #endif
961 }
962 
963 //-------------------------------------------------------------------------------------------------
964 /// Set IR debug function.
965 /// @param eLevel \b IN: E_IR_DBGLVL_NONE/E_IR_DBGLVL_WARNING/E_IR_DBGLVL_ERROR/E_IR_DBGLVL_INFO/E_IR_DBGLVL_ALL
966 /// @return E_IR_OK: Success
967 /// @return E_IR_FAIL or other values: Failure
968 //-------------------------------------------------------------------------------------------------
MDrv_IR_SetDbgLevel(IR_DbgLvl eLevel)969 IR_Result MDrv_IR_SetDbgLevel(IR_DbgLvl eLevel)
970 {
971     IR_DBG_INFO("Debug level: %u\n", eLevel);
972 
973     _gIRDbgLevel = eLevel;
974     return E_IR_OK;
975 }
976 
977 #ifdef MSOS_TYPE_LINUX
978 #include <unistd.h>
979 #include <fcntl.h>
980 #include <signal.h>
981 #include <sys/ioctl.h>
982 #include <stdio.h>
983 #include <string.h>
984 //#include <asm-mips/types.h>
985 #include <errno.h>
986 
987 #define IR_MODULE_KERNAL_NAME       "/dev/ir"
988 static int IR_fd = 0;
989 
MDrv_IR_OpenDevice(void)990 void MDrv_IR_OpenDevice(void)
991 {
992     if (IR_fd==0)   //First time open
993     {
994         IR_fd = open(IR_MODULE_KERNAL_NAME, O_RDWR);
995         if (IR_fd < 0)
996         {
997             IR_DBG_ERR("Fail to open IR Kernal Module\n");
998         }
999     }
1000 }
1001 
MDrv_IR_InitCfg(IR_InitCfgParam * pInitCfg)1002 void MDrv_IR_InitCfg(IR_InitCfgParam* pInitCfg)
1003 {
1004     IR_InitCfgParam InitCfgParam;
1005     int iResult;
1006 
1007     if (IR_fd < 0)
1008     {
1009         IR_DBG_ERR("IR file descriptor is not been opened\n");
1010     }
1011 
1012     memcpy((void*)&InitCfgParam,(void*)pInitCfg,sizeof(IR_InitCfgParam));
1013     iResult = ioctl(IR_fd, MDRV_IR_INITCFG,&InitCfgParam);
1014     if(iResult < 0)
1015     {
1016         IR_DBG_ERR("IR Initial Configuration Fails!\n");
1017     }
1018 }
1019 
MDrv_IR_TimeCfg(IR_TimeCfgParam * pTimeCfg)1020 void MDrv_IR_TimeCfg(IR_TimeCfgParam* pTimeCfg)
1021 {
1022     IR_TimeCfgParam TimeCfgParam;
1023     int iResult;
1024 
1025     if (IR_fd < 0)
1026     {
1027         IR_DBG_ERR("IR file descriptor is not been opened\n");
1028     }
1029 
1030     memcpy((void*)&TimeCfgParam,(void*)pTimeCfg,sizeof(IR_TimeCfgParam));
1031     iResult = ioctl(IR_fd, MDRV_IR_TIMECFG,&TimeCfgParam);
1032     if(iResult < 0)
1033     {
1034         IR_DBG_ERR("IR Time Configuration Fails!\n");
1035     }
1036 }
1037 
MDrv_IR_GetPulseShot(IR_PulseShotInfo * pPulseShotInfo)1038 void MDrv_IR_GetPulseShot(IR_PulseShotInfo* pPulseShotInfo)
1039 {
1040     int iResult;
1041 
1042     if (IR_fd < 0)
1043     {
1044         IR_DBG_ERR("IR file descriptor is not been opened\n");
1045     }
1046     iResult = ioctl(IR_fd, MDRV_IR_GET_SWSHOT_BUF, pPulseShotInfo);
1047     if(iResult < 0)
1048     {
1049         IR_DBG_ERR("IR Get Pulse Shot Fails!\n");
1050     }
1051 }
1052 
MDrv_IR_SetMultiHeaderCode(MS_MultiIR_HeaderInfo * pMultiHeaderCode)1053 void MDrv_IR_SetMultiHeaderCode(MS_MultiIR_HeaderInfo* pMultiHeaderCode)
1054 {
1055     MS_MultiIR_HeaderInfo MultiHeaderCode;
1056     int iResult;
1057 
1058     if (IR_fd < 0)
1059     {
1060         IR_DBG_ERR("IR file descriptor is not been opened\n");
1061     }
1062 
1063     memcpy((void*)&MultiHeaderCode,(void*)pMultiHeaderCode,sizeof(MS_MultiIR_HeaderInfo));
1064     iResult = ioctl(IR_fd, MDRV_IR_SET_HEADER, &MultiHeaderCode);
1065     if(iResult < 0)
1066     {
1067         IR_DBG_ERR("IR Set Multi-Header Code Fails!\n");
1068     }
1069 }
1070 
1071 #endif
1072 //--------------------------------------------------------------------------------------------------
1073 // Utopia2.0 will call this function to register IR module
1074 //--------------------------------------------------------------------------------------------------
1075 enum
1076 {
1077     IR_POOL_ID_IR0=0
1078 } eIR_PoolID;
1079 
IRRegisterToUtopia(FUtopiaOpen ModuleType)1080 void IRRegisterToUtopia(FUtopiaOpen ModuleType)
1081 {
1082     // 1. create a module(module_name, SHM_size), and register to utopia2.0
1083     void* pUtopiaModule = NULL;
1084     UtopiaModuleCreate(MODULE_IR, 0, &pUtopiaModule);
1085     UtopiaModuleRegister(pUtopiaModule);
1086 
1087     // register func for module, after register here, then ap call UtopiaOpen/UtopiaIoctl/UtopiaClose can call to these registered standard func
1088     UtopiaModuleSetupFunctionPtr(pUtopiaModule, (FUtopiaOpen)IROpen, (FUtopiaClose)IRClose, (FUtopiaIOctl)IRIoctl);
1089 
1090     // 2. Resource register
1091     void* psResource = NULL;
1092 
1093     // start func to add resources of a certain Resource_Pool
1094     UtopiaModuleAddResourceStart(pUtopiaModule, IR_POOL_ID_IR0);
1095 
1096     // create a resouce and regiter it to a certain Resource_Pool, resource can alloc private for internal use
1097     UtopiaResourceCreate("ir0", sizeof(IR_RESOURCE_PRIVATE), &psResource);
1098     UtopiaResourceRegister(pUtopiaModule, psResource, IR_POOL_ID_IR0);
1099 
1100     UtopiaModuleAddResourceEnd(pUtopiaModule, IR_POOL_ID_IR0);
1101 
1102 }
1103 
1104 //--------------------------------------------------------------------------------------------------
1105 // Utopia2.0 will call this function to get a instance to use IR
1106 // @ \b in: 32ModuleVersion => this is for checking if API version is the same
1107 //--------------------------------------------------------------------------------------------------
IROpen(void ** ppInstance,MS_U32 u32ModuleVersion,void * pAttribute)1108 MS_U32 IROpen(void** ppInstance, MS_U32 u32ModuleVersion, void* pAttribute)
1109 {
1110     MS_U32 u32RetShmID, u32RetShmSize;
1111 	MS_VIRT u32RetAddr;
1112     MS_U32 u32Ret;
1113 
1114     //Check DRV_REVISION
1115     if(u32ModuleVersion != IR_VERSION)
1116     {
1117         //ULOGE(TAG_IR, "\033[35mFunction = %s, Line = %d, ERROR, DRV_VERSION is not IR_VERSION\033[m\n", __PRETTY_FUNCTION__, __LINE__);
1118         //return FALSE;
1119     }
1120 
1121     // for multi-process safe, check if already other Instance exist
1122     IR_MUTEX_LOCK();
1123     u32Ret = MsOS_SHM_GetId((MS_U8*)"IR_Instance", sizeof(MS_U32), &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
1124     if(u32Ret == 0)
1125     {
1126         // first create, set value as 0
1127         MsOS_SHM_GetId((MS_U8*)"IR_Instance", sizeof(MS_U32), &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_CREATE);
1128         *(MS_U32 *)u32RetAddr = 0;
1129     }
1130 
1131     if(*(MS_U32 *)u32RetAddr == 1)
1132     {
1133         IR_MUTEX_UNLOCK();
1134         return FALSE;
1135     }
1136     else
1137     {
1138         *(MS_U32 *)u32RetAddr = 1;
1139         IR_MUTEX_UNLOCK();
1140     }
1141 
1142     IR_INSTANT_PRIVATE *pIRPri = NULL;
1143 
1144     // instance is allocated here, also can allocate private for internal use, ex, IR_INSTANT_PRIVATE, ppInstance will point to a pointer of the created UTOPIA_INSTANCE
1145     UtopiaInstanceCreate(sizeof(IR_INSTANT_PRIVATE), ppInstance);
1146     // set the pIRPri point to the private of UTOPIA_INSTANCE
1147     UtopiaInstanceGetPrivate(*ppInstance, (void**)&pIRPri);
1148 
1149 
1150 
1151 	MDrv_IR_Init((IR_RegCfg *)pAttribute);
1152 
1153     return TRUE;
1154 }
1155 
IRIoctl(void * pInstance,MS_U32 u32Cmd,void * pArgs)1156 MS_U32 IRIoctl(void* pInstance, MS_U32 u32Cmd, void* pArgs)
1157 {
1158 	return 0; // FIXME: error code
1159 }
1160 
IRClose(void * pInstance)1161 MS_U32 IRClose(void* pInstance)
1162 {
1163     MS_U32 u32RetShmID, u32RetShmSize;
1164 	MS_VIRT u32RetAddr;
1165     MS_U32 u32Ret;
1166 
1167 	u32RetAddr = 0 ; //fix coverity isue
1168     UtopiaInstanceDelete(pInstance);
1169 
1170     u32Ret = MsOS_SHM_GetId((MS_U8*)"IR_Instance", sizeof(MS_U32), &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
1171 
1172     if( (u32Ret == 0) || (*(MS_U32 *)u32RetAddr == 0) )
1173     {
1174         return FALSE;
1175     }
1176     else
1177     {
1178         IR_MUTEX_LOCK();
1179         *(MS_U32 *)u32RetAddr = 0;
1180         IR_MUTEX_UNLOCK();
1181         return TRUE;
1182     }
1183 }
1184 
1185 
1186 
MDrv_IR_SetPowerState(EN_POWER_MODE u16PowerState)1187 MS_U32 MDrv_IR_SetPowerState(EN_POWER_MODE u16PowerState)
1188 {
1189 	static EN_POWER_MODE _prev_u16PowerState = E_POWER_MECHANICAL;
1190 	MS_U16 u16Return = UTOPIA_STATUS_FAIL;
1191 	IR_RegCfg tmpRegCfg;
1192 
1193 	if (u16PowerState == E_POWER_SUSPEND)
1194 	{
1195 		_prev_u16PowerState = u16PowerState;
1196 		u16Return = UTOPIA_STATUS_SUCCESS;//SUSPEND_OK;
1197 	}
1198 	else if (u16PowerState == E_POWER_RESUME)
1199 	{
1200 
1201 		if (_prev_u16PowerState == E_POWER_SUSPEND)
1202 		{
1203             MDrv_IR_Init(&tmpRegCfg);
1204 
1205 			_prev_u16PowerState = u16PowerState;
1206 			u16Return = UTOPIA_STATUS_SUCCESS;//RESUME_OK;
1207 		}
1208 		else
1209 		{
1210 			ULOGE(TAG_IR, "[%s,%5d]It is not suspended yet. We shouldn't resume\n",__FUNCTION__,__LINE__);
1211 			u16Return = UTOPIA_STATUS_FAIL;//SUSPEND_FAILED;
1212 		}
1213 	}
1214 	else
1215 	{
1216 		ULOGE(TAG_IR, "[%s,%5d]Do Nothing: %d\n",__FUNCTION__,__LINE__,u16PowerState);
1217 		u16Return = UTOPIA_STATUS_FAIL;
1218 	}
1219 
1220 	return u16Return;// for success
1221 }
1222 
1223 
1224 
1225