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