Touchscreen开发实例

    基于HDF驱动模型,加载启动Touchscreen驱动,代码形式如下,具体原理可参考HDF驱动开发指南

    执行初始化

    如下初始化流程包含常用的步骤,实际业务开发时,可根据具体需求增删及修改如下初始化中的相关步骤,具体示例如下。

    1. {
    2. (void)object;
    3. /* 创建全局数据结构体,用于存储器件驱动相关信息 */
    4. g_coreData = (TouchCoreData *)OsalMemAlloc(sizeof(TouchCoreData));
    5. if (g_coreData == NULL) {
    6. HDF_LOGE("%s: malloc failed", __func__);
    7. return HDF_ERR_MALLOC_FAIL;
    8. }
    9. if (memset_s(g_coreData, sizeof(TouchCoreData), 0, sizeof(TouchCoreData)) != EOK) {
    10. HDF_LOGE("%s: memset_s fail", __func__);
    11. return;
    12. }
    13. /* 初始化全局数据结构体,将器件驱动相关的配置信息,进行解析赋值 */
    14. TouchConfigInit(g_coreData);
    15. /* 设置GPIO相关的属性及状态 */
    16. if (TouchSetupGpio(g_coreData)) {
    17. goto ERR_EXIT;
    18. }
    19. /* 设置并获取I2C BUS操作句柄 */
    20. if (TouchSetupI2c(g_coreData)) {
    21. goto ERR_EXIT;
    22. }
    23. /* 创建Task用于监听处理中断业务 */
    24. if (TouchIrqTaskInit(g_coreData)) {
    25. goto ERR_EXIT;
    26. }
    27. /* 进行电源初始化配置及操作 */
    28. if (TouchPowerInit(g_coreData)) {
    29. goto ERR_EXIT;
    30. }
    31. /* 创建input设备文件 */
    32. (void)mkdir("/dev/input", DEFAULT_DIR_MODE);
    33. if (register_driver(TOUCH_DEVICE, &g_touchDevOps, TOUCH_DEVICE_MODE, NULL)) {
    34. HDF_LOGE("%s: register touch dev failed", __func__);
    35. goto ERR_EXIT;
    36. }
    37. HDF_LOGE("%s: exit succ", __func__);
    38. return HDF_SUCCESS;
    39. ERR_EXIT:
    40. if (g_coreData->i2cClient.i2cHandle != NULL) {
    41. DeviceHandleDestroy(g_coreData->i2cClient.i2cHandle);
    42. g_coreData->i2cClient.i2cHandle = NULL;
    43. }
    44. OsalMemFree(g_coreData);
    45. g_coreData = NULL;
    46. return HDF_FAILURE;
    47. }
    1. static void TouchConfigInit(TouchCoreData *cd)
    2. {
    3. /* init waitqueue for poll */
    4. __init_waitqueue_head(&cd->pollWait);
    5. /* 配置i2c从地址、总线号、报点范围 */
    6. cd->i2cClient.i2cCfg.addr = DRIVER_CHIP_I2C_ADDR;
    7. cd->i2cClient.i2cCfg.busNum = I2C_BUS_NUM;
    8. cd->inputCfg.solutionY = TOUCH_SOLUTION_Y;
    9. /* 配置input设备类型,本例为Touch驱动 */
    10. cd->inputDevType = INDEV_TYPE_TOUCH;
    11. /* 配置reset、irq的gpio号,以及irq的中断触发方式 */
    12. cd->rstGpioNum = RST_GPIO_OFFSET;
    13. cd->intGpioNum = INT_GPIO_OFFSET;
    14. cd->irqFlag = OSAL_IRQF_TRIGGER_FALLING;
    15. }

    配置及使用IO管脚

    如下为reset和irq管脚的初始化配置,统一使用PAL接口实现对GPIO的操作,具体可参考PLATFORM提供的

    配置I2C的IO管脚复用,以及其操作句柄的获取,可参考PLATFORM提供的I2C接口使用指导

    1. static int TouchSetupI2c(TouchCoreData *cd)
    2. {
    3. /* config I2C reuse I2C7 */
    4. writel(I2C_REG_CFG, IO_DEVICE_ADDR(I2C7_DATA_REG_ADDR));
    5. writel(I2C_REG_CFG, IO_DEVICE_ADDR(I2C7_CLK_REG_ADDR));
    6. /* get i2c handle */
    7. cd->i2cClient.i2cHandle = I2cOpen(cd->i2cClient.i2cCfg.busNum);
    8. if (cd->i2cClient.i2cHandle == NULL) {
    9. HDF_LOGE("open i2c failed");
    10. return HDF_FAILURE;
    11. }
    12. HDF_LOGI("%s: exit succ", __func__);
    13. return HDF_SUCCESS;
    14. }
    1. static int TouchIrqTaskInit(TouchCoreData *cd)
    2. {
    3. /* 初始化消息事件 */
    4. int ret = LOS_EventInit(&g_touchEventIrq);
    5. if (ret != HDF_SUCCESS) {
    6. HDF_LOGE("LOS_EventInit failed, ret = %d", ret);
    7. return HDF_FAILURE;
    8. }
    9. /* 注册中断 */
    10. ret = GpioSetIrq(cd->intGpioNum, cd->irqFlag, IrqHandle, cd);
    11. if (ret != 0) {
    12. HDF_LOGE("register irq failed, ret %d", ret);
    13. return ret;
    14. }
    15. /* 使能中断 */
    16. ret = GpioEnableIrq(cd->intGpioNum);
    17. if (ret != HDF_SUCCESS) {
    18. HDF_LOGE("enable irq failed, ret %d", ret);
    19. return HDF_FAILURE;
    20. }
    21. /* 创建中断处理Task,其负责input event数据的读取和解析 */
    22. TSK_INIT_PARAM_S handleEventTask = {0};
    23. UINT32 handleEventTaskID;
    24. handleEventTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TouchHandleEvent;
    25. handleEventTask.uwStackSize = TASK_SIZE;
    26. handleEventTask.pcName = "HdfTouchEventHandler";
    27. handleEventTask.usTaskPrio = TASK_PRIO_LEVEL_TWO;
    28. handleEventTask.uwResved = LOS_TASK_STATUS_DETACHED;
    29. if (LOS_TaskCreate(&handleEventTaskID, &handleEventTask) != HDF_SUCCESS) {
    30. HDF_LOGE("%s: LOS_TaskCreate fail, HdfTouchEventHandler", __func__);
    31. return HDF_FAILURE;
    32. }
    33. HDF_LOGI("%s: exit succ", __func__);
    34. return HDF_SUCCESS;
    35. }

    中断响应函数

    Task处理函数

    1. static void TouchHandleEvent(void)
    2. {
    3. InputEventData event;
    4. TouchCoreData *cd = GetCoreData();
    5. (void)memset_s(&event, sizeof(InputEventData), 0, sizeof(InputEventData));
    6. while (true) {
    7. int ret = LOS_EventRead(&g_touchEventIrq, EVENT_SYNC, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
    8. if (ret != EVENT_SYNC) {
    9. OsalMSleep(TASK_SLEEP_MS);
    10. } else {
    11. /* 报点事件的读取及解析 */
    12. if (EventHandler(cd, &event) == HDF_SUCCESS) {
    13. TouchWakeupPoll();
    14. }
    15. }
    16. /* 使能中断 */
    17. ret = GpioEnableIrq(cd->intGpioNum);
    18. if (ret != HDF_SUCCESS) {
    19. HDF_LOGE("enable irq failed, ret %d", ret);
    20. }
    21. if (cd->shouldStop) {
    22. HDF_LOGE("%s: the event task should be stoped", __func__);
    23. break;
    24. }
    25. }
    26. }

    创建及操作设备文件

    1. /* 创建设备文件 */
    2. register_driver(TOUCH_DEVICE, &g_touchDevOps, TOUCH_DEVICE_MODE, NULL);
    3. /* 文件操作ops */
    4. static const struct file_operations_vfs g_touchDevOps = {
    5. .open = TouchOpen,
    6. .close = TouchClose,
    7. .read = NULL,
    8. .write = NULL,
    9. .seek = NULL,
    10. .ioctl = TouchIoctl,
    11. .mmap = NULL,
    12. #ifndef CONFIG_DISABLE_POLL
    13. .poll = TouchPoll,
    14. #endif
    15. .unlink = NULL,
    16. };
    17. /* Ioctl的操作方式 */
    18. static int TouchIoctl(FAR struct file *filep, int cmd, unsigned long arg)
    19. {
    20. int ret;
    21. if (filep == NULL) {
    22. HDF_LOGE("%s: param is null", __func__);
    23. return HDF_ERR_INVALID_PARAM;
    24. }
    25. switch (cmd) {
    26. case INPUT_IOCTL_GET_EVENT_DATA:
    27. ret = IoctlReadInputEvent(arg);
    28. break;
    29. case INPUT_IOCTL_GET_DEVICE_TYPE:
    30. ret = IoctlGetDeviceType(arg);
    31. break;
    32. case INPUT_IOCTL_GET_CHIP_INFO:
    33. ret = IoctlGetChipInfo(arg);
    34. break;
    35. default:
    36. ret = 0;
    37. HDF_LOGE("%s: cmd unknown, cmd = 0x%x", __func__, cmd);
    38. break;
    39. }