MSM8909+Android5.1.1鍵盤驅動淺析
MSM8909+Android5.1.1鍵盤驅動------概述
採用SN7326帶智能指掃描的鍵盤擴充晶片,通過I2C介面來讀取其狀態寄存器的值就可知道是單按鍵還是多按鍵按下,可知道具體是哪個按鍵按下。然後鍵盤驅動調用input_event()上報linux的掃描碼,比如KEY_RIGHT,然後傳遞給android架構層,流程如:
圖1
下面介紹要實現鍵盤驅動所涉及的主要方方面面
1.Input子系統
Linux輸入裝置總類繁雜,常見的包括有按鍵、鍵盤、觸控螢幕、滑鼠、搖杆等等,他們本身就是字元裝置,而linux核心將這些裝置的共同性抽象出來,簡化驅動開發建立了一個input子系統。輸入子系統由核心層(Input Core)、驅動層和事件處理層(EventHandler)三部份組成。一個輸入事件,如滑鼠移動,鍵盤按鍵按下,joystick的移動等等通過
input driver -> Input core -> Eventhandler -> userspace 到達使用者空間傳給應用程式。
圖2
除了input driver部分,其他的核心已經寫好,基本不需要修改,所以我們需要寫一個I2C input driver。
2.Linux核心I2C裝置驅動
因為我們是通過基於I2C介面的sn7326晶片來掃描按鍵的,所以需要寫I2C裝置驅動。
Linux核心I2C裝置驅動包含3層[10],分別是:I2C匯流排驅動(I2C core)、I2C控制器驅動(I2C adapter)及I2C裝置的驅動(I2C driver)。I2C匯流排驅動主要實現對I2C匯流排及控制器和裝置驅動的管理。這部分代碼為通用部分,Linux核心已經完善,不需要改動。I2C控制器驅動跟硬體相關,主要是構造一個與I2C匯流排層介面的資料結構,並通過介面函數向I2C匯流排註冊一個控制器。同時,實現對I2C控制器中斷的處理函數,完成I2C裝置具體功能的實現。I2C裝置驅動主要是構造一個與I2C匯流排層介面的資料結構,通過介面函數向I2C匯流排層註冊一個I2C裝置驅動。同時構造一個與使用者層介面的資料結構,通過介面函數向核心註冊一個字元型裝置。
我們這裡是要開發一個I2C裝置驅動。
3.按鍵硬體碼、Linux掃描碼和android的鍵盤碼
3.1按鍵硬體碼
硬體碼是我的命名,就是指按下按鍵時,最初的按鍵標識編碼值,這個和具體的按鍵設計、採用的鍵盤擴充IC晶片的設計相關,比如sn7326
圖3
這裡的映射表就是硬體碼值。
3.2Linux掃描碼
掃描碼是LinuxInput系統中規定的碼值,好比PC鍵盤上每個鍵的索引值。都是數字。在裝置上輸入一下命令後,按鍵可以探測到得到每個按鍵的掃描碼Code.
Linux的掃描碼在\kernel\include\uapi\linux\input.h定義,比如:/* *Keys and buttons * *Most of the keys/buttons are modeled after USB HUT 1.12 *(see http://www.usb.org/developers/hidpage). *Abbreviations in the comments: * AC- Application Control * AL- Application Launch Button * SC- System Control */ #define KEY_RESERVED 0#define KEY_ESC 1#define KEY_1 2#define KEY_2 3#define KEY_3 4#define KEY_4 5#define KEY_5 6#define KEY_6 7#define KEY_7 8#define KEY_8 9#define KEY_9 10#define KEY_0 11
3.3Android的鍵盤碼
Android也定義了一套碼,叫作鍵盤碼,通過一個/system/usr/keylayout/來將兩套碼對應起來。這裡用的是sn7326.kl。(如果沒有其它*.kl,則是預設的qwerty.kl)
/frameworks/base/data/keyboards/Generic.kl定義,比如:
## Generic key layout file for fullalphabetic US English PC style external keyboards.## This file is intentionally very genericand is intended to support a broad rang of keyboards.# Do not edit the generic key layout tosupport a specific keyboard; instead, create# a new key layout file with the requiredkeyboard configuration.# key 1 ESCAPEkey 2 1key 3 2key 4 3key 5 4key 6 5key 7 6key 8 7key 9 8key 10 9key 11 0