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 "osal_mem.h"
11 #include "gpio_if.h"
12 #include "hdf_core_log.h"
13 #include "hdf_input_device_manager.h"
14 #include "event_hub.h"
15 #include "hdf_key.h"
16
17 #define CHECK_PARSER_RET(ret, str) do { \
18 if ((ret) != HDF_SUCCESS) { \
19 HDF_LOGE("%s: %s failed, ret = %d!", __func__, str, ret); \
20 return HDF_FAILURE; \
21 } \
22 } while (0)
23
KeyIrqHandle(uint16_t intGpioNum,void * data)24 int32_t KeyIrqHandle(uint16_t intGpioNum, void *data)
25 {
26 int32_t ret;
27 uint16_t gpioValue = 0;
28 KeyDriver *driver = (KeyDriver *)data;
29 if (driver == NULL) {
30 return HDF_FAILURE;
31 }
32 KeyEventData *event = &driver->eventData;
33 if (event == NULL) {
34 return HDF_FAILURE;
35 }
36 ret = GpioDisableIrq(intGpioNum);
37 if (ret != HDF_SUCCESS) {
38 HDF_LOGE("%s: disable irq failed, ret %d", __func__, ret);
39 }
40
41 ret = GpioRead(intGpioNum, &gpioValue);
42 if (ret != HDF_SUCCESS) {
43 HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret);
44 return HDF_FAILURE;
45 }
46 uint64_t curTime = OsalGetSysTimeMs();
47 driver->preStatus = gpioValue;
48 driver->timeStamp = curTime;
49
50 if (gpioValue == GPIO_VAL_LOW) {
51 event->definedEvent = INPUT_KEY_DOWN;
52 input_report_key(driver->inputdev, KEY_POWER, 1);
53 } else if (gpioValue == GPIO_VAL_HIGH) {
54 event->definedEvent = INPUT_KEY_UP;
55 input_report_key(driver->inputdev, KEY_POWER, 0);
56 }
57 input_sync(driver->inputdev);
58
59 GpioEnableIrq(intGpioNum);
60 return HDF_SUCCESS;
61 }
62
SetupKeyIrq(KeyDriver * keyDrv)63 static int32_t SetupKeyIrq(KeyDriver *keyDrv)
64 {
65 uint16_t intGpioNum = keyDrv->keyCfg->gpioNum;
66 uint16_t irqFlag = keyDrv->keyCfg->irqFlag;
67 int32_t ret = GpioSetDir(intGpioNum, GPIO_DIR_IN);
68 if (ret != HDF_SUCCESS) {
69 HDF_LOGE("%s: gpio set dir failed, ret %d", __func__, ret);
70 return ret;
71 }
72 ret = GpioSetIrq(intGpioNum, irqFlag | GPIO_IRQ_USING_THREAD, KeyIrqHandle, keyDrv);
73 if (ret != HDF_SUCCESS) {
74 HDF_LOGE("%s: register irq failed, ret %d", __func__, ret);
75 return ret;
76 }
77 ret = GpioEnableIrq(intGpioNum);
78 if (ret != HDF_SUCCESS) {
79 HDF_LOGE("%s: enable irq failed, ret %d", __func__, ret);
80 return HDF_FAILURE;
81 }
82 return HDF_SUCCESS;
83 }
84
KeyInit(KeyDriver * keyDrv)85 static int32_t KeyInit(KeyDriver *keyDrv)
86 {
87 int32_t ret = SetupKeyIrq(keyDrv);
88 CHECK_RETURN_VALUE(ret);
89 return HDF_SUCCESS;
90 }
91
KeyConfigInstance(struct HdfDeviceObject * device)92 static KeyChipCfg *KeyConfigInstance(struct HdfDeviceObject *device)
93 {
94 KeyChipCfg *keyCfg = (KeyChipCfg *)OsalMemAlloc(sizeof(KeyChipCfg));
95 if (keyCfg == NULL) {
96 HDF_LOGE("%s: malloc key config failed", __func__);
97 return NULL;
98 }
99 (void)memset_s(keyCfg, sizeof(KeyChipCfg), 0, sizeof(KeyChipCfg));
100 keyCfg->hdfKeyDev = device;
101
102 if (ParseKeyConfig(device->property, keyCfg) != HDF_SUCCESS) {
103 HDF_LOGE("%s: parse key config failed", __func__);
104 OsalMemFree(keyCfg);
105 keyCfg = NULL;
106 }
107 return keyCfg;
108 }
109
KeyDriverInstance(KeyChipCfg * keyCfg)110 static KeyDriver *KeyDriverInstance(KeyChipCfg *keyCfg)
111 {
112 KeyDriver *keyDrv = (KeyDriver *)OsalMemAlloc(sizeof(KeyDriver));
113 if (keyDrv == NULL) {
114 HDF_LOGE("%s: malloc key driver failed", __func__);
115 return NULL;
116 }
117 (void)memset_s(keyDrv, sizeof(KeyDriver), 0, sizeof(KeyDriver));
118
119 keyDrv->devType = keyCfg->devType;
120 keyDrv->keyCfg = keyCfg;
121
122 return keyDrv;
123 }
124
InputDeviceInstance(KeyDriver * keyDrv)125 static InputDevice *InputDeviceInstance(KeyDriver *keyDrv)
126 {
127 InputDevice *inputDev = (InputDevice *)OsalMemAlloc(sizeof(InputDevice));
128 if (inputDev == NULL) {
129 HDF_LOGE("%s: malloc input device failed", __func__);
130 return NULL;
131 }
132 (void)memset_s(inputDev, sizeof(InputDevice), 0, sizeof(InputDevice));
133
134 inputDev->pvtData = (void *)keyDrv;
135 inputDev->devType = keyDrv->devType;
136 inputDev->devName = keyDrv->keyCfg->keyName;
137 inputDev->hdfDevObj = keyDrv->keyCfg->hdfKeyDev;
138 keyDrv->inputdev = inputDev;
139
140 return inputDev;
141 }
142
RegisterKeyDevice(KeyChipCfg * keyCfg)143 static int32_t RegisterKeyDevice(KeyChipCfg *keyCfg)
144 {
145 int32_t ret;
146 KeyDriver *keyDrv = KeyDriverInstance(keyCfg);
147 if (keyDrv == NULL) {
148 HDF_LOGE("%s: instance key config failed", __func__);
149 return HDF_ERR_MALLOC_FAIL;
150 }
151
152 ret = KeyInit(keyDrv);
153 if (ret != HDF_SUCCESS) {
154 HDF_LOGE("%s: key driver init failed, ret %d", __func__, ret);
155 goto EXIT;
156 }
157
158 InputDevice *inputDev = InputDeviceInstance(keyDrv);
159 if (inputDev == NULL) {
160 HDF_LOGE("%s: instance input device failed", __func__);
161 goto EXIT;
162 }
163
164 ret = RegisterInputDevice(inputDev);
165 if (ret != HDF_SUCCESS) {
166 goto EXIT1;
167 }
168 return HDF_SUCCESS;
169
170 EXIT1:
171 OsalMemFree(inputDev->pkgBuf);
172 OsalMemFree(inputDev);
173 EXIT:
174 OsalMemFree(keyDrv);
175 HDF_LOGE("%s: exit failed", __func__);
176 return HDF_FAILURE;
177 }
178
HdfKeyDriverInit(struct HdfDeviceObject * device)179 static int32_t HdfKeyDriverInit(struct HdfDeviceObject *device)
180 {
181 int32_t ret;
182 HDF_LOGI("%s: enter", __func__);
183 if (device == NULL) {
184 return HDF_ERR_INVALID_PARAM;
185 }
186
187 KeyChipCfg *keyCfg = KeyConfigInstance(device);
188 if (keyCfg == NULL) {
189 HDF_LOGE("%s: instance key config failed", __func__);
190 return HDF_ERR_MALLOC_FAIL;
191 }
192
193 ret = RegisterKeyDevice(keyCfg);
194 if (ret != HDF_SUCCESS) {
195 goto EXIT;
196 }
197 HDF_LOGI("%s: exit succ!", __func__);
198 return HDF_SUCCESS;
199
200 EXIT:
201 OsalMemFree(keyCfg);
202 return HDF_FAILURE;
203 }
204
HdfKeyDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)205 static int32_t HdfKeyDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
206 {
207 (void)cmd;
208 if (client == NULL || data == NULL || reply == NULL) {
209 HDF_LOGE("%s: param is null", __func__);
210 return HDF_FAILURE;
211 }
212 return HDF_SUCCESS;
213 }
214
HdfKeyDriverBind(struct HdfDeviceObject * device)215 static int32_t HdfKeyDriverBind(struct HdfDeviceObject *device)
216 {
217 if (device == NULL) {
218 return HDF_ERR_INVALID_PARAM;
219 }
220 static struct IDeviceIoService keyService = {
221 .object.objectId = 1,
222 .Dispatch = HdfKeyDispatch,
223 };
224 device->service = &keyService;
225 return HDF_SUCCESS;
226 }
227
228 struct HdfDriverEntry g_hdfKeyEntry = {
229 .moduleVersion = 1,
230 .moduleName = "HDF_KEY",
231 .Bind = HdfKeyDriverBind,
232 .Init = HdfKeyDriverInit,
233 };
234
235 HDF_INIT(g_hdfKeyEntry);
236