三星的主流核心支援其實已存在相當久,幾乎可說是所有 ARM-based SoC 中支援最完整的。但經常關心 ARM Linux kernel 發展的網友也許會發現到,怎麼核心中每項周邊都有驅動程式支援,卻獨獨缺了觸控面板?
其實相關的 patch 早已在各個專案中使用 (如 OpenMoko),但由於都是直接操作暫存器,而非架構在 Ben Dooks 的 adc driver 之上(詳見之前的文章),是故一直沒有被整合進去。今年四月初 Nelson Castillo 將原來在 OpenMoko 使用的驅動程式移植至主流核心,並使用 adc driver 來做取樣的工作。雖然已有作為先期準備的 patch 被整合,但直到目前為止完整的驅動程式仍未進行合併。
最近關於這個議題又有了新的爭論。由於 Nelson 的版本引進了多層次的濾波器(filter)來去除不合法的取樣點,Russell King 認為這違背了 policy-mechanism 分離的原則;所有的取樣點應該原封不動地往上傳遞至 user-space(tslib)來做處理,在驅動程式中使用 filter 是缺乏彈性的作法(附帶一提,Russell 是 tslib 的作者)。但 Nelson 認為,在驅動程式中,filter 可以根據需要,透過回傳值來要求 adc driver 多抓一些取樣點來作判斷;而這是 user-space 所無法達成的優點。且這樣的設計方式可以解決在電阻式面板所遇到的問題(在觸控筆按下和釋放的瞬間,會有大量的雜訊出現)。
就我個人測試過的經驗,Nelson 的 patch 確實比單純只使用 tslib,觸控板的表現要好得多,筆觸變得比較順暢,且抖動的情況減少很多。雖然在整合進 board-dependent 的程式碼時相對比較麻煩,不過其效果似乎是值得這麼做的。
2009年5月13日 星期三
S3C24xx ADC driver (2)
在第一篇文章中我們提到,adc driver 簡化了一部分硬體操作的細節,並提供 API 讓驅動程式使用。但就 touchscreen 驅動程式開發者的立場來看,它仍然有一些問題(以下純屬個人意見,僅供參考):
也許以後會有所改變吧,不過,誰知道呢 :)
- 雖然它給予驅動程式開發者在擷取數據上的方便性,但並未處理與觸控板相關的硬體操作,故開發者仍必須自行設定相關的暫存器來處理按下及釋放的事件;由於 ADC 硬體本身就額外支援觸控板的功能,adc driver 做為硬體與 touchscreen driver 間的中介層,應儘量隱藏硬體的細節,並提供完整的介面供上層驅動程式使用,而如今開發者除了須自行設定暫存器外,還必須先查看 adc driver 的原始碼,了解它如何設定暫存器,以避免自己的程式碼去干擾 adc driver 的運作,似乎失去了資訊隱藏的意義。
- 這點比較見人見智;一般來說,驅動程式在呼叫 ioremap() 之前,會先呼叫 request_mem_region() 來防止其他驅動程式存取特定的暫存器群。但為了讓 touchscreen driver 也能夠存取暫存器,adc driver 允許 touchscreen driver 映射該區塊,於是變成兩個驅動程式存取同一組暫存器群的局面。我是不知道其他人怎麼想,但我就是覺得很怪,其中一部分程式碼若不小心更新了不該更新的暫存器,那是有可能會影響到另一個驅動程式的運作,造成潛在的錯誤。
也許以後會有所改變吧,不過,誰知道呢 :)
2009年4月3日 星期五
S3C24xx ADC driver
上個月花了相當多的時間在研究 S3C24xx 的觸控面板控制器和驅動程式,在這邊稍微分享一下心得,並介紹目前在 mainstream kernel 所實做的 ADC driver core。
S3C24xx 的 ADC 控制器共有 8 個 channel,其中有四個 channel 可設定來接收觸控螢幕的訊號,並提供多種轉換模式,例如手動轉換 x 及 y 座標,或是讓控制器自動轉換等等。同時控制器也可偵測觸控筆「按下」或「釋放」的動作。但是需注意的是,同一時間只能有一種模式可以運作;換言之,驅動程式必須適時地在以下三種模式間切換:
除了被用做接收觸控訊號的四個 channel 外,剩下的另外四個則可連接其他的感測器。過去分散於各個專案中的觸控驅動程式 (截至目前尚未整合進入 mainstream),都是直接操作控制器,因而多出的四個 channel 即便接上了裝置,該驅動程式也無法與 touchscreen driver 共存 (不同的 driver 存取同一組暫存器會發生 race condition 的問題)。因此為了讓這些不同裝置的驅動程式能夠共用該控制器,Ben Dooks 在 2.6.28 引入了 ADC driver core (以下簡稱 adc driver),定義了一組介面,讓上層驅動程式能夠透過該介面來使用控制器。
若要使用 adc driver,驅動程式需要定義自己的回呼函式 (callback function),並向它註冊,註冊函式會回傳一個型態為 s3c_adc_client 的指標,其後的函式呼叫則以該指標做為第一個引數。adc driver 內部維護了一個要求佇列來紀錄來自外部的服務需求,並給予觸控有關的需求最高的優先權,以便可即時回應使用者的操作。在運作過程中,adc driver 會不斷地呼叫先前所註冊的 callback 以通知驅動程式處理取樣的數據,次數則可在要求服務時以參數設定。
對觸控驅動程式的開發者來說,adc driver 簡化了一部分複雜的細節,讓開發者透過函式介面來要求服務,而不必操作底層的暫存器。但我必須指出,它只是簡化了「一部分」,並非全部;至於為何,我們留待下一篇文章來探討。
S3C24xx 的 ADC 控制器共有 8 個 channel,其中有四個 channel 可設定來接收觸控螢幕的訊號,並提供多種轉換模式,例如手動轉換 x 及 y 座標,或是讓控制器自動轉換等等。同時控制器也可偵測觸控筆「按下」或「釋放」的動作。但是需注意的是,同一時間只能有一種模式可以運作;換言之,驅動程式必須適時地在以下三種模式間切換:
- 偵測「按下」的動作
- 偵測「釋放」的動作
- 取樣並轉換 x 及 y 座標
除了被用做接收觸控訊號的四個 channel 外,剩下的另外四個則可連接其他的感測器。過去分散於各個專案中的觸控驅動程式 (截至目前尚未整合進入 mainstream),都是直接操作控制器,因而多出的四個 channel 即便接上了裝置,該驅動程式也無法與 touchscreen driver 共存 (不同的 driver 存取同一組暫存器會發生 race condition 的問題)。因此為了讓這些不同裝置的驅動程式能夠共用該控制器,Ben Dooks 在 2.6.28 引入了 ADC driver core (以下簡稱 adc driver),定義了一組介面,讓上層驅動程式能夠透過該介面來使用控制器。
若要使用 adc driver,驅動程式需要定義自己的回呼函式 (callback function),並向它註冊,註冊函式會回傳一個型態為 s3c_adc_client 的指標,其後的函式呼叫則以該指標做為第一個引數。adc driver 內部維護了一個要求佇列來紀錄來自外部的服務需求,並給予觸控有關的需求最高的優先權,以便可即時回應使用者的操作。在運作過程中,adc driver 會不斷地呼叫先前所註冊的 callback 以通知驅動程式處理取樣的數據,次數則可在要求服務時以參數設定。
對觸控驅動程式的開發者來說,adc driver 簡化了一部分複雜的細節,讓開發者透過函式介面來要求服務,而不必操作底層的暫存器。但我必須指出,它只是簡化了「一部分」,並非全部;至於為何,我們留待下一篇文章來探討。
訂閱:
文章 (Atom)