1 /* 2 * Copyright (c) 2006-2024 RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2012-06-02 Bernard the first version 9 * 2018-08-02 Tanek split run and sleep modes, support custom mode 10 * 2019-04-28 Zero-Free improve PM mode and device ops interface 11 * 2020-11-23 zhangsz update pm mode select 12 * 2020-11-27 zhangsz update pm 2.0 13 * 2024-07-04 wdfk-prog The device is registered and uninstalled by linked list 14 */ 15 16 #ifndef __PM_H__ 17 #define __PM_H__ 18 19 #include <stdint.h> 20 #include <rtthread.h> 21 #include <drivers/lptimer.h> 22 23 /* All modes used for rt_pm_request() and rt_pm_release() */ 24 enum 25 { 26 /* sleep modes */ 27 PM_SLEEP_MODE_NONE = 0, 28 PM_SLEEP_MODE_IDLE, 29 PM_SLEEP_MODE_LIGHT, 30 PM_SLEEP_MODE_DEEP, 31 PM_SLEEP_MODE_STANDBY, 32 PM_SLEEP_MODE_SHUTDOWN, 33 PM_SLEEP_MODE_MAX, 34 }; 35 36 enum 37 { 38 /* run modes*/ 39 PM_RUN_MODE_HIGH_SPEED = 0, 40 PM_RUN_MODE_NORMAL_SPEED, 41 PM_RUN_MODE_MEDIUM_SPEED, 42 PM_RUN_MODE_LOW_SPEED, 43 PM_RUN_MODE_MAX, 44 }; 45 46 enum 47 { 48 RT_PM_FREQUENCY_PENDING = 0x01, 49 }; 50 51 /* The name of all modes used in the msh command "pm_dump" */ 52 #define PM_SLEEP_MODE_NAMES \ 53 { \ 54 "None Mode", \ 55 "Idle Mode", \ 56 "LightSleep Mode", \ 57 "DeepSleep Mode", \ 58 "Standby Mode", \ 59 "Shutdown Mode", \ 60 } 61 62 #define PM_RUN_MODE_NAMES \ 63 { \ 64 "High Speed", \ 65 "Normal Speed", \ 66 "Medium Speed", \ 67 "Low Mode", \ 68 } 69 70 #ifndef PM_USING_CUSTOM_CONFIG 71 /** 72 * Modules used for 73 * pm_module_request(PM_BOARD_ID, PM_SLEEP_MODE_IDLE) 74 * pm_module_release(PM_BOARD_ID, PM_SLEEP_MODE_IDLE) 75 * pm_module_release_all(PM_BOARD_ID, PM_SLEEP_MODE_IDLE) 76 */ 77 enum pm_module_id { 78 PM_NONE_ID = 0, 79 PM_POWER_ID, 80 PM_BOARD_ID, 81 PM_BSP_ID, 82 PM_MAIN_ID, 83 PM_PMS_ID, 84 PM_PMC_ID, 85 PM_TASK_ID, 86 PM_SPI_ID, 87 PM_I2C_ID, 88 PM_UART_ID, 89 PM_CAN_ID, 90 PM_ETH_ID, 91 PM_SENSOR_ID, 92 PM_LCD_ID, 93 PM_KEY_ID, 94 PM_TP_ID, 95 PM_MODULE_MAX_ID, /* enum must! */ 96 }; 97 98 #else 99 100 #include <pm_cfg.h> 101 102 #endif /* PM_USING_CUSTOM_CONFIG */ 103 104 #ifndef RT_PM_DEFAULT_SLEEP_MODE 105 #define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_NONE 106 #endif 107 108 #ifndef RT_PM_DEFAULT_DEEPSLEEP_MODE 109 #define RT_PM_DEFAULT_DEEPSLEEP_MODE PM_SLEEP_MODE_DEEP 110 #endif 111 112 #ifndef RT_PM_DEFAULT_RUN_MODE 113 #define RT_PM_DEFAULT_RUN_MODE PM_RUN_MODE_NORMAL_SPEED 114 #endif 115 116 /** 117 * device control flag to request or release power 118 */ 119 #define RT_PM_DEVICE_CTRL_RELEASE (RT_DEVICE_CTRL_BASE(PM) + 0x00) 120 #define RT_PM_DEVICE_CTRL_REQUEST (RT_DEVICE_CTRL_BASE(PM) + 0x01) 121 122 struct rt_pm; 123 124 /** 125 * low power mode operations 126 */ 127 struct rt_pm_ops 128 { 129 void (*sleep)(struct rt_pm *pm, rt_uint8_t mode); 130 void (*run)(struct rt_pm *pm, rt_uint8_t mode); 131 void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout); 132 void (*timer_stop)(struct rt_pm *pm); 133 rt_tick_t (*timer_get_tick)(struct rt_pm *pm); 134 }; 135 136 struct rt_device_pm_ops 137 { 138 rt_err_t (*suspend)(const struct rt_device *device, rt_uint8_t mode); 139 void (*resume)(const struct rt_device *device, rt_uint8_t mode); 140 rt_err_t (*frequency_change)(const struct rt_device *device, rt_uint8_t mode); 141 }; 142 143 struct rt_device_pm 144 { 145 const struct rt_device *device; 146 const struct rt_device_pm_ops *ops; 147 rt_slist_t list; 148 }; 149 150 struct rt_pm_module 151 { 152 rt_uint8_t req_status; 153 rt_bool_t busy_flag; 154 rt_uint32_t timeout; 155 rt_uint32_t start_time; 156 }; 157 158 /** 159 * power management 160 */ 161 struct rt_pm 162 { 163 struct rt_device parent; 164 165 /* modes */ 166 rt_uint8_t modes[PM_SLEEP_MODE_MAX]; 167 rt_uint8_t sleep_mode; /* current sleep mode */ 168 rt_uint8_t run_mode; /* current running mode */ 169 170 /* modules request status*/ 171 struct rt_pm_module module_status[PM_MODULE_MAX_ID]; 172 173 /* sleep request table */ 174 rt_uint32_t sleep_status[PM_SLEEP_MODE_MAX - 1][(PM_MODULE_MAX_ID + 31) / 32]; 175 176 /* the list of device, which has PM feature */ 177 rt_slist_t device_list; 178 struct rt_device_pm *device_pm; 179 180 /* if the mode has timer, the corresponding bit is 1*/ 181 rt_uint8_t timer_mask; 182 rt_uint8_t flags; 183 184 const struct rt_pm_ops *ops; 185 }; 186 187 enum 188 { 189 RT_PM_ENTER_SLEEP = 0, 190 RT_PM_EXIT_SLEEP, 191 }; 192 193 struct rt_pm_notify 194 { 195 void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data); 196 void *data; 197 }; 198 199 rt_err_t rt_pm_request(rt_uint8_t sleep_mode); 200 rt_err_t rt_pm_release(rt_uint8_t sleep_mode); 201 rt_err_t rt_pm_release_all(rt_uint8_t sleep_mode); 202 rt_err_t rt_pm_run_enter(rt_uint8_t run_mode); 203 204 void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops); 205 void rt_pm_device_unregister(struct rt_device *device); 206 207 void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data); 208 void rt_pm_default_set(rt_uint8_t sleep_mode); 209 210 void rt_system_pm_init(const struct rt_pm_ops *ops, 211 rt_uint8_t timer_mask, 212 void *user_data); 213 rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode); 214 rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode); 215 rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode); 216 void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout); 217 rt_uint32_t rt_pm_module_get_status(void); 218 rt_uint8_t rt_pm_get_sleep_mode(void); 219 struct rt_pm *rt_pm_get_handle(void); 220 221 /* sleep : request or release */ 222 rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode); 223 rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode); 224 rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id); 225 rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id); 226 rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id); 227 rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id); 228 rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id); 229 rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id); 230 231 #endif /* __PM_H__ */ 232