1. 程式人生 > >MT3561平臺 GT928觸控式螢幕驅動客製化觸控的開關

MT3561平臺 GT928觸控式螢幕驅動客製化觸控的開關

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, &gt_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, &gtp_esd_check_work, TPD_ESD_CHECK_CIRCLE); //work 重新加入排程

#endif

#ifdef GTP_CHARGER_DETECT

queue_delayed_work(gtp_charger_check_workqueue, &gtp_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(&gtp_esd_check_work); //取消work排程

#endif

#ifdef GTP_CHARGER_DETECT

cancel_delayed_work_sync(&gtp_charger_check_work);

#endif

#ifdef TPD_PROXIMITY

if (tpd_proximity_flag == 1)

return;

#endif

}

irq_state 這個引數為了保證tpd_opentpd_close 成對出現才會有實際的開關操作,原因在於 disable_irqenable_irq需成對操作

圖1

具體的時序操作如圖1,

具體操作的命令:

echo touch 1 > /proc/gt9xx_config //開螢幕

echo touch 0 > /proc/gt9xx_config //關閉螢幕