mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-08-27 10:51:15 -04:00
2746dec278
Signed-off-by: lianghua <lianghua14@huawei.com>
236 lines
6.3 KiB
C
236 lines
6.3 KiB
C
/*
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
|
*
|
|
* HDF is dual licensed: you can use it either under the terms of
|
|
* the GPL, or the BSD license, at your option.
|
|
* See the LICENSE file in the root of this repository for complete details.
|
|
*/
|
|
|
|
#include "hdf_device_desc.h"
|
|
#include "osal_mem.h"
|
|
#include "gpio_if.h"
|
|
#include "hdf_log.h"
|
|
#include "hdf_input_device_manager.h"
|
|
#include "event_hub.h"
|
|
#include "hdf_key.h"
|
|
|
|
#define CHECK_PARSER_RET(ret, str) do { \
|
|
if ((ret) != HDF_SUCCESS) { \
|
|
HDF_LOGE("%s: %s failed, ret = %d!", __func__, str, ret); \
|
|
return HDF_FAILURE; \
|
|
} \
|
|
} while (0)
|
|
|
|
int32_t KeyIrqHandle(uint16_t intGpioNum, void *data)
|
|
{
|
|
int32_t ret;
|
|
uint16_t gpioValue = 0;
|
|
KeyDriver *driver = (KeyDriver *)data;
|
|
if (driver == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
KeyEventData *event = &driver->eventData;
|
|
if (event == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
ret = GpioDisableIrq(intGpioNum);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: disable irq failed, ret %d", __func__, ret);
|
|
}
|
|
|
|
ret = GpioRead(intGpioNum, &gpioValue);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret);
|
|
return HDF_FAILURE;
|
|
}
|
|
uint64_t curTime = OsalGetSysTimeMs();
|
|
driver->preStatus = gpioValue;
|
|
driver->timeStamp = curTime;
|
|
|
|
if (gpioValue == GPIO_VAL_LOW) {
|
|
event->definedEvent = INPUT_KEY_DOWN;
|
|
input_report_key(driver->inputdev, KEY_POWER, 1);
|
|
} else if (gpioValue == GPIO_VAL_HIGH) {
|
|
event->definedEvent = INPUT_KEY_UP;
|
|
input_report_key(driver->inputdev, KEY_POWER, 0);
|
|
}
|
|
input_sync(driver->inputdev);
|
|
|
|
GpioEnableIrq(intGpioNum);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t SetupKeyIrq(KeyDriver *keyDrv)
|
|
{
|
|
uint16_t intGpioNum = keyDrv->keyCfg->gpioNum;
|
|
uint16_t irqFlag = keyDrv->keyCfg->irqFlag;
|
|
int32_t ret = GpioSetDir(intGpioNum, GPIO_DIR_IN);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: gpio set dir failed, ret %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
ret = GpioSetIrq(intGpioNum, irqFlag | GPIO_IRQ_USING_THREAD, KeyIrqHandle, keyDrv);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: register irq failed, ret %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
ret = GpioEnableIrq(intGpioNum);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: enable irq failed, ret %d", __func__, ret);
|
|
return HDF_FAILURE;
|
|
}
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t KeyInit(KeyDriver *keyDrv)
|
|
{
|
|
int32_t ret = SetupKeyIrq(keyDrv);
|
|
CHECK_RETURN_VALUE(ret);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static KeyChipCfg *KeyConfigInstance(struct HdfDeviceObject *device)
|
|
{
|
|
KeyChipCfg *keyCfg = (KeyChipCfg *)OsalMemAlloc(sizeof(KeyChipCfg));
|
|
if (keyCfg == NULL) {
|
|
HDF_LOGE("%s: malloc key config failed", __func__);
|
|
return NULL;
|
|
}
|
|
(void)memset_s(keyCfg, sizeof(KeyChipCfg), 0, sizeof(KeyChipCfg));
|
|
keyCfg->hdfKeyDev = device;
|
|
|
|
if (ParseKeyConfig(device->property, keyCfg) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: parse key config failed", __func__);
|
|
OsalMemFree(keyCfg);
|
|
keyCfg = NULL;
|
|
}
|
|
return keyCfg;
|
|
}
|
|
|
|
static KeyDriver *KeyDriverInstance(KeyChipCfg *keyCfg)
|
|
{
|
|
KeyDriver *keyDrv = (KeyDriver *)OsalMemAlloc(sizeof(KeyDriver));
|
|
if (keyDrv == NULL) {
|
|
HDF_LOGE("%s: malloc key driver failed", __func__);
|
|
return NULL;
|
|
}
|
|
(void)memset_s(keyDrv, sizeof(KeyDriver), 0, sizeof(KeyDriver));
|
|
|
|
keyDrv->devType = keyCfg->devType;
|
|
keyDrv->keyCfg = keyCfg;
|
|
|
|
return keyDrv;
|
|
}
|
|
|
|
static InputDevice *InputDeviceInstance(KeyDriver *keyDrv)
|
|
{
|
|
InputDevice *inputDev = (InputDevice *)OsalMemAlloc(sizeof(InputDevice));
|
|
if (inputDev == NULL) {
|
|
HDF_LOGE("%s: malloc input device failed", __func__);
|
|
return NULL;
|
|
}
|
|
(void)memset_s(inputDev, sizeof(InputDevice), 0, sizeof(InputDevice));
|
|
|
|
inputDev->pvtData = (void *)keyDrv;
|
|
inputDev->devType = keyDrv->devType;
|
|
inputDev->devName = keyDrv->keyCfg->keyName;
|
|
inputDev->hdfDevObj = keyDrv->keyCfg->hdfKeyDev;
|
|
keyDrv->inputdev = inputDev;
|
|
|
|
return inputDev;
|
|
}
|
|
|
|
static int32_t RegisterKeyDevice(KeyChipCfg *keyCfg)
|
|
{
|
|
int32_t ret;
|
|
KeyDriver *keyDrv = KeyDriverInstance(keyCfg);
|
|
if (keyDrv == NULL) {
|
|
HDF_LOGE("%s: instance key config failed", __func__);
|
|
return HDF_ERR_MALLOC_FAIL;
|
|
}
|
|
|
|
ret = KeyInit(keyDrv);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: key driver init failed, ret %d", __func__, ret);
|
|
goto EXIT;
|
|
}
|
|
|
|
InputDevice *inputDev = InputDeviceInstance(keyDrv);
|
|
if (inputDev == NULL) {
|
|
HDF_LOGE("%s: instance input device failed", __func__);
|
|
goto EXIT;
|
|
}
|
|
|
|
ret = RegisterInputDevice(inputDev);
|
|
if (ret != HDF_SUCCESS) {
|
|
goto EXIT1;
|
|
}
|
|
return HDF_SUCCESS;
|
|
|
|
EXIT1:
|
|
OsalMemFree(inputDev->pkgBuf);
|
|
OsalMemFree(inputDev);
|
|
EXIT:
|
|
OsalMemFree(keyDrv);
|
|
HDF_LOGE("%s: exit failed", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
static int32_t HdfKeyDriverInit(struct HdfDeviceObject *device)
|
|
{
|
|
int32_t ret;
|
|
HDF_LOGI("%s: enter", __func__);
|
|
if (device == NULL) {
|
|
return HDF_ERR_INVALID_PARAM;
|
|
}
|
|
|
|
KeyChipCfg *keyCfg = KeyConfigInstance(device);
|
|
if (keyCfg == NULL) {
|
|
HDF_LOGE("%s: instance key config failed", __func__);
|
|
return HDF_ERR_MALLOC_FAIL;
|
|
}
|
|
|
|
ret = RegisterKeyDevice(keyCfg);
|
|
if (ret != HDF_SUCCESS) {
|
|
goto EXIT;
|
|
}
|
|
HDF_LOGI("%s: exit succ!", __func__);
|
|
return HDF_SUCCESS;
|
|
|
|
EXIT:
|
|
OsalMemFree(keyCfg);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
static int32_t HdfKeyDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
|
|
{
|
|
(void)cmd;
|
|
if (client == NULL || data == NULL || reply == NULL) {
|
|
HDF_LOGE("%s: param is null", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t HdfKeyDriverBind(struct HdfDeviceObject *device)
|
|
{
|
|
if (device == NULL) {
|
|
return HDF_ERR_INVALID_PARAM;
|
|
}
|
|
static struct IDeviceIoService keyService = {
|
|
.object.objectId = 1,
|
|
.Dispatch = HdfKeyDispatch,
|
|
};
|
|
device->service = &keyService;
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
struct HdfDriverEntry g_hdfKeyEntry = {
|
|
.moduleVersion = 1,
|
|
.moduleName = "HDF_KEY",
|
|
.Bind = HdfKeyDriverBind,
|
|
.Init = HdfKeyDriverInit,
|
|
};
|
|
|
|
HDF_INIT(g_hdfKeyEntry);
|