1 /*
2 * Copyright (c) 2020-2021 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 "hdf_device_desc.h"
10 #include "platform_core.h"
11 #include "gpio_if.h"
12 #include "gpio/gpio_core.h"
13 #include "gpio/gpio_service.h"
14
15 #define HDF_LOG_TAG gpio_service
16
GpioServiceIoRead(struct HdfSBuf * data,struct HdfSBuf * reply)17 static int32_t GpioServiceIoRead(struct HdfSBuf *data, struct HdfSBuf *reply)
18 {
19 int32_t ret;
20 uint16_t gpio;
21 uint16_t value;
22
23 if (data == NULL || reply == NULL) {
24 HDF_LOGE("%s: data or reply is NULL", __func__);
25 return HDF_ERR_INVALID_PARAM;
26 }
27
28 if (!HdfSbufReadUint16(data, &gpio)) {
29 HDF_LOGE("%s: read gpio number fail", __func__);
30 return HDF_ERR_IO;
31 }
32
33 ret = GpioRead(gpio, &value);
34 if (ret != HDF_SUCCESS) {
35 HDF_LOGE("%s: read gpio fail:%d", __func__, ret);
36 return ret;
37 }
38
39 if (!HdfSbufWriteUint16(reply, value)) {
40 HDF_LOGE("%s: write subf fail:%d", __func__, ret);
41 return ret;
42 }
43
44 return ret;
45 }
46
GpioServiceIoWrite(struct HdfSBuf * data,struct HdfSBuf * reply)47 static int32_t GpioServiceIoWrite(struct HdfSBuf *data, struct HdfSBuf *reply)
48 {
49 int32_t ret;
50 uint16_t gpio;
51 uint16_t value;
52
53 if (data == NULL || reply == NULL) {
54 HDF_LOGE("%s: data or reply is NULL", __func__);
55 }
56
57 if (!HdfSbufReadUint16(data, &gpio)) {
58 HDF_LOGE("%s: read gpio number fail", __func__);
59 return HDF_ERR_IO;
60 }
61
62 if (!HdfSbufReadUint16(data, &value)) {
63 HDF_LOGE("%s: read gpio value fail", __func__);
64 return HDF_ERR_IO;
65 }
66
67 ret = GpioWrite(gpio, value);
68 if (ret != HDF_SUCCESS) {
69 HDF_LOGE("%s: write gpio fail:%d", __func__, ret);
70 return ret;
71 }
72
73 return ret;
74 }
75
GpioServiceIoGetDir(struct HdfSBuf * data,struct HdfSBuf * reply)76 static int32_t GpioServiceIoGetDir(struct HdfSBuf *data, struct HdfSBuf *reply)
77 {
78 int32_t ret;
79 uint16_t gpio;
80 uint16_t dir;
81
82 if (data == NULL || reply == NULL) {
83 HDF_LOGE("%s: data or reply is NULL", __func__);
84 return HDF_ERR_INVALID_PARAM;
85 }
86
87 if (!HdfSbufReadUint16(data, &gpio)) {
88 HDF_LOGE("%s: read gpio number fail", __func__);
89 return HDF_ERR_IO;
90 }
91
92 ret = GpioGetDir(gpio, &dir);
93 if (ret != HDF_SUCCESS) {
94 HDF_LOGE("%s: get gpio dir fail:%d", __func__, ret);
95 return ret;
96 }
97
98 if (!HdfSbufWriteUint16(reply, dir)) {
99 HDF_LOGE("%s: write subf fail:%d", __func__, ret);
100 return ret;
101 }
102
103 return ret;
104 }
105
GpioServiceIoSetDir(struct HdfSBuf * data,struct HdfSBuf * reply)106 static int32_t GpioServiceIoSetDir(struct HdfSBuf *data, struct HdfSBuf *reply)
107 {
108 int32_t ret;
109 uint16_t gpio;
110 uint16_t dir;
111
112 if (data == NULL || reply == NULL) {
113 HDF_LOGE("%s: data or reply is NULL", __func__);
114 return HDF_ERR_INVALID_PARAM;
115 }
116
117 if (!HdfSbufReadUint16(data, &gpio)) {
118 HDF_LOGE("%s: read gpio number fail", __func__);
119 return HDF_ERR_IO;
120 }
121
122 if (!HdfSbufReadUint16(data, &dir)) {
123 HDF_LOGE("%s: read gpio dir fail", __func__);
124 return HDF_ERR_IO;
125 }
126
127 ret = GpioSetDir(gpio, dir);
128 if (ret != HDF_SUCCESS) {
129 HDF_LOGE("%s: set gpio dir fail:%d", __func__, ret);
130 return ret;
131 }
132
133 return ret;
134 }
135
GpioServiceIoSetIrq(struct HdfSBuf * data,struct HdfSBuf * reply)136 static int32_t GpioServiceIoSetIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
137 {
138 uint16_t gpio;
139 uint16_t mode;
140
141 if (data == NULL || reply == NULL) {
142 HDF_LOGE("%s: data or reply is NULL", __func__);
143 return HDF_ERR_INVALID_PARAM;
144 }
145
146 if (!HdfSbufReadUint16(data, &gpio)) {
147 HDF_LOGE("%s: read gpio fail", __func__);
148 return HDF_ERR_IO;
149 }
150
151 if (!HdfSbufReadUint16(data, &mode)) {
152 HDF_LOGE("%s: read gpio mode fail", __func__);
153 return HDF_ERR_IO;
154 }
155
156 return HDF_SUCCESS;
157 }
158
GpioServiceIoUnsetIrq(struct HdfSBuf * data,struct HdfSBuf * reply)159 static int32_t GpioServiceIoUnsetIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
160 {
161 uint16_t gpio;
162 (void)reply;
163
164 if (data == NULL) {
165 HDF_LOGE("%s: data is NULL", __func__);
166 return HDF_ERR_INVALID_PARAM;
167 }
168
169 if (!HdfSbufReadUint16(data, &gpio)) {
170 HDF_LOGE("%s: read gpio number fail", __func__);
171 return HDF_ERR_IO;
172 }
173
174 return HDF_SUCCESS;
175 }
176
GpioServiceIoEnableIrq(struct HdfSBuf * data,struct HdfSBuf * reply)177 static int32_t GpioServiceIoEnableIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
178 {
179 int32_t ret;
180 uint16_t gpio;
181 (void)reply;
182
183 if (data == NULL) {
184 HDF_LOGE("%s: data is NULL", __func__);
185 return HDF_ERR_INVALID_PARAM;
186 }
187
188 if (!HdfSbufReadUint16(data, &gpio)) {
189 HDF_LOGE("%s: read gpio number fail", __func__);
190 return HDF_ERR_IO;
191 }
192
193 ret = GpioEnableIrq(gpio);
194 if (ret != HDF_SUCCESS) {
195 HDF_LOGE("%s: enable gpio irq fail:%d", __func__, ret);
196 return ret;
197 }
198
199 return ret;
200 }
201
GpioServiceIoDisableIrq(struct HdfSBuf * data,struct HdfSBuf * reply)202 static int32_t GpioServiceIoDisableIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
203 {
204 int32_t ret;
205 uint16_t gpio;
206 (void)reply;
207
208 if (data == NULL) {
209 HDF_LOGE("%s: data is NULL", __func__);
210 return HDF_ERR_INVALID_PARAM;
211 }
212
213 if (!HdfSbufReadUint16(data, &gpio)) {
214 HDF_LOGE("%s: read gpio number fail", __func__);
215 return HDF_ERR_IO;
216 }
217
218 ret = GpioDisableIrq(gpio);
219 if (ret != HDF_SUCCESS) {
220 HDF_LOGE("%s: disable gpio irq fail:%d", __func__, ret);
221 return ret;
222 }
223
224 return ret;
225 }
226
227
GpioServiceDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)228 static int32_t GpioServiceDispatch(struct HdfDeviceIoClient *client, int cmd,
229 struct HdfSBuf *data, struct HdfSBuf *reply)
230 {
231 int32_t ret;
232
233 switch (cmd) {
234 case GPIO_IO_READ:
235 return GpioServiceIoRead(data, reply);
236 case GPIO_IO_WRITE:
237 return GpioServiceIoWrite(data, reply);
238 case GPIO_IO_GETDIR:
239 return GpioServiceIoGetDir(data, reply);
240 case GPIO_IO_SETDIR:
241 return GpioServiceIoSetDir(data, reply);
242 case GPIO_IO_SETIRQ:
243 return GpioServiceIoSetIrq(data, reply);
244 case GPIO_IO_UNSETIRQ:
245 return GpioServiceIoUnsetIrq(data, reply);
246 case GPIO_IO_ENABLEIRQ:
247 return GpioServiceIoEnableIrq(data, reply);
248 case GPIO_IO_DISABLEIRQ:
249 return GpioServiceIoDisableIrq(data, reply);
250 default:
251 ret = HDF_ERR_NOT_SUPPORT;
252 break;
253 }
254 return ret;
255 }
256
GpioServiceBind(struct HdfDeviceObject * device)257 static int32_t GpioServiceBind(struct HdfDeviceObject *device)
258 {
259 int32_t ret;
260 struct PlatformManager *gpioMgr = NULL;
261
262 PLAT_LOGI("GpioServiceBind: enter");
263 if (device == NULL) {
264 HDF_LOGE("GpioServiceBind: device is NULL");
265 return HDF_ERR_INVALID_OBJECT;
266 }
267
268 gpioMgr = GpioManagerGet();
269 if (gpioMgr == NULL) {
270 HDF_LOGE("GpioServiceBind: get gpio manager fail");
271 return HDF_PLT_ERR_DEV_GET;
272 }
273
274 ret = PlatformDeviceCreateService(&gpioMgr->device, GpioServiceDispatch);
275 if (ret != HDF_SUCCESS) {
276 HDF_LOGE("GpioServiceBind: create gpio service fail:%d", ret);
277 return ret;
278 }
279
280 ret = PlatformDeviceBind(&gpioMgr->device, device);
281 if (ret != HDF_SUCCESS) {
282 HDF_LOGE("GpioServiceBind: bind gpio device fail:%d", ret);
283 (void)PlatformDeviceDestroyService(&gpioMgr->device);
284 return ret;
285 }
286
287 PLAT_LOGI("GpioServiceBind: success");
288 return HDF_SUCCESS;
289 }
290
GpioServiceInit(struct HdfDeviceObject * device)291 static int32_t GpioServiceInit(struct HdfDeviceObject *device)
292 {
293 (void)device;
294 return HDF_SUCCESS;
295 }
296
GpioServiceRelease(struct HdfDeviceObject * device)297 static void GpioServiceRelease(struct HdfDeviceObject *device)
298 {
299 struct PlatformManager *gpioMgr = NULL;
300
301 PLAT_LOGI("GpioServiceRelease: enter");
302 if (device == NULL) {
303 PLAT_LOGI("GpioServiceRelease: device is null");
304 return;
305 }
306
307 gpioMgr = GpioManagerGet();
308 if (gpioMgr == NULL) {
309 HDF_LOGE("GpioServiceBind: get gpio manager fail");
310 return;
311 }
312
313 (void)PlatformDeviceUnbind(&gpioMgr->device, device);
314 (void)PlatformDeviceDestroyService(&gpioMgr->device);
315 PLAT_LOGI("GpioServiceRelease: done");
316 }
317
318 struct HdfDriverEntry g_gpioServiceEntry = {
319 .moduleVersion = 1,
320 .Bind = GpioServiceBind,
321 .Init = GpioServiceInit,
322 .Release = GpioServiceRelease,
323 .moduleName = "HDF_PLATFORM_GPIO_MANAGER",
324 };
325 HDF_INIT(g_gpioServiceEntry);
326