android TP驅動移植調試筆記(轉)

1. 添加I2C 設備shell

TP 通常採用的是I2C 做爲數據和命令接口,因此TP 驅動也能夠歸類爲I2C 驅動。TP驅動的主要邏輯不在這裏,可是瞭解了Linux 的I2C 體系架構,就能夠對整個驅動流程有了架構

更加清晰的認識,但這裏不詳細展開討論I2C 的體系架構,只圍繞怎麼移植開發TP 驅動展開討論。函數

在板級文件中,也就是瑞星微的代碼文件board-rk30-sdk.c 中,實例化一個i2c_board_info結構體,該結構抽象描述一個具體的i2c 設備,而後將該實例添加到__i2c_board_list 全局鏈表中。舉個實例:編碼

#if defined (CONFIG_TOUCHSCREEN_PIXCIR)操作系統

{.net

.type = "pixcir_ts",調試

.addr = 0x5c,code

.flags =0,orm

.irq = RK30_PIN4_PC2,blog

.platform_data = &pixcir_info,

},

#endif

瞭解I2C 體系架構的應該都知道,Linux 系統在能成功找到I2C adapter 以後,也就是找到I2C 控制器以後,就會掃描__i2c_board_list 這個鏈表,每找到一個i2c_board_info,就會生成一個i2c_client,i2c_client 的部分信息來自於i2c_board_info,一部分來自於i2c_adapter。i2c_client 就表示一個真真切切的i2c 設備,由於它既有描述它基本屬性的信息,也有描述它行爲的方法,通俗的說就是I2C 的傳輸方法。

如今咱們能夠回過頭來詳細說說前面的提到的i2c_board_info結構體中各個成員的意義了。type成員用來賦給後來生成的i2c_client中的name成員,i2c_client中的name就表示這個i2c_client的名字。addr是這個i2c設備的地址,它和I2C控制器一塊兒表示表示這個i2c設備,假如咱們的TP是掛載在控制器0上,那麼0-005c則表示是這個i2c設備,0-005c咱們也能夠在sys系統裏面找到。Flag是i2c讀寫的標誌,爲0表示爲寫,1表示讀。Irq是這個i2c設備的中斷腳。Platform_data是在驅動註冊時用到。

 

2. 添加I2C驅動

熟悉Linux設備驅動模型的人都瞭解設備,驅動,總線的關係,上面咱們講的是設備,光有設備不行,還得有驅動。通常TP供應商都會有驅動提供給咱們,這裏咱們以瑞星微SDK中的pixcir_i2c_ts.c來做個例子。

第一步是添加i2c驅動:

i2c_add_driver(&pixcir_i2c_ts_driver);

這裏就不展開討論這個函數了,pixcir_i2c_ts_driver的定義以下:

static struct i2c_driver pixcir_i2c_ts_driver = {

.driver = {

.owner = THIS_MODULE,

.name = "pixcir_i2c_ts_v3.3.09",

#ifdef PIX_DRV_ATTR

.groups = pixcir_drv_grp,

#endif

},

#ifndef CONFIG_HAS_EARLYSUSPEND

.suspend = pixcir_i2c_ts_suspend,

.resume = pixcir_i2c_ts_resume,

#endif

.probe = pixcir_i2c_ts_probe,

.remove = __devexit_p(pixcir_i2c_ts_remove),

.id_table = pixcir_i2c_ts_id,

};

按照Linux設備驅動模型,一旦總線上有新的驅動加入,則系統會自動去搜索掛載在這個總線上的全部設備,而後拿每一個設備的name跟驅動的id_table比較,若是兩個的名字同樣,那麼接下來就會執行驅動裏面的probe函數。

 

3. TP驅動中的Probe

不管是什麼樣的TP驅動,在probe中不外乎就作如下幾件事情:

1) 申請TP相應的IO口,而後重啓一下設備

2) 申請TP中斷,熟悉Linux中斷的人都應該知道中斷的頂半部和底半部機制,因而要申請一個工做隊列和初始化一個工做任務。

