GSLX680触摸屏驱动移植

  1. GSLX680 触摸屏
    触摸屏按照触摸屏的工作原理和传输信息的介质,可以分为四种,它们分别为电阻式、电容感应式、红外线式以及表面声波式。GSLX680 为电容式触摸屏,挂接在I2C总线上,通过I2C总线来传输触摸屏数据。该芯片的连接方式如所示及与T3板子的I2C连接如所示。
    GSLX680触摸屏驱动移植
    1. SylixOS 电容式触摸屏分析
      SylixOS下将电容式触摸屏封装成一个字符设备,应用程序只需通过read函数读取触摸屏设备,即可获取到填充有触摸坐标信息的mouse_event_notify 结构体。
      1, 电容屏初始化
      INT touchDrv (VOID)
      {
      struct file_operations fileOper;
      INT iDrvNum;
      lib_memset(&fileOper, 0, sizeof(struct file_operations));
      fileOper.owner = THIS_MODULE;
      fileOper.fo_create = touchOpen;
      fileOper.fo_open = __touchOpen;
      fileOper.fo_close =
      touchClose;
      fileOper.fo_read = touchRead;
      fileOper.fo_lstat = __touchLstat;
      fileOper.fo_ioctl =
      touchIoctl;
      iDrvNum = iosDrvInstallEx2(&fileOper, LW_DRV_TYPE_NEW_1);
      DRIVER_LICENSE(iDrvNum, "Dual BSD/GPL->Ver 1.0");
      DRIVER_AUTHOR(iDrvNum, "Xu.Guizhou");
      DRIVER_DESCRIPTION(iDrvNum, "touch driver.")
      return (iDrvNum);
      }
      创建触摸屏设备的逻辑如下:
      iError = iosDevAddEx(&pTouchDev->TOUCH_devHdr, pcName, iDrvNum, DT_CHR);
      if (iError) {
      _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY);
      __SHEAP_FREE(pTouchDev);
      printk(KERN_ERR "touchDevCreate(): failed to create touch device %s!\n", pcName);
      return (PX_ERROR);
      }

2, 电容触摸屏事件上抛线程
触摸事件提交分为上下半程处理,下半程线程会阻塞等待触摸中断事件产生。当产生了触摸中断时,会调用touchHandleEvents 获取坐标值,并将获取到的坐标值填入mouse_event_notify 结构体,最终通过消息队列传送到触摸屏定义的 read 函数中。用户调用触摸驱动的 read 函数时,即可获取到触摸事件信息。
static PVOID
touchThread (PVOID pvArg)
{
INT iEventNum;
PTOUCH_DEV pTouchDev = (PTOUCH_DEV)pvArg;
while (!pTouchDev->TOUCH_bQuit) {
API_SemaphoreBPend(pTouchDev->TOUCH_hSignal, LW_OPTION_WAIT_INFINITE);
if (pTouchDev->TOUCH_bQuit) {
break;
}
iEventNum = __touchHandleEvents(pTouchDev);
if (iEventNum == PX_ERROR) {
printk(KERN_ERR "touch: handle touch event fail!\n");
} else if (iEventNum > 0) {
SEL_WAKE_UP_ALL(&pTouchDev->TOUCH_selList, SELREAD);
}
}
return (LW_NULL);
}

