關於I2C tp的那點事兒

  1. 添加I2C 設備
    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)
    {
    .type = “pixcir_ts”,
    .addr = 0x5c,
    .flags =0,
    .irq = RK30_PIN4_PC2,
    .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);
  4. 向輸入子系統註冊設備:
    input_register_device(ts->input_dev);
  1. 觸摸屏調試常見問題參考:
    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打印出點信息。
————————————————
版權聲明:本文爲CSDN博主「jkzrc」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/jkzrc/article/details/18549957

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章