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
rtc_get_info(uint64_t * features,struct optee_rtc_time * range_min,struct optee_rtc_time * range_max)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
rtc_get_time(struct optee_rtc_time * tm)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
rtc_set_time(struct optee_rtc_time * tm)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
rtc_get_offset(long * offset)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
rtc_set_offset(long offset)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
rtc_register(struct rtc * rtc __unused)101 static inline void rtc_register(struct rtc *rtc __unused) {}
102
rtc_get_info(uint64_t * features __unused,struct optee_rtc_time * range_min __unused,struct optee_rtc_time * range_max __unused)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
rtc_get_time(struct optee_rtc_time * tm __unused)110 static inline TEE_Result rtc_get_time(struct optee_rtc_time *tm __unused)
111 {
112 return TEE_ERROR_NOT_SUPPORTED;
113 }
114
rtc_set_time(struct optee_rtc_time * tm __unused)115 static inline TEE_Result rtc_set_time(struct optee_rtc_time *tm __unused)
116 {
117 return TEE_ERROR_NOT_SUPPORTED;
118 }
119
rtc_get_offset(long * offset __unused)120 static inline TEE_Result rtc_get_offset(long *offset __unused)
121 {
122 return TEE_ERROR_NOT_SUPPORTED;
123 }
124
rtc_set_offset(long offset __unused)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