embox

Форк
0
163 строки · 2.7 Кб
1
/**
2
 * @
3
 *
4
 * @date Nov 23, 2020
5
 * @author Anton Bondarev
6
 */
7

8
#include <errno.h>
9
#include <time.h>
10
#include <stddef.h>
11

12
#include <kernel/lthread/lthread.h>
13

14
#include <drivers/rtc.h>
15

16
#include <embox/unit.h>
17

18
EMBOX_UNIT_INIT(rtc_unit_init);
19

20
static struct lthread rtc_lthread;
21

22
extern struct rtc_device *global_rtc_device;
23

24
struct rtc_device *rtc_get_device(char *name) {
25
	return global_rtc_device;
26
}
27

28
int rtc_get_time(struct rtc_device *rtc, struct tm *tm) {
29
	int res;
30

31
	if (!rtc || !rtc->rtc_ops || !rtc->rtc_ops->get_time) {
32
		return -EINVAL;
33
	}
34

35
	res = rtc->rtc_ops->get_time(rtc, tm);
36

37
	return res;
38
}
39

40
int rtc_set_time(struct rtc_device *rtc, struct tm *tm) {
41
	int res;
42

43
	if (!rtc || !rtc->rtc_ops || !rtc->rtc_ops->set_time) {
44
		return -EINVAL;
45
	}
46

47
	res = rtc->rtc_ops->set_time(rtc, tm);
48

49
	return res;
50
}
51

52
int rtc_get_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) {
53
	int res;
54

55
	if (!rtc || !rtc->rtc_ops || !rtc->rtc_ops->get_alarm) {
56
		return -EINVAL;
57
	}
58

59
	res = rtc->rtc_ops->get_alarm(rtc, &(alarm->tm));
60

61
	return res;
62
}
63

64
int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) {
65
	int res;
66

67
	if (!rtc || !rtc->rtc_ops || !rtc->rtc_ops->set_alarm) {
68
		return -EINVAL;
69
	}
70

71
	res = rtc_alarm_irq_enable(rtc, 0);
72
	if (res) {
73
		goto out;
74
	}
75
	res = rtc->rtc_ops->set_alarm(rtc, &(alarm->tm));
76
	if (res) {
77
		goto out;
78
	}
79
	res = rtc_alarm_irq_enable(rtc, 1);
80

81
out:
82
	return res;
83
}
84

85
int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *t) {
86
	int res;
87

88
	if (!rtc || !t) {
89
		return -EINVAL;
90
	}
91

92
	if (rtc->irq_task) {
93
		return -EBUSY;
94
	}
95

96
	res = rtc_alarm_irq_enable(rtc, 0);
97
	if (res) {
98
		goto out;
99
	}
100
	rtc->irq_task = t;
101
	res = rtc_alarm_irq_enable(rtc, 1);
102
out:
103
	return res;
104
}
105

106
void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *t) {
107
	int res;
108

109
	if (!rtc || (rtc->irq_task != t)) {
110
		return;
111
	}
112

113
	if (rtc->irq_task) {
114
		return;
115
	}
116

117
	res = rtc_alarm_irq_enable(rtc, 0);
118
	if (res) {
119
		goto out;
120
	}
121
	rtc->irq_task = NULL;
122

123
out:
124
	return;
125
}
126

127
int rtc_alarm_irq_enable(struct rtc_device *rtc, int enabled) {
128
	int res;
129

130
	if (!rtc || !rtc->rtc_ops || !rtc->rtc_ops->alarm_irq_enable) {
131
		return -EINVAL;
132
	}
133

134
	res = rtc->rtc_ops->alarm_irq_enable(rtc,enabled);
135

136
	return res;
137
}
138

139
void rtc_update_irq(struct rtc_device *rtc, int num, uint32_t events) {
140
	rtc_alarm_irq_enable(rtc, 0);
141
	if (rtc->irq_task && rtc->irq_task->func) {
142
		lthread_launch(&rtc_lthread);
143
	}
144
}
145

146
static int rtc_lthread_handler(struct lthread *self) {
147

148
	if (!global_rtc_device) {
149
		return 0;
150
	}
151

152
	if (global_rtc_device->irq_task && global_rtc_device->irq_task->func) {
153
		global_rtc_device->irq_task->func(global_rtc_device->irq_task->private_data);
154
	}
155

156
	return 0;
157
}
158

159

160
static int rtc_unit_init(void) {
161
	lthread_init(&rtc_lthread, rtc_lthread_handler);
162
	return 0;
163
}
164

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.