INIT_WORK(&tsdata->work.work, pixcir_ts_poscheck);

pixcir_wq = create_singlethread_workqueue("pixcir_wq");

TP的數據上報流程是,當人手按下的時候,TP則產生一箇中斷,在中斷服務程序中,將數據讀出而且經過輸入子系統將數據上報給操做系統。

3) TP在硬件上經過I2C接口告訴人們它的數據,在軟件上則是經過輸入子系統告訴操做系統它的數據,而使用輸入子系統的第一步則是申請一個輸入子設備:

input_allocate_device();

這裏不詳細展開討論這個函數裏面的東西了,輸入子系統通訊的基本單位是事件,事件有三種屬性:類型(type),編碼(code),值(value)。輸入子系統支持不少種事件,不少種事件編碼,因此在使用輸入設備前,要先設置這個設備支持何種類型的事件,何種事件編碼。

4)通常的TP驅動支持的是如下幾種事件

__set_bit(EV_KEY, input->evbit);

__set_bit(EV_ABS, input->evbit);

__set_bit(EV_SYN, input->evbit);

5)肯定多點觸摸的協議。多點觸摸的協議有A協議跟B協議之分。A類在每次報點後加 input_mt_sync(touch_dev->input_dev);

   B類須要在probe中執行input_mt_init_slots(ts->input_dev, ts->max_touch_num);再在每次報點前input_mt_slot(ts->input_dev, index);

6) 向輸入子系統註冊設備:

input_register_device(ts->input_dev);

 

4. 觸摸屏調試常見問題參考:

1)在加載了驅動後,解不了鎖。

能夠先用USB鼠標解鎖。若是能夠用adb的話,也能夠直接用adb shell input keyevent 82解鎖

2)點擊屏幕沒反應

肯定i2c設備供電正常,肯定probe被執行了沒,若是被執行了,再肯定IO有沒有先進行初始化,有沒有重啓設備,再肯定I2C通不通,點擊屏幕可否進入中斷。

3)probe沒被執行。檢查i2c_board_info終端的type成員定義是否跟i2c_driver中的id_table同樣。

4)I2C不通。檢查供電正常否,有沒有重啓設備,i2c地址有沒有錯誤,有的i2c設備是用7位,有的是用8位,8位的則必須右移一位

5)最常發生的問題,TP的報點不對。

這個問題到目前爲止還沒總結出一個方法論。我的調試經驗覺得,這個跟LCD的分辨率,TP的分辨率,輸入子系統設置都有關係。

先討論一個對例子肯定屏幕的分辨率,假如分辨率爲800 * 1280,那麼應該是下圖的樣子:

 

 

  

 

  

圖表 1 LCD屏幕表示圖

假如TP的分辨率也是800 * 1280

  

  

 

 

  

圖表 2 TP分辨率表示圖

如上面兩幅圖所示,LCD和TP的分辨率是同樣的,而且原點同樣,假如這時輸入子系統參數設置爲:

    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, 800, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, 1280, 0, 0);

那麼此時上報的點應該是不用通過任何轉換的,也就是說上報的點是對的。

咱們再討論另一種狀況,假如TP的分辨率爲:

  

 

 

 

  

圖表 3 TP分辨率標示圖

 

值得一提的是,TP的x,y軸能夠互換,可是原點是不會變化的。如圖3的TP跟圖1的LCD,因爲LCD的原點跟TP的原點不同,那麼上報的點則必須通過驅動轉換。轉換的公式爲:

X=800 - y1;

Y=x1;

6)如何找LCD原點跟TP原點。

LCD原點應該是在系統沒作任何翻轉以前,在系統點亮的時候,小企鵝出現的地方

TP的原點,應該是在TP驅動裏x,y沒通過邏輯轉換以前,用printk打印出點信息。

轉載: http://blog.csdn.net/jkzrc/article/details/18549957

相關文章
相關標籤/搜索