1 /*
2 * Copyright (c) 2022-2023 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("RtcServiceIoReadTime: host read time fail!");
28 return ret;
29 }
30
31 if (!HdfSbufWriteBuffer(reply, &time, sizeof(time))) {
32 HDF_LOGE("RtcServiceIoReadTime: write buffer fail!");
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("RtcServiceIoWriteTime: read buffer fail!");
47 return HDF_ERR_IO;
48 }
49
50 ret = RtcHostWriteTime(host, time);
51 if (ret != HDF_SUCCESS) {
52 HDF_LOGE("RtcServiceIoWriteTime: host write time fail!");
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("RtcServiceIoReadAlarm: read alarmIndex fail!");
67 return HDF_ERR_IO;
68 }
69
70 ret = RtcHostReadAlarm(host, (enum RtcAlarmIndex)alarmIndex, &time);
71 if (ret != HDF_SUCCESS) {
72 HDF_LOGE("RtcServiceIoReadAlarm: host read alarm fail!");
73 return ret;
74 }
75
76 if (!HdfSbufWriteBuffer(reply, &time, sizeof(time))) {
77 HDF_LOGE("RtcServiceIoReadAlarm: write buffer fail!");
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("RtcServiceIoWriteAlarm: read alarmIndex fail!");
93 return HDF_ERR_IO;
94 }
95
96 if (!HdfSbufReadBuffer(data, (const void **)&time, &len) || sizeof(*time) != len) {
97 HDF_LOGE("RtcServiceIoWriteAlarm: read buffer fail!");
98 return HDF_ERR_IO;
99 }
100
101 ret = RtcHostWriteAlarm(host, (enum RtcAlarmIndex)alarmIndex, time);
102 if (ret != HDF_SUCCESS) {
103 HDF_LOGE("RtcServiceIoWriteAlarm: host write alarm fail!");
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("RtcAlarmServiceCallback: rtc get service fail!");
119 return HDF_FAILURE;
120 }
121
122 data = HdfSbufObtainDefaultSize();
123 if (data == NULL) {
124 HDF_LOGE("RtcAlarmServiceCallback: fail to obtain data!");
125 return HDF_ERR_IO;
126 }
127 if (!HdfSbufWriteUint8(data, index)) {
128 HDF_LOGE("RtcAlarmServiceCallback: write index fail!");
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("RtcAlarmServiceCallback: send event fail, ret=%d!", 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
146 if (data == NULL) {
147 HDF_LOGE("RtcServiceIoRegisterAlarmCallback: data is null!");
148 return HDF_ERR_INVALID_PARAM;
149 }
150 if (!HdfSbufReadUint32(data, &alarmIndex)) {
151 HDF_LOGE("RtcServiceIoRegisterAlarmCallback: read alarmIndex fail!");
152 return HDF_ERR_IO;
153 }
154
155 return RtcHostRegisterAlarmCallback(host, alarmIndex, RtcAlarmServiceCallback);
156 }
157
RtcServiceIoInterruptEnable(struct RtcHost * host,struct HdfSBuf * data)158 static int32_t RtcServiceIoInterruptEnable(struct RtcHost *host, struct HdfSBuf *data)
159 {
160 int32_t ret;
161 uint32_t alarmIndex = 0;
162 uint8_t enable = 0;
163
164 if (!HdfSbufReadUint32(data, &alarmIndex)) {
165 HDF_LOGE("RtcServiceIoInterruptEnable: read alarmIndex fail!");
166 return HDF_ERR_IO;
167 }
168
169 if (!HdfSbufReadUint8(data, &enable)) {
170 HDF_LOGE("RtcServiceIoInterruptEnable: read enable fail!");
171 return HDF_ERR_IO;
172 }
173
174 ret = RtcHostAlarmInterruptEnable(host, (enum RtcAlarmIndex)alarmIndex, enable);
175 if (ret != HDF_SUCCESS) {
176 HDF_LOGE("RtcServiceIoInterruptEnable: host alarm interrupt enable fail, ret: %d!", ret);
177 return ret;
178 }
179
180 return HDF_SUCCESS;
181 }
182
RtcServiceIoGetFreq(struct RtcHost * host,struct HdfSBuf * reply)183 static int32_t RtcServiceIoGetFreq(struct RtcHost *host, struct HdfSBuf *reply)
184 {
185 int32_t ret;
186 uint32_t freq = 0;
187
188 ret = RtcHostGetFreq(host, &freq);
189 if (ret != HDF_SUCCESS) {
190 HDF_LOGE("RtcServiceIoGetFreq: host get freq fail! ret: %d!", ret);
191 return ret;
192 }
193
194 if (!HdfSbufWriteUint32(reply, freq)) {
195 HDF_LOGE("RtcServiceIoGetFreq: write freq fail!");
196 return HDF_ERR_IO;
197 }
198
199 return HDF_SUCCESS;
200 }
201
RtcServiceIoSetFreq(struct RtcHost * host,struct HdfSBuf * data)202 static int32_t RtcServiceIoSetFreq(struct RtcHost *host, struct HdfSBuf *data)
203 {
204 int32_t ret;
205 uint32_t freq = 0;
206
207 if (!HdfSbufReadUint32(data, &freq)) {
208 HDF_LOGE("RtcServiceIoSetFreq: read freq fail");
209 return HDF_ERR_IO;
210 }
211
212 ret = RtcHostSetFreq(host, freq);
213 if (ret != HDF_SUCCESS) {
214 HDF_LOGE("RtcServiceIoSetFreq: host set freq fail! ret: %d!", ret);
215 return ret;
216 }
217
218 return HDF_SUCCESS;
219 }
220
RtcServiceIoReset(struct RtcHost * host)221 static int32_t RtcServiceIoReset(struct RtcHost *host)
222 {
223 int32_t ret;
224
225 ret = RtcHostReset(host);
226 if (ret != HDF_SUCCESS) {
227 HDF_LOGE("RtcServiceIoReset: host reset fail, ret: %d!", ret);
228 return ret;
229 }
230
231 return HDF_SUCCESS;
232 }
233
RtcServiceIoReadReg(struct RtcHost * host,struct HdfSBuf * data,struct HdfSBuf * reply)234 static int32_t RtcServiceIoReadReg(struct RtcHost *host, struct HdfSBuf *data, struct HdfSBuf *reply)
235 {
236 int32_t ret;
237 uint8_t usrDefIndex = 0;
238 uint8_t value = 0;
239
240 if (!HdfSbufReadUint8(data, &usrDefIndex)) {
241 HDF_LOGE("RtcServiceIoReadReg: read usrDefIndex fail!");
242 return HDF_ERR_IO;
243 }
244
245 ret = RtcHostReadReg(host, usrDefIndex, &value);
246 if (ret != HDF_SUCCESS) {
247 HDF_LOGE("RtcServiceIoReadReg: host read reg fail, ret: %d!", ret);
248 return ret;
249 }
250
251 if (!HdfSbufWriteUint8(reply, value)) {
252 HDF_LOGE("RtcServiceIoReadReg: write value fail!");
253 return HDF_ERR_IO;
254 }
255
256 return HDF_SUCCESS;
257 }
258
RtcServiceIoWriteReg(struct RtcHost * host,struct HdfSBuf * data)259 static int32_t RtcServiceIoWriteReg(struct RtcHost *host, struct HdfSBuf *data)
260 {
261 int32_t ret;
262 uint8_t usrDefIndex = 0;
263 uint8_t value = 0;
264
265 if (!HdfSbufReadUint8(data, &usrDefIndex)) {
266 HDF_LOGE("RtcServiceIoWriteReg: read usrDefIndex fail!");
267 return HDF_ERR_IO;
268 }
269
270 if (!HdfSbufReadUint8(data, &value)) {
271 HDF_LOGE("RtcServiceIoWriteReg: read value fail!");
272 return HDF_ERR_IO;
273 }
274
275 ret = RtcHostWriteReg(host, usrDefIndex, value);
276 if (ret != HDF_SUCCESS) {
277 HDF_LOGE("RtcServiceIoWriteReg: host write reg fail, ret: %d!", ret);
278 return ret;
279 }
280
281 return HDF_SUCCESS;
282 }
283
RtcIoDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)284 int32_t RtcIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
285 {
286 struct RtcHost *host = NULL;
287
288 if (client == NULL) {
289 HDF_LOGE("RtcIoDispatch: client is null!");
290 return HDF_ERR_INVALID_OBJECT;
291 }
292
293 if (client->device == NULL) {
294 HDF_LOGE("RtcIoDispatch: client->device is null!");
295 return HDF_ERR_INVALID_OBJECT;
296 }
297
298 if (client->device->service == NULL) {
299 HDF_LOGE("RtcIoDispatch: client->device->service is null!");
300 return HDF_ERR_INVALID_OBJECT;
301 }
302
303 host = (struct RtcHost *)client->device->service;
304
305 switch (cmd) {
306 case RTC_IO_READTIME:
307 return RtcServiceIoReadTime(host, reply);
308 case RTC_IO_WRITETIME:
309 return RtcServiceIoWriteTime(host, data);
310 case RTC_IO_READALARM:
311 return RtcServiceIoReadAlarm(host, data, reply);
312 case RTC_IO_WRITEALARM:
313 return RtcServiceIoWriteAlarm(host, data);
314 case RTC_IO_REGISTERALARMCALLBACK:
315 return RtcServiceIoRegisterAlarmCallback(host, data);
316 case RTC_IO_ALARMINTERRUPTENABLE:
317 return RtcServiceIoInterruptEnable(host, data);
318 case RTC_IO_GETFREQ:
319 return RtcServiceIoGetFreq(host, reply);
320 case RTC_IO_SETFREQ:
321 return RtcServiceIoSetFreq(host, data);
322 case RTC_IO_RESET:
323 return RtcServiceIoReset(host);
324 case RTC_IO_READREG:
325 return RtcServiceIoReadReg(host, data, reply);
326 case RTC_IO_WRITEREG:
327 return RtcServiceIoWriteReg(host, data);
328 default:
329 HDF_LOGE("RtcIoDispatch: cmd %d is not support!", cmd);
330 return HDF_ERR_NOT_SUPPORT;
331 }
332 }
333