1 /*
2 * Copyright (c) 2020-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 "gpio/gpio_service.h"
10 #include "gpio/gpio_core.h"
11 #include "gpio_if.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_device_object.h"
14 #include "platform_core.h"
15 #include "platform_listener_common.h"
16 #include "securec.h"
17
18 #define HDF_LOG_TAG gpio_service
19
GpioServiceIoRead(struct HdfSBuf * data,struct HdfSBuf * reply)20 static int32_t GpioServiceIoRead(struct HdfSBuf *data, struct HdfSBuf *reply)
21 {
22 int32_t ret;
23 uint16_t gpio;
24 uint16_t value;
25
26 if (data == NULL || reply == NULL) {
27 HDF_LOGE("%s: data or reply is NULL!", __func__);
28 return HDF_ERR_INVALID_PARAM;
29 }
30
31 if (!HdfSbufReadUint16(data, &gpio)) {
32 HDF_LOGE("%s: failed to read gpio number!", __func__);
33 return HDF_ERR_IO;
34 }
35
36 ret = GpioRead(gpio, &value);
37 if (ret != HDF_SUCCESS) {
38 HDF_LOGE("%s: failed to read gpio:%d!", __func__, ret);
39 return ret;
40 }
41
42 if (!HdfSbufWriteUint16(reply, value)) {
43 HDF_LOGE("%s: failed to write subf:%d!", __func__, ret);
44 return ret;
45 }
46
47 return ret;
48 }
49
GpioServiceIoWrite(struct HdfSBuf * data,struct HdfSBuf * reply)50 static int32_t GpioServiceIoWrite(struct HdfSBuf *data, struct HdfSBuf *reply)
51 {
52 int32_t ret;
53 uint16_t gpio;
54 uint16_t value;
55
56 (void)reply;
57 if (data == NULL) {
58 HDF_LOGE("%s: data is NULL!", __func__);
59 }
60
61 if (!HdfSbufReadUint16(data, &gpio)) {
62 HDF_LOGE("%s: failed to read gpio number!", __func__);
63 return HDF_ERR_IO;
64 }
65
66 if (!HdfSbufReadUint16(data, &value)) {
67 HDF_LOGE("%s: failed to read gpio value!", __func__);
68 return HDF_ERR_IO;
69 }
70
71 ret = GpioWrite(gpio, value);
72 if (ret != HDF_SUCCESS) {
73 HDF_LOGE("%s: failed to write gpio:%d!", __func__, ret);
74 return ret;
75 }
76
77 return ret;
78 }
79
GpioServiceIoGetDir(struct HdfSBuf * data,struct HdfSBuf * reply)80 static int32_t GpioServiceIoGetDir(struct HdfSBuf *data, struct HdfSBuf *reply)
81 {
82 int32_t ret;
83 uint16_t gpio;
84 uint16_t dir;
85
86 if (data == NULL || reply == NULL) {
87 HDF_LOGE("%s: data or reply is NULL!", __func__);
88 return HDF_ERR_INVALID_PARAM;
89 }
90
91 if (!HdfSbufReadUint16(data, &gpio)) {
92 HDF_LOGE("%s: failed to read gpio number!", __func__);
93 return HDF_ERR_IO;
94 }
95
96 ret = GpioGetDir(gpio, &dir);
97 if (ret != HDF_SUCCESS) {
98 HDF_LOGE("%s: failed to get gpio dir:%d!", __func__, ret);
99 return ret;
100 }
101
102 if (!HdfSbufWriteUint16(reply, dir)) {
103 HDF_LOGE("%s: failed to write subf:%d!", __func__, ret);
104 return ret;
105 }
106
107 return ret;
108 }
109
GpioServiceIoSetDir(struct HdfSBuf * data,struct HdfSBuf * reply)110 static int32_t GpioServiceIoSetDir(struct HdfSBuf *data, struct HdfSBuf *reply)
111 {
112 int32_t ret;
113 uint16_t gpio;
114 uint16_t dir;
115
116 (void)reply;
117 if (data == NULL) {
118 HDF_LOGE("%s: data is NULL!", __func__);
119 return HDF_ERR_INVALID_PARAM;
120 }
121
122 if (!HdfSbufReadUint16(data, &gpio)) {
123 HDF_LOGE("%s: failed to read gpio number!", __func__);
124 return HDF_ERR_IO;
125 }
126
127 if (!HdfSbufReadUint16(data, &dir)) {
128 HDF_LOGE("%s: failed to read gpio dir!", __func__);
129 return HDF_ERR_IO;
130 }
131
132 ret = GpioSetDir(gpio, dir);
133 if (ret != HDF_SUCCESS) {
134 HDF_LOGE("%s: failed to set gpio dir:%d!", __func__, ret);
135 return ret;
136 }
137
138 return ret;
139 }
140
GpioServiceUpdate(uint16_t gpio)141 static void GpioServiceUpdate(uint16_t gpio)
142 {
143 int32_t ret;
144 uint32_t id;
145 struct HdfSBuf *data = NULL;
146 struct PlatformManager *gpioMgr = NULL;
147
148 gpioMgr = GpioManagerGet();
149 if (gpioMgr == NULL || gpioMgr->device.hdfDev == NULL) {
150 HDF_LOGE("%s: failed to get gpio manager!", __func__);
151 return;
152 }
153
154 id = PLATFORM_LISTENER_EVENT_GPIO_INT_NOTIFY;
155 data = HdfSbufObtainDefaultSize();
156 if (data == NULL) {
157 HDF_LOGE("%s: failed to obtain data!", __func__);
158 return;
159 }
160 if (!HdfSbufWriteUint16(data, gpio)) {
161 HDF_LOGE("%s: failed to write gpio!", __func__);
162 HdfSbufRecycle(data);
163 return;
164 }
165 ret = HdfDeviceSendEvent(gpioMgr->device.hdfDev, id, data);
166 HdfSbufRecycle(data);
167 HDF_LOGD("%s:set service info done, ret = %d, id = %d!", __func__, ret, id);
168 }
169
GpioServiceIrqFunc(uint16_t gpio,void * data)170 static int32_t GpioServiceIrqFunc(uint16_t gpio, void *data)
171 {
172 (void)data;
173 HDF_LOGD("%s:%d", __func__, gpio);
174 GpioServiceUpdate(gpio);
175 return HDF_SUCCESS;
176 }
177
GpioServiceIoSetIrq(struct HdfSBuf * data,struct HdfSBuf * reply)178 static int32_t GpioServiceIoSetIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
179 {
180 uint16_t gpio;
181 uint16_t mode;
182 int32_t ret;
183
184 (void)reply;
185 if (data == NULL) {
186 HDF_LOGE("%s: data is NULL!", __func__);
187 return HDF_ERR_INVALID_PARAM;
188 }
189
190 if (!HdfSbufReadUint16(data, &gpio)) {
191 HDF_LOGE("%s: failed to read gpio number!", __func__);
192 return HDF_ERR_IO;
193 }
194
195 if (!HdfSbufReadUint16(data, &mode)) {
196 HDF_LOGE("%s: failed to read gpio mode!", __func__);
197 return HDF_ERR_IO;
198 }
199
200 ret = GpioSetIrq(gpio, mode, GpioServiceIrqFunc, NULL);
201 if (ret != HDF_SUCCESS) {
202 HDF_LOGE("%s: failed to set gpio irq:%d!", __func__, ret);
203 return ret;
204 }
205 return HDF_SUCCESS;
206 }
207
GpioServiceIoUnsetIrq(struct HdfSBuf * data,struct HdfSBuf * reply)208 static int32_t GpioServiceIoUnsetIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
209 {
210 uint16_t gpio;
211
212 (void)reply;
213 if (data == NULL) {
214 HDF_LOGE("%s: data is NULL!", __func__);
215 return HDF_ERR_INVALID_PARAM;
216 }
217
218 if (!HdfSbufReadUint16(data, &gpio)) {
219 HDF_LOGE("%s: failed to read gpio number!", __func__);
220 return HDF_ERR_IO;
221 }
222
223 if (GpioUnsetIrq(gpio, NULL) != HDF_SUCCESS) {
224 HDF_LOGE("%s: failed to unset gpio irq!", __func__);
225 return HDF_ERR_IO;
226 }
227
228 return HDF_SUCCESS;
229 }
230
GpioServiceIoEnableIrq(struct HdfSBuf * data,struct HdfSBuf * reply)231 static int32_t GpioServiceIoEnableIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
232 {
233 int32_t ret;
234 uint16_t gpio;
235
236 (void)reply;
237 if (data == NULL) {
238 HDF_LOGE("%s: data is NULL!", __func__);
239 return HDF_ERR_INVALID_PARAM;
240 }
241
242 if (!HdfSbufReadUint16(data, &gpio)) {
243 HDF_LOGE("%s: failed to read gpio number!", __func__);
244 return HDF_ERR_IO;
245 }
246
247 ret = GpioEnableIrq(gpio);
248 if (ret != HDF_SUCCESS) {
249 HDF_LOGE("%s: failed to enable gpio irq:%d!", __func__, ret);
250 return ret;
251 }
252
253 return ret;
254 }
255
GpioServiceIoDisableIrq(struct HdfSBuf * data,struct HdfSBuf * reply)256 static int32_t GpioServiceIoDisableIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
257 {
258 int32_t ret;
259 uint16_t gpio;
260
261 (void)reply;
262 if (data == NULL) {
263 HDF_LOGE("%s: data is NULL!", __func__);
264 return HDF_ERR_INVALID_PARAM;
265 }
266
267 if (!HdfSbufReadUint16(data, &gpio)) {
268 HDF_LOGE("%s: failed to read gpio number!", __func__);
269 return HDF_ERR_IO;
270 }
271
272 ret = GpioDisableIrq(gpio);
273 if (ret != HDF_SUCCESS) {
274 HDF_LOGE("%s: failed to disable gpio irq:%d!", __func__, ret);
275 return ret;
276 }
277
278 return ret;
279 }
280
GpioServiceIoGetNumByName(struct HdfSBuf * data,struct HdfSBuf * reply)281 static int32_t GpioServiceIoGetNumByName(struct HdfSBuf *data, struct HdfSBuf *reply)
282 {
283 int32_t ret;
284 const char *gpioNameData = NULL;
285
286 if (data == NULL || reply == NULL) {
287 HDF_LOGE("%s: data or reply is NULL!", __func__);
288 return HDF_ERR_INVALID_PARAM;
289 }
290
291 gpioNameData = HdfSbufReadString(data);
292 if (gpioNameData == NULL) {
293 HDF_LOGE("%s: gpioNameData is NULL!", __func__);
294 return HDF_ERR_IO;
295 }
296
297 ret = GpioGetByName(gpioNameData);
298 if (ret < 0) {
299 HDF_LOGE("%s: failed to get gpio global number by gpioName!", __func__);
300 return ret;
301 }
302
303 if (!HdfSbufWriteInt32(reply, ret)) {
304 HDF_LOGE("%s: failed to write gpio global number!", __func__);
305 return HDF_ERR_IO;
306 }
307
308 return HDF_SUCCESS;
309 }
310
GpioServiceDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)311 static int32_t GpioServiceDispatch(
312 struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
313 {
314 int32_t ret;
315
316 (void)client;
317 switch (cmd) {
318 case GPIO_IO_READ:
319 return GpioServiceIoRead(data, reply);
320 case GPIO_IO_WRITE:
321 return GpioServiceIoWrite(data, reply);
322 case GPIO_IO_GETDIR:
323 return GpioServiceIoGetDir(data, reply);
324 case GPIO_IO_SETDIR:
325 return GpioServiceIoSetDir(data, reply);
326 case GPIO_IO_SETIRQ:
327 return GpioServiceIoSetIrq(data, reply);
328 case GPIO_IO_UNSETIRQ:
329 return GpioServiceIoUnsetIrq(data, reply);
330 case GPIO_IO_ENABLEIRQ:
331 return GpioServiceIoEnableIrq(data, reply);
332 case GPIO_IO_DISABLEIRQ:
333 return GpioServiceIoDisableIrq(data, reply);
334 case GPIO_IO_GET_NUM_BY_NAME:
335 return GpioServiceIoGetNumByName(data, reply);
336 default:
337 ret = HDF_ERR_NOT_SUPPORT;
338 break;
339 }
340 return ret;
341 }
342
GpioServiceBind(struct HdfDeviceObject * device)343 static int32_t GpioServiceBind(struct HdfDeviceObject *device)
344 {
345 int32_t ret;
346 struct PlatformManager *gpioMgr = NULL;
347
348 HDF_LOGI("%s: enter", __func__);
349 if (device == NULL) {
350 HDF_LOGE("%s: device is NULL!", __func__);
351 return HDF_ERR_INVALID_OBJECT;
352 }
353
354 gpioMgr = GpioManagerGet();
355 if (gpioMgr == NULL) {
356 HDF_LOGE("%s: failed to get gpio manager!", __func__);
357 return HDF_PLT_ERR_DEV_GET;
358 }
359
360 ret = PlatformDeviceCreateService(&gpioMgr->device, GpioServiceDispatch);
361 if (ret != HDF_SUCCESS) {
362 HDF_LOGE("%s: failed to create gpio service:%d!", __func__, ret);
363 return ret;
364 }
365
366 ret = PlatformDeviceBind(&gpioMgr->device, device);
367 if (ret != HDF_SUCCESS) {
368 HDF_LOGE("%s: failed to bind gpio device:%d!", __func__, ret);
369 (void)PlatformDeviceDestroyService(&gpioMgr->device);
370 return ret;
371 }
372
373 HDF_LOGI("%s: success!", __func__);
374 return HDF_SUCCESS;
375 }
376
GpioServiceInit(struct HdfDeviceObject * device)377 static int32_t GpioServiceInit(struct HdfDeviceObject *device)
378 {
379 (void)device;
380 return HDF_SUCCESS;
381 }
382
GpioServiceRelease(struct HdfDeviceObject * device)383 static void GpioServiceRelease(struct HdfDeviceObject *device)
384 {
385 struct PlatformManager *gpioMgr = NULL;
386
387 HDF_LOGI("%s: enter", __func__);
388 if (device == NULL) {
389 HDF_LOGI("%s: device is NULL!", __func__);
390 return;
391 }
392
393 gpioMgr = GpioManagerGet();
394 if (gpioMgr == NULL) {
395 HDF_LOGE("%s: failed to get gpio manager!", __func__);
396 return;
397 }
398
399 (void)PlatformDeviceUnbind(&gpioMgr->device, device);
400 (void)PlatformDeviceDestroyService(&gpioMgr->device);
401 HDF_LOGI("%s: done!", __func__);
402 }
403
404 struct HdfDriverEntry g_gpioServiceEntry = {
405 .moduleVersion = 1,
406 .Bind = GpioServiceBind,
407 .Init = GpioServiceInit,
408 .Release = GpioServiceRelease,
409 .moduleName = "HDF_PLATFORM_GPIO_MANAGER",
410 };
411 HDF_INIT(g_gpioServiceEntry);
412