xref: /nrf52832-nimble/rt-thread/components/drivers/include/drivers/pm.h (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, 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  */
11 
12 #ifndef __PM_H__
13 #define __PM_H__
14 
15 #include <rtthread.h>
16 
17 #ifndef PM_HAS_CUSTOM_CONFIG
18 
19 /* All modes used for rt_pm_request() adn rt_pm_release() */
20 enum
21 {
22     /* run modes */
23     PM_RUN_MODE_NORMAL = 0,
24 
25     /* sleep modes */
26     PM_SLEEP_MODE_SLEEP,
27     PM_SLEEP_MODE_TIMER,
28     PM_SLEEP_MODE_SHUTDOWN,
29 };
30 
31 /* The name of all modes used in the msh command "pm_dump" */
32 #define PM_MODE_NAMES           \
33 {                               \
34     "Running Mode",             \
35                                 \
36     "Sleep Mode",               \
37     "Timer Mode",               \
38     "Shutdown Mode",            \
39 }
40 
41 /* run mode count : 1 */
42 #define PM_RUN_MODE_COUNT       1
43 /* sleep mode count : 3 */
44 #define PM_SLEEP_MODE_COUNT     3
45 
46 /* support redefining default run mode */
47 #ifndef PM_RUN_MODE_DEFAULT
48 #define PM_RUN_MODE_DEFAULT     0
49 #endif
50 
51 /* support redefining default sleep mode */
52 #ifndef PM_SLEEP_MODE_DEFAULT
53 #define PM_SLEEP_MODE_DEFAULT   (PM_SLEEP_MODE_START)
54 #endif
55 
56 /* support redefining the minimum tick into sleep mode */
57 #ifndef PM_MIN_ENTER_SLEEP_TICK
58 #define PM_MIN_ENTER_SLEEP_TICK   (1)
59 #endif
60 
61 #else /* PM_HAS_CUSTOM_CONFIG */
62 
63 #include <pm_cfg.h>
64 
65 #ifndef PM_RUN_MODE_COUNT
66 #error  "You must defined PM_RUN_MODE_COUNT on pm_cfg.h"
67 #endif
68 
69 #ifndef PM_SLEEP_MODE_COUNT
70 #error  "You must defined PM_SLEEP_MODE_COUNT on pm_cfg.h"
71 #endif
72 
73 #ifndef PM_MODE_DEFAULT
74 #error  "You must defined PM_MODE_DEFAULT on pm_cfg.h"
75 #endif
76 
77 #ifndef PM_MODE_NAMES
78 #error  "You must defined PM_MODE_NAMES on pm_cfg.h"
79 #endif
80 
81 #ifndef PM_RUN_MODE_DEFAULT
82 #error  "You must defined PM_RUN_MODE_DEFAULT on pm_cfg.h"
83 #endif
84 
85 /* The default sleep mode(PM_SLEEP_MODE_DEFAULT) are not required.
86  * If the default mode is defined, it is requested once in rt_system_pm_init()
87  */
88 
89 #endif /* PM_HAS_CUSTOM_CONFIG */
90 
91 /* run mode must start at 0 */
92 #define PM_RUN_MODE_START       0
93 /* the values of the run modes and sleep mode must be consecutive */
94 #define PM_SLEEP_MODE_START     PM_RUN_MODE_COUNT
95 /* all mode count */
96 #define PM_MODE_COUNT           (PM_RUN_MODE_COUNT + PM_SLEEP_MODE_COUNT)
97 /* The last mode, will be request in rt_system_pm_init() */
98 #define PM_MODE_MAX             (PM_RUN_MODE_COUNT + PM_SLEEP_MODE_COUNT - 1)
99 
100 #if PM_MODE_COUNT > 32
101 #error "The number of modes cannot exceed 32"
102 #endif
103 
104 /**
105  * device control flag to request or release power
106  */
107 #define RT_PM_DEVICE_CTRL_REQUEST   0x01
108 #define RT_PM_DEVICE_CTRL_RELEASE   0x02
109 
110 struct rt_pm;
111 
112 /**
113  * low power mode operations
114  */
115 struct rt_pm_ops
116 {
117     void (*enter)(struct rt_pm *pm);
118     void (*exit)(struct rt_pm *pm);
119 
120 #if PM_RUN_MODE_COUNT > 1
121     void (*frequency_change)(struct rt_pm *pm, rt_uint32_t frequency);
122 #endif
123 
124     void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
125     void (*timer_stop)(struct rt_pm *pm);
126     rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
127 };
128 
129 struct rt_device_pm_ops
130 {
131 #if PM_RUN_MODE_COUNT > 1
132     void (*frequency_change)(const struct rt_device* device);
133 #endif
134 
135     void (*suspend)(const struct rt_device* device);
136     void (*resume) (const struct rt_device* device);
137 };
138 
139 struct rt_device_pm
140 {
141     const struct rt_device* device;
142     const struct rt_device_pm_ops* ops;
143 };
144 
145 /**
146  * power management
147  */
148 struct rt_pm
149 {
150     struct rt_device parent;
151 
152     /* modes */
153     rt_uint8_t modes[PM_MODE_COUNT];
154     rt_uint8_t current_mode;    /* current pm mode */
155     rt_uint8_t exit_count;
156 
157     /* the list of device, which has PM feature */
158     rt_uint8_t device_pm_number;
159     struct rt_device_pm* device_pm;
160     struct rt_semaphore  device_lock;
161 
162     /* if the mode has timer, the corresponding bit is 1*/
163     rt_uint32_t timer_mask;
164 
165     const struct rt_pm_ops *ops;
166 };
167 
168 void rt_pm_enter(void);
169 void rt_pm_exit(void);
170 
171 void rt_pm_request(rt_ubase_t mode);
172 void rt_pm_release(rt_ubase_t mode);
173 
174 void rt_pm_register_device(struct rt_device* device, const struct rt_device_pm_ops* ops);
175 void rt_pm_unregister_device(struct rt_device* device);
176 
177 void rt_system_pm_init(const struct rt_pm_ops *ops,
178                        rt_uint8_t              timer_mask,
179                        void                   *user_data);
180 
181 #endif /* __PM_H__ */
182