Chinaunix首页 | 论坛 | 博客
  • 博客访问: 301041
  • 博文数量: 47
  • 博客积分: 1411
  • 博客等级: 上尉
  • 技术积分: 500
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-23 09:10
文章分类

全部博文(47)

文章存档

2009年(3)

2008年(4)

2007年(14)

2006年(26)

我的朋友

分类: LINUX

2006-06-18 21:16:50

Sharp Zaurus PDA真的是很强。刷了个2.6.14+opie, 感觉很棒。但刷完后碰到了几个问题。
1)键盘map不对头。由于我买的sl-7500c,是大陆版的,所以键盘相对于日版的750有了不少变化,所以刷入的kernel键盘隐射很乱。
2)LCD刷新频率有问题,总是特别闪。目前还不知道哪里的问题,可能需要研究LCD驱动了。
3)电源管理不稳定。有时能reboot,有时suspend后,触摸屏失效。倒是有点像imx31那个板子。


下午把第一个问题解决了。看了一下kernel对keyboard的隐射机制。目前所知,2.6.14以后的内核能够在启动时动态的从/etc/keymap-2.6.map中更新内核defkeymap。所以我很方便的修改etc下的map配置就ok。
下面简单介绍一下kernel的keyboard map和driver。

内核默认keymap配置文件: $(KSRC)/drivers/char/defkeymap.map
文件内格式比较容易理解,下面是键盘上一个按钮的map entry:
keycode   [code]  =  [mapped kernel code]         [mapped kernel code when shift]
          [alt/control] [alt/control]    keycode    [code] = [mapped kernel code]
          .........
第 一行中[code]是驱动根据扫描码转换后提交给内核的代码,内核通过这行,将[code]隐射到[mapped kernel code], 该隐射代码为一个字符串,在内核中唯一定义,比如:阿拉伯数字1 —— one, @ —— at , = —— numbersign。所以你只要弄清楚keyboard driver中把一个按键的扫描码转成那个code,就可以修改相应code隐射行,然kernel去做隐射。该行最后一项是在shift在被按下时隐射 的kernel code。
第二行是可选的,描述了在按下alt或ctrl,或多个组合功能键时的隐射。所以如果有多个组合,就有多行描述。
理解了这个文件的格式,我们就可以很容易的修改不同设备的按键隐射,当然如果kernel没有从/etc下reload的功能,那么只能重新编译kernel了:-)。

keyboard driver最重要的工作就是把获得的用户按键的扫描码,转换成隐射配置文件中的[code]。当然各个键盘有各自不同的扫描码,所以一般都要维护一个扫描码的隐射表,贴一下zaurus corgi keyscan:
+static unsigned char corgikbd_keycode[NR_SCANCODES] = {
+ 0, /* 0 */
+ 0, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, 0, 0, 0, 0, 0, 0, 0, /* 1-16 */
+ 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, 0, 0, 0, 0, 0, 0, 0, /* 17-32 */
+ KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */
+ CORGI_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */
+ CORGI_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, /* 65-80 */
+ CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0, /* 81-96 */
+ KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0, /* 97-112 */
+ CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0, /* 113-124 */
+ CORGI_HINGE_0, CORGI_HINGE_1, CORGI_HINGE_2 /* 125-127 */
+};
很简单,这个数组就是以扫描码为下标,[code]为元素的一维数组。
驱动的活从interrupt开始,ISR负责调用函数去scan keyboard,通过I/O操作获得按键扫描码,再从数组中去code,最后调用input_report_key向kernel报告按键。
Zaurus的键盘有点像以前接口课上学过的简单键盘,通过逐次扫描每一列,在每一列上再逐次扫描每一行的方式获得按键。这个键盘的数电设计还有点印象。

阅读(2185) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~