• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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