/* * Copyright (c) 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_encoder.h" #include "event_hub.h" #include "gpio_if.h" #include "hdf_device_desc.h" #include "hdf_log.h" #include "osal_mem.h" #include "osal_timer.h" #define TIMER_INTERVAL_ENCODER 5 static void EncoderTimerFunc(uintptr_t arg) { int32_t ret; EncoderDriver *encoderDrv = (EncoderDriver *)arg; uint16_t gpioClk = encoderDrv->encoderCfg->gpioClk; uint16_t gpioData = encoderDrv->encoderCfg->gpioData; uint16_t gpioSW = encoderDrv->encoderCfg->gpioSW; ret = GpioRead(gpioClk, &encoderDrv->encoderClkNowSta); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret); return; } ret = GpioRead(gpioData, &encoderDrv->encoderDataNowSta); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret); return; } ret = GpioRead(gpioSW, &encoderDrv->encoderSWNowSta); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret); return; } if (encoderDrv->encoderClkNowSta != encoderDrv->encoderClkPreSta) { if (encoderDrv->encoderClkNowSta == 0) { if (encoderDrv->encoderDataNowSta == 1) { input_report_rel(encoderDrv->inputDev, REL_WHEEL, 1); } else { input_report_rel(encoderDrv->inputDev, REL_WHEEL, -1); } input_sync(encoderDrv->inputDev); } encoderDrv->encoderClkPreSta = encoderDrv->encoderClkNowSta; encoderDrv->encoderDataPreSta = encoderDrv->encoderDataNowSta; } if (encoderDrv->encoderSWPreSta != encoderDrv->encoderSWNowSta) { if (encoderDrv->encoderSWNowSta == 0) { input_report_key(encoderDrv->inputDev, KEY_OK, 0); } else { input_report_key(encoderDrv->inputDev, KEY_OK, 1); } encoderDrv->encoderSWPreSta = encoderDrv->encoderSWNowSta; input_sync(encoderDrv->inputDev); } } static EncoderCfg *EncoderConfigInstance(struct HdfDeviceObject *device) { int32_t ret; EncoderCfg *encoderCfg = (EncoderCfg *)OsalMemAlloc(sizeof(EncoderCfg)); if (encoderCfg == NULL) { HDF_LOGE("%s: malloc encoder config failed", __func__); return NULL; } ret = memset_s(encoderCfg, sizeof(EncoderCfg), 0, sizeof(EncoderCfg)); if (ret != 0) { HDF_LOGE("%s: memset_s encoder config failed", __func__); OsalMemFree(encoderCfg); return NULL; } encoderCfg->hdfEncoderDev = device; if (ParseEncoderConfig(device->property, encoderCfg) != HDF_SUCCESS) { HDF_LOGE("%s: parse encoder config failed", __func__); OsalMemFree(encoderCfg); return NULL; } return encoderCfg; } static EncoderDriver *EncoderDriverInstance(EncoderCfg *encoderCfg) { int32_t ret; EncoderDriver *encoderDrv = (EncoderDriver *)OsalMemAlloc(sizeof(EncoderDriver)); if (encoderDrv == NULL) { HDF_LOGE("%s: malloc key driver failed", __func__); return NULL; } ret = memset_s(encoderDrv, sizeof(EncoderDriver), 0, sizeof(EncoderDriver)); if (ret != 0) { HDF_LOGE("%s: memset encoder driver failed", __func__); OsalMemFree(encoderDrv); return NULL; } encoderDrv->devType = encoderCfg->devType; encoderDrv->encoderCfg = encoderCfg; return encoderDrv; } static int32_t EncoderInit(EncoderDriver *EncoderDrv) { int32_t ret; uint16_t gpioClk = EncoderDrv->encoderCfg->gpioClk; uint16_t gpioData = EncoderDrv->encoderCfg->gpioData; uint16_t gpioSW = EncoderDrv->encoderCfg->gpioSW; GpioSetDir(gpioClk, GPIO_DIR_IN); GpioSetDir(gpioData, GPIO_DIR_IN); GpioSetDir(gpioSW, GPIO_DIR_IN); ret = OsalTimerCreate(&EncoderDrv->timer, TIMER_INTERVAL_ENCODER, EncoderTimerFunc, EncoderDrv); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: create timer failed, ret = %d\n", __func__, ret); return HDF_FAILURE; } ret = OsalTimerStartLoop(&EncoderDrv->timer); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: start timer failed, ret = %d\n", __func__, ret); return HDF_FAILURE; } ret = GpioRead(gpioClk, &EncoderDrv->encoderClkNowSta); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret); return HDF_FAILURE; } ret = GpioRead(gpioData, &EncoderDrv->encoderDataNowSta); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret); return HDF_FAILURE; } ret = GpioRead(gpioSW, &EncoderDrv->encoderSWNowSta); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret); return HDF_FAILURE; } EncoderDrv->encoderClkPreSta = EncoderDrv->encoderClkNowSta; EncoderDrv->encoderDataPreSta = EncoderDrv->encoderDataNowSta; return HDF_SUCCESS; } static InputDevice *InputDeviceInstance(EncoderDriver *encoderDrv) { int32_t ret; InputDevice *inputDev = (InputDevice *)OsalMemAlloc(sizeof(InputDevice)); if (inputDev == NULL) { HDF_LOGE("%s: malloc input device failed", __func__); return NULL; } ret = memset_s(inputDev, sizeof(InputDevice), 0, sizeof(InputDevice)); if (ret != 0) { HDF_LOGE("%s: memset encoder driver failed", __func__); OsalMemFree(inputDev); return NULL; } ret = OsalMutexInit(&inputDev->mutex); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: Init mutex error", __func__); OsalMemFree(inputDev); return NULL; } inputDev->pvtData = (void *)encoderDrv; inputDev->devType = encoderDrv->devType; inputDev->hdfDevObj = encoderDrv->encoderCfg->hdfEncoderDev; encoderDrv->inputDev = inputDev; return inputDev; } static int32_t RegisterEncoderDevice(EncoderCfg *encoderCfg, struct HdfDeviceObject *device) { int32_t ret; EncoderDriver *encoderDrv = EncoderDriverInstance(encoderCfg); if (encoderDrv == NULL) { HDF_LOGE("%s: instance encoder driver failed", __func__); return HDF_ERR_MALLOC_FAIL; } device->priv = (void *)encoderDrv; ret = EncoderInit(encoderDrv); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: key driver init failed, ret %d", __func__, ret); goto EXIT; } InputDevice *inputDev = InputDeviceInstance(encoderDrv); 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(encoderDrv); return HDF_FAILURE; } static int32_t HdfEnCoderDriverInit(struct HdfDeviceObject *device) { int32_t ret; if (device == NULL) { HDF_LOGE("%s: param is null", __func__); return HDF_ERR_INVALID_PARAM; } EncoderCfg *encoderCfg = EncoderConfigInstance(device); if (encoderCfg == NULL) { HDF_LOGE("%s: instance encoder config failed", __func__); return HDF_ERR_MALLOC_FAIL; } ret = RegisterEncoderDevice(encoderCfg, device); if (ret != HDF_SUCCESS) { goto EXIT; } HDF_LOGI("%s: exit succ!", __func__); return HDF_SUCCESS; EXIT: OsalMemFree(encoderCfg); return HDF_FAILURE; } static int32_t HdfEnCoderDispatch(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 void HdfEncoderDriverRelease(struct HdfDeviceObject *device) { EncoderDriver *driver = NULL; InputDevice *inputDev = NULL; if (device == NULL || device->priv == NULL) { HDF_LOGE("%s: param is null", __func__); return; } driver = (EncoderDriver *)device->priv; inputDev = driver->inputDev; if (inputDev != NULL) { UnregisterInputDevice(inputDev); driver->inputDev = NULL; } OsalMemFree(driver); } static int32_t HdfEnCoderDriverBind(struct HdfDeviceObject *device) { if (device == NULL) { return HDF_ERR_INVALID_PARAM; } static struct IDeviceIoService enCoderService = { .object.objectId = 1, .Dispatch = HdfEnCoderDispatch, }; device->service = &enCoderService; return HDF_SUCCESS; } struct HdfDriverEntry g_hdfEnCoderEntry = { .moduleVersion = 1, .moduleName = "HDF_ENCODER", .Bind = HdfEnCoderDriverBind, .Init = HdfEnCoderDriverInit, .Release = HdfEncoderDriverRelease, }; HDF_INIT(g_hdfEnCoderEntry);