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