xref: /optee_os/core/include/drivers/rtc.h (revision f3f9432f8fd584d6427c575d49810be584f8433c)
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