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