1*f3f9432fSClément Léger /* SPDX-License-Identifier: BSD-2-Clause */ 2*f3f9432fSClément Léger /* 3*f3f9432fSClément Léger * Copyright 2022 Microchip. 4*f3f9432fSClément Léger */ 5*f3f9432fSClément Léger 6*f3f9432fSClément Léger #ifndef DRIVERS_RTC_H 7*f3f9432fSClément Léger #define DRIVERS_RTC_H 8*f3f9432fSClément Léger 9*f3f9432fSClément Léger #include <tee_api_types.h> 10*f3f9432fSClément Léger #include <util.h> 11*f3f9432fSClément Léger 12*f3f9432fSClément Léger /* The RTC allows to set/get offset for correction */ 13*f3f9432fSClément Léger #define RTC_CORRECTION_FEATURE BIT(0) 14*f3f9432fSClément Léger 15*f3f9432fSClément Léger struct optee_rtc_time { 16*f3f9432fSClément Léger uint32_t tm_year; 17*f3f9432fSClément Léger uint32_t tm_mon; 18*f3f9432fSClément Léger uint32_t tm_mday; 19*f3f9432fSClément Léger uint32_t tm_hour; 20*f3f9432fSClément Léger uint32_t tm_min; 21*f3f9432fSClément Léger uint32_t tm_sec; 22*f3f9432fSClément Léger uint32_t tm_wday; 23*f3f9432fSClément Léger }; 24*f3f9432fSClément Léger 25*f3f9432fSClément Léger struct rtc { 26*f3f9432fSClément Léger const struct rtc_ops *ops; 27*f3f9432fSClément Léger struct optee_rtc_time range_min; 28*f3f9432fSClément Léger struct optee_rtc_time range_max; 29*f3f9432fSClément Léger }; 30*f3f9432fSClément Léger 31*f3f9432fSClément Léger /* 32*f3f9432fSClément Léger * struct rtc_ops - The RTC device operations 33*f3f9432fSClément Léger * 34*f3f9432fSClément Léger * @get_time: Get the RTC time. 35*f3f9432fSClément Léger * @set_time: Set the RTC time. 36*f3f9432fSClément Léger * @get_offset: Get the RTC offset. 37*f3f9432fSClément Léger * @set_offset: Set the RTC offset 38*f3f9432fSClément Léger */ 39*f3f9432fSClément Léger struct rtc_ops { 40*f3f9432fSClément Léger TEE_Result (*get_time)(struct rtc *rtc, struct optee_rtc_time *tm); 41*f3f9432fSClément Léger TEE_Result (*set_time)(struct rtc *rtc, struct optee_rtc_time *tm); 42*f3f9432fSClément Léger TEE_Result (*get_offset)(struct rtc *rtc, long *offset); 43*f3f9432fSClément Léger TEE_Result (*set_offset)(struct rtc *rtc, long offset); 44*f3f9432fSClément Léger }; 45*f3f9432fSClément Léger 46*f3f9432fSClément Léger #ifdef CFG_DRIVERS_RTC 47*f3f9432fSClément Léger extern struct rtc *rtc_device; 48*f3f9432fSClément Léger 49*f3f9432fSClément Léger /* Register a RTC device as the system RTC */ 50*f3f9432fSClément Léger void rtc_register(struct rtc *rtc); 51*f3f9432fSClément Léger 52*f3f9432fSClément Léger static inline TEE_Result rtc_get_info(uint64_t *features, 53*f3f9432fSClément Léger struct optee_rtc_time *range_min, 54*f3f9432fSClément Léger struct optee_rtc_time *range_max) 55*f3f9432fSClément Léger { 56*f3f9432fSClément Léger if (!rtc_device) 57*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 58*f3f9432fSClément Léger 59*f3f9432fSClément Léger if (rtc_device->ops->set_offset) 60*f3f9432fSClément Léger *features = RTC_CORRECTION_FEATURE; 61*f3f9432fSClément Léger *range_min = rtc_device->range_min; 62*f3f9432fSClément Léger *range_max = rtc_device->range_max; 63*f3f9432fSClément Léger 64*f3f9432fSClément Léger return TEE_SUCCESS; 65*f3f9432fSClément Léger } 66*f3f9432fSClément Léger 67*f3f9432fSClément Léger static inline TEE_Result rtc_get_time(struct optee_rtc_time *tm) 68*f3f9432fSClément Léger { 69*f3f9432fSClément Léger if (!rtc_device) 70*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 71*f3f9432fSClément Léger 72*f3f9432fSClément Léger return rtc_device->ops->get_time(rtc_device, tm); 73*f3f9432fSClément Léger } 74*f3f9432fSClément Léger 75*f3f9432fSClément Léger static inline TEE_Result rtc_set_time(struct optee_rtc_time *tm) 76*f3f9432fSClément Léger { 77*f3f9432fSClément Léger if (!rtc_device || !rtc_device->ops->set_time) 78*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 79*f3f9432fSClément Léger 80*f3f9432fSClément Léger return rtc_device->ops->set_time(rtc_device, tm); 81*f3f9432fSClément Léger } 82*f3f9432fSClément Léger 83*f3f9432fSClément Léger static inline TEE_Result rtc_get_offset(long *offset) 84*f3f9432fSClément Léger { 85*f3f9432fSClément Léger if (!rtc_device || !rtc_device->ops->get_offset) 86*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 87*f3f9432fSClément Léger 88*f3f9432fSClément Léger return rtc_device->ops->get_offset(rtc_device, offset); 89*f3f9432fSClément Léger } 90*f3f9432fSClément Léger 91*f3f9432fSClément Léger static inline TEE_Result rtc_set_offset(long offset) 92*f3f9432fSClément Léger { 93*f3f9432fSClément Léger if (!rtc_device || !rtc_device->ops->set_offset) 94*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 95*f3f9432fSClément Léger 96*f3f9432fSClément Léger return rtc_device->ops->set_offset(rtc_device, offset); 97*f3f9432fSClément Léger } 98*f3f9432fSClément Léger 99*f3f9432fSClément Léger #else 100*f3f9432fSClément Léger 101*f3f9432fSClément Léger static inline void rtc_register(struct rtc *rtc __unused) {} 102*f3f9432fSClément Léger 103*f3f9432fSClément Léger static inline TEE_Result rtc_get_info(uint64_t *features __unused, 104*f3f9432fSClément Léger struct optee_rtc_time *range_min __unused, 105*f3f9432fSClément Léger struct optee_rtc_time *range_max __unused) 106*f3f9432fSClément Léger { 107*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 108*f3f9432fSClément Léger } 109*f3f9432fSClément Léger 110*f3f9432fSClément Léger static inline TEE_Result rtc_get_time(struct optee_rtc_time *tm __unused) 111*f3f9432fSClément Léger { 112*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 113*f3f9432fSClément Léger } 114*f3f9432fSClément Léger 115*f3f9432fSClément Léger static inline TEE_Result rtc_set_time(struct optee_rtc_time *tm __unused) 116*f3f9432fSClément Léger { 117*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 118*f3f9432fSClément Léger } 119*f3f9432fSClément Léger 120*f3f9432fSClément Léger static inline TEE_Result rtc_get_offset(long *offset __unused) 121*f3f9432fSClément Léger { 122*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 123*f3f9432fSClément Léger } 124*f3f9432fSClément Léger 125*f3f9432fSClément Léger static inline TEE_Result rtc_set_offset(long offset __unused) 126*f3f9432fSClément Léger { 127*f3f9432fSClément Léger return TEE_ERROR_NOT_SUPPORTED; 128*f3f9432fSClément Léger } 129*f3f9432fSClément Léger #endif 130*f3f9432fSClément Léger #endif /* DRIVERS_RTC_H */ 131