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