• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /**
16  ****************************************************************************************
17  *
18  * @file pwrkey_api.c
19 
20  * @brief PWRKEY API functions
21  *
22  ****************************************************************************************
23  */
24 
25 /*
26  * INCLUDE FILES
27  ****************************************************************************************
28  */
29 #include "pwrkey_api.h"
30 #include "lp_ticker_api.h"
31 #include "ll.h"
32 #include "dbg.h"
33 
34 #define PWRKEY_DEBUG_PRINTF(fmt, ...)       do {} while(0) //dbg(fmt, ##__VA_ARGS__)//
35 
36 pwrkey_irq_handler_t pwrkey_irq_cb = NULL;
37 int pwrkey_tick_timeout = 0;
38 int pwrkey_released = 0;
39 uint32_t pwrkey_down_time_ms = 0;
40 uint32_t pwrkey_up_time_ms = 0;
41 uint32_t pwrkey_ponchk_time_ms = 0;
42 
43 #if PLF_PMIC
44 
pwrkey_tick_evt_hndlr(uint32_t id)45 void pwrkey_tick_evt_hndlr(uint32_t id)
46 {
47     pwrkey_tick_timeout = 1;
48 }
49 
pwrkey_irq_evt_hndlr(int evt)50 void pwrkey_irq_evt_hndlr(int evt)
51 {
52     const ticker_data_t *lp_tick_d = get_lp_ticker_data();
53     if (evt == PWRKEY_IRQ_EVENT_KEYDOWN) {
54         pwrkey_down_time_ms = ticker_read(lp_tick_d) / 1000;
55     } else if (evt == PWRKEY_IRQ_EVENT_KEYUP) {
56         pwrkey_up_time_ms = ticker_read(lp_tick_d) / 1000;
57     }
58     if ((pwrkey_down_time_ms > pwrkey_ponchk_time_ms) && (pwrkey_up_time_ms > pwrkey_down_time_ms) &&
59         ((pwrkey_up_time_ms - pwrkey_down_time_ms) > user_pwrkey_poweroff_time_get())) {
60         pmic_chip_shutdown();
61     }
62     PWRKEY_DEBUG_PRINTF("pwrkey:%x\n",evt);
63     if ((evt == PWRKEY_IRQ_EVENT_KEYUP) ||
64         (evt == PWRKEY_IRQ_EVENT_KEYUP_SINGLE)) {
65         pwrkey_released = 1;
66     }
67 }
68 
pwrkey_init(void)69 void pwrkey_init(void)
70 {
71     if (user_pwrkey_enabled()) {
72         int key_held = pmic_powerkey_enable();
73         if (user_pwrkey_poweron_time_get() && (key_held == 0)) {
74             pmic_chip_shutdown(); // pwrkey released
75         }
76         pmic_irq_enable(0x01UL << PMIC_RTC_CORE_IRQn);
77         pwrkey_irq_callback_register(pwrkey_irq_evt_hndlr);
78     }
79 }
80 
pwrkey_poweron_check(void)81 void pwrkey_poweron_check(void)
82 {
83     unsigned int user_pon_time_ms = user_pwrkey_poweron_time_get();
84     if (user_pwrkey_enabled() && user_pon_time_ms) {
85         // start timer, reg timer & pwrkey cb
86         const ticker_data_t *lp_tick_d = get_lp_ticker_data();
87         ticker_event_t lp_tick_e;
88         uint32_t tgt_time_us;
89         if (user_pon_time_ms > 400) {
90             user_pon_time_ms -= 400;
91         }
92         ticker_set_handler(lp_tick_d, pwrkey_tick_evt_hndlr);
93         tgt_time_us = ticker_read(lp_tick_d) + user_pon_time_ms * 1000;
94         ticker_insert_event(lp_tick_d, &lp_tick_e, tgt_time_us, 0);
95         while (1) {
96             uint32_t cur_time_us;
97             __WFI();
98             cur_time_us = ticker_read(lp_tick_d);
99             critical_section_start();
100             pwrkey_ponchk_time_ms = cur_time_us / 1000;
101             PWRKEY_DEBUG_PRINTF("tmr=%x,key=%x\n",pwrkey_tick_timeout,pwrkey_released);
102             if (pwrkey_tick_timeout) {
103                 break; // timer irq first, boot to app
104             } else if (pwrkey_released) {
105                 // pwrkey irq first, shutdown
106                 pmic_chip_shutdown();
107             }
108             critical_section_end();
109         }
110     }
111 }
112 
pwrkey_irq_handler(int event)113 void pwrkey_irq_handler(int event)
114 {
115     // callback func
116     if (pwrkey_irq_cb) {
117         pwrkey_irq_cb(event);
118     }
119 }
120 
pwrkey_irq_callback_register(pwrkey_irq_handler_t callback)121 void pwrkey_irq_callback_register(pwrkey_irq_handler_t callback)
122 {
123     pwrkey_irq_cb = callback;
124 }
125 
126 #if 0
127 void user_secure_shutdown(void)
128 {
129     sleep_level_set(PM_LEVEL_POWER_OFF);
130     user_sleep_allow(1);
131     user_powerkey_pressed();
132 }
133 #endif
134 
user_pwrkey_enabled(void)135 __WEAK int user_pwrkey_enabled(void)
136 {
137     return USER_DEFINED_PWRKEY_EN;
138 }
139 
user_pwrkey_poweron_time_get(void)140 __WEAK unsigned int user_pwrkey_poweron_time_get(void)
141 {
142     return USER_DEFINED_POWERON_TIME_MS;
143 }
144 
user_pwrkey_poweroff_time_get(void)145 __WEAK unsigned int user_pwrkey_poweroff_time_get(void)
146 {
147     return USER_DEFINED_POWEROFF_TIME_MS;
148 }
149 
150 #endif
151