xref: /utopia/UTPA2-700.0.x/modules/pwm/drv/pwm/drvPWM.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    drvPWM.c
98 /// @brief  Pulse Width Modulation Driver Interface
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 // Include Files
104 ////////////////////////////////////////////////////////////////////////////////
105 #include "MsCommon.h"
106 #ifdef MSOS_TYPE_LINUX_KERNEL
107 #include <linux/string.h>
108 #else
109 #include <string.h>
110 #endif
111 #include "MsVersion.h"
112 #include "drvPWM.h"
113 #include "halPWM.h"
114 #include "drvMMIO.h"
115 #include "MsDevice.h"
116 #include "MsOS.h"
117 #include "drvSEM.h"
118 #include "ULog.h"
119 
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 // Local defines & local structures
123 ////////////////////////////////////////////////////////////////////////////////
124 #define TAG_PWM "PWM"
125 
126 #define PWM_DBG_FUNC()            if (_geDbfLevel >= E_PWM_DBGLV_ALL)                   \
127                                        {MS_DEBUG_MSG(ULOGD(TAG_PWM, "\t====   %s   ====\n", __FUNCTION__));}
128 
129 #define PWM_DBG_INFO(x, args...)  if (_geDbfLevel >= E_PWM_DBGLV_INFO )                 \
130                                        {MS_DEBUG_MSG(ULOGI(TAG_PWM, x, ##args));}
131 
132 #define PWM_DBG_ERR(x, args...)   if (_geDbfLevel >= E_PWM_DBGLV_ERR_ONLY)				\
133                                        {MS_DEBUG_MSG(ULOGE(TAG_PWM, x, ##args));}
134 
135 
136 #define PWM_SEM_LOCK() MDrv_SEM_Lock(E_SEM_PM, SEM_WAIT_FOREVER);
137 #define PWM_SEM_UNLOCK() MDrv_SEM_Unlock(E_SEM_PM);
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 // Local & Global Variables
141 ////////////////////////////////////////////////////////////////////////////////
142 static MS_BOOL  _gbInitPWM = FALSE;
143 static PWM_DbgLv _gbInitPWM_DbgLv = E_PWM_DBGLV_NONE;
144 //static PWM_Arg _gsPWMDesc;
145 static PWM_DbgLv _geDbfLevel = E_PWM_DBGLV_NONE;
146 static MSIF_Version _drv_pwm_version = {
147     .DDI = { PWM_DRV_VERSION },
148 };
149 
150 static MS_BOOL g_Enable_Record[PWM_Num] ={1, 1, 1, 1};
151 static MS_U32 g_Shift_Record[PWM_Num] = {0, 0, 0, 0};
152 static MS_U32 g_Period_Record[PWM_Num] = {0, 0, 0, 0};
153 static MS_U32 g_Duty_Record[PWM_Num] = {0, 0, 0, 0};
154 static MS_BOOL g_Vsync_Record[PWM_Num] ={0, 0, 0, 0};
155 
156 static PWM_DrvStatus   _pwmStatus =
157                         {
158                             .PWM0 = FALSE,
159                             .PWM1 = FALSE,
160                             .PWM2 = FALSE,
161                             .PWM3 = FALSE,
162                             .PWM4 = FALSE,
163                             .PWM5 = FALSE,
164                             .PWM6 = FALSE,
165                             .PWM7 = FALSE,
166                             .PWM8 = FALSE,
167                         };
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 // Local Function
171 ////////////////////////////////////////////////////////////////////////////////
172 static MS_BOOL _PWM_IsInit(void);
173 
174 //-------------------------------------------------------------------------------------------------
175 /// Description: Set debug level for debug message
176 /// @param eLevel    \b debug level for PWM driver
177 /// @return E_PWM_OK : succeed
178 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
179 //-------------------------------------------------------------------------------------------------
MDrv_PWM_SetDbgLevel(PWM_DbgLv eLevel)180 PWM_Result MDrv_PWM_SetDbgLevel(PWM_DbgLv eLevel)
181 {
182     PWM_DBG_INFO("%s(%u)\r\n", __FUNCTION__, eLevel);
183 
184     _geDbfLevel = eLevel;
185 
186     return E_PWM_OK;
187 }
188 
189 //------------------------------------------------------------------------------
190 /// Description : Show the PWM driver version
191 /// @param  ppVersion \b OUT: output PWM driver version
192 /// @return E_PWM_OK : succeed
193 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
194 //------------------------------------------------------------------------------
MDrv_PWM_GetLibVer(const MSIF_Version ** ppVersion)195 PWM_Result MDrv_PWM_GetLibVer(const MSIF_Version **ppVersion)
196 {
197     PWM_DBG_FUNC();
198 
199     if (!ppVersion)
200         return E_PWM_FAIL;
201 
202     *ppVersion = &_drv_pwm_version;
203     return E_PWM_OK;
204 }
205 
206 //------------------------------------------------------------------------------
207 /// Description : Show the PWM_PAD is PWM(True) or GPIO(false)
208 /// @param  pStatus \b OUT: output PWM driver status
209 /// @return E_PWM_OK : succeed
210 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
211 //------------------------------------------------------------------------------
MDrv_PWM_GetStatus(PWM_DrvStatus * pStatus)212 PWM_Result MDrv_PWM_GetStatus(PWM_DrvStatus *pStatus)
213 {
214     memcpy(pStatus, &_pwmStatus, sizeof(PWM_DrvStatus));
215     return E_PWM_OK;
216 }
217 
218 //-------------------------------------------------------------------------------------------------
219 /// Description : Check PWM is initial or not
220 /// @return TRUE : PWM was initied
221 /// @return FALSE : PWM was not initied
222 //-------------------------------------------------------------------------------------------------
_PWM_IsInit(void)223 static MS_BOOL _PWM_IsInit(void)
224 {
225     PWM_DBG_FUNC();
226     if (!_gbInitPWM)
227         PWM_DBG_ERR("Call MDrv_PWM_Init first!\n");
228     return _gbInitPWM;
229 }
230 
231 //-------------------------------------------------------------------------------------------------
232 /// Description: Initial PWM driver
233 /// @param eLevel    \b debug level for PWM driver
234 /// @return E_PWM_OK : succeed
235 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
236 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Init(PWM_DbgLv eLevel)237 PWM_Result MDrv_PWM_Init(PWM_DbgLv eLevel)
238 {
239     MS_VIRT virtBaseAddr = 0;
240     MS_VIRT virtBaseAddr1 = 0;
241     MS_VIRT virtBaseAddr2 = 0;
242     MS_PHY u32BaseSize = 0; /* No use */
243 
244 	_gbInitPWM_DbgLv = eLevel; //store for STD resume
245     MDrv_PWM_SetDbgLevel(eLevel);
246 
247     if(!_gbInitPWM)
248     {
249         if(!MDrv_MMIO_GetBASE(&virtBaseAddr, &u32BaseSize, MS_MODULE_PWM))
250         {
251             PWM_DBG_ERR("Get IOMAP Base faill!\n");
252             return E_PWM_FAIL;
253         }
254 
255         if(!MDrv_MMIO_GetBASE(&virtBaseAddr1, &u32BaseSize, MS_MODULE_CHIPTOP))
256         {
257             PWM_DBG_ERR("Get CHIPTOP Base faill!\n");
258             return E_PWM_FAIL;
259         }
260 
261         if(!MDrv_MMIO_GetBASE(&virtBaseAddr2, &u32BaseSize, MS_MODULE_PM))
262         {
263             PWM_DBG_ERR("Get PM Base faill!\n");
264             return E_PWM_FAIL;
265         }
266         HAL_PWM_SetIOMapBase(virtBaseAddr, virtBaseAddr2);
267         HAL_PWM_SetChipTopIOMapBase(virtBaseAddr1);
268         PWM_DBG_INFO("%s has MMIO base 0x%08X\r\n", __FUNCTION__,  virtBaseAddr);
269         /* Set All pad output and Is PWM. But it still needs to be enable */
270         if( !HAL_PWM_Init() )
271         {
272             PWM_DBG_ERR("PWM Hal Initial Fail\n");
273             return E_PWM_FAIL;
274         }
275 
276         MDrv_SEM_Init(); // for sc4 bank protect
277 
278         _gbInitPWM = TRUE;
279         return E_PWM_OK;
280     }
281     else
282     {
283         PWM_DBG_ERR("PWM has be initiated!\n");
284         return E_PWM_OK;
285     }
286 }
287 
288 //-------------------------------------------------------------------------------------------------
289 /// Description: IOutput enable_bar of PWM pads
290 /// @param u8IndexPWM    \b which pwm is setting
291 /// @param bOenPWM    \b True/False for enable/disable
292 /// @return E_PWM_OK : succeed
293 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
294 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Oen(PWM_ChNum u8IndexPWM,MS_BOOL bOenPWM)295 PWM_Result MDrv_PWM_Oen(PWM_ChNum u8IndexPWM, MS_BOOL bOenPWM)
296 {
297     PWM_Result ret = E_PWM_OK;
298     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bOenPWM);
299 
300     switch(u8IndexPWM)
301     {
302         case E_PWM_CH0:
303             _pwmStatus.PWM0 = TRUE;
304             break;
305         case E_PWM_CH1:
306             _pwmStatus.PWM1 = TRUE;
307             break;
308         case E_PWM_CH2:
309             _pwmStatus.PWM2 = TRUE;
310             break;
311         case E_PWM_CH3:
312             _pwmStatus.PWM3 = TRUE;
313             break;
314         case E_PWM_CH4:
315             _pwmStatus.PWM4 = TRUE;
316             break;
317         case E_PWM_CH5:
318             _pwmStatus.PWM5 = TRUE;
319             break;
320         case E_PWM_CH6:
321             _pwmStatus.PWM6 = TRUE;
322             break;
323         case E_PWM_CH7:
324             _pwmStatus.PWM7 = TRUE;
325             break;
326         case E_PWM_CH8:
327             _pwmStatus.PWM8 = TRUE;
328             break;
329         default:
330             MS_ASSERT(0);
331     }
332 
333     if( !(HAL_PWM_Oen(u8IndexPWM, bOenPWM)||_PWM_IsInit()) )
334     {
335         ret = E_PWM_FAIL;
336     }
337     return ret;
338 }
339 
340 //-------------------------------------------------------------------------------------------------
341 /// Description: Set the period of the specific pwm
342 /// @param u8IndexPWM    \b which pwm is setting
343 /// @param u16PeriodPWM    \b the 18-bit period value
344 /// @return E_PWM_OK : succeed
345 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
346 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Period(PWM_ChNum u8IndexPWM,MS_U32 u32PeriodPWM)347 PWM_Result MDrv_PWM_Period(PWM_ChNum u8IndexPWM, MS_U32 u32PeriodPWM)
348 {
349     PWM_Result ret = E_PWM_FAIL;
350     PWM_DBG_INFO("%s(%u, 0x%08X)\r\n", __FUNCTION__, u8IndexPWM, (int)u32PeriodPWM);
351 
352     PWM_SEM_LOCK();
353     do{
354         HAL_PWM_Period(u8IndexPWM, u32PeriodPWM);
355         ret = E_PWM_OK;
356         if (g_Enable_Record[u8IndexPWM] == 1)
357         {
358             g_Period_Record[u8IndexPWM]  = u32PeriodPWM;
359         }
360 
361     }while(0);
362     PWM_SEM_UNLOCK();
363 
364     return ret;
365 }
366 
367 
MDrv_PWM_GetProperty(PWM_Property eProperty,PWM_ChNum u8IndexPWM,MS_U32 * u32PWMVar)368 PWM_Result MDrv_PWM_GetProperty(PWM_Property eProperty, PWM_ChNum u8IndexPWM, MS_U32 *u32PWMVar)
369 {
370     PWM_SEM_LOCK();
371     switch(eProperty)
372     {
373         case E_PWM_GetPeriod:
374             *u32PWMVar = HAL_PWM_GetPeriod(u8IndexPWM);
375             break;
376         case E_PWM_GetDutyCycle:
377             *u32PWMVar = HAL_PWM_GetDutyCycle(u8IndexPWM);
378             break;
379         case E_PWM_GetShift:
380             *u32PWMVar = HAL_PWM_GetShift(u8IndexPWM);
381             break;
382         case E_PWM_GetDiv:
383             *u32PWMVar = (MS_U32)HAL_PWM_GetDiv(u8IndexPWM);
384             break;
385         case E_PWM_GetPolarity:
386             *u32PWMVar = (MS_U32)HAL_PWM_GetPolarity(u8IndexPWM);
387             break;
388         case E_PWM_GetVdben:
389             *u32PWMVar = (MS_U32)HAL_PWM_GetVDBen(u8IndexPWM);
390             break;
391         case E_PWM_GetRsten:
392             *u32PWMVar = (MS_U32)HAL_PWM_GetVrest(u8IndexPWM);
393             break;
394         case E_PWM_GetDben:
395             *u32PWMVar = (MS_U32)HAL_PWM_GetDBen(u8IndexPWM);
396             break;
397         case E_PWM_GetOen:
398             *u32PWMVar = (MS_U32)HAL_PWM_GetOen(u8IndexPWM);
399             break;
400         default:
401             ULOGE(TAG_PWM, "[Utopia] PWM is not support!!\n");
402             PWM_SEM_UNLOCK();
403             return E_PWM_FAIL;
404     }
405     PWM_SEM_UNLOCK();
406     return E_PWM_OK;
407 }
408 
409 //-------------------------------------------------------------------------------------------------
410 /// Description: Set the Duty of the specific pwm
411 /// @param u8IndexPWM    \b which pwm is setting
412 /// @param u16DutyPWM    \b the 18-bit Duty value
413 /// @return E_PWM_OK : succeed
414 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
415 //-------------------------------------------------------------------------------------------------
MDrv_PWM_DutyCycle(PWM_ChNum u8IndexPWM,MS_U32 u32DutyPWM)416 PWM_Result MDrv_PWM_DutyCycle(PWM_ChNum u8IndexPWM, MS_U32 u32DutyPWM)
417 {
418     PWM_Result ret = E_PWM_FAIL;
419     PWM_DBG_INFO("%s(%u, 0x%08X)\r\n", __FUNCTION__, u8IndexPWM, (int)u32DutyPWM);
420 
421     PWM_SEM_LOCK();
422     do{
423         HAL_PWM_DutyCycle(u8IndexPWM, u32DutyPWM);
424         ret = E_PWM_OK;
425         if (g_Enable_Record[u8IndexPWM] == 1)
426         {
427             g_Duty_Record[u8IndexPWM]  = u32DutyPWM;
428         }
429 
430     }while(0);
431     PWM_SEM_UNLOCK();
432 
433     return ret;
434 }
435 
436 //-------------------------------------------------------------------------------------------------
437 /// Description: Set the Unit_Div of the pwm
438 /// @param u16UnitDivPWM    \b the Unit Div value
439 /// @return E_PWM_OK : succeed
440 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
441 //-------------------------------------------------------------------------------------------------
MDrv_PWM_UnitDiv(MS_U16 u16UnitDivPWM)442 PWM_Result MDrv_PWM_UnitDiv(MS_U16 u16UnitDivPWM)
443 {
444     PWM_Result ret = E_PWM_OK;
445     PWM_DBG_INFO("%s(0x%04X)\r\n", __FUNCTION__, u16UnitDivPWM);
446 
447     PWM_SEM_LOCK();
448     if(!HAL_PWM_UnitDiv(u16UnitDivPWM))
449     {
450         ret = E_PWM_FAIL;
451     }
452     PWM_SEM_UNLOCK();
453     return ret;
454 }
455 
456 //-------------------------------------------------------------------------------------------------
457 /// Description: Set the Div of the specific pwm
458 /// @param u8IndexPWM    \b which pwm is setting
459 /// @param u16DivPWM    \b the 16-bit div value
460 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Div(PWM_ChNum u8IndexPWM,MS_U16 u16DivPWM)461 void MDrv_PWM_Div(PWM_ChNum u8IndexPWM, MS_U16 u16DivPWM)
462 {
463     PWM_SEM_LOCK();
464     PWM_DBG_INFO("%s(%u, 0x%04X)\r\n", __FUNCTION__, u8IndexPWM, u16DivPWM);
465     HAL_PWM_Div(u8IndexPWM, u16DivPWM);
466     PWM_SEM_UNLOCK();
467 }
468 
469 //-------------------------------------------------------------------------------------------------
470 /// Description:  Set the Polarity of the specific pwm
471 /// @param u8IndexPWM    \b which pwm is setting
472 /// @param bPolPWM    \b True/False for Inverse/Non-inverse
473 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Polarity(PWM_ChNum u8IndexPWM,MS_BOOL bPolPWM)474 void MDrv_PWM_Polarity(PWM_ChNum u8IndexPWM, MS_BOOL bPolPWM)
475 {
476     PWM_SEM_LOCK();
477     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bPolPWM);
478     HAL_PWM_Polarity(u8IndexPWM, bPolPWM);
479     PWM_SEM_UNLOCK();
480 }
481 
482 //-------------------------------------------------------------------------------------------------
483 /// Description: Set the Vsync Double buffer of the specific pwm
484 /// @param u8IndexPWM    \b which pwm is setting
485 /// @param bVdbenPWM    \b True/False for Enable/Disable
486 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Vdben(PWM_ChNum u8IndexPWM,MS_BOOL bVdbenPWM)487 void MDrv_PWM_Vdben(PWM_ChNum u8IndexPWM, MS_BOOL bVdbenPWM)
488 {
489     PWM_SEM_LOCK();
490     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bVdbenPWM);
491     HAL_PWM_VDBen(u8IndexPWM, bVdbenPWM);
492     PWM_SEM_UNLOCK();
493 }
494 
495 //-------------------------------------------------------------------------------------------------
496 /// Description: Set the Hsync reset of the specific pwm
497 /// @param u8IndexPWM    \b which pwm is setting
498 /// @param bRstPWM    \b True/False for Enable/Disable
499 //-------------------------------------------------------------------------------------------------
MDrv_PWM_ResetEn(PWM_ChNum u8IndexPWM,MS_BOOL bRstPWM)500 void MDrv_PWM_ResetEn(PWM_ChNum u8IndexPWM, MS_BOOL bRstPWM)
501 {
502     PWM_SEM_LOCK();
503     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bRstPWM);
504     HAL_PWM_Vrest(u8IndexPWM, bRstPWM);
505     if (g_Enable_Record[u8IndexPWM] == 1)
506     {
507         g_Vsync_Record[u8IndexPWM]  = bRstPWM;
508     }
509     PWM_SEM_UNLOCK();
510 }
511 
512 //-------------------------------------------------------------------------------------------------
513 /// Description:  Set the Double buffer of the specific pwm
514 /// @param u8IndexPWM    \b which pwm is setting
515 /// @param bDbenPWM    \b True/False for Enable/Disable
516 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Dben(PWM_ChNum u8IndexPWM,MS_BOOL bDbenPWM)517 void MDrv_PWM_Dben(PWM_ChNum u8IndexPWM, MS_BOOL bDbenPWM)
518 {
519     PWM_SEM_LOCK();
520     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bDbenPWM);
521     HAL_PWM_DBen(u8IndexPWM, bDbenPWM);
522     PWM_SEM_UNLOCK();
523 }
524 
MDrv_PWM_IMPULSE_EN(PWM_ChNum u8IndexPWM,MS_BOOL bdbenPWM)525 void MDrv_PWM_IMPULSE_EN(PWM_ChNum u8IndexPWM, MS_BOOL bdbenPWM)
526 {
527     PWM_SEM_LOCK();
528     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bdbenPWM);
529     HAL_PWM_IMPULSE_EN(u8IndexPWM, bdbenPWM);
530     PWM_SEM_UNLOCK();
531 }
532 
MDrv_PWM_ODDEVEN_SYNC(PWM_ChNum u8IndexPWM,MS_BOOL bdbenPWM)533 void MDrv_PWM_ODDEVEN_SYNC(PWM_ChNum u8IndexPWM, MS_BOOL bdbenPWM)
534 {
535     PWM_SEM_LOCK();
536     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bdbenPWM);
537     HAL_PWM_ODDEVEN_SYNC(u8IndexPWM, bdbenPWM);
538     PWM_SEM_UNLOCK();
539 }
540 
541 //-------------------------------------------------------------------------------------------------
542 /// Description:  Set the Rst Mux of the specific pwm
543 /// @param u8IndexPWM    \b which pwm is setting
544 /// @param bMuxPWM    \b True/False for Enable/Disable
545 //-------------------------------------------------------------------------------------------------
MDrv_PWM_RstMux(PWM_ChNum u8IndexPWM,MS_BOOL bMuxPWM)546 void MDrv_PWM_RstMux(PWM_ChNum u8IndexPWM, MS_BOOL bMuxPWM)
547 {
548     PWM_SEM_LOCK();
549     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bMuxPWM);
550     HAL_PWM_RstMux(u8IndexPWM, bMuxPWM);
551     PWM_SEM_UNLOCK();
552 }
553 
554 //-------------------------------------------------------------------------------------------------
555 /// Description: Set the Rst_Cnt of the specific pwm
556 /// @param u8IndexPWM    \b which pwm is setting
557 /// @param u8RstCntPWM    \b the Rst_Cnt value
558 //-------------------------------------------------------------------------------------------------
MDrv_PWM_RstCnt(PWM_ChNum u8IndexPWM,MS_U8 u8RstCntPWM)559 void MDrv_PWM_RstCnt(PWM_ChNum u8IndexPWM, MS_U8 u8RstCntPWM)
560 {
561     PWM_SEM_LOCK();
562     PWM_DBG_INFO("%s(%u, 0x%02X)\r\n", __FUNCTION__, u8IndexPWM, u8RstCntPWM);
563     HAL_PWM_RstCnt(u8IndexPWM, u8RstCntPWM);
564     PWM_SEM_UNLOCK();
565 }
566 
567 //-------------------------------------------------------------------------------------------------
568 /// Description: Set the Bypass Unit of the specific pwm
569 /// @param u8IndexPWM    \b which pwm is setting
570 /// @param bBypassPWM    \b True/False for Enable/Disable
571 //-------------------------------------------------------------------------------------------------
MDrv_PWM_BypassUnit(PWM_ChNum u8IndexPWM,MS_BOOL bBypassPWM)572 void MDrv_PWM_BypassUnit(PWM_ChNum u8IndexPWM, MS_BOOL bBypassPWM)
573 {
574     PWM_SEM_LOCK();
575     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bBypassPWM);
576     HAL_PWM_BypassUnit(u8IndexPWM, bBypassPWM);
577     PWM_SEM_UNLOCK();
578 }
579 
580 //-------------------------------------------------------------------------------------------------
581 /// Description: Counter mode for PWM0 and PWM1
582 /// @param u8CntModePWM    \b Cnt Mode
583 /// @return E_PWM_OK : succeed
584 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
585 /// @note    \n
586 ///     11: PWM1 donate internal divider to PWM0    \n
587 ///     10: PWM0 donate internal divider to PWM1    \n
588 ///     0x: Normal mode    \n
589 //-------------------------------------------------------------------------------------------------
MDrv_PWM01_CntMode(PWM_CntMode u8CntModePWM)590 PWM_Result MDrv_PWM01_CntMode(PWM_CntMode u8CntModePWM)
591 {
592     PWM_Result ret = E_PWM_FAIL;
593     PWM_DBG_INFO("%s(%u)\r\n", __FUNCTION__, u8CntModePWM);
594     PWM_SEM_LOCK();
595     if( HAL_PWM01_CntMode(u8CntModePWM) )
596     {
597 		ret = E_PWM_OK;
598     }
599     PWM_SEM_UNLOCK();
600     return ret;
601 }
602 
603 //-------------------------------------------------------------------------------------------------
604 /// Description: Counter mode for PWM2 and PWM3
605 /// @param u8CntModePWM    \b Cnt Mode
606 /// @return E_PWM_OK : succeed
607 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
608 /// @note    \n
609 ///     11: PWM3 donate internal divider to PWM2    \n
610 ///     10: PWM2 donate internal divider to PWM3    \n
611 ///     0x: Normal mode    \n
612 //-------------------------------------------------------------------------------------------------
MDrv_PWM23_CntMode(PWM_CntMode u8CntModePWM)613 PWM_Result MDrv_PWM23_CntMode(PWM_CntMode u8CntModePWM)
614 {
615     PWM_Result ret = E_PWM_FAIL;
616     PWM_DBG_INFO("%s(%u)\r\n", __FUNCTION__, u8CntModePWM);
617     PWM_SEM_LOCK();
618     if( HAL_PWM23_CntMode(u8CntModePWM) )
619     {
620 		ret = E_PWM_OK;
621     }
622     PWM_SEM_UNLOCK();
623     return ret;
624 }
625 
626 //-------------------------------------------------------------------------------------------------
627 /// Description: Counter mode for PWM6 and PWM7
628 /// @param u8CntModePWM    \b Cnt Mode
629 /// @return E_PWM_OK : succeed
630 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
631 /// @note    \n
632 ///     11: PWM7 donate internal divider to PWM6    \n
633 ///     10: PWM6 donate internal divider to PWM7    \n
634 ///     0x: Normal mode    \n
635 //-------------------------------------------------------------------------------------------------
MDrv_PWM67_CntMode(PWM_CntMode u8CntModePWM)636 PWM_Result MDrv_PWM67_CntMode(PWM_CntMode u8CntModePWM)
637 {
638     PWM_Result ret = E_PWM_FAIL;
639     PWM_DBG_INFO("%s(%u)\r\n", __FUNCTION__, u8CntModePWM);
640     PWM_SEM_LOCK();
641     if( HAL_PWM67_CntMode(u8CntModePWM) )
642     {
643 		ret = E_PWM_OK;
644     }
645     PWM_SEM_UNLOCK();
646     return ret;
647 }
648 
649 //-------------------------------------------------------------------------------------------------
650 /// Description: Set the Shift of the specific pwm
651 /// @param u8IndexPWM    \b which pwm is setting
652 /// @param u16DutyPWM    \b the 18-bit Shift value
653 /// @return E_PWM_OK : succeed
654 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
655 //-------------------------------------------------------------------------------------------------
MDrv_PWM_Shift(PWM_ChNum u8IndexPWM,MS_U32 u32DutyPWM)656 PWM_Result MDrv_PWM_Shift(PWM_ChNum u8IndexPWM, MS_U32 u32DutyPWM)
657 {
658     PWM_Result ret = E_PWM_FAIL;
659     PWM_DBG_INFO("%s(%u, 0x%08X)\r\n", __FUNCTION__, u8IndexPWM, (int) u32DutyPWM);
660     PWM_SEM_LOCK();
661     if ( HAL_PWM_Shift(u8IndexPWM, u32DutyPWM) )
662     {
663         ret = E_PWM_OK;
664         if (g_Enable_Record[u8IndexPWM] == 1)
665         {
666             g_Shift_Record[u8IndexPWM]  = u32DutyPWM;
667         }
668 
669     }
670     PWM_SEM_UNLOCK();
671     return ret;
672 }
673 
674 
MDrv_PWM_Nvsync(PWM_ChNum u8IndexPWM,MS_BOOL bNvsPWM)675 void MDrv_PWM_Nvsync(PWM_ChNum u8IndexPWM, MS_BOOL bNvsPWM)
676 {
677     PWM_SEM_LOCK();
678     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bNvsPWM);
679     HAL_PWM_Nvsync(u8IndexPWM, bNvsPWM);
680     PWM_SEM_UNLOCK();
681 }
682 
683 
MDrv_PWM_Align(PWM_ChNum u8IndexPWM,MS_BOOL bAliPWM)684 void MDrv_PWM_Align(PWM_ChNum u8IndexPWM, MS_BOOL bAliPWM)
685 {
686     PWM_SEM_LOCK();
687     PWM_DBG_INFO("%s(%u, %u)\r\n", __FUNCTION__, u8IndexPWM, bAliPWM);
688     HAL_PWM_Align(u8IndexPWM, bAliPWM);
689     PWM_SEM_UNLOCK();
690 }
691 
MDrv_PWM_Set3DMode(PWM_ChNum u8IndexPWM,PWM_3D_Arg * pArraySeting,MS_U8 u8ArraySize)692 MS_BOOL MDrv_PWM_Set3DMode(PWM_ChNum u8IndexPWM, PWM_3D_Arg *pArraySeting, MS_U8 u8ArraySize)
693 {
694     PWM_3D_Arg PWM_Param[MAX_3DPWM_NUM];
695     MS_U8 u8Index=0;
696     MS_U32 u32Shift=0 , u32Duty=0;
697     MS_U32 u32AccumulativeLine=0;
698 
699 
700     /*
701         Error control for handling parameter error
702     */
703     //Judge for which PWM to support 3D function
704     if (HAL_PWM_IsSupport3D(u8IndexPWM) != TRUE)
705     {
706         PWM_DBG_ERR("%s, pwm index[%d] can not support 3D Mode\n", __FUNCTION__, u8IndexPWM);
707         return FALSE;
708     }
709 
710     //Judge for how many different waveform to support
711     if ((u8ArraySize > MAX_3DPWM_NUM) || (MAX_3DPWM_NUM<=0))
712     {
713         PWM_DBG_ERR("%s, pwm index[%d]-[%d] : illeage support number, exceed max number:%d \n", __FUNCTION__, u8IndexPWM, u8ArraySize, MAX_3DPWM_NUM);
714         return FALSE;
715     }
716 
717     /*
718         "u8ArraySize=0" : Disable 3D Mode
719         "u8ArraySize>0" : Set 3D mode
720     */
721     g_Enable_Record[u8IndexPWM] = 0;
722     if (u8ArraySize == 0)
723     {
724         //ULOGD(TAG_PWM, "==%s, %d\n", __FUNCTION__, __LINE__);
725         HAL_PWM_SetMultiDiff(FALSE);
726         MDrv_PWM_ResetEn(u8IndexPWM, g_Vsync_Record[u8IndexPWM]);
727         MDrv_PWM_Period(u8IndexPWM, g_Period_Record[u8IndexPWM]);
728         MDrv_PWM_DutyCycle(u8IndexPWM, g_Duty_Record[u8IndexPWM]);
729         MDrv_PWM_Shift(u8IndexPWM, g_Shift_Record[u8IndexPWM]);
730         MDrv_PWM_Div(u8IndexPWM, 0);
731         //ULOGD(TAG_PWM, "==%s, %d\n", __FUNCTION__, __LINE__);
732         g_Enable_Record[u8IndexPWM] = 1;
733         return TRUE;
734     }
735 
736     //Period Max set
737     MDrv_PWM_Period(u8IndexPWM, 0x3FFFF);
738     MDrv_PWM_Div(u8IndexPWM, (PWM_DIV>0?(PWM_DIV-1):0) );
739 
740     /*
741         Initalize Parameter
742     */
743     memset(PWM_Param, 0, sizeof(PWM_Param));
744     memcpy(PWM_Param, (PWM_3D_Arg *)pArraySeting , sizeof(PWM_3D_Arg)*u8ArraySize);
745 
746     /*
747         Start to set 3D parameter
748     */
749     u32AccumulativeLine = 0;
750     for (u8Index = 0; u8Index<MAX_3DPWM_NUM; u8Index++)
751     {
752         if ((PWM_Param[u8Index].Shift == 0) && (PWM_Param[u8Index].Duty == 0))
753         {
754             u32Shift = 0x0;
755             u32Duty  = 0x0;
756         }
757         else
758         {
759             u32Shift = u32AccumulativeLine + PWM_Param[u8Index].Shift;
760             u32AccumulativeLine = u32Shift;
761             u32Duty = u32AccumulativeLine + PWM_Param[u8Index].Duty;
762             u32AccumulativeLine = u32Duty;
763         }
764 
765         u32Shift = (MS_U32) u32Shift / PWM_DIV;
766         u32Duty =  (MS_U32) u32Duty / PWM_DIV;
767 
768         if (u8Index == 0  && u32Shift == 0)
769             u32Shift = 1;
770 
771         if (HAL_PWM_Set3D_DiffWaveform(u8IndexPWM, u8Index, u32Shift, u32Duty) == FALSE)
772             return FALSE;
773     }
774 
775     /*
776         Trigger 3D mode Config
777     */
778     //Set 3D Diff Enable
779     HAL_PWM_SetMultiDiff(TRUE);
780     //Set Vsync reset Enable
781     MDrv_PWM_ResetEn(u8IndexPWM, TRUE);
782     g_Enable_Record[u8IndexPWM] = 1;
783     return TRUE;
784 }
785 
786 //-------------PM BASE---------------
787 
MDrv_PM_PWM_Enable(void)788 void MDrv_PM_PWM_Enable(void)
789 {
790     HAL_PM_PWM_Enable();
791 }
792 
MDrv_PM_PWM_Period(MS_U16 u16PeriodPWM)793 void MDrv_PM_PWM_Period(MS_U16 u16PeriodPWM)
794 {
795    HAL_PM_PWM_Period(u16PeriodPWM);
796 }
797 
MDrv_PM_PWM_DutyCycle(MS_U16 u16DutyPWM)798 void MDrv_PM_PWM_DutyCycle(MS_U16 u16DutyPWM)
799 {
800    HAL_PM_PWM_DutyCycle(u16DutyPWM);
801 }
802 
MDrv_PM_PWM_Div(MS_U8 u8DivPWM)803 void MDrv_PM_PWM_Div(MS_U8 u8DivPWM)
804 {
805     HAL_PM_PWM_Div(u8DivPWM);
806 }
807 
MDrv_PM_PWM_Polarity(MS_BOOL bPolPWM)808 void MDrv_PM_PWM_Polarity(MS_BOOL bPolPWM)
809 {
810     HAL_PM_PWM_Polarity(bPolPWM);
811 }
812 
MDrv_PM_PWM_Dben(MS_BOOL bDbenPWM)813 void MDrv_PM_PWM_Dben(MS_BOOL bDbenPWM)
814 {
815     HAL_PM_PWM_DBen(bDbenPWM);
816 }
MDrv_PWM_SetPowerState(EN_POWER_MODE u16PowerState)817 MS_U16 MDrv_PWM_SetPowerState(EN_POWER_MODE u16PowerState)
818 {
819 	static EN_POWER_MODE _prev_u16PowerState = E_POWER_MECHANICAL;
820 	MS_U16 u16Return = FALSE;
821 
822 	if (u16PowerState == E_POWER_SUSPEND)
823 	{
824 		_prev_u16PowerState = u16PowerState;
825 		_gbInitPWM = FALSE;
826 		u16Return = 2;//SUSPEND_OK;
827 	}
828 	else if (u16PowerState == E_POWER_RESUME)
829 	{
830 
831 		if (_prev_u16PowerState == E_POWER_SUSPEND)
832 		{
833             MDrv_PWM_Init(_gbInitPWM_DbgLv);
834 
835 			_prev_u16PowerState = u16PowerState;
836 			u16Return = 1;//RESUME_OK;
837 		}
838 		else
839 		{
840 			ULOGE(TAG_PWM, "[%s,%5d]It is not suspended yet. We shouldn't resume\n",__FUNCTION__,__LINE__);
841 			u16Return = 3;//SUSPEND_FAILED;
842 		}
843 	}
844 	else
845 	{
846 		ULOGE(TAG_PWM, "[%s,%5d]Do Nothing: %d\n",__FUNCTION__,__LINE__,u16PowerState);
847 		u16Return = FALSE;
848 	}
849 
850 	return u16Return;// for success
851 }
852 
853 //-------------------------------------------------------------------------------------------------
854 /// Description: inverse 3D flag
855 /// @param bInvPWM   \b True/False for Enable/Disable
856 /// @return E_PWM_OK : succeed
857 /// @return E_PWM_FAIL : fail before timeout or illegal parameters
858 //-------------------------------------------------------------------------------------------------
MDrv_PWM_INV_3D_Flag(MS_BOOL bInvPWM)859 PWM_Result MDrv_PWM_INV_3D_Flag(MS_BOOL bInvPWM)
860 {
861     PWM_Result ret = E_PWM_FAIL;
862     if ( HAL_PWM_INV_3D_Flag(bInvPWM))
863     {
864         ret = E_PWM_OK;
865     }
866     return ret;
867 }
868 
MDrv_PWM_3D_LR_Sync(PWM_ChNum u8IndexPWM,MS_BOOL bNvsPWM,N_LR_SYNC_SEL LrSyncSel,MS_U8 u8RstCnt)869 void MDrv_PWM_3D_LR_Sync(PWM_ChNum u8IndexPWM, MS_BOOL bNvsPWM, N_LR_SYNC_SEL LrSyncSel, MS_U8 u8RstCnt)
870 {
871     MDrv_PWM_RstCnt(u8IndexPWM, u8RstCnt);
872     MDrv_PWM_RstMux(u8IndexPWM, bNvsPWM);
873     HAL_PWM_LR_RST_SEL(u8IndexPWM, (bNvsPWM ? LrSyncSel : E_VSYNC));
874     MDrv_PWM_Nvsync(u8IndexPWM, bNvsPWM);
875     MDrv_PWM_Align(u8IndexPWM, FALSE);
876 }
877