MT3561 开关触摸屏GT928逻辑
1 . MT3561 触摸屏的驱动文件路径:
kernel-3.18/drivers/input/touchscreen/mediatek/GT928/gt9xx_driver.c
2. 需求: 提供接口控制触摸屏幕的开关
此处使用 /proc/gt9xx_config文件作为文件节点提供控制接口
3.具体实现:
(本文档分析此功能的实现方式,并不对触摸屏的驱动架构进行详细的分析)
驱动的注册函数中,发现驱动probe函数中已经创建了proc下的文件节点
static s32 tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
….................................
gt91xx_config_proc = proc_create(GT91XX_CONFIG_PROC_FILE, 0660, NULL, >_upgrade_proc_fops);
//创建proc目录下的文件节点
…..................................
}
static const struct file_operations gt_upgrade_proc_fops = {
.write = gt91xx_config_write_proc,
.read = gt91xx_config_read_proc
}; //该节点提供的操作的操作函数
static ssize_t gt91xx_config_write_proc(struct file *file, const char *buffer, size_t count,
loff_t *ppos)
{
…................................
if (sscanf(temp, "%s %d", (char *)&mode_str, &mode) == -1)
return -EINVAL;
//解析输入的字符, 根据这里可以看出 调用此函数时 传入命令的格式为: write操作 命令 数值
…...............
if (strcmp(mode_str, "switch") == 0) {
if (mode == 0) /* turn off */
tpd_off();
else if (mode == 1) /* turn on */
tpd_on();
else
GTP_ERROR("error mode :%d", mode);
return count;
}
// 原生写操作接口已经提供了开关屏幕的操作,命令 “switch” ,数值为 0关闭 1打开
//这里的tpd_on函数以及tpd_off函数 实际使用tpd_off操作时存在卡机重启问题,这跟平台硬件
//不匹配有关,所以后续根据触摸屏的手册客制化开关屏幕的功能
…..............................................
if (strcmp(mode_str, "touch") == 0) {
if (mode == 0) /* turn off */
tpd_close();
else if (mode == 1) /* turn on */
tpd_open();
else
GTP_ERROR("error mode :%d", mode);
return count;
}
//此处为客制化开关机的修改, 新加命令 “touch” , 参数 0 关闭 ,1 打开
}
static void tpd_open(void) //触摸屏的打开操作就是让触摸屏进入normal mode (具体时序根据对应 的芯片手册进行操作)
{
if(_irq_state == 0){
tpd_gpio_output(1,0);
msleep(2);
tpd_gpio_output(1,1);
msleep(10);
tpd_gpio_output(1,0); //唤醒(高电平时间大于2~5ms)
gtp_int_sync(); //重新配置引脚为eint 模式
mutex_lock(&i2c_access);
tpd_halt = 0;
enable_irq(touch_irq); //开中断
_irq_state = 1;
mutex_unlock(&i2c_access);
GTP_ERROR("GTP enter NormalMode!");
#ifdef TPD_PROXIMITY
if (tpd_proximity_flag == 1)
return;
#endif
#if GTP_ESD_PROTECT
queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, TPD_ESD_CHECK_CIRCLE); //work 重新加入调度
#endif
#ifdef GTP_CHARGER_DETECT
queue_delayed_work(gtp_charger_check_workqueue, >p_charger_check_work,
TPD_CHARGER_CHECK_CIRCLE);
#endif
}
}
// 触摸屏的关闭操作就是让触摸屏进入sleep mode
static void tpd_close(void)
{
s32 ret = -1;
s8 retry = 0;
u8 i2c_control_buf[3] = { (u8) (GTP_REG_SLEEP >> 8), (u8) GTP_REG_SLEEP
if(_irq_state == 1){
mutex_lock(&i2c_access);
disable_irq(touch_irq);
_irq_state = 0;
tpd_halt = 1;
mutex_unlock(&i2c_access);
//gpio_direction_output(tpd_int_gpio_number, 0);
tpd_gpio_output(1,0);
msleep(20); //先拉低EINT 引脚
while (retry++ < 5) {
ret = gtp_i2c_write(i2c_client_point, i2c_control_buf, 3); //再设置寄存器进入sleep mode
if (ret > 0) {
GTP_ERROR("GTP enter SleepMode!");
return;
}
msleep(20);
}
#if GTP_ESD_PROTECT
cancel_delayed_work_sync(>p_esd_check_work); //取消work调度
#endif
#ifdef GTP_CHARGER_DETECT
cancel_delayed_work_sync(>p_charger_check_work);
#endif
#ifdef TPD_PROXIMITY
if (tpd_proximity_flag == 1)
return;
#endif
}
}
irq_state 这个参数为了保证tpd_open和tpd_close 成对出现才会有实际的开关操作,原因在于 disable_irq和 enable_irq需成对操作
图1
具体的时序操作如图1,
具体操作的命令:
echo touch 1 > /proc/gt9xx_config //开屏幕
echo touch 0 > /proc/gt9xx_config //关闭屏幕