/* * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __XRADIO_PM_H #define __XRADIO_PM_H #include #include #include "sys/list.h" #include "driver/chip/hal_prcm.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Defined all supported low power state. * @note: * PM_MODE_ON is used for test. * PM_MODE_SLEEP is used for devices wakeup system. In this mode CPU is * in WFI mode and running at low frequency, all devices are powered on. * set to work mode if you want this device to wakeup system, or else * disable this device to save power. * PM_MODE_STANDBY is used for network or some special wakeup sources to * wakeup system. In this mode CPU and all devices has been powered off, * network can work normally and can wakeup system by received data from * network. Also some special wakeup sources like wakeup timer or IO can * wakeup system if you set this wakeup sources properly. * PM_MODE_HIBERNATION is used for some special wakeup sources to wakeup system. * System will restartup when wakeup. In this mode CPU and all devices * has been powered off beside network. Only some special wakeup sources * can startup system, and can get wakeup event at startup. */ enum suspend_state_t { PM_MODE_ON = 0, PM_MODE_SLEEP = 1, PM_MODE_STANDBY = 2, PM_MODE_HIBERNATION = 3, PM_MODE_MAX = 4, }; #define PM_MODE_MAGIC (0x7FF20000) /** @brief Platform pm mode support. */ #define PM_SUPPORT_SLEEP (1<Device will be registered. * @retval 0 if success or other if failed. */ extern int pm_register_ops(struct soc_device *dev); /** * @brief Unregister a set of system core operations. * @param dev: * @arg dev->Device will be unregistered. * @retval 0 if success or other if failed. */ extern int pm_unregister_ops(struct soc_device *dev); /** * @brief Set a magin to synchronize with net. */ extern void pm_set_sync_magic(void); /** * @brief Set system to a lowpower mode with timeout. * @param state: * @arg state->The lowpower mode will enter. * @param tmo: * @arg tmo->Timeout based on mS. * @retval 0 if success or other if failed. */ extern int pm_enter_mode_timeout(enum suspend_state_t state, uint32_t tmo); /** * @brief Set system to a lowpower mode. * @param state: * @arg state->The lowpower mode will enter. * @retval 0 if success or other if failed. */ extern int pm_enter_mode(enum suspend_state_t state); /** * @brief Abort suspend. */ extern void pm_suspend_abort(void); /** * @brief Get system pm mode. * @retval PM_MODE_ON: if runing or other if during suspending or resumeing. */ extern enum suspend_state_t pm_get_mode(void); /** * @brief Initialize the PM-related part of a device object. * @note not use printf for this fun is called very earlier. * @retval 0 if success or other if failed. */ extern int pm_init(void); /** * @brief Alloc resources. */ extern void pm_start(void); /** * @brief Releas resources. */ extern void pm_stop(void); /** * @brief Set dump addr and len for debug. */ extern void pm_set_dump_addr(uint32_t addr, uint32_t len, uint32_t idx); /** * @brief Set suspend test level. * @param level: * @arg level->Suspend will exit when run up to setted level. */ extern void pm_set_test_level(enum suspend_test_level_t level); /** * @brief Set delay ms in debug mode. * @note To prevent mutual interference between devices. * @param ms: * @arg ms->The delayed ms between two devices. */ extern void pm_set_debug_delay_ms(unsigned int ms); /** @brief Show suspend statistic info. */ extern void pm_stats_show(void); /** * @brief Select pm modes used on this platform. * @note Select modes at init for some modes are not used on some platforms. * This will prevent enter unselected modes. * @param select: * @arg select->The selected modes set. */ extern void pm_mode_platform_select(unsigned int select); #ifdef CONFIG_WLAN /** * @brief register wlan power on/off callback. * @note Wlan power on/off calback will be called when pm enter select modes. * @param wlan_power_cb: * @arg wlan_power_cb->Wlan power on/off calback. * @param select: * @arg select->The selected modes set. * retval 0 if success or other if failed. */ extern int pm_register_wlan_power_onoff(pm_module_power_onoff wlan_power_cb, unsigned int select); /** @brief unregister wlan power on/off callback. */ extern void pm_unregister_wlan_power_onoff(void); #endif #ifdef CONFIG_BT /** * @brief Select bt power modes when enter pm. * @note bt power on/off calback will called when pm enter select modes. * @param bt_power_cb: * @arg bt_power_cb->bt power on/off calback. * @param select: * @arg select->The selected modes set. * retval 0 if success or other if failed. */ int pm_register_bt_power_onoff(pm_module_power_onoff bt_power_cb, unsigned int select); /** @brief unregister bt power on/off callback. */ void pm_unregister_bt_power_onoff(void); #endif #ifdef CONFIG_BLE /** * @brief Select ble power modes when enter pm. * @note ble power on/off calback will called when pm enter select modes. * @param ble_power_cb: * @arg ble_power_cb->ble power on/off calback. * @param select: * @arg select->The selected modes set. * retval 0 if success or other if failed. */ int pm_register_ble_power_onoff(pm_module_power_onoff ble_power_cb, unsigned int select); /** @brief unregister ble power on/off callback. */ void pm_unregister_ble_power_onoff(void); #endif /** * check if any wake-up interrupts are pending */ extern int pm_check_wakeup_irqs(void); extern void pm_set_suspend_resume_latency(unsigned int enter_lat, unsigned int exit_lat); extern unsigned int pm_get_suspend_latency(void); extern unsigned int pm_get_resume_latency(void); extern unsigned int pm_get_suspend_resume_latency(void); extern int pm_test(void); extern void pm_set_debug_mask(uint16_t debug_mask); void pm_standby_sram_retention_only(uint32_t sramN); #ifdef CONFIG_PM_WAKELOCKS /** * @brief Lock wl. * @param[in] wl Wakelock to lock, assign wl's name and set other members * to 0 if first use this wl. * @retval 0 if success or other if failed. * * @note system will not goto suspend before unlock this wl, support lock many * times, Use FOREVER mode, TIMEOUT mode can also used at the same time, * see struct wakelock note. */ int pm_wake_lock(struct wakelock *wl); /** * @brief Unlock wl. * @param[in] wl Wakelock to unlock. * @retval 0 if success or other if failed. * * @note Unlock wl locked by pm_wake_lock, must used in pairs with pm_wake_lock. */ int pm_wake_unlock(struct wakelock *wl); /** * @brief Update wl's timeout. * @param[in] wl Wakelock to operated, assign wl's name and set other members * to 0 if first use this wl. * @param[in] timeout Based on ms. * @retval 0 if success or other if failed. * * @note System will not goto suspend before timeout. Use TIMEOUT mode, FOREVER * mode can also used at the same time, see struct wakelock note. Set * timeout to 0 to disable this wl's timeout mode. */ int pm_wake_lock_timeout(struct wakelock *wl, uint32_t timeout); /* @brief Show all wakelocks info. */ void pm_wakelocks_show(void); #endif #else /* CONFIG_PM */ static inline int pm_register_ops(struct soc_device *dev) { return 0; } static inline int pm_unregister_ops(struct soc_device *dev) { return 0; } static inline void pm_set_sync_magic(void) { ; } static inline int pm_enter_mode_timeout(enum suspend_state_t state, uint32_t tmo) { return 0; } static inline int pm_enter_mode(enum suspend_state_t state) { return 0; } static inline void pm_suspend_abort(void) { ; } static inline enum suspend_state_t pm_get_mode(void) { return PM_MODE_ON; } static inline int pm_init(void) { return 0; } static inline void pm_start(void) { ; } static inline void pm_stop(void) { ; } static inline void pm_set_test_level(enum suspend_test_level_t level) { ; } static inline void pm_set_debug_delay_ms(unsigned int ms) { ; } static inline void pm_stats_show(void) { ; } static inline void pm_mode_platform_select(unsigned int select) { ; } static inline int pm_register_wlan_power_onoff(pm_module_power_onoff wlan_power_cb, unsigned int select) { return 0; } static inline int pm_register_bt_power_onoff(pm_module_power_onoff bt_power_cb, unsigned int select) { return 0; } static inline void pm_unregister_bt_power_onoff(void) { ; } static inline int pm_register_ble_power_onoff(pm_module_power_onoff ble_power_cb, unsigned int select) { return 0; } static inline void pm_unregister_ble_power_onoff(void) { ; } static inline int pm_check_wakeup_irqs(void) { return 0; } static inline int pm_test(void) { return 0; } #endif /* CONFIG_PM */ #ifdef __cplusplus } #endif #endif /* __XRADIO_PM_H */