3. 电容触摸屏触摸中断产生
手指触摸时中断处理逻辑如下:
static irqreturn_t __touchIsr (PTOUCH_DEV pTouchDev, ULONG ulVector)
{
irqreturn_t irqreturn;
irqreturn = API_GpioSvrIrq(pTouchDev->TOUCH_data.T_uiIrq);
if (irqreturn == LW_IRQ_HANDLED) {
API_GpioClearIrq(pTouchDev->TOUCH_data.T_uiIrq);
API_SemaphoreBPost(pTouchDev->TOUCH_hSignal);
}
return (irqreturn);
}

  1. 移植GSLX680 触摸屏
    将Linux下的驱动代码移植到SylixOS下,需要将硬件初始化动作及获取触摸屏坐标值。
    1, 硬件初始化动作放在设备的open动作下,包括创建I2C子设备,GPIO中断申请,芯片初始化:
    static INT touchHwInit (PTOUCH_DEV pTouchDev, PCHAR pcName)
    {
    INT iError;
    pTouchDev->TOUCH_pI2cDevice =
    API_I2cDeviceCreate(pTouchDev->TOUCH_data.T_pcBusName,
    pcName,
    pTouchDev->TOUCH_data.T_usAddr,
    0);
    if (pTouchDev->TOUCH_pI2cDevice == LW_NULL) {
    printk(KERN_ERR "
    touchHwInit(): failed to create i2c device %s, slave addr 0x%x!\n",
    pTouchDev->TOUCH_data.T_pcBusName,
    pTouchDev->TOUCH_data.T_usAddr);
    goto __error_handle;
    }
    /*

    • 设置触摸屏中断
      */

    iError = API_GpioRequestOne(pTouchDev->TOUCH_data.T_uiIrq,
    pTouchDev->TOUCH_data.T_uiIrqCfg,
    "touch_eint");
    if (iError != ERROR_NONE) {
    printk(KERN_ERR "touchHwInit(): failed to request irq gpio!\n");
    goto
    error_handle;
    }
    iError = API_GpioSetupIrq(pTouchDev->TOUCH_data.T_uiIrq, pTouchDev->TOUCH_data.T_uiIrqCfg, 1);
    if (iError == PX_ERROR) {
    printk(KERN_ERR "touchHwInit(): failed to setup gpio irq!\n");
    goto
    error_handle;
    }
    pTouchDev->TOUCH_ulVector = (ULONG)iError;
    printk("__touchHwInit %d\n\r",iError);
    /*

    • 申请触摸屏复位管脚
      /
      iError = API_GpioRequestOne(pTouchDev->TOUCH_data.T_uiReset,
      pTouchDev->TOUCH_data.T_uiRstVal | LW_GPIOF_DIR_OUT,
      "touch_reset");
      if (iError != ERROR_NONE) {
      printk(KERN_ERR "touchHwInit(): failed to request rst gpio!\n");
      goto
      error_handle;
      }
      __touchReset(pTouchDev); /
      Reset Touch Screen /
      if (pTouchDev->pDrvFunc->init) { /
      Init Touch Screen */
      pTouchDev->pDrvFunc->init(pTouchDev);
      }
      return (ERROR_NONE);
      __error_handle:
      API_GpioFree(pTouchDev->TOUCH_data.T_uiIrq);
      API_GpioFree(pTouchDev->TOUCH_data.T_uiReset);

    if (pTouchDev->TOUCH_pI2cDevice) {
    API_I2cDeviceDelete(pTouchDev->TOUCH_pI2cDevice);
    pTouchDev->TOUCH_pI2cDevice = LW_NULL;
    }
    return (PX_ERROR);
    }

2, 获取坐标事件函数,gslX680GetEvent 将获取的坐标上报:
static TOUCH_DRV_FUNC _G_Gsl680DrvFunc = {
.getevent = gslX680GetEvent,
.init = gslX680Init,
.deinit = NULL,
.reset = NULL,
};
INT gslX680GetEvent (PTOUCH_DEV pTouchDev, mouse_event_notify events[])
{
INT iError;
UCHAR ucBuffer[36];
u8 read_buf[4] = {0};

iError =  gsl_ts_read(pTouchDev, 0x80, ucBuffer, GSL_CONTACT_SIZE);
if (iError == PX_ERROR) {
    printk(KERN_WARNING "touch: get touch point error!\n");
    return  (PX_ERROR);
}

if(ucBuffer[0] == 0xff) {
    return  (iError);
}

iError = gsl_ts_read( pTouchDev, 0xbc, read_buf, sizeof(read_buf));

if (iError == PX_ERROR) {
    printk(KERN_WARNING "touch: read 0xbc failed!\n");
    return  (iError);
}

if (read_buf[3] == 0 && read_buf[2] == 0 && read_buf[1] == 0 && read_buf[0] == 0){
    iError = process_gslX680_data(pTouchDev,events,ucBuffer);
} else {
    reset_chip(pTouchDev);
    startup_chip(pTouchDev);
    iError = 0;
}

return  (iError);

}

  1. 参考资料
    《SylixOS应用程序开发手册》

猜你喜欢

转载自blog.51cto.com/13927802/2386483