Android底層開發之Linux輸入子系統要不要判斷系統休眠狀態上報索引值

來源:互聯網
上載者:User

Android底層開發之Linux輸入子系統要不要判斷系統休眠狀態上報索引值

Android底層開發之Linux輸入子系統要不要判斷系統休眠狀態上報索引值

 

題外話:一個問題研究到最後,那邊記錄文檔的前半部分基本上都是無用的,甚至是錯誤的。重點在最後,前邊僅僅是一些假想推測。

 

在調試一下紅外遙控器input驅動時,直接採用的是一個半成品的驅動在上邊實現的自己的裝置的匹配,但同時遇到了一些關於input輸入子系統的疑惑。

按鍵一般有「按下和抬起」兩個狀態一般使用0和1來分別表示。一般如下方式上報按鍵索引值就可以完成「按下和抬起」兩個狀態的收集。

input_event(ddata->input, EV_KEY, KEY_POWER, 1);

input_sync(ddata->input);

但是最近遇到一個奇怪的問題是核心中的KEY_WAKEUP喚醒索引值使用上述方法上報時,使用者空間只能檢測到狀態0,第二次按鍵時才會有狀態1。這樣導致Android系統不能正常喚醒,需要按兩次才能喚醒系統。

 

目前的解決方案是將之前上報KEY_WAKEUP的地上改為KEY_POWER索引值。但是好奇心引著我弄清楚它們是怎麼回事。

 

經驗出這裡邊上報如下一樣連續上報1/0狀態才可以在使用者空間正常的檢測到1/0狀態。

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 1);

input_sync(ddata->input);

 

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);

input_sync(ddata->input);

 

直覺告訴我可以是由於我對這個兩個api的不瞭解造成的,比較是凡事必有因的。

除了KEY_WAKEUP換個其它索引值試試。結果和KEY_WAKEUPG一樣不能同步,可以推斷出是非POWER按鍵就不行。這可以能所在代碼位置有關係:

}else if ((get_suspend_state())&&(ddata->keycode==KEY_POWER)){

input_event(ddata->input, EV_KEY, KEY_POWER, 1);

input_sync(ddata->input);

}

 

再進一步測試在非PM_SUSPEND_ON電源模式下,所有的按鍵都是如何的。測試結果是所有的非POWER按鍵都出現了按鍵不能同步的問題。但是不能以點概面,使用GPIO串連的物理按鍵並不會有此問題,那麼就排除了input子系統中做了手腳。問題出就出在了Remote control驅動中對的處理。

找出了問題所在了,確實是出在了Remote control驅動中,上報索引值對PM狀態進行了判斷,如果

static void remotectl_timer(unsigned long _data)

if(ddata->press != ddata->pre_press) {

ddata->pre_press = ddata->press = 0;

 

if (get_suspend_state()==0){

//input_event(ddata->input, EV_KEY, ddata->keycode, 1);

//input_sync(ddata->input);

input_event(ddata->input, EV_KEY, ddata->keycode, 0);

input_sync(ddata->input);

}else if ((get_suspend_state())&&(ddata->keycode==KEY_POWER)){

//input_event(ddata->input, EV_KEY, KEY_WAKEUP, 1);

//input_sync(ddata->input);

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);

input_sync(ddata->input);

}

}

將過濾條件去除後,可以和GPIO串連的物理按鍵一樣的效果了,即無論系統處理什麼樣的狀態,休眠或者喚醒狀態都上傳了索引值。同時這也給我帶來了一個疑惑,按鍵驅動中要不要進行suspend狀態判斷,根據Android中的經驗所有的狀態都要上傳的,響應不響應是看上層系統的決定;但是如果對於普通的嵌入式Linux系統就不一定了,如果input子系統在系統休眠的時候上傳了索引值,那麼對應的應用程式層可以就會直接去響應索引值。要使用哪種方法實現,這是一個悖論!結合Android的宏這樣實現了:

diff --git a/drivers/input/remotectl/rkxx_remotectl.c b/drivers/input/remotectl/rkxx_remotectl.c

index db91516..201c5dd 100644

--- a/drivers/input/remotectl/rkxx_remotectl.c

+++ b/drivers/input/remotectl/rkxx_remotectl.c

@@ -306,6 +306,10 @@ static void remotectl_do_something(unsigned long data)

if ((ddata->scanData&0x0ff) == ((~ddata->scanData >> 8)&0x0ff)){

if (remotectl_keycode_lookup(ddata)){

ddata->press = 1;

+#ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state

+ input_event(ddata->input, EV_KEY, ddata->keycode, 1);

+ input_sync(ddata->input);

+#else

if (ddata->keycode==KEY_POWER || get_suspend_state()==PM_SUSPEND_ON){

input_event(ddata->input, EV_KEY, ddata->keycode, 1);

input_sync(ddata->input);

@@ -314,6 +318,7 @@ static void remotectl_do_something(unsigned long data)

}

//input_event(ddata->input, EV_KEY, ddata->keycode, ddata->press);

//input_sync(ddata->input);

+#endif // CONFIG_ANDROID

ddata->state = RMC_SEQUENCE;

}else{

ddata->state = RMC_PRELOAD;

@@ -437,6 +442,10 @@ static void remotectl_timer(unsigned long _data)

if(ddata->press != ddata->pre_press) {

ddata->pre_press = ddata->press = 0;

 

+#ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state

+ input_event(ddata->input, EV_KEY, ddata->keycode, 0);

+ input_sync(ddata->input);

+#else

if (get_suspend_state()==0){

//input_event(ddata->input, EV_KEY, ddata->keycode, 1);

//input_sync(ddata->input);

@@ -448,6 +457,7 @@ static void remotectl_timer(unsigned long _data)

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);

input_sync(ddata->input);

}

+#endif // CONFIG_ANDROID

}

#ifdef CONFIG_PM

remotectl_wakeup(_data);

如果是Android系統,那麼無論kernel處理什麼樣的休眠狀態都即時地上報索引值。這樣保證在休眠播放音樂的時候可以控制音頻大小。這也正是目前Android手機的實現方式

 

 

還有一點:按鍵中的狀0,並不是input_sync(ddata->input);發出的,它只會發出當前的值。它僅僅是一個「同步」,意思是資料都準備好了,可以發送了。還是沒有對驅動瞭解的很清楚加上自己的一些瞎想像誤導了自己。核心input驅動中是不區分POWER鍵,WAKEUP鍵;真是有差異了,問題一定是出在了自己的驅動代碼中。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.