1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "devsvc_manager_clnt.h"
10 #include "hdf_device_desc.h"
11 #include "hdf_device_object.h"
12 #include "hdf_log.h"
13 #include "osal_mem.h"
14 #include "platform_listener_common.h"
15 #include "rtc_core.h"
16 #include "rtc_if.h"
17
18 #define HDF_LOG_TAG rtc_service_c
19
RtcServiceIoReadTime(struct RtcHost * host,struct HdfSBuf * reply)20 static int32_t RtcServiceIoReadTime(struct RtcHost *host, struct HdfSBuf *reply)
21 {
22 int32_t ret;
23 struct RtcTime time;
24
25 ret = RtcHostReadTime(host, &time);
26 if (ret != HDF_SUCCESS) {
27 HDF_LOGE("%s: host read time fail!", __func__);
28 return ret;
29 }
30
31 if (!HdfSbufWriteBuffer(reply, &time, sizeof(time))) {
32 HDF_LOGE("%s: write buffer fail!", __func__);
33 return HDF_ERR_IO;
34 }
35
36 return HDF_SUCCESS;
37 }
38
RtcServiceIoWriteTime(struct RtcHost * host,struct HdfSBuf * data)39 static int32_t RtcServiceIoWriteTime(struct RtcHost *host, struct HdfSBuf *data)
40 {
41 int32_t ret;
42 uint32_t len;
43 struct RtcTime *time = NULL;
44
45 if (!HdfSbufReadBuffer(data, (const void **)&time, &len) || sizeof(*time) != len) {
46 HDF_LOGE("%s: read buffer fail!", __func__);
47 return HDF_ERR_IO;
48 }
49
50 ret = RtcHostWriteTime(host, time);
51 if (ret != HDF_SUCCESS) {
52 HDF_LOGE("%s: host write time fail!", __func__);
53 return ret;
54 }
55
56 return HDF_SUCCESS;
57 }
58
RtcServiceIoReadAlarm(struct RtcHost * host,struct HdfSBuf * data,struct HdfSBuf * reply)59 static int32_t RtcServiceIoReadAlarm(struct RtcHost *host, struct HdfSBuf *data, struct HdfSBuf *reply)
60 {
61 int32_t ret;
62 uint32_t alarmIndex = 0;
63 struct RtcTime time;
64
65 if (!HdfSbufReadUint32(data, &alarmIndex)) {
66 HDF_LOGE("%s: read alarmIndex fail!", __func__);
67 return HDF_ERR_IO;
68 }
69
70 ret = RtcHostReadAlarm(host, (enum RtcAlarmIndex)alarmIndex, &time);
71 if (ret != HDF_SUCCESS) {
72 HDF_LOGE("%s: host read alarm fail!", __func__);
73 return ret;
74 }
75
76 if (!HdfSbufWriteBuffer(reply, &time, sizeof(time))) {
77 HDF_LOGE("%s: write buffer fail!", __func__);
78 return HDF_ERR_IO;
79 }
80
81 return HDF_SUCCESS;
82 }
83
RtcServiceIoWriteAlarm(struct RtcHost * host,struct HdfSBuf * data)84 static int32_t RtcServiceIoWriteAlarm(struct RtcHost *host, struct HdfSBuf *data)
85 {
86 int32_t ret;
87 uint32_t len;
88 uint32_t alarmIndex = 0;
89 struct RtcTime *time = NULL;
90
91 if (!HdfSbufReadUint32(data, &alarmIndex)) {
92 HDF_LOGE("%s: read alarmIndex fail!", __func__);
93 return HDF_ERR_IO;
94 }
95
96 if (!HdfSbufReadBuffer(data, (const void **)&time, &len) || sizeof(*time) != len) {
97 HDF_LOGE("%s: read buffer fail!", __func__);
98 return HDF_ERR_IO;
99 }
100
101 ret = RtcHostWriteAlarm(host, (enum RtcAlarmIndex)alarmIndex, time);
102 if (ret != HDF_SUCCESS) {
103 HDF_LOGE("%s: host write alarm fail!", __func__);
104 return ret;
105 }
106
107 return HDF_SUCCESS;
108 }
109
RtcAlarmServiceCallback(enum RtcAlarmIndex index)110 static int32_t RtcAlarmServiceCallback(enum RtcAlarmIndex index)
111 {
112 struct RtcHost *host = NULL;
113 int32_t ret;
114 struct HdfSBuf *data = NULL;
115
116 host = (struct RtcHost *)DevSvcManagerClntGetService("HDF_PLATFORM_RTC");
117 if (host == NULL) {
118 HDF_LOGE("%s rtc get service fail", __func__);
119 return HDF_FAILURE;
120 }
121
122 data = HdfSbufObtainDefaultSize();
123 if (data == NULL) {
124 HDF_LOGE("%s HdfSbufObtainDefaultSize failed", __func__);
125 return HDF_ERR_IO;
126 }
127 if (!HdfSbufWriteUint8(data, index)) {
128 HDF_LOGE("%s: write index fail!", __func__);
129 HdfSbufRecycle(data);
130 return HDF_ERR_IO;
131 }
132 ret = HdfDeviceSendEvent(host->device, PLATFORM_LISTENER_EVENT_RTC_ALARM_NOTIFY, data);
133 if (ret != HDF_SUCCESS) {
134 HDF_LOGE("%s:send event failed, ret=%d", __func__, ret);
135 HdfSbufRecycle(data);
136 return ret;
137 }
138 HdfSbufRecycle(data);
139 return HDF_SUCCESS;
140 }
141
RtcServiceIoRegisterAlarmCallback(struct RtcHost * host,struct HdfSBuf * data)142 static int32_t RtcServiceIoRegisterAlarmCallback(struct RtcHost *host, struct HdfSBuf *data)
143 {
144 uint32_t alarmIndex;
145 if (data == NULL) {
146 return HDF_ERR_INVALID_PARAM;
147 }
148 if (!HdfSbufReadUint32(data, &alarmIndex)) {
149 HDF_LOGE("%s: read alarmIndex fail!", __func__);
150 return HDF_ERR_IO;
151 }
152
153 return RtcHostRegisterAlarmCallback(host, alarmIndex, RtcAlarmServiceCallback);
154 }
155
RtcServiceIoInterruptEnable(struct RtcHost * host,struct HdfSBuf * data)156 static int32_t RtcServiceIoInterruptEnable(struct RtcHost *host, struct HdfSBuf *data)
157 {
158 int32_t ret;
159 uint32_t alarmIndex = 0;
160 uint8_t enable = 0;
161
162 if (!HdfSbufReadUint32(data, &alarmIndex)) {
163 HDF_LOGE("%s: read alarmIndex fail!", __func__);
164 return HDF_ERR_IO;
165 }
166
167 if (!HdfSbufReadUint8(data, &enable)) {
168 HDF_LOGE("%s: read enable fail!", __func__);
169 return HDF_ERR_IO;
170 }
171
172 ret = RtcHostAlarmInterruptEnable(host, (enum RtcAlarmIndex)alarmIndex, enable);
173 if (ret != HDF_SUCCESS) {
174 HDF_LOGE("%s: host alarm interrupt enable fail! ret :%d", __func__, ret);
175 return ret;
176 }
177
178 return HDF_SUCCESS;
179 }
180
RtcServiceIoGetFreq(struct RtcHost * host,struct HdfSBuf * reply)181 static int32_t RtcServiceIoGetFreq(struct RtcHost *host, struct HdfSBuf *reply)
182 {
183 int32_t ret;
184 uint32_t freq = 0;
185
186 ret = RtcHostGetFreq(host, &freq);
187 if (ret != HDF_SUCCESS) {
188 HDF_LOGE("%s: host get freq fail! ret :%d", __func__, ret);
189 return ret;
190 }
191
192 if (!HdfSbufWriteUint32(reply, freq)) {
193 HDF_LOGE("%s: write freq fail!", __func__);
194 return HDF_ERR_IO;
195 }
196
197 return HDF_SUCCESS;
198 }
199
RtcServiceIoSetFreq(struct RtcHost * host,struct HdfSBuf * data)200 static int32_t RtcServiceIoSetFreq(struct RtcHost *host, struct HdfSBuf *data)
201 {
202 int32_t ret;
203 uint32_t freq = 0;
204
205 if (!HdfSbufReadUint32(data, &freq)) {
206 HDF_LOGE("%s: read freq fail", __func__);
207 return HDF_ERR_IO;
208 }
209
210 ret = RtcHostSetFreq(host, freq);
211 if (ret != HDF_SUCCESS) {
212 HDF_LOGE("%s: host set freq fail! ret :%d", __func__, ret);
213 return ret;
214 }
215
216 return HDF_SUCCESS;
217 }
218
RtcServiceIoReset(struct RtcHost * host)219 static int32_t RtcServiceIoReset(struct RtcHost *host)
220 {
221 int32_t ret;
222
223 ret = RtcHostReset(host);
224 if (ret != HDF_SUCCESS) {
225 HDF_LOGE("%s: host reset fail! ret :%d", __func__, ret);
226 return ret;
227 }
228
229 return HDF_SUCCESS;
230 }
231
RtcServiceIoReadReg(struct RtcHost * host,struct HdfSBuf * data,struct HdfSBuf * reply)232 static int32_t RtcServiceIoReadReg(struct RtcHost *host, struct HdfSBuf *data, struct HdfSBuf *reply)
233 {
234 int32_t ret;
235 uint8_t usrDefIndex = 0;
236 uint8_t value = 0;
237
238 if (!HdfSbufReadUint8(data, &usrDefIndex)) {
239 HDF_LOGE("%s: read usrDefIndex fail!", __func__);
240 return HDF_ERR_IO;
241 }
242
243 ret = RtcHostReadReg(host, usrDefIndex, &value);
244 if (ret != HDF_SUCCESS) {
245 HDF_LOGE("%s: host read reg fail! ret :%d", __func__, ret);
246 return ret;
247 }
248
249 if (!HdfSbufWriteUint8(reply, value)) {
250 HDF_LOGE("%s: write value fail!", __func__);
251 return HDF_ERR_IO;
252 }
253
254 return HDF_SUCCESS;
255 }
256
RtcServiceIoWriteReg(struct RtcHost * host,struct HdfSBuf * data)257 static int32_t RtcServiceIoWriteReg(struct RtcHost *host, struct HdfSBuf *data)
258 {
259 int32_t ret;
260 uint8_t usrDefIndex = 0;
261 uint8_t value = 0;
262
263 if (!HdfSbufReadUint8(data, &usrDefIndex)) {
264 HDF_LOGE("%s: read usrDefIndex fail!", __func__);
265 return HDF_ERR_IO;
266 }
267
268 if (!HdfSbufReadUint8(data, &value)) {
269 HDF_LOGE("%s: read value fail!", __func__);
270 return HDF_ERR_IO;
271 }
272
273 ret = RtcHostWriteReg(host, usrDefIndex, value);
274 if (ret != HDF_SUCCESS) {
275 HDF_LOGE("%s: host write reg fail! ret :%d", __func__, ret);
276 return ret;
277 }
278
279 return HDF_SUCCESS;
280 }
281
RtcIoDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)282 int32_t RtcIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
283 {
284 struct RtcHost *host = NULL;
285
286 if (client == NULL) {
287 HDF_LOGE("%s: client is NULL", __func__);
288 return HDF_ERR_INVALID_OBJECT;
289 }
290
291 if (client->device == NULL) {
292 HDF_LOGE("%s: client->device is NULL", __func__);
293 return HDF_ERR_INVALID_OBJECT;
294 }
295
296 if (client->device->service == NULL) {
297 HDF_LOGE("%s: client->device->service is NULL", __func__);
298 return HDF_ERR_INVALID_OBJECT;
299 }
300
301 host = (struct RtcHost *)client->device->service;
302
303 switch (cmd) {
304 case RTC_IO_READTIME:
305 return RtcServiceIoReadTime(host, reply);
306 case RTC_IO_WRITETIME:
307 return RtcServiceIoWriteTime(host, data);
308 case RTC_IO_READALARM:
309 return RtcServiceIoReadAlarm(host, data, reply);
310 case RTC_IO_WRITEALARM:
311 return RtcServiceIoWriteAlarm(host, data);
312 case RTC_IO_REGISTERALARMCALLBACK:
313 return RtcServiceIoRegisterAlarmCallback(host, data);
314 case RTC_IO_ALARMINTERRUPTENABLE:
315 return RtcServiceIoInterruptEnable(host, data);
316 case RTC_IO_GETFREQ:
317 return RtcServiceIoGetFreq(host, reply);
318 case RTC_IO_SETFREQ:
319 return RtcServiceIoSetFreq(host, data);
320 case RTC_IO_RESET:
321 return RtcServiceIoReset(host);
322 case RTC_IO_READREG:
323 return RtcServiceIoReadReg(host, data, reply);
324 case RTC_IO_WRITEREG:
325 return RtcServiceIoWriteReg(host, data);
326 default:
327 return HDF_ERR_NOT_SUPPORT;
328 }
329 }